From 208b3089bb21ec6c22a6730f95a007465603d34d Mon Sep 17 00:00:00 2001 From: Abel Deuring Date: Wed, 3 Jan 2024 17:24:41 +0100 Subject: [PATCH 1/2] Add support for I2C EEPROMs with page sizes other than 128 in eeprom_i2c.py. --- eeprom/i2c/eep_i2c.py | 6 ++++-- eeprom/i2c/eeprom_i2c.py | 22 ++++++++++++++++++++-- 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/eeprom/i2c/eep_i2c.py b/eeprom/i2c/eep_i2c.py index 1db9b9a..f9c1489 100644 --- a/eeprom/i2c/eep_i2c.py +++ b/eeprom/i2c/eep_i2c.py @@ -132,8 +132,10 @@ def cptest(eep=None): # Assumes pre-existing filesystem of either type print("Fail mounting device. Have you formatted it?") return print("Mounted device.") - cp("eep_i2c.py", "/eeprom/") - cp("eeprom_i2c.py", "/eeprom/") + cp(__file__, "/eeprom/") + # We may have the source file or a precompiled binary (*.mpy) + suffix = __file__[__file__.rfind('.'):] + cp("eeprom_i2c" + suffix, "/eeprom/") print('Contents of "/eeprom": {}'.format(uos.listdir("/eeprom"))) print(uos.statvfs("/eeprom")) diff --git a/eeprom/i2c/eeprom_i2c.py b/eeprom/i2c/eeprom_i2c.py index 7fc1f91..844eb95 100644 --- a/eeprom/i2c/eeprom_i2c.py +++ b/eeprom/i2c/eeprom_i2c.py @@ -16,10 +16,18 @@ T24C128 = const(16384) # 16KiB 128Kbits T24C64 = const(8192) # 8KiB 64Kbits T24C32 = const(4096) # 4KiB 32Kbits +_PAGE_SIZES = { + T24C32: const(0x20), + T24C64: const(0x20), + T24C128: const(0x40), + T24C256: const(0x40), + T24C512: const(0x80), + } + # Logical EEPROM device consists of 1-8 physical chips. Chips must all be the # same size, and must have contiguous addresses. class EEPROM(BlockDevice): - def __init__(self, i2c, chip_size=T24C512, verbose=True, block_size=9, addr=_ADDR, max_chips_count=_MAX_CHIPS_COUNT): + def __init__(self, i2c, chip_size=T24C512, verbose=True, block_size=9, addr=_ADDR, max_chips_count=_MAX_CHIPS_COUNT, page_size=None): self._i2c = i2c if chip_size not in (T24C32, T24C64, T24C128, T24C256, T24C512): print("Warning: possible unsupported chip. Size:", chip_size) @@ -29,6 +37,16 @@ class EEPROM(BlockDevice): self._i2c_addr = 0 # I2C address of current chip self._buf1 = bytearray(1) self._addrbuf = bytearray(2) # Memory offset into current chip + if page_size is None: + if chip_size not in _PAGE_SIZES: + raise ValueError( + f'The page size for chip size {chip_size} is not known.' + 'Please specify it in the parameter page_size') + self._page_mask = ~(_PAGE_SIZES[chip_size] - 1) + self._page_size = _PAGE_SIZES[chip_size] + else: + self._page_mask = ~(page_size - 1) + self._page_size = page_size # Check for a valid hardware configuration def scan(self, verbose, chip_size, addr, max_chips_count): @@ -67,7 +85,7 @@ class EEPROM(BlockDevice): self._addrbuf[0] = (la >> 8) & 0xFF self._addrbuf[1] = la & 0xFF self._i2c_addr = self._min_chip_address + ca - pe = (addr & ~0x7F) + 0x80 # byte 0 of next page + pe = (addr & self._page_mask) + self._page_size # byte 0 of next page return min(nbytes, pe - la) # Read or write multiple bytes at an arbitrary address From 6399f9f6d3f1b5ea5bb2705def4183bb81facfab Mon Sep 17 00:00:00 2001 From: Abel Deuring Date: Sat, 6 Jan 2024 16:07:04 +0100 Subject: [PATCH 2/2] - "Meaning" of the new EEPROM constructor parameter `page_size` changed from the size itself to the binary logarithm of the size. - Default value of this parameter changed from None to 7, to match the behaviour of the constructor in its previous form, as discussed in the PR. - Dictionary _PAGE_SIZES removed. - Documentation updated. --- eeprom/i2c/I2C.md | 1 + eeprom/i2c/eeprom_i2c.py | 22 +++------------------- 2 files changed, 4 insertions(+), 19 deletions(-) diff --git a/eeprom/i2c/I2C.md b/eeprom/i2c/I2C.md index 9c3ad72..be02b89 100644 --- a/eeprom/i2c/I2C.md +++ b/eeprom/i2c/I2C.md @@ -132,6 +132,7 @@ Arguments: is `2**block_size` so is 512 bytes by default. 5. `addr` override base address for first chip 6. `max_chips_count` override max_chips_count + 7. `page_size=7` The binary logarithm of the page size of the EEPROMs, i.e., the page size in bytes is `2 ** page_size`. The page size may vary between chips from different manufacturers even for the same storage size. Note that specifying a too large value will most likely lead to data corruption in write operations. Look up the correct value for your setup in the chip's datasheet. With `addr` and `max_chips_count` override, it's possible to make multiple configuration diff --git a/eeprom/i2c/eeprom_i2c.py b/eeprom/i2c/eeprom_i2c.py index 844eb95..c64a7c6 100644 --- a/eeprom/i2c/eeprom_i2c.py +++ b/eeprom/i2c/eeprom_i2c.py @@ -16,18 +16,10 @@ T24C128 = const(16384) # 16KiB 128Kbits T24C64 = const(8192) # 8KiB 64Kbits T24C32 = const(4096) # 4KiB 32Kbits -_PAGE_SIZES = { - T24C32: const(0x20), - T24C64: const(0x20), - T24C128: const(0x40), - T24C256: const(0x40), - T24C512: const(0x80), - } - # Logical EEPROM device consists of 1-8 physical chips. Chips must all be the # same size, and must have contiguous addresses. class EEPROM(BlockDevice): - def __init__(self, i2c, chip_size=T24C512, verbose=True, block_size=9, addr=_ADDR, max_chips_count=_MAX_CHIPS_COUNT, page_size=None): + def __init__(self, i2c, chip_size=T24C512, verbose=True, block_size=9, addr=_ADDR, max_chips_count=_MAX_CHIPS_COUNT, page_size=7): self._i2c = i2c if chip_size not in (T24C32, T24C64, T24C128, T24C256, T24C512): print("Warning: possible unsupported chip. Size:", chip_size) @@ -37,16 +29,8 @@ class EEPROM(BlockDevice): self._i2c_addr = 0 # I2C address of current chip self._buf1 = bytearray(1) self._addrbuf = bytearray(2) # Memory offset into current chip - if page_size is None: - if chip_size not in _PAGE_SIZES: - raise ValueError( - f'The page size for chip size {chip_size} is not known.' - 'Please specify it in the parameter page_size') - self._page_mask = ~(_PAGE_SIZES[chip_size] - 1) - self._page_size = _PAGE_SIZES[chip_size] - else: - self._page_mask = ~(page_size - 1) - self._page_size = page_size + self._page_size = 2 ** page_size + self._page_mask = ~(self._page_size - 1) # Check for a valid hardware configuration def scan(self, verbose, chip_size, addr, max_chips_count):