memory-24x

CLI reference

glasgow run memory-24x

Read and write memories compatible with 24-series EEPROM memory, such as Microchip 24C02C, Atmel 24C256, or hundreds of other memories that typically have “24X” (where X is some letter) in their part number.

If the address of a read or write operation points past 255 (for one address byte memories) or 65536 (for two address byte memories), the I²C address has the extra address bits added to it. For example, running glasgow memory-24x -A 0x51 -W 2 read 0x10358 0x100 reads 0x100 bytes from memory address 0x358 at I²C device address 0x52.

Page size

The memory performs writes by first latching incoming data into a page buffer, and committing the page buffer after a stop condition. The internal address counter wraps around to the start of the page whenever the end of the page is reached. Using the correct page size is very important: while a smaller page size can always be used with a memory that has a larger actual page size, the inverse is not true. On the other hand, using the right page size significantly improves performance.

The default page size in this applet is 8, because no memories with page smaller than 8 bytes have been observed so far. If the writes are too slow, look up the page size in the memory documentation. If the writes seem to be corrupted, use the --page-size 1 option.

The pinout of a typical 24-series IC is as follows (the A2:0 pins may be N/C in large devices):

 A0 @ * VCC
 A1 * * WP#
 A2 * * SCL
GND * * SDA
usage: glasgow run memory-24x [-h] [-V SPEC] [--scl PIN] [--sda PIN]
                              [-A I2C-ADDR] -W {1,2} [-P PAGE-SIZE] [-f FREQ]
                              OPERATION ...
-h, --help

show this help message and exit

-V <spec>, --voltage <spec>

configure I/O port voltage to SPEC (e.g.: ‘3.3’, ‘A=5.0,B=3.3’, ‘A=SA’)

--scl <pin>

bind the applet I/O line ‘scl’ to PIN (default: ‘A0’, required)

--sda <pin>

bind the applet I/O line ‘sda’ to PIN (default: ‘A1’, required)

-A <i2c-addr>, --i2c-address <i2c-addr>

I²C address of the memory; typically 0b1010(A2)(A1)(A0) (default: 0b1010000)

-W {1,2}, --address-width {1,2}

number of address bytes to use (one of: 1 2)

-P <page-size>, --page-size <page-size>

page size; writes will be split at addresses that are multiples of PAGE-SIZE

-f <freq>, --frequency <freq>

set SCL frequency to FREQ kHz (default: 400, range: 100…4000)

glasgow run memory-24x read
usage: glasgow run memory-24x read [-h] [-f FILENAME] ADDRESS LENGTH
address

read memory starting at address ADDRESS, with wraparound

length

read LENGTH bytes from memory

-h, --help

show this help message and exit

-f <filename>, --file <filename>

write memory contents to FILENAME

glasgow run memory-24x verify
usage: glasgow run memory-24x verify [-h] (-d DATA | -f FILENAME) ADDRESS
address

verify memory starting at address ADDRESS

-h, --help

show this help message and exit

-d <data>, --data <data>

compare memory with DATA as hex bytes

-f <filename>, --file <filename>

compare memory with contents of FILENAME

glasgow run memory-24x write
usage: glasgow run memory-24x write [-h] (-d DATA | -f FILENAME) ADDRESS
address

write memory starting at address ADDRESS

-h, --help

show this help message and exit

-d <data>, --data <data>

write memory with DATA as hex bytes

-f <filename>, --file <filename>

write memory with contents of FILENAME

API reference

class glasgow.applet.memory._24x.Memory24xInterface(logger: Logger, interface: I2CControllerInterface, i2c_address: int, address_width: Literal[1, 2], page_size: int)
async read(address: int, length: int) bytes

Read length bytes at address.

If address is larger than the maximum representable given the address width (i.e. greater than 0x100 or 0x10000 for 1 and 2 address byte memories respectively), the “extra” address bits are carried over into the I²C address by addition. For example, calling read(0x10358, 0x100) when configured with i2c_address=0x51, address_width=2 reads 0x100 bytes from memory address 0x358 at I²C device address 0x52.

Note

While this behavior is suitable for most memories, there may be cases where it is not appropriate; for example, if a memory wraps over at 0x100 byte or 0x10000 byte boundaries instead of returning data that would be read from the next I²C address over.

Raises:

I2CNotAcknowledged – If communication fails; if a previous write hasn’t completed yet.

async write(address: int, data: bytes | bytearray | memoryview)

Write data bytes at address.

The data is broken up into chunks such that each chunk is aligned to, and no larger than, page_size. This algorithm assumes that partial page writes update only the part being written, which is true for virtually every 24-series memory.

The note on address bit carry-over in read() also applies here, with the caveat that reading is done in one long request, but writing is done page-wise, and the address is sent anew for each write.

This method waits for the write to complete by polling the device until it responds to its address (“Acknowledge Polling”).

Raises:

I2CNotAcknowledged – If communication fails; if a previous write hasn’t completed yet.