Erase EEPROM

Go To Last Post
10 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi,

I am doing a project with an AT90USB1287 (4K EEPROM).

I've been looking around but I could not find a method to clear the EEPROM from the application.

In "avr/eeprom.h" there is only a function to transfer bytes from sram to eeprom. However what I want is to erase the entire contents of the eeprom.

So why not using the chip erase from the AVR Studio? Well, I want to erase the eeprom contents when a user presses a button for example (i.e. I am not connected to any programming platform).

The solution I have so far is to erase the eeprom byte after byte but this will reduce the memory's life by 8 times as each byte will rewrite its page (8 bytes - Datasheet, pag. 372).

Any ideas on how should I do that?

Thanks,
Omar

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Make a nice cup of tea and have a sit down.

Most normal applications will never exceed the EEPROM lifetime. And I presume that you are already reading the eeprom location first. No point in writing 0xFF if it already contains 0xFF!

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
for (i=0; i

but why do this? Just write your code so it makes no assumption about the unused EEPROM location state as David says.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I agree with Cliff - use a "valid" byte before each block of data in the EEPROM. If the valid byte does not match your current "valid" value, then ignore the data. In your application, you could simply choose a different valid value when the user tells you, save that value off in the "current valid value" location, and any blocks of data that don't have the proper "valid" prefix are no longer... umm... valid.

Simple, easy, no rewrites, happens almost instantaneously - what's not to like? :D

Stu

Engineering seems to boil down to: Cheap. Fast. Good. Choose two. Sometimes choose only one.

Newbie? Be sure to read the thread Newbie? Start here!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks for all the replies.

I also thought about the idea where instead of erasing byte after byte I could use the eeprom_write_block function to write page after page (i.e. blocks of page_bytes).

Based on your suggestions, I think a code like below might be useful:

void EraseEEPROM()
{
 uint8_t sreg, i;
 uint16_t addr;
 uint8_t clear[8] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
 uint8_t data[8];

 sreg = SREG;
 cli();

 // Write page by page using the block writing method
 for(addr = 0; addr < EEPROM_END; addr += 8)
 {
   eeprom_read_block((void *)&data[0], (const void *)addr, 8);
   for(i = 0; i < 8; i++)
     if(data[i] != 0xFF)
     {
       eeprom_write_block((void*)&clear[0], (void*)addr, 8);
       break;
     }
 }
		
 SREG = sreg;
}

Very useful ideas from all, thank you.

Omar

Last Edited: Thu. May 27, 2010 - 04:07 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I had never actually looked at how avr-gcc implements eeprom_write_byte().

It makes no attempt to read the existing contents, so it writes regardless. This can seriously compromise your eeprom endurance. So I would write a 'eeprom_update_byte()' function.
Using 'eeprom_write_block()' simply calls the 'eeprom_write-byte()' primitive.

Incidentally, CodeVision handles this transparently.

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

So I would write a 'eeprom_update_byte()' function.

David,

Someone beat you to it. Sadly the online copy of the avr-libc manual does not seem to reflect this but the eeprom.h in WinAVR20100110 now has:

===========================================================================
    - In addition to the write functions there is a set of update ones.
    This functions read each byte first and skip the burning if the
    old value is the same with new.  The scaning direction is from
    high address to low, to obtain quick return in common cases.

and:

/** \ingroup avr_eeprom
    Update a byte \a __value to EEPROM address \a __p.
 */
void eeprom_update_byte (uint8_t *__p, uint8_t __value);

/** \ingroup avr_eeprom
    Update a word \a __value to EEPROM address \a __p.
 */
void eeprom_update_word (uint16_t *__p, uint16_t __value);

/** \ingroup avr_eeprom
    Update a 32-bit double word \a __value to EEPROM address \a __p.
 */
void eeprom_update_dword (uint32_t *__p, uint32_t __value);

/** \ingroup avr_eeprom
    Update a float \a __value to EEPROM address \a __p.
 */
void eeprom_update_float (float *__p, float __value);

/** \ingroup avr_eeprom
    Update a block of \a __n bytes to EEPROM address \a __dst from \a __src.
    \note The argument order is mismatch with common functions like strcpy().
 */
void eeprom_update_block (const void *__src, void *__dst, size_t __n);

So GCC finally caught up with CV in this respect ;-)

This from the source code tracker:

Quote:
Revision 1974 - (view) (download) (as text) (annotate) - [select for diffs]
Modified Fri Jun 5 22:58:34 2009 UTC (11 months, 2 weeks ago) by dmix
File length: 17906 byte(s)
Diff to previous 1946
Apply the patch #6718 (optimize the EEPROM functions).
Rewrite all function definitions. Add a set of 'update' functions. Add a
set of float arg functions. Add a documentation.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I am still using 2008, which does not have the 'update' functions. Perhaps I should install the 2010 release.

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

Perhaps I should install the 2010 release.

With something that grows organically like GCC (or Linux for that matter) I'd always use the latest version as it likely has more bug fixes and features. OTOH the ftdi_sio fiasco in Ubuntu 9.10 makes me wonder if one should always "jump right in" or leave it for a "cooling off" period first.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I've edited my previous post with a function that should do the job.

However looking at the update_block function it seems the functionality is done, possibly more efficient.

Thus the update_block method could be used in a simple for through all the pages in the EEPROM.

Omar