News:

;) This forum is the property of Proton software developers

Main Menu

Edata issues on 18F27K42

Started by JohnB, Aug 01, 2022, 03:11 PM

Previous topic - Next topic

JohnB

At the top of my program I have
  EDATA 1,9,270
On startup up I read the EEPROM

  FilterMode = Eread 0
  FilterOnTime = ERead 1
  TargetPoolTemp = ERead 2

  HrsOut Dec FilterMode ,$D
  HrsOut Dec FilterOnTime, $D
  HRSOut Dec TargetPoolTemp, $D
  HrsOut Dec TargetPoolTemp.lowbyte ,$D
  HrsOut Dec TargetPoolTemp.Highbyte,$D

This is the result
  14
  255
  65282
  2
  255


Any idea what is going on?


JohnB

John Lawton

You haven't shown your variable definitions, are FilterMode and FilterOnTime both bytes and TargetPoolTemp a word?

JohnB

Yes only the TargetPoolTemp is a Word
JohnB

Pepe

the hexadecimal number ff02 (255 02) is 65282 in decimal

trastikata

I was looking through the assembler code generated for this device when using the EEPROM - I am not sure but shouldn't the value passed to NVMADRLH be 0x31 instead of 0x39?

tumbleweed

#5
Quote from: trastikata on Aug 01, 2022, 08:55 PMshouldn't the value passed to NVMADRLH be 0x31 instead of 0x39?
If I'm looking at the same basic results as you, it's not setting NVMADRLH=0x39, it's setting the BSR=0x39 (movlb 0x39), which is the proper bank for the NVM registers.

I compiled the following, and I didn't notice an issue with the EDATA statement or the three EREADs either...
Device = 18F27K42
Xtal = 64

Dim FilterMode As Byte
Dim FilterOnTime As Byte
Dim TargetPoolTemp As Word

EData 1,9,270

FilterMode = ERead 0
FilterOnTime = ERead 1
TargetPoolTemp = ERead 2


keytapper

Quote from: JohnB on Aug 01, 2022, 04:00 PMYes only the TargetPoolTemp is a Word
Hence you should define as Word 270, for you Edata line. I read that on page 375 of the manual (3rd page of Cdata explanation)
Ignorance comes with a cost

JohnB

Here is a complete demo of issue...

  EData 1,9,270,2,74,72,70

  Device = 18F27K42
  Xtal = 64                                ' using pll at full speed (62.5nS/instruction)

  Declare Optimiser_Level = 3
  Declare Dead_Code_Remove = On

  $define true 1
  $define false 0

  Declare Bootloader = 0

  Declare HRSout_Pin = PORTC.6
  Declare HRsin_Pin = PORTC.7
  Declare Hserial_Baud = 115200            ' Set baud rate to 115200
  Declare Hserial_RCSTA = %10010000        ' Enable serial port and continuous receive
  Declare Hserial_TXSTA = %00100100        ' Enable transmit and asynchronous mode
  Declare Hserial_Clear = On               ' Enable Error clearing on received characters      ' Clear the buffer before receiving

  Declare HRSout2_Pin = PORTC.4
  Declare HRSin2_Pin = PORTC.5
  Declare Hserial2_Baud = 115200           ' Set baud rate to 115200
  Declare Hserial2_RCSTA = %10010000       ' Enable serial port and continuous receive
  Declare Hserial2_TXSTA = %00100100       ' Enable transmit and asynchronous mode
  Declare Hserial2_Clear = On              ' Enable Error clearing on received characters      ' Clear the buffer before receiving
  Declare HSerial1_Terminator = CRLF

  Declare SDA_Pin = PortB.0
  Declare Scl_Pin = PortB.1

  Declare Access_Upper_64K = True          ' Set the compiler to see all 128K of flash memory

  Symbol BUFFER_SIZE = 256

  Dim AirTemperature AS Word
  DIm PoolTemperature As Word
  Dim TargetPoolTemp As Word
  Dim HeatDemand As byte      ; True when target temp < Pool Temp
  Dim FilterMode as Byte      ' 0=off, 1=Auto, 2=Manual
  dim FilterOnTime As byte    ' 6-24Hrs
  Dim HeatingEnabled As Byte  ' True/false
  Dim Hysterisis AS byte      ' Hysterisis applied to temperature control
  Dim PHMaxVal As byte        ' Alarm  upper limit
  Dim PHMinVal As Byte        ' Alarm Lower Limit
  Dim RedoxVal AS Byte        ' Alarm sterilsation

  GoTo Start

  proc GetSavedInfo()
    FilterMode = Eread 0
    FilterOnTime = ERead 1
    TargetPoolTemp = ERead 2
    Hysterisis = ERead 4
    PhMaxval = ERead 5
    PhMinval = ERead 6
    RedoxVal = eread 7
    HeatingEnabled = FilterMode.7
    FIlterMode.7 = 0
    HrsOut Dec FilterMode ,$D
    HrsOut Dec FilterOnTime, $D
    HRSOut Dec TargetPoolTemp, $D
    HrsOut Dec Hysterisis ,$D
    HrsOut Dec phMaxVAl,$D
    HrsOut Dec PHMinVal, $D
    HRSOut Dec RedoxVal, $D
  endproc

  Proc SaveInfo()
    FilterMode.7=HeatingEnabled
    EWrite 0,FilterMode,filterOnTime,TargetPoolTemp,Hysterisis,PHMaxVal,phMinVal,RedoxVal
    FilterMode.7=0
  endproc

  Start:

  GetSavedInfo()

This is the output:

1
255
65282
2
255
72
255


Am I doing something wrong or is there an issue?





JohnB

JohnB

#8
I think some of the problem has been with the TinyBootloader I am using. It doesn't seem to program the EEPROM on this device.
I am not sure about the save to eeprom but I am now happy it is reading correctly the eeprom.

Edit - it was down to TinyBootloader overwriting the Eeprom  - I have now switched of eeprom write
JohnB

keytapper

Better you write your first line as follow:
EData 1,9, Word 270,2,74,72,70
Ignorance comes with a cost

top204

Just as a mind settler for both myself and you John, I have created the test program below that writes and reads the on-board EEPROM on PIC18FxxK42 devices. It has been physically tested on one of my Positron8 boards that use a PIC18F27K42 device operating at 64MHz. It writes differing bit sized values to on-board EEPROM and reads them back from on-board EEPROM and transmits them to a serial terminal at 9600 Baud:

'
'   /\\\\\\\\\
'  /\\\///////\\\
'  \/\\\     \/\\\                                                 /\\\          /\\\
'   \/\\\\\\\\\\\/        /\\\\\     /\\\\\\\\\\     /\\\\\\\\   /\\\\\\\\\\\  /\\\\\\\\\\\  /\\\\\\\\\
'    \/\\\//////\\\      /\\\///\\\  \/\\\//////    /\\\/////\\\ \////\\\////  \////\\\////  \////////\\\
'     \/\\\    \//\\\    /\\\  \//\\\ \/\\\\\\\\\\  /\\\\\\\\\\\     \/\\\         \/\\\        /\\\\\\\\\\
'      \/\\\     \//\\\  \//\\\  /\\\  \////////\\\ \//\\///////      \/\\\ /\\     \/\\\ /\\   /\\\/////\\\
'       \/\\\      \//\\\  \///\\\\\/    /\\\\\\\\\\  \//\\\\\\\\\\    \//\\\\\      \//\\\\\   \//\\\\\\\\/\\
'        \///        \///     \/////     \//////////    \//////////      \/////        \/////     \////////\//
'                                  Let's find out together what makes a PIC Tick!
'
' Test Writing and Reading to/from on-board EEPROM on a PIC18FxxK42 device
' Writes differing sized values to EEPROM, then reads them back and transmits what was read on a serial terminal
'
' Written for the Positron8 BASIC compiler by Les Johnson
'
    Device = 18F47K42                                   ' Tell the compiler what device to compile for
    Declare Xtal = 64                                   ' Tell the compiler what frequency the device is operating at
    Declare Float_Display_Type = Fast                   ' Enable the faster and more accurate Float to ASCII converter
'
' Setup USART1
'
    Declare Hserial1_Baud = 9600                        ' The Baud rate for USART1
    Declare HRSOut1_Pin   = PORTC.6                     ' The pin to use for USART1
'
' Create some variables
'
    Dim MyByte  As Byte
    Dim MyWord  As Word
    Dim MyDword As Dword
    Dim MyFloat As Float
   
    Dim EEPROM_bOffset As Byte                          ' Holds the offset of the EEPROM data
    Dim Flash_bOffset  As Byte                          ' Holds the offset of the flash memory data     
'
' Create Flash memory data of differing bit sizes
'
    Dim Fl_Data8  As Flash8  = 20, 21, 22, 23, 24, 25, 26, 27, 28
    Dim Fl_Data16 As Flash16 = 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
    Dim Fl_Data32 As Flash32 = 20000000, 20000001, 20000002, 20000003, 20000004, 20000005, 20000006, 20000007, 20000008
    Dim Fl_DataF  As FlashF  = 0.2, 1.2, 2.2, 3.2, 4.2, 5.2, 6.2, 7.2, 8.2
'
' Create EEPROM data of differing bit sizes
'
EE_Data8  EData As Byte  0, 1, 2, 3, 4, 5, 6, 7, 8
EE_Data16 EData As Word  1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008
EE_Data32 EData As Dword 10000000, 10000001, 10000002, 10000003, 10000004, 10000005, 10000006, 10000007, 10000008
EE_DataF  EData As Float 0.1, 1.1, 2.1, 3.1, 4.1, 5.1, 6.1, 7.1, 8.1

'---------------------------------------------------------------------------------------
' The main program starts here
' Write to on-board EEPROM and then read it and transmit what was read to a serial terminal
'
Main:
    EEPROM_Erase()                                      ' Erase all on-board EEPROM   
    EEPROM_WriteTest()                                  ' Write differing values to EEPROM
    EEPROM_ReadTest()                                   ' Read what was written to EEPROM and transmit it
 
'---------------------------------------------------------------------------------------
' Write EEPROM data in different bit-sized values
' Input     : None
' Output    : None
' Notes     : None
'
Proc EEPROM_WriteTest()
    HRSOut1Ln "Writing 8-bit Data"
    EEPROM_bOffset = EE_Data8                           ' Load the EEPROM offset with the EE_Data8 position
    For EEPROM_bOffset = 0 To 8                         ' Create a loop to read from flash and write to EEPROM
        MyByte = CRead8 Fl_Data8[EEPROM_bOffset]        ' Read the 8-bit data from flash memory
        EWrite EEPROM_bOffset, [MyByte]                 ' Write the 8-bit data to EEPROM
    Next                                                ' Close the loop
   
    HRSOut1Ln "Writing 16-bit Data"
    EEPROM_bOffset = EE_Data16                          ' Load the EEPROM offset with the EE_Data16 position
    For Flash_bOffset = 0 To 8                          ' Create a loop to read from flash and write to EEPROM
        MyWord = CRead16 Fl_Data16[Flash_bOffset]       ' Read the 16-bit data from flash memory
        EWrite EEPROM_bOffset, [MyWord]                 ' Write the 16-bit data to EEPROM
        EEPROM_bOffset = EEPROM_bOffset + 2             ' Increment the EEPROM offset by 2 because a 16-bit value takes 2 bytes
    Next                                                ' Close the loop
   
    HRSOut1Ln "Writing 32-bit Data"
    EEPROM_bOffset = EE_Data32                          ' Load the EEPROM offset with the EE_Data32 position
    For Flash_bOffset = 0 To 8                          ' Create a loop to read from flash and write to EEPROM
        MyDword = CRead32 Fl_Data32[Flash_bOffset]      ' Read the 32-bit data from flash memory
        EWrite EEPROM_bOffset, [MyDword]                ' Write the 32-bit data to EEPROM
        EEPROM_bOffset = EEPROM_bOffset + 4             ' Increment the EEPROM offset by 4 because a 32-bit value takes 4 bytes
    Next                                                ' Close the loop
   
    HRSOut1Ln "Writing Float Data"
    EEPROM_bOffset = EE_DataF                           ' Load the EEPROM offset with the EE_DataF position
    For Flash_bOffset = 0 To 8                          ' Create a loop to read from flash and write to EEPROM
        MyFloat = CRead32 Fl_DataF[Flash_bOffset]       ' Read the 32-bit data from flash memory
        EWrite EEPROM_bOffset, [MyFloat]                ' Write the 32-bit data to EEPROM
        EEPROM_bOffset = EEPROM_bOffset + 4             ' Increment the EEPROM offset by 4 because a 32-bit Float value takes 4 bytes
    Next                                                ' Close the loop
EndProc

'---------------------------------------------------------------------------------------
' Read EEPROM data in different bit-sized values
' Input     : None
' Output    : None
' Notes     : The data read is transmitted to a serial terminal
'
Proc EEPROM_ReadTest()
    HRSOut1Ln "\rRead 8-bit Data"
    For EEPROM_bOffset = 0 To 8                         ' Create a loop to read from EEPROM
        MyByte = ERead EE_Data8 + EEPROM_bOffset        ' Read the 8-bit data from EEPROM
        HRSOut1Ln "Offset ", Dec2 EEPROM_bOffset, " contains ", Dec MyByte ' Transmit what was read to a serial terminal
    Next                                                ' Close the loop
   
    HRSOut1Ln "\rRead 16-bit Data"
    For EEPROM_bOffset = 0 To 16 Step 2                 ' Create a loop to read from EEPROM with an increment of 2 for 16-bit reads
        MyWord = ERead EE_Data16 + EEPROM_bOffset       ' Read the 16-bit data from EEPROM
        HRSOut1Ln "Offset ", Dec2 EEPROM_bOffset, " contains ", Dec MyWord  ' Transmit what was read to a serial terminal
    Next                                                ' Close the loop

    HRSOut1Ln "\rRead 32-bit Data"
    For EEPROM_bOffset = 0 To 32 Step 4                 ' Create a loop to read from EEPROM with an increment of 4 for 32-bit reads
        MyDword = ERead EE_Data32 + EEPROM_bOffset      ' Read the 32-bit data from EEPROM
        HRSOut1Ln "Offset ", Dec2 EEPROM_bOffset, " contains ", Dec MyDword ' Transmit what was read to a serial terminal
    Next                                                ' Close the loop
   
    HRSOut1Ln "\rRead Float Data"
    For EEPROM_bOffset = 0 To 32 Step 4                 ' Create a loop to read from EEPROM with an increment of 4 for 32-bit reads
        MyFloat = ERead EE_DataF + EEPROM_bOffset       ' Read the 32-bit data from EEPROM
        HRSOut1Ln "Offset ", Dec2 EEPROM_bOffset, " contains ", Dec1 MyFloat ' Transmit what was read to a serial terminal
    Next                                                ' Close the loop
EndProc
 
'---------------------------------------------------------------------------------------
' Erase the on-board EEPROM
' Input     : None
' Output    : None
' Notes     : Does not erase an EEPROM element if it does not need too
'
Proc EEPROM_Erase()
    Dim wCount As Word
    Dim bValue As Byte
   
    HRSOut1Ln "Erasing EEPROM"
    For wCount = (_eeprom - 1) DownTo 0                 ' Create a loop for the amount of EEPROM on the device
        bValue = ERead wCount                           ' Read an 8-bit value from EEPROM
        If bValue <> $FF Then                           ' Does the EEPROM position already contain a value of 255?
            EWrite wCount,[$FF]                         ' No. So write a value of 255 to its position
        EndIf
    Next                                                ' Close the loop
EndProc
 
'---------------------------------------------------------------------------------------
' Setup for internal oscillator operating at 64MHz on a PIC18F27K42 device
'
Config_Start
    RSTOSC = HFINTOSC_64MHZ ' HFINTOSC with HFFRQ = 64 MHz and CDIV = 1:1
    FEXTOSC = Off           ' HS off
    WDTE = Off              ' WDT Disabled. SWDTEN is ignored
    CLKOUTEN = Off          ' CLKOUT function is disabled
    PR1WAY = Off            ' PRLOCK bit can be set and cleared repeatedly
    CSWEN = On              ' Writing to NOSC and NDIV is allowed
    Debug = Off             ' Background debugger disabled
    FCMEN = Off             ' Fail-Safe Clock Monitor disabled
    MCLRE = EXTMCLR         ' If LVP = 0, MCLR pin is MCLR' If LVP = 1, RE3 pin function is MCLR
    PWRTS = PWRT_Off        ' PWRT is disabled
    MVECEN = Off            ' Interrupt contoller does not use vector table to prioritise interrupts
    IVT1WAY = Off           ' IVTLOCK bit can be cleared and set repeatedly
    LPBOREN = Off           ' ULPBOR disabled
    BOREN = Off             ' Brown-out Reset disabled
    BORV = VBOR_2P45        ' Brown-out Reset Voltage (VBOR) set to 2.45V
    ZCD = Off               ' ZCD disabled. ZCD can be enabled by setting the ZCDSEN bit of ZCDCON
    PPS1WAY = Off           ' PPSLOCK bit can be set and cleared repeatedly (subject to the unlock sequence)
    STVREN = Off            ' Stack full/underflow will not cause Reset
    XINST = Off             ' Extended Instruction Set and Indexed Addressing Mode disabled
    WDTCPS = WDTCPS_2       ' Divider ratio 1:128
    WDTCWS = WDTCWS_0       ' window delay = 87.5. no software control' keyed access required
    WDTCCS = LFINTOSC       ' WDT reference clock is the 31.0 kHz LFINTOSC
    BBSIZE = BBSIZE_1024    ' Boot Block size is 1024 words
    BBEN = Off              ' Boot block disabled
    SAFEN = Off             ' SAF disabled
    WRTAPP = Off            ' Application Block not write protected
    WRTB = Off              ' Configuration registers (300000-30000Bh) not write-protected
    WRTC = Off              ' Boot Block (000000-0007FFh) not write-protected
    WRTD = Off              ' Data EEPROM not write-protected
    WRTSAF = Off            ' SAF not Write Protected
    LVP = Off               ' HV on MCLR/VPP must be used for programming
    Cp = Off                ' PFM and Data EEPROM code protection disabled
Config_End

On the serial terminal, it will display:
Erasing EEPROM
Writing 8-bit Data
Writing 16-bit Data
Writing 32-bit Data
Writing Float Data

Read 8-bit Data
Offset 00 contains 20
Offset 01 contains 21
Offset 02 contains 22
Offset 03 contains 23
Offset 04 contains 24
Offset 05 contains 25
Offset 06 contains 26
Offset 07 contains 27
Offset 08 contains 28

Read 16-bit Data
Offset 00 contains 2000
Offset 02 contains 2001
Offset 04 contains 2002
Offset 06 contains 2003
Offset 08 contains 2004
Offset 10 contains 2005
Offset 12 contains 2006
Offset 14 contains 2007
Offset 16 contains 2008

Read 32-bit Data
Offset 00 contains 20000000
Offset 04 contains 20000001
Offset 08 contains 20000002
Offset 12 contains 20000003
Offset 16 contains 20000004
Offset 20 contains 20000005
Offset 24 contains 20000006
Offset 28 contains 20000007
Offset 32 contains 20000008

Read Float Data
Offset 00 contains 0.2
Offset 04 contains 1.2
Offset 08 contains 2.2
Offset 12 contains 3.2
Offset 16 contains 4.2
Offset 20 contains 5.2
Offset 24 contains 6.2
Offset 28 contains 7.2
Offset 32 contains 8.2


To test if the bootloader is writing to EEPROM, just use the EEPROM_ReadTest() procedure in the main program, so it reads the Edata values that are in the program, and it should display:

Read 8-bit Data
Offset 00 contains 0
Offset 01 contains 1
Offset 02 contains 2
Offset 03 contains 3
Offset 04 contains 4
Offset 05 contains 5
Offset 06 contains 6
Offset 07 contains 7
Offset 08 contains 8

Read 16-bit Data
Offset 00 contains 1000
Offset 02 contains 1001
Offset 04 contains 1002
Offset 06 contains 1003
Offset 08 contains 1004
Offset 10 contains 1005
Offset 12 contains 1006
Offset 14 contains 1007
Offset 16 contains 1008

Read 32-bit Data
Offset 00 contains 10000000
Offset 04 contains 10000001
Offset 08 contains 10000002
Offset 12 contains 10000003
Offset 16 contains 10000004
Offset 20 contains 10000005
Offset 24 contains 10000006
Offset 28 contains 10000007
Offset 32 contains 10000008

Read Float Data
Offset 00 contains 0.1
Offset 04 contains 1.1
Offset 08 contains 2.1
Offset 12 contains 3.1
Offset 16 contains 4.1
Offset 20 contains 5.1
Offset 24 contains 6.1
Offset 28 contains 7.1
Offset 32 contains 8.1


My mantra in life has always been K.I.S.S, wherever and whenever possible, and "never" second guess. :-)

In your original post John, I would lay out the EEPROM data so it is more clear to read and easier to maintain. For example:

    Dim bFilterMode     As Byte
    Dim bFilterOnTime   As Byte
    Dim wTargetPoolTemp As Word
'
' Create EEPROM data
'   
EE_FilterMode     EData Byte 1
EE_FilterOnTime   EData Byte 9
EE_TargetPoolTemp EData Word 270

    bFilterMode     = ERead EE_FilterMode
    bFilterOnTime   = ERead EE_FilterOnTime
    wTargetPoolTemp = ERead EE_TargetPoolTemp

The above method gives a meaning to each piece of EEPROM data and guarantees their value sizes. So even if "EE_TargetPoolTemp" has an 8-bit value placed into it, it will still occupy two bytes in EEPROM, so the offsets will remain the same. In a non-formatted Edata table, the compiler reads the size of the constant value and places its seperate bytes in EEPROM (1 byte for 8-bit, 2 bytes for 16-bit, 4 bytes for 32-bit etc). So if a smaller value is placed in a slot that originally had a larger value in it within and Edata table, all the offsets of the other EEPROM elements after it change as well.

Notice the preceding characters to variable names (b and w) and to the EEPROM offset texts (EE_)? This shows in the main block of code what a variable's size is, and that a piece of text as a parameter is an EData element. It makes code writing and reading a lot easier because it takes the guesswork out of it when using the tighter flash and RAM restrictions of microcontrollers.

I always use:

"t" for a Bit variable (short for Tetra)
"b" for a Byte variable
"m" for a Pin variable (short for a pin "mask")
"w" for a Word variable
"l" for a Long variable
"d" for a Dword variable
"f" for a Float variable
"s" for a String variable
"c" for a Constant value or Constant alias
etc...

Also remember, EData tables do not take up any flash memory, so you could have seperate EData tables filled with 1024 values and it will not take any more code or time from the device, because they are placed as assembler constant directives in the EEPROM address.


JohnB

Thanks Les  I haven't been too fussy about commenting and readability, I was just trying to get to grips with the mechanisms and work put how to test things when I don't have an ICD to hand.  Im getting there slowly and appreciate all the help I have had from the forum
JohnB

JonW

Just seen this post, I had the same issue John and ran a similar test like Les has done. Think I may write a new bootloader at some point, tiny bootloader works but I have seen odd behavior at times and if you mess about with the boot settings it can mash the whole config so make sure you make a copy of the tiny configs!.  I generally just flash the IC direct via ICSP now to make sure and hence why I added the ICSP to the dev boards you have.