Forum Menu




 


Log in Problems?
New User? Sign Up!
AVR Freaks Forum Index

Post new topic   Reply to topic
View previous topic Printable version Log in to check your private messages View next topic
Author Message
danni
PostPosted: Mar 21, 2010 - 08:55 PM
Raving lunatic


Joined: Sep 05, 2001
Posts: 2496


Reading the EEPROM need longer than reading the SRAM.
Writing the EEPROM need over 1000 times longer and was also limited in count.

Thus I use always the follwing approach:
I manipulate not the EEPROM directly, I establish an image on the SRAM and do all the access on it.
And to update the SRAM image (e.g. after reset) or write back to the EEPROM, I call a function to do so.
Since the AVR-GCC routines cause a big code bloat, I wrote my own function.
Since reading or writing the EEPROM need many similar steps, I combined both into a single function.
Also to avoid unneeded EEPROM wearout, I write only, if the EEPROM content was different to the new value.

Following the eeprom.c:
Code:

#include <util/atomic.h>


void eeprom_rw( uint16_t eep, uint8_t *sram, uint8_t len, uint8_t write )
{
  uint8_t val;

  do{
    EEAR = eep;
    EECR |= 1<<EERE;                    // read
    val = EEDR;
    if( write ){                        // write or read action
      if( *sram != val ){               // if not equal
        EEDR = *sram;                   // load data
        ATOMIC_BLOCK(ATOMIC_FORCEON){
          EECR |= 1<<EEMPE;
          EECR |= 1<<EEPE;              // write
        }
        while( EECR & 1<<EEPE );        // wait until write done
      }
    }else{
      *sram = val;
    }
    sram++;
    eep++;
  }while( --len );                      // 1..256 byte
}


And the eeprom.h:
Code:

void eeprom_rw( uint16_t eep, uint8_t *sram, uint8_t len, uint8_t write );

#define eeprom_read(sram, eep, len)     eeprom_rw( eep, (void*)sram, len, 0 )
#define eeprom_write(eep, sram, len)    eeprom_rw( eep, (void*)sram, len, 1 )


Then I combine all parameters, which must be stored, into a struct and update always the whole struct.
Since unneeded EEPROM wearout was suppressed, you can always store the whole struct, even if only one parameter was changed.

Following an example code:
Code:

#include <avr/io.h>
#include "eeprom.h"


#define EE_ADDR 1


struct{
  uint32_t p0;
  float p1;
  int16_t p2;
  uint8_t p3;
}eeprom_data;



int main( void )
{
  eeprom_read( &eeprom_data, EE_ADDR, sizeof(eeprom_data) );

  eeprom_data.p0++;

  eeprom_write( EE_ADDR, &eeprom_data, sizeof(eeprom_data) );

  for(;;){
  }
}



Peter
 
 View user's profile Send private message  
Reply with quote Back to top
bretm
PostPosted: Mar 26, 2010 - 10:00 PM
Rookie


Joined: Mar 15, 2010
Posts: 49


You're writing one byte at a time, sequentially. According to the avr-libc FAQ (any independent confirmation?), when you write one byte, the hardware is actually erasing and rewriting an entire page, typically 4 bytes. So if you want to maximize EEPROM lifetime, consider having your block-writing routine spread the bytes across pages by rotating the two MSBs of the address down to the LSB positions. The details vary by EEPROM page size and capacity.

This works best if you're using less than 1/4th of the EEPROM (for 4-byte pages) and doesn't help at all if you're updating 3/4ths or more.
 
 View user's profile Send private message  
Reply with quote Back to top
Koshchi
PostPosted: Mar 27, 2010 - 01:46 AM
10k+ Postman


Joined: Nov 17, 2004
Posts: 13815
Location: Vancouver, BC

Quote:
According to the avr-libc FAQ (any independent confirmation?), when you write one byte, the hardware is actually erasing and rewriting an entire page, typically 4 bytes.

I have never heard this before, and looking through all the Atmel application notes concerning EEPROM that I could find turned up nothing. App note avr103 seems to directly contradict the page assertion. And avr101, which specifically deals with extending the life of EEPROM fails to mention it.

_________________
Regards,
Steve A.

The Board helps those that help themselves.
 
 View user's profile Send private message  
Reply with quote Back to top
danni
PostPosted: Mar 27, 2010 - 10:41 AM
Raving lunatic


Joined: Sep 05, 2001
Posts: 2496


bretm wrote:
You're writing one byte at a time, sequentially.


Yes.

Until now, I have no ATtiny/ATmega seen, which support page write from the application.
Thus no page write can be implemented.

Page write was only possible with an external programmer.


Peter
 
 View user's profile Send private message  
Reply with quote Back to top
paulster
PostPosted: Mar 27, 2010 - 01:30 PM
Newbie


Joined: Feb 09, 2010
Posts: 6


That's a nice solution to bulk reading and writing the EEPROM, which is handy as I was thinking about doing just that.

It's a shame there doesn't appear to be a way of doing a page-wide write though, if that's what is happening behind the scenes.

A good (IMO) addition to the code would be to extend it to structures >255 bytes long so an array of program data could, for instance, be read out of EEPROM at startup.
 
 View user's profile Send private message  
Reply with quote Back to top
bretm
PostPosted: Apr 02, 2010 - 09:31 PM
Rookie


Joined: Mar 15, 2010
Posts: 49


Koshchi wrote:
I have never heard this before, and looking through all the Atmel application notes concerning EEPROM that I could find turned up nothing.


The source of this seems to be avr-libc developer Bob Paddock, based on info recieved "from the factory":

http://lists.gnu.org/archive/html/avr-l ... 00000.html
"The factory has confirmed, via my FAE, that the listed Endurance figures are on a page bases, and not a byte bases."

http://blog.designer-iii.com/avr_eeprom ... dress-zero
Commenting on adding the FAQ entry

Contradicts this:

http://www.atmel.com/dyn/resources/prod ... oc2546.pdf
"When writing to EEPROM one byte is written at a time."

I think I'll just sacrifice a couple of pages of EEPROM to see what happens. Keep writing to one byte on one page and to four bytes on another page until the bytes stop reading back correctly.
 
 View user's profile Send private message  
Reply with quote Back to top
ezharkov
PostPosted: Apr 02, 2010 - 09:45 PM
Resident


Joined: Jun 21, 2005
Posts: 881
Location: Chicago area, USA

bretm wrote:
I think I'll just sacrifice a couple of pages of EEPROM to see what happens. Keep writing to one byte on one page and to four bytes on another page until the bytes stop reading back correctly.
I have tried that. Other freaks also tried similar things. See this thread, for example.

Eugene Zharkov
 
 View user's profile Send private message  
Reply with quote Back to top
bretm
PostPosted: Apr 02, 2010 - 11:44 PM
Rookie


Joined: Mar 15, 2010
Posts: 49


Ok, that seems pretty definitive. And bpaddock posted there, too. Sorry to pollute the thread with bad info! Very Happy
 
 View user's profile Send private message  
Reply with quote Back to top
Display posts from previous:     
Jump to:  
All times are GMT + 1 Hour
Post new topic   Reply to topic
View previous topic Printable version Log in to check your private messages View next topic
Powered by PNphpBB2 © 2003-2006 The PNphpBB Group
Credits