Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

AT24C32 True Write Cycle Time

Status
Not open for further replies.
All i know is what the data sheet says, and it says there is a page size of 32 bytes.

Ok. I looked at the datasheet. If you're signaling at 100kHz, the time you're getting is only just enough for communications. So, the response you get is immediate. The datasheet explicitly says that the input gets disabled during the write cycle. From that, I would conclude that it is most likely a bug in your program and it either doesn't pull ACK at all, or pulls it incorrectly.
 
Ok. I looked at the datasheet. If you're signaling at 100kHz, the time you're getting is only just enough for communications. So, the response you get is immediate. The datasheet explicitly says that the input gets disabled during the write cycle. From that, I would conclude that it is most likely a bug in your program and it either doesn't pull ACK at all, or pulls it incorrectly.

Hello again,

Well, there would have to be a bug in the Wire library then because that is what my program really uses to communicate.
I did not write the Wire library, but it is used for a lot of I2C devices like the 1602 LCD display. It seems to work on everything i've used it for.
 
Well, there would have to be a bug in the Wire library then because that is what my program really uses to communicate.
I did not write the Wire library, but it is used for a lot of I2C devices like the 1602 LCD display. It seems to work on everything i've used it for.

I don't know what is the Wire library, but I do know that any software may have bugs. Could be a bug in the library. Could be a bug in the code which uses the library. Could be a bug in time measurements. Or perhaps the chip is not AT24C32, but some newer pin-compatible replacement. Any of these seems more likely than a fundamental flaw in the datasheet.
 
I don't know what is the Wire library, but I do know that any software may have bugs. Could be a bug in the library. Could be a bug in the code which uses the library. Could be a bug in time measurements. Or perhaps the chip is not AT24C32, but some newer pin-compatible replacement. Any of these seems more likely than a fundamental flaw in the datasheet.

Hi,

The Wire library is a library that was written quite a while back and has been used with the Arudino IDE for years now.
My only guess is that the code returns without waiting for the EEPROM to finish, or else the EEPROM is much faster under certain conditions. One of these conditions might be when it is brand new, as this one is. It's a guessing game that's why i posted this thread to find out if anyone here might know already and save me from some work. So it's not about trying to guess what might be wrong really, it's about someone being able to tell me what is wrong without any guess work because i already have several guesses :) I still appreciated you looking into this though and if you feel up to doing some tests too that's cool also.

My only option seems to be to take Pommie's advice and write a larger set of data, and time it with a stop watch. It cant return after every byte then because the internal storage of the EEPROM (ram) would have to be 4096 bytes. It could be so, but if so i would think they would mention that on the data sheet.

See i'd like to know what is happening definitively, if that is possible. My only remaining fear is that the test may prove fast, but then later in the EEPROM cycle life it starts to slow down. I dont want to have to waste the EEPROM just for the test. I guess one or two tests that involve a large amount of data being written cant hurt though as the cycle life is quoted as being more than 1 million writes.
 
Do you have a digital scope?
Capture the data and clock signals.
If you only have a analog scope, then put the CPU in a write for ever loop. Set a pin high, write, set pin low, inc pointers, jump to start. Then using scope or frequency counter measure the frequency of the pin. (don't use your CPU to count time)

ALSO
If you write the same information all the time, it might take "no" time. If you write a 3F on top of 3F the memory might signal back done very fast. If you use different data every time it will be slower. (maybe)
 
or else the EEPROM is much faster under certain conditions. One of these conditions might be when it is brand new, as this one is.

I think the write cycle uses some sort of internal oscillator to time the write. The oscillator is probably not very accurate which should produce variance in timing between parts (for example, when I was testing write speed with PICs, I found that internally timed operations vary by about 10% between chips). So I guess it can change a little with age, and definitely will change with temperature. But I don't think there could be many-fold difference.

If you write the whole chip with random values without any extra delays between bytes, then read it back and compare, you will see whether you have some sort of bug in the code or not.

I would also read the markings on the chip, just to make sure it is what they say it is.
 
I think the write cycle uses some sort of internal oscillator to time the write. The oscillator is probably not very accurate which should produce variance in timing between parts (for example, when I was testing write speed with PICs, I found that internally timed operations vary by about 10% between chips). So I guess it can change a little with age, and definitely will change with temperature. But I don't think there could be many-fold difference.

If you write the whole chip with random values without any extra delays between bytes, then read it back and compare, you will see whether you have some sort of bug in the code or not.

I would also read the markings on the chip, just to make sure it is what they say it is.


Hi again,

Yes, good idea. I just have to find the time and energy now to sit down and write a routine using that library to do the tests. Wont take too long so maybe tonight or tomorrow.

The kind if timing change i was talking about might vary due to the chip age itself, like how many times that cell was written to in the past. I dont know if the cells degrade over cycle time, but i would not doubt it if they do. Someone else also mentiond that the 10ms is a max spec and i keep forgetting that too, but i figured at least 1ms anyway. We'll soon see :)
 
Do you have a digital scope?
Capture the data and clock signals.
If you only have a analog scope, then put the CPU in a write for ever loop. Set a pin high, write, set pin low, inc pointers, jump to start. Then using scope or frequency counter measure the frequency of the pin. (don't use your CPU to count time)

ALSO
If you write the same information all the time, it might take "no" time. If you write a 3F on top of 3F the memory might signal back done very fast. If you use different data every time it will be slower. (maybe)

Hi,

Yeah my scope is analog. I do have a decent frequency counter though. Note i am not trying to wear out the EEPROM either.
Yes i'll be sure to write random data or in such an ordered way that it cant be the same data twice for any byte.

The way i see it is if i do use an external timing source, even a digital stop watch, i should get times that dont rely on the internal timing of the chip or cpu so it should start to make some sense. I'll definitely report any time values that result from the testing.
 
If you write 60 time a second, you eye should be able to see it. Could write to the last byte and not use it just in case.
You can measure the time from the last data until the ack is done.
 
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.
 
Last edited:
When I used one of these chips, I remember having to resend the control byte with the write bit set and the chip will acknowledge only when the write cycle is over. This would, of course, mean altering the write byte routine.

Edit in the datasheet http://www.atmel.com/images/doc0336.pdf ACKNOWLEDGE POLLING is at the bottom of page 9.

Mike.
 
When I used one of these chips, I remember having to resend the control byte with the write bit set and the chip will acknowledge only when the write cycle is over. This would, of course, mean altering the write byte routine.

Edit in the datasheet http://www.atmel.com/images/doc0336.pdf ACKNOWLEDGE POLLING is at the bottom of page 9.

Mike.


Hi again,

That's very interesting, i will look into that too, especially after what i found out after my previous post update.
I found out that the "Wire" library (as it is called and titled and included as "Wire.h", returns a 0xFF while the byte write cycle is in progress internally to the EEPROM. That's not as nice as i had hoped, as i was hoping that it returned something larger than one byte just to show that the operation was not complete. Maybe there's a way to check for an error, but i dont know yet.

This, as i suspected might happen, messes up the nice and clean way of continuously reading the EEPROM (with a timeout period too) until the byte to be written is actually returned ,as that means it was written successfully, and i dont care if the byte was there previously as long as it is there after the write. Because of the return of 0xFF on incomplete that means i'd have to check for a byte of 0xFF to be written and go into a 10ms delay, but only for that byte value. That's not too bad i guess, but it would have been better if it was not that way. If it returned say 0xFFFF that would be much better as that could not be a byte read then.

I'll have to check and see how hard it would be to change the library either to return a 0xFFFF or something like that or else try to send that extra control command you were talking about. Should be interesting.

Funny thing too, before i found out there was an I2C library for the Arduino i write my own mini library to work with an external ADC unit. If i used my own library i would be done by now :)
I find this a lot though in programming for various things, like Windows too. It seems easier to write something myself than to fool with code that is already written but doesnt quite do the job yet. Seems to take longer trying to understand someone else's code than to just write it myself.

I am sort of surprised though that no one here seems to have used the Wire library, or a Wire library for their own microcontroller type, as i thought that was the de facto standard in microcontroller communcations for I2C.
 
I hate generic libraries for exactly this sort of reason... My system has two devices on the I2C bus.. RTC and a 24lc256 one is byte address and the other is word.. I have two separate routines to read write.... I have made a generic routine to accept address size, length differences, random or sequential... It just gets cluttered..

The easiest way is the "serialization" route... The a sequential read / write and the jobs done... All newer languages (including arduino C++) use serialization...

Make a union ie:-

union IOBUF
{
int data[4];
char dataArray[8];
} serial;

Then load the integers via serial.data[0] = "0xa0a0"
when you store sequentially you only need to traverse the byte array!!
Then you only have one housekeeping delay!!!

for(index = 0; index < 8; index++)
outSomewhere = serial.dataArray[index];

This way you only ever block read / write...
 
Funny thing too, before i found out there was an I2C library for the Arduino i write my own mini library to work with an external ADC unit. If i used my own library i would be done by now :)
I find this a lot though in programming for various things, like Windows too. It seems easier to write something myself than to fool with code that is already written but doesnt quite do the job yet. Seems to take longer trying to understand someone else's code than to just write it myself.

Exactly. It's been my experience too. People use libraries for everything because they "don't want to re-invent the wheel". If something goes wrong they may spend days (if not weeks) trying to fix it. In contrast, "re-inventing the wheel" not only provides invaluable learning experience, it actually make things done faster and better.
 
Hi,

Yeah that reminds me, i havent tried my FRAM yet :)

I found that the 'read' function in this Wire lib is supposed to return 0xFFFF as i had hoped, but i had declared the variables as type 'byte' so they might have been doing an implied cast to byte value so i could only read 0xFF. Funny thing though, when i changed the type to the more accurate 'int' type, it didnt help because the lib function still thinks there is a byte available and so returns type int but it is still value 0xFF ha ha. All it does is look at the buffer to see if there is any buffer address left that had not been returned yet, and returns a non error. Too bad, but on anther site someone suggested something like this:

bool Ready(uint8_t DeviceI2CAddress)
{
Wire.beginTransmission();
return !Wire.endTransmission();
}

All i have to do is call that function until it returns a 1, then the byte is actually available and the write cycle has ended.

I tested this although i put that function inline along with some timeout code, and i found that it does in fact work. Before using the function my routine would print out FF 01
FF 02
FF FF 03
FF 04

something like that, and the FF's indicate false reads so there was always at least one false read before the actual byte was returned, but AFTER using the little check routine i get this now:
01
02
03
04
etc.

up to the 256'th byte which says it waits before returning a byte now. Cute.

Another suggestion was to do the low level polling of the EEPROM as suggested here too, but the code is more low level so i'll have to study it before i consider using it. The above works pretty well though so i dont know if i will bother or not.

The other suggestion was as suspected too, that the EEPROM write time takes longer as the EEPROM ages, ages cycle wise, so in the future that 2ms measurement may increase to 10ms and of course at some point it will not write correctly and that's where the Read() comparison comes into play, to test the actual value written after the programmed timeout.

This turned out to be interesting.
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top