[fpc-pascal] FPC/Lazarus on RPi4 - How to read/write I2C connected EEPROM?

Bo Berglund bo.berglund at gmail.com
Mon Apr 3 22:41:10 CEST 2023

On Mon, 3 Apr 2023 14:37:48 -0400, "Jeffrey A. Wormsley via fpc-pascal"
<fpc-pascal at lists.freepascal.org> wrote:

>I noticed you put the part number in the original email.
>Interestingly, the data sheet mentions 64 byte pages, and 1,000,000 erase
>cycles, but does not mention the need to erase a page before writing.  So
>perhaps this part does not have that restriction.
>If you're making a library specifically for this part, then I guess you
>don't have to worry about this.  If you're making a library for generic
>eeprom support, I think you might want to consider that not all parts
>behave this way.

You alerted me to the page size which I have been mis-reading until now it seems
This 128 kbit part is apparently built like this:

- 16384 memory bytes
- Organized as 256 64 byte "pages"
- The page write buffer is 64 bytes, i.e. the same size as a memory "page"

Then there is a discusion about the way the write buffer maps onto the memory
array, which I didn't understand fully...

Page Write
By continuing to load data into the Page Write Buffer after
the 1st data byte and before issuing the STOP condition, up
to  64  bytes  can  be  written  simultaneously  during  one
internal Write cycle (Figure 8). If more data bytes are loaded
than locations available to the end of page, then loading will
continue from the beginning of page, i.e. the page address is
latched and the address count automatically increments to
and then wraps-around at the page boundary. Previously
loaded data can thus be overwritten by new data. What is
eventually written to memory reflects the latest Page Write
Buffer contents. Only data loaded within the most recent
Page Write sequence will be written to memory.

Maybe it is like this:

The page write buffer is 64 bytes and incoming data are written to the buffer
starting at an address (I assume) within that buffer given by the last 6 bits of
the address being written in the command.

This to me reads like the same place in the buffer as eventually in the memory
*page* when written.
And if one continues to send data to the part after reaching the end of the
buffer it writes those to the beginning of the buffer instead (wrap-around,
which is bad and will destroy data).

Finally when the transfer is ended (STOP condition) then the buffer somehow is
moved onto the main memory.

Here I am unclear on how it works, one possibility would be that there is some
bit field or similar on chip that marks bytes in the buffer that have been
written by incoming data. Then all other bytes can be filled from the page in
main memory by reading those to unwritten locations in the buffer.

Or else maybe simpler: when the write starts and the page is determined the
buffer may be filled from a main memory page copy and then overwritten by
incoming data...

Now the buffer has a content that is the same as in main memory except for the
data that were sent in.
So then the part may erase the page in main memory as you stated and once that
is done write the buffer content on top of the page that is now blanked out to
0xff cells.

I cannot think of any other procedure that matches what the datasheet says..
And if it is like this you are right that the cells must be bulk erased before
one can write random data there...
But it is handled without the user having to do anything at all...

Now I have to go back into my code and adjust the handling for the write buffer,
since I can only send in at most 64 bytes at a time and that only if the write
starts at 6 bit address 0 in the buffer. Otherwise less data can be written in
each cycle.

I am transfering the data to write to the write procedure as a TBytes array of
random size and the code needs to start (in most cases) by sending in a smaller
than 64 byte write packet and then fill with full 64 byte pages and then
finalize with a short page at the end of the write procedure. Unless everything
happens to align on 64 byte address boundaries...

Getting a bit dizzy...
But still the main Freepascal interface into Linux that I got from GitHub works
so this is just a case of sequencing the commands correctly! :-)

Thanks for making me read closer into the datasheet!

Bo Berglund
Developer in Sweden

More information about the fpc-pascal mailing list