Shop OBEX P1 Docs P2 Docs Learn Events
reading and writing eeprom — Parallax Forums

reading and writing eeprom

4x5n4x5n Posts: 745
edited 2011-10-23 11:10 in Propeller 1
I know there are objects in OBEX but I still have a number of questions regarding reading and writing to eeprom. The first is when loading a program from an eeprom does it start at the beginning (IE address 0) and work it's way down? This is important for a number of reasons. The first and most obvious is that I have a board (Gadget Gangsters USB board and Parallax quickstart) that has 64K or ram and would like to use the half unused for my own use to store operating state and variables. I'm also thinking that since I'm not using nearly all the 32K of eeprom that normally included with a propeller board. I'm thinking of using that as well. I know that in that case the data I store will be overwritten when I reload the program but that's OK.

While I'm asking questions about eeproms and their use can someone explain how to read and write to eeprom in english. :-) I've gone through the code in the exchange and it's not making a lot of sense to me. Just a quick paragraph or two so that I can make sense out of the code in the exchange. Thanks in advance.

Comments

  • Mike GreenMike Green Posts: 23,101
    edited 2011-10-21 21:48
    When loading a program from EEPROM, the loader starts with location zero and copies to the end of the 32K. If there is more than 32K, nothing is accessed beyond the 1st 32K unless your program explicitly does so.

    It's possible to write to the locations in EEPROM used to initialize variables in your program, thus providing a persistent initial value that will indeed be erased if you download a new copy of the program to EEPROM.

    There are several loaders in the ObEx that will load from other 32K areas of EEPROM. FemtoBasic will do this for you.

    Probably the simplest and most straightforward object to use for reading and writing EEPROM is "Basic_I2C_Driver".
  • 4x5n4x5n Posts: 745
    edited 2011-10-22 09:42
    Mike,

    Thanks for your quick response and help. While a search of the OBEX didn't turn up you "basic_i2c_driver" I managed to find it bundled in another object.

    The code is clear and help clear out some of the fuzz. It looks like my problem is that I need to searching with google to find the I2C spec and learn the I2C protocol.
  • ChrisGaddChrisGadd Posts: 310
    edited 2011-10-22 11:45
    The datasheet does a decent job of explaining the signalling.

    I2C PASM 01.spin
    Here's a program I wrote when learning how the EEPROM works, that reads 500 bytes from the beginning of the EEPROM and sends it to the serial terminal.

    Quick explanation: I2C is a two-wire protocol, one clock line and one data line, connected as master and slaves. In idle condition, both lines are high. Transmissions begin with a start bit, which is a down-clock on the data line while the clock is high. Aside form the start and the stop, the data line only changes while the clock is low, and data is sampled when clock is high. After eight data bits are transmitted, the receiving device sends an ACK (data line low) to acknowledge receipt of the data, or a NAK (data line high) to signal that it didn't receive. Ends with a stop bit which is an up-clock on data while clock is already high. That's pretty much all there is to I2C.

    For my program, I send a start, send the control byte which is the EEPROM code (1010), chip select bits which allow you to address the chip by soldering A0, A1, and A2 to Vcc or ground, in this case (000), and the read/write bit cleared to indicate a write. Since it's a write, the next two bytes contain an address that I want to access inside the EEPROM. Since I want to read from the beginning I transmit $0000. I then send another start bit, which aborts the write operation but leaves the EEPROM address pointer set to $0000. Send the control byte again, except with the read/write bit set this time. After receiving an acknowledge from the EEPROM, the next 8 clocks each read a bit of data. After the eighth bit, I transmit an acknowledge in order to continue reading. After the 500th byte, send a NAK to stop reading, and send a stop bit.
  • 4x5n4x5n Posts: 745
    edited 2011-10-22 17:38
    Chris, Thanks for your post and link to your pasm code. I was going through it and noticed that at one point you do:
    mov cnt,I2C_bit_delay
    add cnt,cnt

    I don't get the reason for it. I understand you're writing to the "shadow" register but wonder how you read it back again? Don't reads of "cnt" read the counter?
  • Mike GreenMike Green Posts: 23,101
    edited 2011-10-22 18:07
    The read-only registers, like CNT, are only valid in the source field of the instruction. If you use that address in the destination field, you get the shadow register. Since the WRxxxx hub writes use the destination field as their data source, you could write the CNT shadow register to hub RAM directly. The WAITCNT uses the destination field for the system clock time to wait for. That works very nicely with the two instructions you've given.
  • BitsBits Posts: 414
    edited 2011-10-23 08:38
    Try this, the only thing I have left out is the i2c object.
    Var
      long Temp1, Temp2
      byte Master, ID 
    
    Pub Initialize
      i2c.Initialize( SCL )    
      Get_Eeprom
    
    
    Pub Main   
      {{Run code}}
    
    
      
    Pub Get_Eeprom
    {{Pay close attention to the numbers 1,4 a 1 = byte and a 4 = long}}
    
    
      readIt(32_703,@Master,1)  
      readIt(32_702,@ID,1)
      readIt(32_604,@Temp1,4)
      readIt(32_600,@Temp2,4)
    
    
    Pub Set_Eeprom
      
      writeIt(32_703,@Master,1)  
      writeIt(32_702,@ID,1)   
      writeIt(32_604,@Temp1,4)       
      writeIt(32_600,@Temp2,4)
    
    Pub readIt (address, Data, type)
    
    
      IF i2c.ReadPage(SCL, EEPROM, Address, Data, type)
         Abort 
    
    
    Pub writeIt(Address, Data, type) | startTime
    
    
      IF i2c.WritePage(SCL, EEPROM, Address, Data, type)
          Abort 
      startTime := cnt 
      repeat while i2c.WriteWait(SCL, EEPROM, Address)
        if cnt - startTime > clkfreq / 10
          Abort
    
  • BitsBits Posts: 414
    edited 2011-10-23 08:41
    Well I have tried to post this a few different ways and yet I am unable to do so. I have attached the code.
    Attachment not found.

    Can someone let me in on the secret of placing a code example. I though it was the [ code ] and [ / code ]?
  • PJAllenPJAllen Banned Posts: 5,065
    edited 2011-10-23 08:49
    The secret:
    • type code, inside brackets
    • copy and paste (as text) the "code" to be posted
    • type /code, inside brackets
  • BitsBits Posts: 414
    edited 2011-10-23 08:56
    That is what I figured yet it still failed to list it. I suppose it has something to do with whats in my code. Perhaps a symbol is causing the problem.
  • ElectricAyeElectricAye Posts: 4,561
    edited 2011-10-23 08:57
    Bits wrote: »
    That is what I figured yet it still failed to list it. I suppose it has something to do with whats in my code. Perhaps a symbol is causing the problem.

    This is the same thing PJ suggested, but Phil Pilgrim made a nice link to it that you can share with others for future reference:

    attachment.php?attachmentid=78421&d=1297987572
  • PJAllenPJAllen Banned Posts: 5,065
    edited 2011-10-23 09:45
    There shouldn't be any spaces between code and its brackets, likewise /code and its brackets.

    Find more secrets --> http://forums.parallax.com/misc.php?do=bbcode
  • BitsBits Posts: 414
    edited 2011-10-23 11:10
    I will try again
    Var
    
    
      long Temp1, Temp2
      byte Master, ID 
      
    Pub Initialize
    
    
      i2c.Initialize(SCL)    
      Get_Eeprom
      main
    
    Pub Main   
      {{Run code}}
    
    
      
    Pub Get_Eeprom
    {{Pay close attention to the numbers 1,4 a 1 = byte and a 4 = long}}
    
    
      readIt(32_703,@Master,1)  
      readIt(32_702,@ID,1)
      readIt(32_604,@Temp1,4)
      readIt(32_600,@Temp2,4)
    
    
    Pub Set_Eeprom
     {{ use this during run time to store new variables in eeprom }}
      writeIt(32_703,@Master,1)  
      writeIt(32_702,@ID,1)   
      writeIt(32_604,@Temp1,4)       
      writeIt(32_600,@Temp2,4)
    
    
    Pub readIt(address, Data, type)
    
    
      IF i2c.ReadPage(SCL, EEPROM, Address, Data, type)
         Abort 
    
    
    Pub writeIt(Address, Data, type) | startTime
    
    
      IF i2c.WritePage(SCL, EEPROM, Address, Data, type)
          Abort 
      startTime := cnt 
      repeat while i2c.WriteWait(SCL, EEPROM, Address)
        if cnt - startTime > clkfreq / 10
          Abort
    
Sign In or Register to comment.