Shop OBEX P1 Docs P2 Docs Learn Events
Storing Data in Propeller Boot EEPROM — Parallax Forums

Storing Data in Propeller Boot EEPROM

BeanBean Posts: 8,129
edited 2008-01-09 12:14 in Propeller 1
If I have a program that doesn't use all of the 32K program space, can I store data in the upper end of the 32K EEPROM ?

I need about 1K on the Propeller demo board.

Can I just use the last 1K ?
Does the propeller have any checksum or anthing that will get screwed up ?
Does it store the program starting at address 0 ?


Here is the code I'm trying (Uses the i2cObject)

[noparse][[/noparse]edit] I have posted working code further down...
  I2C.Init(29, 28, TRUE) ' Use Propeller Demo Board EEPROM
  I2C.Start
 
  I2C.i2cStart
  I2C.i2cWrite($A0, 8)
  I2C.i2cWrite(124, 8)
  I2C.i2cWrite(0, 8)
  I2C.i2cWrite("H", 8)
  I2C.i2cWrite("E", 8)
  I2C.i2cWrite("L", 8)
  I2C.i2cWrite("L", 8)
  I2C.i2cWrite("O", 8)
  I2C.i2cStop
  WAITCNT(4000000 + cnt)  
 
  I2C.i2cStart
  I2C.i2cWrite($A0, 8)
  I2C.i2cWrite(124, 8)
  I2C.i2cWrite(0, 8)
  I2C.i2cStart
  I2C.i2cWrite($A1, 8)
  Overlay.PutChar(I2C.i2CRead(1))
  Overlay.PutChar(I2C.i2CRead(1))
  Overlay.PutChar(I2C.i2CRead(1))
  Overlay.PutChar(I2C.i2CRead(1))
  Overlay.PutChar(I2C.i2CRead(1))
  I2C.i2cStop



Bean.
·

▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Cheap used 4-digit LED display with driver IC·www.hc4led.com

Low power SD Data Logger www.sddatalogger.com
SX-Video Display Modules www.sxvm.com
Stuff I'm selling on ebay http://search.ebay.com/_W0QQsassZhittconsultingQQhtZ-1

"USA Today has come out with a new survey - apparently, three out of every four people make up 75% of the population." - David Letterman

Post Edited (Bean (Hitt Consulting)) : 12/30/2006 5:25:22 PM GMT

Comments

  • Mike GreenMike Green Posts: 23,101
    edited 2006-12-28 21:51
    Bean,
    Your basic concept is fine. The bootloader doesn't care what's beyond the end of your program in EEPROM. When you download a new program via the Propeller Tool and ask for it to be written to EEPROM, the whole 32K gets written and your saved data will get erased.

    Your posted code doesn't wait for the data to be written to EEPROM before trying to write again. The EEPROM will not respond for about 5ms. Unless you use a paged write (depends on the EEPROM, but a 32 byte page size will usually work) to a page boundary and only one address select at the beginning of the page, then up to a page's worth of data, then a stop sequence. This will result in only one write cycle for the whole thing.

    Easiest thing to do is just insert a 5ms delay after each byte written.

    The program is loaded starting at EEPROM location zero and the checksum is only through the end of the program (and a few bytes beyond to the start of the stack space).

    Use the "readLocation" and "writeLocation" routines in the I2C object. There's also a "writePage" routine. They do the start/address/data/stop stuff for you and are in the current version of the I2C object (1.4 or later). There's also a "devicePresent" routine that you can use instead of waiting for a write to finish. The EEPROM will appear as "present" when it's finished with the write cycle.
    Mike
  • BeanBean Posts: 8,129
    edited 2006-12-29 00:21
    Mike,
    I downloaded version 1.3 from Parallax website. I can't seem to find 1.4 in the forums ???

    Anyway, I'm still not having any luck.

    I changed the code to this:

      I2C.Init(29, 28, TRUE) ' Use Propeller Demo Board EEPROM
      I2C.Start
     
      I2C.WriteLocation($A0, 31744, "H", 16, 8) 
      WAITCNT(4000000 + cnt)
      I2C.WriteLocation($A0, 31745, "E", 16, 8) 
      WAITCNT(4000000 + cnt)
      I2C.WriteLocation($A0, 31746, "L", 16, 8) 
      WAITCNT(4000000 + cnt)
      I2C.WriteLocation($A0, 31747, "L", 16, 8) 
      WAITCNT(4000000 + cnt)
      I2C.WriteLocation($A0, 31748, "O", 16, 8) 
      WAITCNT(4000000 + cnt)
     
      Overlay.PutChar(I2C.ReadLocation($A0, 31744, 16, 8))
      Overlay.PutChar(I2C.ReadLocation($A0, 31745, 16, 8))
      Overlay.PutChar(I2C.ReadLocation($A0, 31746, 16, 8))
      Overlay.PutChar(I2C.ReadLocation($A0, 31747, 16, 8))
      Overlay.PutChar(I2C.ReadLocation($A0, 31748, 16, 8))
     
    

    P.S. I running at 40MHz if that matters...

    Bean.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Cheap used 4-digit LED display with driver IC·www.hc4led.com

    Low power SD Data Logger www.sddatalogger.com
    SX-Video Display Modules www.sxvm.com
    Stuff I'm selling on ebay http://search.ebay.com/_W0QQsassZhittconsultingQQhtZ-1

    "USA Today has come out with a new survey - apparently, three out of every four people make up 75% of the population." - David Letterman
  • BeanBean Posts: 8,129
    edited 2006-12-29 17:13
    It seems the i2cobject version 1.3 doesn't work correctly with the propeller eeprom.
    I changed the i2cStart and i2cStop code and got it working partially.

    Mike, can you post a link to version 1.4. I'll try that.

    Bean.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Cheap used 4-digit LED display with driver IC·www.hc4led.com

    Low power SD Data Logger www.sddatalogger.com
    SX-Video Display Modules www.sxvm.com
    Stuff I'm selling on ebay http://search.ebay.com/_W0QQsassZhittconsultingQQhtZ-1

    "USA Today has come out with a new survey - apparently, three out of every four people make up 75% of the population." - David Letterman
  • CatweazleCatweazle Posts: 17
    edited 2006-12-29 20:08
    Hello,

    I've tried the I2Cobject out. I connected a external EERPOM (24LC512) but should be the same as the 24LC256.
    EEPROM adresspins A0..A2 and WP(writeprotect) are tied to GND

    Port A7 = SDA (Pullup 10k to 3v3)
    Port A6 = SCL (Pullup 10k to 3v3)

    The Code... (using i2cObject version 1.3)

    '
    ' init i2c driver
    i2cObject.init(7,6,false) ' SDA=A7, SCL=A6 , (24LC512)

    ' write an "x" to adress 0
    i2cObject.writeLocation($A0, 0, "x", 16, 8) ' $A0+i2cDeviceAdress, EEPROMadress, EEPROMdata, Adressbits, Databits
    waitcnt(400_000 + cnt) 'wait 5ms @ 5MHz - this is very important !!!

    ' read adress 0
    eepromdata:=i2cObject.readLocation($A0,0,16,8) ' $A0+i2cDeviceAdress, EEPROMadress, Adressbits, Databits

    ' eepromdata holds the data ("x") now
    '



    i2cDeviceAdress = 0 (A0..A2 are tied to GND, so the EEPROM device adress is 0)

    - Eric
  • Mike CookMike Cook Posts: 829
    edited 2006-12-29 20:14

    Don't know if this helps or not...

    But I'm using v1.3 of the i2cObject.spin, talking to a DS1307 hanging off the same pins as the Propeller's eeprom (PINS 28 & 29). I'm using a 'Home built' demo board that has the I2C lines pulled up to +3.3VDC

    So far I have not noticed any issue with the I2C driver, but like I stated I'm communicating with a RTC chip and not the Propeller's eeprom.

    <EDIT>

    If your using the Propeller Demo Board, it only has SDA pulled up, that might be the problem, here's a link the the Parallax Demo Board's schematic:

    http://www.parallax.com/dl/docs/prod/prop/PropDemoDschem.pdf

    Just an ASSUMPTION here but I think the I2C spec wants both SDA & SCL pulled up.

    </EDIT>

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Mike

    Post Edited (Mike Cook) : 12/29/2006 8:28:01 PM GMT
  • sharpiesharpie Posts: 150
    edited 2006-12-29 20:35
    I have also had much luck with using the same eeprom my code is stored in with the folllowing...

    rom.Init(i2cSDA, i2cSCL, false)
        
      if rom.isStarted == true
        txt.out($0D)  
        txt.str(string("Started OK"))
      else
        txt.out($00)  
        txt.str(string("Start Failed"))
      txt.out($0D)  
      txt.str(string("i2c Message:"))
      txt.dec(rom.getError)        
      waitcnt(5_000_000+cnt)
      if rom.devicePresent(EEPROM_Addr) == true
        txt.out($0D)  
        txt.str(string("Selftest PASSED"))
        waitcnt(50_000_000+cnt)
        txt.out($00)
        outa[noparse][[/noparse]led] := low
        cognew(DoStuff,@stack1)
        cognew(DoMoreStuff,@stack2)
      else
        txt.out($00)  
        txt.str(string("Selftest FAILED"))    
    
     
     
    Pub DoStuff
        rom.writeLocation(EEPROM_ADDR, eepromLocation, data, 16, 8)
        waitcnt(50_000 + cnt)
        eepromlocation++
    
    

    Wouldn't work on the demo board due to the pullups, but works great every time with them on my custom boards(with the pullups).
  • CatweazleCatweazle Posts: 17
    edited 2006-12-29 20:35
    Bean, after having a second look at your code

    you have written:

    I2C.Init(29, 28, TRUE) ' Use Propeller Demo Board EEPROM
    I2C.Start

    instead you should try:


    I2C.Init(29, 28, FALSE) ' Use Propeller Demo Board EEPROM
    I2C.Start ' you don't need this


    hope that work ...

    - Eric

    Post Edited (Catweazle) : 12/29/2006 8:41:08 PM GMT
  • CatweazleCatweazle Posts: 17
    edited 2006-12-29 20:52
    EDIT:
    the I2C.Init(29, 28, FALSE) works only with 10k Pullup resistor on SCL !!
    At 40Mhz you need a waitcnt(200_000 + cnt)

    - Eric
  • BeanBean Posts: 8,129
    edited 2006-12-30 17:18
    I have modified some code that Beau sent me to work with the Propeller Boot EEPROM.

    The attached code drives the SCL line, so don't use it for general I2C stuff. It is written specifically to read/write from/to the Propeller Boot·EEPROM.

    I'm using the code to read/write from/to the last 6K (26624 thru 32767) of the 32KB EEPROM on the Propeller demo board.

    Don't forget that when you save code to the Propeller EEPROM·(F11) it ALL·gets erased.

    Comments welcome, (Beau?)

    Bean.




    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Cheap used 4-digit LED display with driver IC·www.hc4led.com

    Low power SD Data Logger www.sddatalogger.com
    SX-Video Display Modules www.sxvm.com
    Stuff I'm selling on ebay http://search.ebay.com/_W0QQsassZhittconsultingQQhtZ-1

    "USA Today has come out with a new survey - apparently, three out of every four people make up 75% of the population." - David Letterman

    Post Edited (Bean (Hitt Consulting)) : 12/30/2006 11:55:44 PM GMT
  • JavalinJavalin Posts: 892
    edited 2007-01-02 09:46
    Chaps,

    Just to clarify the earlier versions of the i2cObject did expect (following the i2c spec) that both sca/scl would be pulled up. But the current version allows you to specify when you init the object a true/false to indicate whether the scl will be pulled up.

    This is explained in detail within the i2cDemo.spin & i2cObject.spin code documentation.

    (Note the SDA HAS to be pulled up)

    I've attached version 1.4 - its "beta" as I've been really lazy recently and haven't 100% tested it to my satisfaction.· I'll get off my backside and sort it out soon.· Version 1.4 does "page read" and "page write" on eeproms.

    James
  • djh82ukdjh82uk Posts: 193
    edited 2007-07-04 16:56
    Ok Sorry if I am thick, but can someone help me use hitt's code?

    I want to write 2 numbers to storage, but I don't know what variable to pass to the write and read methods?

    as I how do I work them out?

    Thanks

    DJH
  • Mike GreenMike Green Posts: 23,101
    edited 2007-07-04 17:37
    The Object Exchange has an entry for "Basic I2C Driver". In the comments at the beginning, there's a simple example of writing a small (32 byte) buffer to EEPROM and reading the same area back. If you want to write two numbers (both LONGs), then read them back, you could use the ReadLong and WriteLong routines in the object to do this. If you declared the object with 'OBJ I2C : "Basic I2C Driver"' and your variables are XXX and YYY:
    I2C.WriteLong(I2C#BootPin,I2C#EEPROM,@XXX,@XXX)
    waitcnt(clkfreq/100 + cnt)  ' Wait 10ms for write to finish
    I2C.WriteLong(I2C#BootPin,I2C#EEPROM,@YYY,@YYY)
    waitcnt(clkfreq/100 + cnt)  ' Wait 10ms for write to finish
    
    


    What this does is to store XXX and YYY in the EEPROM locations where they are initialized from during a reset or power on. Normally these are cleared to zero when the program is downloaded by the Propeller Tool and you've overwritten these zero values in the EEPROM. If you don't want to use these locations, you can choose any others that are not occupied by your program and its data. The easiest thing to do is to start at the end of the EEPROM ($7FF4) and work downwards since the Propeller Tool fills the EEPROM from location zero upwards. This would look like:
    I2C.WriteLong(I2C#BootPin,I2C#EEPROM,$7FF4,@XXX)
    waitcnt(clkfreq/100 + cnt)  ' Wait 10ms for write to finish
    I2C.WriteLong(I2C#BootPin,I2C#EEPROM,$7FF0,@YYY)
    waitcnt(clkfreq/100 + cnt)  ' Wait 10ms for write to finish
    
    


    To read this back in you'd need to do: XXX := I2C.ReadLong(I2C#BootPin,I2C#EEPROM,$7FF4)
    or YYY := I2C.ReadLong(I2C#BootPin,I2C#EEPROM,$7FF0)

    Post Edited (Mike Green) : 7/4/2007 5:41:57 PM GMT
  • djh82ukdjh82uk Posts: 193
    edited 2007-07-04 19:19
    Thank you

    I was hoping to write to the onboard eeprom on the proto board, will that object do it? I did not think it would. (hence the reasons for beans addition?)

    I guess by the look of it beans version does not support longs? just bits? So if I used that one I would have the split the long into bits?

    basically I am trying to store a max speed, say for instance 17.21MPH is made up of 2 variables, 17 and 21.

    Just to make my intentions clearer

    Thanks for your help so far [noparse]:)[/noparse]

    DJH
  • Mike GreenMike Green Posts: 23,101
    edited 2007-07-04 19:35
    Both of the objects in the Object Exchange will work with the extra EEPROM on the Protoboard or the Hydra. On the Protoboard, the valid address range is $0000 through $FFFF. On the Hydra, the address range is $00000 through $1FFFF for the on-board EEPROM. If there's a memory expansion card installed on the Hydra, the on-board EEPROM becomes $20000 through $3FFFF and the expansion card then occupies $00000 through $1FFFF.

    Bean's ReadLocation and WriteLocation routines handle single bytes only. If you want to handle words or longs, you have to do these one byte at a time.

    From your description, I'm not sure how you're storing your speed value. 17.21MPH is a single value of some sort and there are all sorts of ways to store this. You could have 4 digits as ASCII characters. That still takes only one long variable (for the 4 bytes). A floating point value also takes 4 bytes. If you used a scaled fixed point value, it's still only 2 bytes (as 1721 hundreths of a mile per hour).
  • djh82ukdjh82uk Posts: 193
    edited 2007-07-04 21:27
    well I do not have the cogs to do the Floating point I think, so I simply made the value (a four digit number) into a most significant bit (var1) and least significant bit (var2), each time there is a new speed I will just compare the first parts, if equal then also compare 2nd parts. But I guess i could just do all that before converting to MSB and LSB.

    Thanks for the info. Do I need any pullups on the proto board?

    DJH
  • Mike GreenMike Green Posts: 23,101
    edited 2007-07-04 22:42
    You can easily store a 4 digit number in a 16 bit (word) variable, then do arithmetic and comparisons more naturally and efficiently.

    Whether you need pullups depends on what you want to connect. The built-in stuff (and the optional I/O in the Accessory Kit) are complete as is. The EEPROM even has pullups on both the clock and data lines so it's easy to connect additional I2C devices. Do keep in mind that the Propeller is a 3.3V device and does require at least a series protective resistor (at least 220 ohm) on an input when connected to a 5V output device.
  • djh82ukdjh82uk Posts: 193
    edited 2007-07-06 15:09
    I have been looking into it, and it appears I need a Pullup resistor on the SDA Line? That should be some fun soldering?

    DJH
  • Mike GreenMike Green Posts: 23,101
    edited 2007-07-06 15:17
    The Protoboard has pullups on both SCL and SDA already. Again, you need additional level shifting circuitry if you are connecting 5V devices to a Propeller. There's a whole "sticky thread" on this subject and it covers I2C devices as well if that's what you need.
  • djh82ukdjh82uk Posts: 193
    edited 2007-07-06 15:20
    thank god for that [noparse]:)[/noparse]

    ok, Im still struggling, using the basic i2c driver I cannot see what variable I must use to put the data in, even with the example, Im kinda assuming it is the "buffer" variable?

    Also to use writelong it want the device select and the address?

    DJH
  • djh82ukdjh82uk Posts: 193
    edited 2007-07-06 15:32
    Ok, think i got it working, but will move over to another thread, sorry for highjacking your thread bean
  • Mike GreenMike Green Posts: 23,101
    edited 2007-07-06 15:40
    What's there to struggle about? There are only 4 parameters for WriteLong. One is the I/O pin number for the clock line and that's predefined if you're using the boot EEPROM (use xxx#BootPin where xxx is the object name). The second is the select code for the EEPROM and that's predefined as well (use xxx#EEPROM). The next is the EEPROM address for the first byte. This should be a multiple of 4 to avoid problems with the paged write mode. The last parameter is the value to be written. That's all.

    You do need a delay after each WriteLong. You can either copy the code in the example or use a fixed 10ms delay with "waitcnt(clkfreq/100 + cnt)".

    To read the value back, you don't need a delay and you only need the first 3 parameters. The ReadLong call is a function call and it returns the value read from the EEPROM.

    There are similar calls for bytes (ReadByte and WriteByte) and words (ReadWord and WriteWord). For words, the EEPROM address should be a multiple of 2. For bytes, there are no restrictions other than that you shouldn't try to store data on top of your program. If you have a Protoboard or Hydra, you can use any address from $8000-$FFFF for the Protoboard or $08000-$1FFFF for the Hydra.

    As I mentioned before, you're usually safe allocating space for EEPROM data store from the end of EEPROM downwards towards the last address shown in the Propeller Tool memory map for your program.
  • djh82ukdjh82uk Posts: 193
    edited 2007-07-06 16:05
    well it seems to be working now with the below code, I know it far from perfect. sorry if I am annoying you with my clear lack of knowledge.

    I know I can get rid of the 2 LSB methods and just pass the function the variable, whih I will sort out next as soon as I can find out how to create random numbers within a given range to help simulate/test it.

    Thanks for all your help
    Somebody said...

    PRI readItmsb
    if i2c.ReadPage(i2c#BootPin, i2c#EEPROM, eepromAddress, @buffer2, 32)
    abort ' an error occurred during the read

    'text.out(13)
    'text.dec(buffer2)

    PRI writeItmsb | startTime

    buffer := wholemax

    if i2c.WritePage(i2c#BootPin, i2c#EEPROM, eepromAddress, @buffer, 32)
    abort ' an error occured during the write
    startTime := cnt ' prepare to check for a timeout
    repeat while i2c.WriteWait(i2c#BootPin, i2c#EEPROM, eepromAddress)
    if cnt - startTime > clkfreq / 10
    abort ' waited more than a 1/10 second for the write to finish

    writeItlsb
    readItmsb

    PRI readItlsb
    if i2c.ReadPage(i2c#BootPin, i2c#EEPROM, eepromAddress2, @buffer2, 32)
    abort ' an error occurred during the read

    'text.out(13)
    'text.dec(buffer2)

    PRI writeItlsb | startTime

    buffer := wholemax

    if i2c.WritePage(i2c#BootPin, i2c#EEPROM, eepromAddress2, @buffer, 32)
    abort ' an error occured during the write
    startTime := cnt ' prepare to check for a timeout
    repeat while i2c.WriteWait(i2c#BootPin, i2c#EEPROM, eepromAddress)
    if cnt - startTime > clkfreq / 10
    abort ' waited more than a 1/10 second for the write to finish

    readItlsb
  • djh82ukdjh82uk Posts: 193
    edited 2007-07-06 16:07
    ok, never mind, it isn't working

    will go back to he drawing board
  • BeanBean Posts: 8,129
    edited 2007-07-06 17:20
    I'm working on an updated version of the Boot EEPROM library in order to support the Prop Dongle.

    I have the code written but it is untested. I hate posting untested code, but if anyone wants to monkey with it I will (just ask).

    [noparse][[/noparse]edit] Oh what the heck, here it is...

    Bean.




    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Never argue with an idiot.· They'll drag you down to their level then beat you with experience.
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    www.hittconsulting.com


    Post Edited (Bean (Hitt Consulting)) : 7/6/2007 5:31:45 PM GMT
  • computer guycomputer guy Posts: 1,113
    edited 2008-01-09 10:12
    If I was to get an eeprom larger than 32k say 64k and write data to the second 32k would the propeller IDE erase the second 32k?

    Thank you smile.gif

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Check out my robot using the propeller RECONAUTOR
  • simonlsimonl Posts: 866
    edited 2008-01-09 10:40
    No; my understanding is that the Propeller Tool only writes the first 32K.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Cheers,

    Simon
    www.norfolkhelicopterclub.co.uk
    You'll always have as many take-offs as landings, the trick is to be sure you can take-off again ;-)
    BTW: I type as I'm thinking, so please don't take any offense at my writing style smile.gif
  • computer guycomputer guy Posts: 1,113
    edited 2008-01-09 11:30
    Thank you simonl smile.gif

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Check out my robot using the propeller RECONAUTOR

    Post Edited (computer guy) : 1/9/2008 1:18:12 PM GMT
  • Nick MuellerNick Mueller Posts: 815
    edited 2008-01-09 12:14
    Why not use my NVVar?

    <http://forums.parallax.com/forums/default.aspx?f=25&m=239157&gt;

    Nick

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Never use force, just go for a bigger hammer!

    The DIY Digital-Readout for mills, lathes etc.:
    YADRO
Sign In or Register to comment.