Hi again,
I found out that the ACK don't mean JACK
Not sure if i understand what you mean by 60 times a second, because that would then mean the EEPROM has time to 'rest' between byte writes, right?
Anyway, i have some better test results now. The little test program simply writes 2048 bytes from address 0 to 2047, and all it does is write the lower byte of the address as in WriteByte(addr, addr&0xFF); where the byte is addr&0xFF which is always only one byte.
The time came in at 370 milliseconds, and that means 180us per write. Trouble is, it did NOT actually put the bytes into EEPROM, but skipped 7 bytes at a time, actually programming in only the 8th byte even though all 8 of each group was sent out to be written. So it was supposed to write bytes (from addr 0):
00 01 02 03 04 etc.,
but here is the actual printout AFTER the routine finishes:
First 64 EEPROM bytes:
00 FF 03 FF FF FF FF FF 08 FF FF FF FF FF FF FF 10 FF FF FF FF FF FF FF 18 FF FF FF FF FF FF FF 20 FF FF FF FF FF FF FF 28 FF FF FF FF FF FF FF 30 FF FF FF FF FF FF FF 38 FF FF FF FF FF FF FF
Note that all the bytes were hex FF to start with except for that 03 byte which was there already and SHOULD have gotten changed to an 0x02 but it did not change. Thus it appears that the routine to store a byte requires some rest time, before the next byte can be written, and that rest time has to be incorporated into the routine separately.
Now that i see it, i should have known better. That's because the Wire library does not intrinsically know what an "EEPROM" is, it only knows I2C protocol, and there is no protocol change (apparently) for an EEPROM so it thinks everything is over and done with when the EEPROM sends the ACK. Now that i think about it, i never saw anything on the data sheet that declared that the EEPROM was going to respond in some unique way once the write was actually physically accomplished, it just ACK's the data going into the EEPROM as I2C protocol, that's it, and wont respond until the internal byte write is truly over. So the ACK don't mean JACK
This tells me now that the code has to be timed separately to allow time for the writes, if there is more than one within about 10ms.
A better way of course, if time allows, would be to try to read the byte back and if it fails then it needs more time. When the byte is read back right after the time it went in, it should be non volatile at that point. I'll try this next and see how long it takes. I expect at least 8 times as long, or about 1 or 2 milliseconds because it was able to write one byte for every 8 bytes presented to it for storage.
Since every write was taking 432us though, that might mean more like 2.5ms per write, so we'll see because that is the next test. However, the max on the data sheet is still 10ms so i have to observe that or else test the data every time.
The routine would be something like:
WriteByte(Addr, byte);
while (1)
{
retv=ReadByte(Addr);
if (retv==byte)
break;
}
//byte should be ok on exit.
Of course a little timeout test would be added too just in case something goes wrong, and that way an error could be triggered.
I'll have to do another little test to try all this. If i wait 10ms then i know it will take 20 seconds to write 2048 bytes so that's no fun
Another question i have yet to answer though is what happens when the byte is not written yet but a read is performed. Does the code hang and wait, or return 0xFF or 0x00? Either return value will not work because the byte written might supposed to be one of those two, so if it didnt actually get stored yet it will still look like it had been written already. That will have to be tested too i guess.
LATER:
Ok, doing the compare byte in vs byte read test AFTER the write proved to work as all bytes were written, and 256 bytes took 537 milliseconds. That's about 2ms per byte.
Next test, to find out what happens if a byte is presented for write and the write is not done yet, does the read operation hang until done or return some silly number like 0x00 or 0xFF.
I might leave this one for tomorrow.