EEPROM programming question

As I understand it, EEPROM is programmed by writing 4 bytes to a page buffer and then executing the actual erase-write cycle.

The EEPROM library has one write routine - write one byte. This means that if I am writing 4 successive bytes, all to the same page, there will be 4 erase-write cycles. This means that no more than 25000 4-byte operations are guaranteed for that page.

The EEPROM library simply calls a lower level routine with the parameters supplied. When I go looking for the low level routine, I find that there are 5 routines available - to write one byte, 2 bytes (word), 4 bytes (dword and float) or a whole block of bytes.

I would presume that these low level routines assemble the data into pages and do one erase-write cycle per page. In fact, the byte routine would have to read three bytes from EEPROM in order to preserve what is already there.

If this is correct, it would seem to make sense to expand the EEPROM library to include calls that can write 2, 4 and many byte quantities and that doing so could greatly increase the life of the EEPROM, especially if the user took care to take advantage of page boundaries.

Am I missing something?

Pete

PeteC:
As I understand it, EEPROM is programmed by writing 4 bytes to a page buffer and then executing the actual erase-write cycle.

Your understanding is not correct. On AVR processors, EEPROM access is bytewise.

From the ATmega datasheet covering the 328, etc.:

Programming the EEPROM
The EEPROM is organized in pages, see Table 27-12 on page 299. When programming the EEPROM, the program data is latched into a page buffer. This allows one page of data to be programmed simultaneously. The programming algorithm for the EEPROM data memory is as follows (refer to ”Programming the Flash” on page 302 for details on Command, Address and Data loading):

  1. A: Load Command “0001 0001”.
  2. G: Load Address High Byte (0x00 - 0xFF).
  3. B: Load Address Low Byte (0x00 - 0xFF).
  4. C: Load Data (0x00 - 0xFF).
  5. E: Latch data (give PAGEL a positive pulse).
    K: Repeat 3 through 5 until the entire buffer is filled.

L: Program EEPROM page

  1. Set BS1 to “0”.
  2. Give WR a negative pulse. This starts programming of the EEPROM page. RDY/BSY goes low.
  3. Wait until to RDY/BSY goes high before programming the next page (See Figure 27-4 for signal waveforms).

In a table it states that pages on the EEPROM are 4 bytes.

"The ATmega48A/PA/88A/PA/168A/PA/328/P contains 256/512/512/1Kbytes of data EEPROM
memory. It is organized as a separate data space, in which single bytes can be read and written."

"The EEPROM data bytes are addressed linearly between 0 and 255/511/511/1023."

Looks like the hardware itself supports writes to 1 byte.

Your point with the datasheet is correct though. It says page size == 4 bytes. However as far as I understand it, it does NOT say that a page will necessarily be erased before it is written. Actually the exact nature of the Algorithm seems to stay somewhat in the dark. Maybe it is described somewhere else (application or upgrade note maybe).

IMHO the EEProm library is a somewhat poor wrapper for avr-libc. In doubt use avr-libc directly and the issue is solved although "none Arduino style" :wink:

Maybe it is described somewhere else (application or upgrade note maybe)

There are at-length discussions of the EEPROM on avrfreaks.net. The consensus is that the "paging" is essentially a buffer to make external programming of the EEPROM more efficient.

Destructive testing by the same folks reveals that the EEPROM is bytewise.

This allows one page of data to be programmed simultaneously.

Being able to write one page at a time and being bytewise are not mutually exclusive.

A very interesting discussion.

I believe all EEPROMS operate the same way - you have to erase a byte to 0xFF, then write the zero bits.

I'll play with this a bit. In several places I read that an erase-write cycle takes 3.3 msec or, if done separately (wait for erase to finish, then write), 3.6 msec.

I am writing 2 bytes in the same page and getting (using millis()) 3 or 4 msec which implies that both bytes are being written simultaneously even though I am making two consecutive calls.

If I find anything definitive, I'll post it.

PeteC:
I believe all EEPROMS operate the same way - you have to erase a byte to 0xFF, then write the zero bits.

I cannot say if that is true for all EEPROMs but it is true for AVR ones.

I am writing 2 bytes in the same page and getting (using millis()) 3 or 4 msec which implies that both bytes are being written simultaneously even though I am making two consecutive calls.

If you are using the Libc or Arduino Core then the last write is "free". The call does not wait for the write to complete. Try writing 3 bytes then 4 bytes.

Just so we don't spin wheels too much, this isn't the first time this (excellent) question has come up:

http://www.avrfreaks.net/index.php?name=PNphpBB2&file=printview&t=96709&start=0