Shop OBEX P1 Docs P2 Docs Learn Events
storing data in EEPROM — Parallax Forums

storing data in EEPROM

shmowshmow Posts: 109
edited 2010-08-09 07:37 in Propeller 1
Hey All,

I'm using Mike Green's Minimal_I2C_Driver (Basic_I2C_Driver - http://obex.parallax.com/objects/26/ . (Thanks Mike!)

I'm trying to understand it, but I'm not sure how to handle devSel or addrReg. What would I put in those variables?

I have the microchip 24LC256 - so, is that device 2 for devSel?

And, addrReg is anywhere from $0000 (0) to $3FFFF ((26000)?

Am I understanding this correctly?

Regards,
Shmow

Comments

  • shmowshmow Posts: 109
    edited 2010-07-27 20:56
    Hey All,

    here's an attempt to store the value 255 in an EEPROM address (not really sure if it works).
    And, an attempt to retrieve what may be in that address too...

    
    CON
        _clkmode = xtal1 + pll16x
        _xinfreq = 5_000_000
    
        SCL = 28
        StoreData = 255  'VALUE TO BE STORED IN EEPROM
        Ack = 0
        DevSel = $00002  'THE NUMBER TWO IN HEX
        AddrReg = $3FFFF 'ADDRESS LOCATION IN EEPROM 
        count = 32
        
    VAR
      byte buffer[noparse][[/noparse]32]
      byte retrievedData     
    
    OBJ
       i2c : "Minimal_I2C_Driver"
       sio : "FullDuplexSerialPlus"
       
    PUB Main
    
      sio.start(31,30,0,115200)
      i2c.initialize(SCL)
      dira[noparse][[/noparse]16..17]~~
    ' INDICATOR LIGHT TO SHOW PROGRAM WILL START IN 4 SECONDS
    ' GIVES ME TIME TO OPEN PARALLAX SERIAL TERMINAL
      outa[noparse][[/noparse]17]~~
      waitcnt(clkfreq*4+cnt)
      outa[noparse][[/noparse]17]~  
      repeat                                          
    '      WHEN BUTTON IS PRESSED, VALUE OF 255 SHOULD BE STORED IN EEPROM (HOW, I DON'T KNOW) 
           if ina[noparse][[/noparse]0] == 1                     
             StoreVal
             waitcnt(clkfreq*3+cnt)         
           else
    '        WHEN BUTTON IS NOT PRESSED, RETRIEVED DATA IS DISPLAYED ON PST (PARALLAX SERIAL TERMINAL)       
             RetrieveVal
             
    
    PRI StoreVal
    
    '    NOT EVEN SURE HOW TO MAKE THIS WORK TO STORE DECIMAL 255 (IN storeData VARIABLE)
    '    
         I2C.WritePage(SCL, devSel, addrReg, @buffer, count)
         
    PRI RetrieveVal
    
    '  VARIABLE IS ASSIGNED VALUE FROM DEVICE 2 (MICROCHIP 24LC256) AT BUFFER LOCATION 32   
       retrievedData := I2C.ReadPage(SCL, devSel, addrReg, @buffer, Count)
         
    '  SHOW DATA ON P SERIAL TERMINAL
       sio.dec(retreivedData)
       sio.Str(string(13," ",13,13))
       waitcnt(clkfreq+cnt)
                              
    
    
    



    If you can decipher what I'm trying to do here then throw me a line cause I'm way in over my head!

    Cheers,
    Shmow
  • jazzedjazzed Posts: 11,803
    edited 2010-07-27 21:40
    I was hoping Mike would jump in ... he may anyway.
    In Mike's driver there are read/write examples in the comments.

    An EEPROM device id is $A0 ... that's what you get with i2c#EEPROM.
    The address range of a 24LC256 is $0000 to $7FFF ... Not sure what $3FFFF will give you.

    To store 255 in location 0 you say buffer[noparse][[/noparse]0] := 255 ... but you should read the buffer first.
    So a call to Mike's readIt method would preceed that.

    Here's a simple, but untested example that should work barring syntax errors, etc....

    Hope this helps some way.
    --Steve

    '' code fragment
    obj i2c : "Minimal_I2C_Driver"
    var byte buffer[noparse][[/noparse]33] ' I have bad habit of adding 1 to buffers :)
    var long eepromAddress
    
    pub main
      eepromAddress := 0  ' global eepromAddress ... not the best way, but ok for demo
      i2c.initialize(28)
      i2c.readIt
      buffer[noparse][[/noparse]eepromAddress // 32] := 255   ' using // 32 makes sure we don't overrun the buffer
      i2c.writeIt
      repeat
    
    


    PRI readIt
       if i2c.ReadPage(i2c#BootPin, i2c#EEPROM, eepromAddress, @buffer, 32)
         abort ' an error occurred during the read
    
    PRI writeIt | startTime
       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
    
    

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Propeller Pages: Propeller JVM
  • shmowshmow Posts: 109
    edited 2010-07-27 22:27
    Hey Steve,
    thanks a'plenty for the helpful reply. I'll run with this to see if I can get things in order.
    Cheers,
    Shmow
  • shmowshmow Posts: 109
    edited 2010-07-27 23:05
    Hey Steve,

    I tested out what you gave me, and I actually got the EEPROM to store my value.
    The problem is that when the power is lost and restored, the value is not there in the EEPROM.
    Isn't there a way to store a value that won't be lost when the power is interrupted?
    Regards,
    Shmow

    Here's my code with your suggestions:

    CON
        _clkmode = xtal1 + pll16x
        _xinfreq = 5_000_000
    
        SCL = 28
        StoreData = 255  'VALUE TO BE STORED IN EEPROM
        eepromaddress = $0000
        
    VAR
      byte buffer[noparse][[/noparse]32]
      byte retrievedData     
    
    OBJ
       i2c : "Minimal_I2C_Driver"
       sio : "FullDuplexSerialPlus"
       
    PUB Main
    
      sio.start(31,30,0,115200)
      i2c.initialize(SCL)
    '  i2c.readit
      dira[noparse][[/noparse]16..17]~~
    ' INDICATOR LIGHT TO SHOW PROGRAM WILL START IN 4 SECONDS
    ' GIVES ME TIME TO OPEN PARALLAX SERIAL TERMINAL
    
      outa[noparse][[/noparse]17]~~
      waitcnt(clkfreq*4+cnt)
      outa[noparse][[/noparse]17]~  
      repeat                                          
    '      WHEN BUTTON IS PRESSED, VALUE OF 255 SHOULD BE STORED IN EEPROM (HOW, I DON'T KNOW) 
           if ina[noparse][[/noparse]0] == 1                     
             StoreVal
             waitcnt(clkfreq*3+cnt)         
           else
    '        WHEN BUTTON IS NOT PRESSED, RETRIEVED DATA IS DISPLAYED ON PST (PARALLAX SERIAL TERMINAL)       
             RetrieveVal
             
    
    PRI StoreVal
    
      buffer[noparse][[/noparse]eepromAddress // 32] := 255
         
    PRI RetrieveVal
    
    '  VARIABLE IS ASSIGNED VALUE FROM DEVICE 2 (MICROCHIP 24LC256) AT BUFFER LOCATION 32   
       retrievedData := buffer[noparse][[/noparse]eepromAddress // 32]
         
    '  SHOW DATA ON P SERIAL TERMINAL
       sio.dec(retrievedData)
       sio.Str(string(13," ",13,13))
       waitcnt(clkfreq+cnt)
    
    
    PRI readIt
       if i2c.ReadPage(i2c#BootPin, i2c#EEPROM, eepromAddress, @buffer, 32)
         abort ' an error occurred during the read
    
    PRI writeIt | startTime
       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       
    
    
  • jazzedjazzed Posts: 11,803
    edited 2010-07-28 02:08
    It seems like you're not calling the writeIt method. Maybe it would help if you add writeIt in StoreVal method after buffer[noparse][[/noparse]eepromAddress // 32] := 255

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Propeller Pages: Propeller JVM
  • shmowshmow Posts: 109
    edited 2010-07-28 02:34
    thanks for pointing that out. I would have never known that.
    I did the same thing for the readit method too, and it works!
    Thanks for your help.

    Here's the final sample code for anyone else following:
    
    CON
        _clkmode = xtal1 + pll16x
        _xinfreq = 5_000_000
    
        SCL = 28
        StoreData = 255  'VALUE TO BE STORED IN EEPROM
        eepromaddress = 0
        
    VAR
      byte buffer[noparse][[/noparse]32]
      byte retrievedData     
    
    OBJ
       i2c : "Minimal_I2C_Driver"
       sio : "FullDuplexSerialPlus"
       
    PUB Main
    
      sio.start(31,30,0,115200)
      i2c.initialize(SCL)
    '  i2c.readit
      dira[noparse][[/noparse]16..17]~~
    ' INDICATOR LIGHT TO SHOW PROGRAM WILL START IN 4 SECONDS
    ' GIVES ME TIME TO OPEN PARALLAX SERIAL TERMINAL
    
      outa[noparse][[/noparse]17]~~
      waitcnt(clkfreq*4+cnt)
      outa[noparse][[/noparse]17]~  
      repeat                                          
    '      WHEN BUTTON IS PRESSED, VALUE OF 255 SHOULD BE STORED IN EEPROM (HOW, I DON'T KNOW) 
           if ina[noparse][[/noparse]0] == 1                     
             StoreVal
             waitcnt(clkfreq*3+cnt)         
           else
    '        WHEN BUTTON IS NOT PRESSED, RETRIEVED DATA IS DISPLAYED ON PST (PARALLAX SERIAL TERMINAL)       
             RetrieveVal
             
    
    PRI StoreVal
    
      buffer[noparse][[/noparse]eepromAddress // 32] := 255
      writeIt
         
    PRI RetrieveVal
    
    '  VARIABLE IS ASSIGNED VALUE FROM DEVICE 2 (MICROCHIP 24LC256) AT BUFFER LOCATION 32   
      readit
      retrievedData := buffer[noparse][[/noparse]eepromAddress // 32]
         
    '  SHOW DATA ON P SERIAL TERMINAL
       sio.dec(retrievedData)
       sio.Str(string(13," ",13,13))
       waitcnt(clkfreq+cnt)
    
    
    PRI readIt
       if i2c.ReadPage(i2c#BootPin, i2c#EEPROM, eepromAddress, @buffer, 32)
         abort ' an error occurred during the read
    
    PRI writeIt | startTime
       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                                              
    
    



    Cheers,
    Shmow
  • park1231park1231 Posts: 4
    edited 2010-08-05 06:27
    I have been following and am unable to get the code working with an 24LC256. ReadPage is returning with an error. Help would be appreciated.

    CON
      _clkmode = xtal1 + pll16x
      _xinfreq = 5_000_000
    
      SCL = 28
    
      eepromAddress = 0
    
    VAR
      byte buffer[noparse][[/noparse]32]
      byte retrieveData
    
    OBJ
      i2c : "Basic_I2C_Driver"
      sio : "FullDuplexSerialPlus"
    
    PUB Main
    
      sio.start(31,30,0,115200)
      i2c.initialize(SCL)
      dira[noparse][[/noparse]6]~~
      outa[noparse][[/noparse]6]~~
      waitcnt(clkfreq*4+cnt)
      outa[noparse][[/noparse]6]~
      RetrieveValue
      sio.str(string("retrieved",13,13))
      sio.str(string("starting transfer",13))
      StoreValue
      sio.str(string("Stored",13))
      waitcnt(clkfreq*4+cnt)
      RetrieveValue
      sio.str(string("retrieved",13))
    
    
    PRI readIt
       if i2c.ReadPage(i2c#BootPin, i2c#EEPROM, eepromAddress, @buffer, 32)
         sio.str(string("A Read Error Ocurred",13)) ' an error occurred during the read
         abort
    
    PRI writeIt | startTime
       if i2c.WritePage(i2c#BootPin, i2c#EEPROM, eepromAddress, @buffer, 32)  
         sio.str(string("A Write Error Ocurred",13))
         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
           sio.str(string("Waiting Failed",13))' waited more than a 1/10 second for the write to finis
           abort
    PRI StoreValue
    
      buffer[noparse][[/noparse]eepromAddress // 32] := 128
      writeIt
    PRI RetrieveValue
    
      readIt
      retrieveData := buffer[noparse][[/noparse]eepromAddress // 32]
    
      sio.dec(retrieveData)
      sio.str(string(13," ",13,13))
      waitcnt(clkfreq+cnt)
    
  • jmspaggijmspaggi Posts: 629
    edited 2010-08-05 16:34
    Shmow,

    Just be careful with that:

      repeat                                          
    '      WHEN BUTTON IS PRESSED, VALUE OF 255 SHOULD BE STORED IN EEPROM (HOW, I DON'T KNOW) 
           if ina[noparse][[/noparse]0] == 1                     
             StoreVal
             waitcnt(clkfreq*3+cnt)         
    
    



    Let's say it takes about 40 instruction to execute it. 20 instructions is 20*12.5ns = 0.25us.

    If you keep your finger for 1sec on the button, you will execute this loop 4000 times.

    An EEPROM can write about 1 000 000 times a value. Then you can have failures and you will have to replace it. So 1 000 000 / 4 000 = 250...

    So if you try your program more than 250 times, you will burn your EEPROM.

    Just update your code with that:

      repeat                                          
    '      WHEN BUTTON IS PRESSED, VALUE OF 255 SHOULD BE STORED IN EEPROM (HOW, I DON'T KNOW) 
           if ina[noparse][[/noparse]0] == 1
             repeat while ina[noparse][[/noparse]0] == 1 ' Add this line to wait until the button is released to store the data only one time.
             StoreVal
             waitcnt(clkfreq*3+cnt)         
    
    




    Just be aware that this will old this cog until you release the button. For my onw project, I have a single cog to handle the inputs, so it's not olding anything on the other cogs.

    JM

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Linux? There is worst, but it's more expensive.
  • lardomlardom Posts: 1,659
    edited 2010-08-09 07:37
    I learned that a variable occupies the same address in memory and ram. The obex has an object called "BS2_Functions". The method, I think, is "Write_Codemem". At any rate I assigned a keypad button to write a variable to eeprom. It easily changes default values which persist through resets.
Sign In or Register to comment.