Hi,
After reading the preceding posts, maybe what is happening is this...
The page size is 4 bytes, so say we first write data 0x10 to location 0x000, 0x11 to location 0x001, 0x12 to location 0x002, and 0x13 to location 0x003. We now have:
0x000 0x10
0x001 0x11
0x002 0x12
0x003 0x13
Next we write 0x20 to location 0x000, and that means it reads locations 0x001 to 0x003 and rewrites them and writes the new data to 0x000 so we have:
0x000 0x20
0x001 0x11
0x002 0x12
0x003 0x13
Maybe what it does is when it rewrites locations 0x001 to 0x003 it does not have the flip any bits so there is no change. But then again that doesnt seem to make sense either because i think when it writes data it first erases the old data and then writes the new data. But maybe if the data in locations 0x001 to 0x003 is already in the erased state nothing changes. So that would mean that the data in those three locations would have to be data with some bits 1 and some bits 0 in order to make sure the test was effective.
I did not study the code in detail to make sure this is what was done but perhaps you can check.
It doesnt seem like it would make too much sense to specify a page size if they had some algorithm that could check to see if the other bytes really had to be changed, unless maybe if we could save 4 bytes in the same write time which would save time in some algorithms. That would mean larger data types (like type long) would write maybe four times faster.
But the test did prove one thing already though, and that is that wear leveling would help, even if not for every single byte. If we had to rewrite type long a lot and only say one or two of them at a time, then we could use successive locations instead of the same location all the time.
If we did use type long, one variable, and we got 1 milliion writes before failure, then with a 1024 byte memory we'd get 256 million writes before failure, which is a lot. Of course if we had to write two longs then we'd only get 128 million writes before failure, but that's still good.
For my purpose for example, i'd want to save the hours, minutes and seconds, which could be stuck into one var of type unsigned long.
So now that we are pretty sure that wear leveling would work for the Arduino and we need to retrieve the stored data on startup, how do we actually retrieve that data? We wont know what location we wrote to last because we cant store that in one location either. Any ideas?
Here's one idea for example...
Start a counter in ram, starting at counter=0x00000000.
Store 0x00000001 to the first four byte locations, and that will be our pointer.
Write new data values to location pointer4, which in this case would be locations 0x004 through 0x007.
Increment the counter.
If the counter gets to some high value like 0x00020000, move to the next four locations by incrementing the pointer to 0x00000002, store the value in the location pointer4 again, clear the counter back to zero.
On startup, read locations 0x000 to 0x003 for the pointer, then use that to read the data at pointer*4.
Read back the actual data.
Start the counter over at 0x00000000, increment the pointer, store it back, store the data into the new location.
So on startup we'd always read the pointer, use that to find the data, start a new counter, increment the pointer, store the data in the new location.
We'd also have to make sure this always works no matter when the power goes out.
Another idea would be to load the entire memory with zeros, and use the first non zero value found as the data bytes. We'd loose some writes this way though as we'd have to zero the bytes on startup.
This would have to be done so that it would work even if the power went out while we were doing the housekeeping.
Something to think about.