Shop OBEX P1 Docs P2 Docs Learn Events
Help writing eeprom upper 32K — Parallax Forums

Help writing eeprom upper 32K

lardomlardom Posts: 1,659
edited 2013-01-01 16:40 in Propeller 1
My object successfully writes to and reads from the lower 32K of my eeprom. I thought adding "+ $8000" would create an automatic offset moving the variable into a predictable location in the upper 32K. The following code does not work.

Ex:
[SIZE=3]PUB Backup_element(idx)

    eeprom.VarBackup(@Y[idx], @Y[idx] [COLOR="#A52A2A"]+ $8000[/COLOR]) [/SIZE]

Having to address memory with hex would be a drag.

Comments

  • Tracy AllenTracy Allen Posts: 6,664
    edited 2012-12-09 10:41
    Depends on the eeprom OBJ. Need to see. Also of course i512k eeprom at least.


    With BASIC_I2C_DRIVER version 1.3, the call would be,
    i2c.writebyte(i2c#BOOTPIN, i2c#EEPROM, address, value)

    and the address in the upper 32k would indeed be +$8000. That passes the value, so if you want to do it by address, it would be byte[@lowAddress].
  • Duane DegnDuane Degn Posts: 10,588
    edited 2012-12-09 10:50
    How are you testing if it works or not?

    If you modify the program in lower EEPROM at all the variables will likely be in a different location so you'd no longer be able to find the previously saved variables.

    Which board are you using? Some early QuickStart boards only had 64K EEPROM. Post #24 of of this thread has a program that will tell you if you have a 32K or 64K EEPROM. The part of the program that tells you the size of the EEPROM works but the rest of the program is very buggy so don't use it as a reference on how access EEPROM.
  • lardomlardom Posts: 1,659
    edited 2012-12-09 22:06
    @Duane Degn, I'm testing my code on both the "Demo Board" and the "QuickStart".

    CON                              
                                     
      _clkmode = xtal1 + pll16x      
      _xinfreq = 5_000_000           
    
    OBJ                                        
    
      Menu  : "Menu"   
      eeprom  : "Propeller Eeprom"  
    
    VAR
        byte Y[5], cog   
        long stack[5]  
    
    PUB main     
      
      Menu.Init    
      Add_value
    
    PUB Init : success
    
      Stop
      success := (cog := cognew(Add_value, @stack)) + 1
    PUB Stop
    
      if cog
        cogstop (cog~ - 1)  
      
    PUB Add_value
      'Displays values in "Y" array
       Load
       repeat      
         Menu.DisplayElement(Y[0], 0)     'need index
         Menu.DisplayElement(Y[1], 1)
         Menu.DisplayElement(Y[2], 2)
         Menu.DisplayElement(Y[3], 3)
         Menu.DisplayElement(Y[4], 4)
         Menu.GetElement(0)           ' Wait for user input  
         Save_It(7)                    'Random value for testing purposes 
    
    [B]PUB Save_It(x) : idx [/B]           
       
      repeat                        ' scan for free slot          
        ifnot Y[idx]                ' use local idx         
          Y[idx] := x               ' found free (==0) quit loop
          [B]Backup_element(idx)[/B]
          quit                      ' update global index and store value
        idx++                                                           
        if idx > 4                  ' If array full,
          bytefill(@Y[0], 0, 5)     ' reset, array and idx  (start addr, value, count)
          Y[0] := x 
          [B]Backup_array[/B]                                                                                            
                                                                                              
    PUB Backup_element(idx)
    
        eeprom.VarBackup(@Y[idx], @Y[idx])      '+ $8000
    
    PUB Backup_array                                 '' Back up entire array to EEPROM
                                                     
       eeprom.VarBackup(@Y, @Y[4])       ' Copy Y array from RAM to EEPROM
    
    PUB Load                                         '' Load entire array from EEPROM
                                                     
      eeprom.VarRestore(@Y, @Y[4])      ' Copy array from EEPROM to RAM
    


    I get my intended results after a reset. It still needs work. I'm going to use this to save 'speed' and 'distance' settings.

    @Tracy Allen, I found "BASIC_I2C_DRIVER version 1.3" I'll study it and try to apply what you've said.
  • MagIO2MagIO2 Posts: 2,243
    edited 2012-12-09 23:43
    Not knowing the "Propeller Eeprom" object, my guess is that it's intention is to store variables from HUB-RAM into the exact same place of EEPROM, so that they are available directly after a reboot!

    Hence, after booting the HUB-RAM is an exact copy of the first 32k of the EEPROM. So, each variable has the same address in HUB-RAM than in EEPROM. With backup you simply give a start- and end-address of what you want to save to the exact same location in EEPROM. That's why you only need 2 parameters. If you'd have a free save to EEPROM function, then you'd need 3 parameters:
    1. source address
    2. destination address
    3. number of bytes to copy.

    Again .. this is what I see reading your code not knowing "Propeller Eeprom". Maybe I am wrong.
  • Duane DegnDuane Degn Posts: 10,588
    edited 2012-12-10 02:55
    lardom wrote: »
    @Duane Degn, I'm testing my code on both the "Demo Board" and the "QuickStart".

    Did you check the sizes of your EEPROMs?

    The Demo Board only has 32K. Some QuickStarts also only have 32K,

    When I use the "PropellerEeprom" object, I only use "ToRam" and "FromRam" since it lets you read or wrtie multiple bytes at a time.

    I think you were using the method "VarBackup" incorrectly (in your top post). The "+ $8000" was causing 32K of hub ram (and one byte of ROM) to be copied to EEPROM. On the demo board you were just writing over the top of the original EEPROM with just about (except for changed variables) data.

    If your EEPROM is only 32K, Whatever addresses you use above $7FFF are treated as if they were the address minus $8000.

    I think below is what you intended for your "Backup_element" method.
    PUB Backup_element(idx)
        eeprom.FromRam(@Y[idx], @Y[idx], @Y[idx] + $8000) 'save single byte to upper EEPROM
    
    


    But again, this would only work with 64K EEPROMs. On 32K EEPROMs the above code would just write to "@Y[ind]".

    It's hard to know what your code is really doing since you reference unknown (to us) object(s).
  • lardomlardom Posts: 1,659
    edited 2012-12-10 10:29
    @MagIO2, As written, it will save an exact copy of my settings in Hub Ram. The reason I added a variable array was to reduce the number of rewrites to the same physical memory location. That also appears to work. I then started thinking that I should make use of all that storage space in high eeprom memory which is where I got stuck. If you want to see what it does I zipped the file:

    @Duane Degn, According to the Quickstart package specs the eeprom is 64K. I'm going to test your code and if it works I'll have to study it closely. It takes a while for stuff to sink in.
  • Duane DegnDuane Degn Posts: 10,588
    edited 2012-12-10 10:40
    [QUOTE=lardom;1149064@Duane Degn, According to the Quickstart package specs the eeprom is 64K.[/QUOTE]

    If you have a relatively new QuickStart if should have 64K. The very first ones made had 32K. Parallax would replace the 32K versions with 64K units if you gave your 32K QS to someone who hadn't used the Propeller before. I had purchased four of the 32K QS boards. It was easy to find four people who hadn't used the Propeller and wanted to try it.
  • lardomlardom Posts: 1,659
    edited 2012-12-10 11:07
    @Duane Degn,
    It was easy to find four people who hadn't used the Propeller and wanted to try it.
    You must be a teacher. I only have 2 QuickStarts,
  • Duane DegnDuane Degn Posts: 10,588
    edited 2012-12-10 13:37
    lardom wrote: »
    @Duane Degn, You must be a teacher. I only have 2 QuickStarts,

    I have many more than the original four now.

    I'm not a teacher now. I did teach high school chemistry and physics before my heart-transplant.
  • MagIO2MagIO2 Posts: 2,243
    edited 2012-12-10 14:14
    It's like I guessed before:
    Let's say you have a variable var[10] in HUB-RAM. The backup( @var, @var[10] ) will simply copy the whole array to the same address in EEPROM that it has in RAM. I other words it really expects 2 RAM-addresses as parameter. This is why an offset of $8000 does not work!

    If you want to implement wear-leveling and storage in upper EEPROM you need the FromRam and ToRam functions. And you need to be aware of the EEPROM pagesize. An EEPROM always writes full pages even if you only changed a byte. A strategy depends on what data you write. Can the data have any value or can you use a dedicated value to mark unused EEPROM space? Or can you efford some overhead which contains a counter? The highest value of a counter-location will then tell you where the actual data is stored.
  • lardomlardom Posts: 1,659
    edited 2012-12-10 15:35
    @MagIO2, I'll modify the code to use "...FromRam and ToRam functions" and study the eeprom documentation to get clear on pagesize. It certainly sounds like I should keep things simple. My app only requires saving five settings and I have more than enough memory in hub ram.

    @Duane Degn, Do you have an idea what percentage of your students continued to study science?
  • MagIO2MagIO2 Posts: 2,243
    edited 2012-12-10 20:41
    Well, it really depends on how often you change those values. If you expect them to be changed often it makes sense to think about wear-leveling. If it's only once in a while >100000 write cycles would be good for a while!

    Do you have a need for SD card in this project? They do wear-leveling themselves.
  • Duane DegnDuane Degn Posts: 10,588
    edited 2012-12-10 23:46
    @MagIO2, I've seen the caution about page sizes mentioned several times in posts about writing to EEPROM. I use the EEPROM for saving data a lot with my Propeller projects but I never worry about page sizes. Is the concern about page sizes because the whole page get written to even for one byte so the EEPROM might get worn out faster than anticipated?

    Most of my program that write to EEPROM only do so a few times a day. I figure at a couple of writes a day it will take a long time to wear out my EEPROMs.

    I remember from writing a driver for some Winbond flash chips, that I had to erase a whole page of memory before writing to the memory. If I wanted to edit a portion of memory, I had to first save the page into hub RAM and then erase the page and write back the entire page with the edited data. I don't take any of these precautions with EEPROM and I haven't noticed any problems.

    Should I be concerned about writing across page boundaries on an EEPROM if I'm only doing so a few times a day?

    As you suggest, I use a SD card for most of my Propeller data storage needs.

    @Larry, I'm not in contact with many of my previous students (it's been about twenty years since I've taught at high school). The few I do know (from being friends of their family) did not pursue a science eduation. I enjoyed teaching immensely; I really enjoyed the students and it was a lot of fun doing demonstrations for the classes.
  • MagIO2MagIO2 Posts: 2,243
    edited 2012-12-11 05:19
    "From these examples, it is clear that both page writes
    and Acknowledge polling can provide significant time
    savings. Writing 128 bytes to the 24LC512 via byte
    writes at 400 kHz requires roughly 652 ms worst-case.
    Switching to Acknowledge polling brings that down to
    roughly 396 ms (assuming typical conditions), nearly a
    40% decrease. Additionally, changing to page writes
    further lowers the time to an impressive 5.95 ms, a
    decrease of over 98%. Overall, the two techniques
    provide a combined time savings of nearly 646 ms,
    increasing the total data throughput a staggering 109
    times over."

    That is what microchip say about their devices.

    So, there are 2 modes of writing to an EEPROM. If the driver you use sends the data byte by byte writing to the EEPROM needs much longer, as after each byte you have to wait for the EEPROM to finish programming. If the driver uses page mode but your code is doing byte-write in random fashion (writing 2 bytes to address x, then some bytes to address y where y>x+page size and then goes back to write something in x+2 again), then the EEPROM will in fact wear out earlier.

    What I understand is, that lardom want's to take care of the wear leveling to maximize the lifetime of the EEPROM. So, if he writes things in page mode he has to be aware of the fact that he is wearing out the whole page in this case.

    Having a look at the used driver, you'll see that Propeller EEPROM.spin is really working in page-mode.
      repeat
        page := addr+64-eeAddr//64<#endaddr+1        ' Find next EEPROM page boundary
        SetAddr(eeAddr)                              ' Give EEPROM starting address
        repeat                                       ' Bytes -> EEPROM until page boundary
          SendByte(byte[addr++])
        until addr == page
        i2cstop                                      ' From 24LC256's page buffer -> EEPROM
        eeaddr := addr - startAddr + eeStart         ' Next EEPROM starting address
      until addr > endAddr                           ' Quit when RAM index > end address
    

    Basic I2C on the other hand has functions for writing in page mode and functions for writing in byte-mode. So, it's on your side to choose the right one.
  • lardomlardom Posts: 1,659
    edited 2012-12-11 08:28
    @MagIO2, If my app was designed to do datalogging then saving to high memory would be necessary. What I've done controls how a stepper moves. I might change the settings 5 times a day. If I build a machine for someone else then adding lite-duty wear leveling capability would add a little extra reliability. The overhead is a non-factor. The main benefit is what I've learned in the process.

    @Duane Degn, I've written in a journal that if you can read a book you can learn in a short time what may have taken the author a lifetime to learn. Teaching is a noble profession. I'm still amazed at how quickly I've learned because of this forum.
  • Duane DegnDuane Degn Posts: 10,588
    edited 2012-12-11 09:19
    @MagIO2, You completely answered my questions about EEPROM. Thank you very much.

    I had looked at the object to see if I could find anything about using pages but I didn't see where pages were mentioned until seeing your post. I think I was expecting the page writes to be taken care of by one of the private, lower level methods. I really appreciate your pointing out the page write section of the code.

    Atmel's datasheet gives the lifetime of their EEPROMs of one million write cycles. So I figure I can write to EEPROM 27 times a day for a hundred years before it wears out. Even if the limit were 100,000 write cycles, I don't think any of my projects use the EEPROM in a way such that I need to worry about wear leveling.

    Thanks again for taking time to explain this concept so well.
    lardom wrote: »
    @Duane Degn, I've written in a journal that if you can read a book you can learn in a short time what may have taken the author a lifetime to learn. Teaching is a noble profession. I'm still amazed at how quickly I've learned because of this forum.

    @Larry, I'm constantly amazed how many people generously help strangers to learn things. I think it's amazing the way we humans are so willing to pass on information we've learned.
  • SeekerSeeker Posts: 58
    edited 2012-12-11 19:22
    For me to get a handle on writing to memory above the lower 32K I used an object called EEPROM_Monitor. I modified it to be able to use a 24C1024 I wanted to play with.

    That is how I finally wrapped my head around how to read and write above 32K. All of the explanations I had read made sense in my head, but not on the Prop until I tried doing it for myself with a 128K EEPROM. Then it became clear, my head was the problem. :)
  • lardomlardom Posts: 1,659
    edited 2012-12-11 20:33
    @Seeker, is there a link to it?
  • SeekerSeeker Posts: 58
    edited 2013-01-01 16:40
    lardom wrote: »
    @Seeker, is there a link to it?

    I am so sorry I missed your question... Holidays began early with in-laws moving in for a month. :)

    This is the one I was talking about http://obex.parallax.com/objects/612/

    I hope this helps if you still need it.
Sign In or Register to comment.