Reading from EEPROM to System variable

cpedw

Senior Member
I can't read a WORD variable from EEPROM as 2 bytes into s_w1 but w1 works fine:
Code:
' TestInternalStorage

#picaxe 14M2

#TERMINAL 4800

Symbol JDN        = s_w1    ' 
'Symbol JDN        = w1    ' 
Symbol addrs     = b26    ' EEPROM read/write address 

    addrs = 0
    READ addrs,  WORD JDN
    sertxd(#JDN,cr,lf)

EEPROM 0,  ( 3, 2)
Incidentally, there isn't a version of EEPROM that goes something like
Code:
EEPROM address, ( WORD wordvariable)
is there?
 

cpedw

Senior Member
Paradoxically, reading a word into s_w1 works after writing the eeprom:
Code:
' TestInternalStorage

#picaxe 14M2

#TERMINAL 4800

Symbol JDN2       = s_w1
Symbol JDN        = w1
Symbol addrs     = b26    ' EEPROM read/write address

    addrs = 0
    READ addrs,  WORD JDN
    sertxd(#JDN,cr,lf)

    addrs = 10
    WRITE addrs,  WORD JDN
    READ addrs,  WORD JDN2
    sertxd(#JDN,cr,lf)
EEPROM 0,  ( 3, 2)
This and the previous post results are all run in the simulator.

Edit: It works fine in a 14M2 so I think it's just a simulator issue.
 
Last edited:

Jack Burns

New Member
Should that have said “sertxd(#JDN2,cr,lf)” in the following code section?
Code:
addrs = 10
    WRITE addrs,  WORD JDN
    READ addrs,  WORD JDN2
    sertxd(#JDN,cr,lf)
 

inglewoodpete

Senior Member
It works fine in a 14M2 so I think it's just a simulator issue.
That is the reason why I use the simulator very rarely. There is nothing safer than using the actual chip for code development. It is often difficult to simulate every "feature" of the chip's hardware and peripherals.

I occasionally use the simulator for developing purely mathematical algorithms but that is all.
 

AllyCat

Senior Member
Hi,

It's the WORD qualifier that I rarely use, because it's not a "real" (interpreter tokenised) command, but an internal MACRO created by the Program Editor. Sometimes these Macros are a convenience, but they may create larger and slower Program Code than a "Do It Yourself" block. In this case, the efficient "DIY" version of READ location , WORD w1 is READ location , b2 : READ location+1 , b3 (NOT READ location , b2 , b3) , because the PE Macro is effectively READ location , b2 : INC location : READ location , b3 : DEC location (since you "expect" the value of the location to be unchanged by the command). A Syntax check shows that the code generated is larger (and thus execution will take longer).
Code:
symbol location = b0
symbol location1 = b1
READ location , WORD w1                                                     ; Adds ~10 bytes to Program
READ location , b2 , b3                                                     ; Adds ~10 bytes
READ location , b2 : READ location1, b3                                     ; Adds ~6 bytes
READ location , b2 : INC location : READ location , b3 : DEC location       ; Adds ~10 bytes
A further complication here is that the System Words (S_Wn) do not have a "byte" equivalent (just as most M2 bytes cannot be accessed as separate bits); so I don't know what is the equivalent "Macro" expansion, but I have observed other bugs in the Simulator when mixing byte variables with the System Words, in a calculation. :(

Cheers, Alan.
 

cpedw

Senior Member
Should that have said “sertxd(#JDN2,cr,lf)” in the following code section?
Code:
addrs = 10
    WRITE addrs,  WORD JDN
    READ addrs,  WORD JDN2
    sertxd(#JDN,cr,lf)
No but there is a mistake in my post 2. It should be:
Code:
' TestInternalStorage

#picaxe 14M2

#TERMINAL 4800

Symbol JDN       = s_w1
'Symbol JDN        = w1
Symbol addrs     = b26    ' EEPROM read/write address

    addrs = 0
    READ addrs,  WORD JDN
    sertxd(#JDN,cr,lf)

    addrs = 10
    WRITE addrs,  WORD JDN
    READ addrs,  WORD JDN
    sertxd(#JDN,cr,lf)
EEPROM 0,  ( 3, 2)
which shows that s_w1 isn't simulated correctly. Changing to w1 works fine. Both work OK in silicon.

An interesting revelation by Allycat but as I'm running out of variables but still got code space available, it doesn't help in this case.
 

Aries

New Member
I've just run your code through the simulator (PE6) and got this as output:
Code:
3
3
Am I missing something?
 

hippy

Technical Support
Staff member
It works fine in a 14M2 so I think it's just a simulator issue
Yes, it does appear to be a simulator issue. I haven't investigated fully but it appears to work with "s_w0" but not with "s_w1" though "s_w7". I will pass the details on.

I would guess testing wasn't as comprehensive as it might have been. One of the problems is there is so much that it is not easy to test everything exhaustively and an issue with a more obscure operation may not be detected than for a more commonly used one. Please accept our apologies if that has been the case.
 

hippy

Technical Support
Staff member
Incidentally, there isn't a version of EEPROM that goes something like
Code:
EEPROM address, ( WORD wordvariable)
is there?
No. You cannot use variables in an EEPROM command because EEPROM values are specified at compilation time, rather than run time.

EEPROM only accepts byte values, truncates numbers greater than 8-bits. If you do want to preload EEPROM with a word value you can use something like -
Code:
Symbol NUMBER = 513
Symbol MSB    = NUMBER /  256
Symbol LSB    = NUMBER // 256

Eeprom 0, (LSB, MSB)

Do
  Read 0, WORD w0
  SerTxd("Got ", #w0, CR, LF)
Loop
 

hippy

Technical Support
Staff member
It works fine in a 14M2 so I think it's just a simulator issue.
If one copies the "picaxe14m2.exe" file from -

C:\Program Files (x86)\Revolution Education\PICAXE Editor\Compilers-beta

to

C:\Program Files (x86)\Revolution Education\PICAXE Editor\Compilers

That should hopefully resolve the simulation issue. Does for me -
Code:
#Picaxe 14M2
#Terminal 4800

w0 = $0201 ; 513 = $02 * 256 + $01
Write 0, WORD w0

Do
  Read 0, WORD s_w1
  SerTxd("Got ", #s_w1, CR, LF)
Loop
 

cpedw

Senior Member
No. You cannot use variables in an EEPROM command because EEPROM values are specified at compilation time, rather than run time.

EEPROM only accepts byte values, truncates numbers greater than 8-bits. If you do want to preload EEPROM with a word value you can use something like -
Code:
Symbol NUMBER = 513
Symbol MSB    = NUMBER /  256
Symbol LSB    = NUMBER // 256

Eeprom 0, (LSB, MSB)

Do
  Read 0, WORD w0
  SerTxd("Got ", #w0, CR, LF)
Loop
Sorry, I meant WORD constant not variable.

But that's a nifty workaround to save me converting words to bytes.
 

AllyCat

Senior Member
Hi,
....a nifty workaround to save me converting words to bytes.
Code:
Symbol NUMBER = 513
Symbol MSB    = NUMBER /  256
Symbol LSB    = NUMBER // 256
Eeprom 0, (LSB, MSB)
Sometimes I have a large number of Word variables to enter, so the trick I use is to write the whole word value for the Low byte (which the PE automatically strips down to a single byte) and then calculate the High byte "by inspection" or with a pocket calculator/phone. For example : EEPROM 513 , 2 , 12345 , 48 , etc..... is still quite "obvious" when reading the program again later.

Cheers, Alan.
 

hippy

Technical Support
Staff member
One trick for handling a lot of word constants is to use a "." as part of the constant's name -
Code:
Symbol FREQ     = 1234
Symbol FREQ.MSB = FREQ /  256
Symbol FREQ.LSB = FREQ // 256
It doesn't have to be "." but I find that convenient.

One can also use #define to simplify things, reduce typing. But "MSB" and "LSB" appear to be predefined keywords and cause syntax check errors so one cannot use those -
Code:
#define xMSB(num) num /  256
#define xLSB(num) num // 256

Symbol FREQ     = 1234
Symbol FREQ.MSB = xMSB(FREQ)
Symbol FREQ.LSB = xLSB(FREQ)
Or one could use a #macro -
Code:
#Macro WordConstant(nam, namMsb, namLsb, num)
  Symbol nam    = num
  Symbol namMsb = num /  256
  Symbol namLsb = num // 256
#EndMacro

WordConstant(FREQ, FREQ.MSB, FREQ.LSB, 1234)
 
Top