Merge pull request #14 from JFF-Bohdan/master

Add support of Microchip AT24C32
pull/16/head
Peter Hinch 2022-10-29 17:35:33 +01:00 zatwierdzone przez GitHub
commit 7c1496783e
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: 4AEE18F83AFDEB23
4 zmienionych plików z 29 dodań i 21 usunięć

Wyświetl plik

@ -76,6 +76,7 @@ In the table below the Interface column includes page size in bytes.
| Microchip | 24xx256 | I2C 128 | 32KiB | EEPROM | [I2C.md](./eeprom/i2c/I2C.md) |
| Microchip | 24xx128 | I2C 128 | 16KiB | EEPROM | [I2C.md](./eeprom/i2c/I2C.md) |
| Microchip | 24xx64 | I2C 128 | 8KiB | EEPROM | [I2C.md](./eeprom/i2c/I2C.md) |
| Microchip | 24xx32 | I2C 32 | 4KiB | EEPROM | [I2C.md](./eeprom/i2c/I2C.md) |
| Adafruit | 4719 | SPI n/a | 512KiB | FRAM | [FRAM_SPI.md](./fram/FRAM_SPI.md) |
| Adafruit | 4718 | SPI n/a | 256KiB | FRAM | [FRAM_SPI.md](./fram/FRAM_SPI.md) |
| Adafruit | 1895 | I2C n/a | 32KiB | FRAM | [FRAM.md](./fram/FRAM.md) |

Wyświetl plik

@ -124,7 +124,8 @@ is detected or if device address lines are not wired as described in
Arguments:
1. `i2c` Mandatory. An initialised master mode I2C bus created by `machine`.
2. `chip_size=T24C512` The chip size in bits. The module provides constants
`T24C64`, `T24C128`, `T24C256`, `T24C512` for the supported chip sizes.
`T24C32`, `T24C64`, `T24C128`, `T24C256`, `T24C512` for the supported
chip sizes.
3. `verbose=True` If `True`, the constructor issues information on the EEPROM
devices it has detected.
4. `block_size=9` The block size reported to the filesystem. The size in bytes

Wyświetl plik

@ -60,8 +60,8 @@ def _testblock(eep, bs):
return "Block test fail 3:" + str(list(res))
def test():
eep = get_eep()
def test(eep=None):
eep = eep if eep else get_eep()
sa = 1000
for v in range(256):
eep[sa + v] = v
@ -99,8 +99,8 @@ def test():
# ***** TEST OF FILESYSTEM MOUNT *****
def fstest(format=False):
eep = get_eep()
def fstest(eep=None, format=False):
eep = eep if eep else get_eep()
try:
uos.umount("/eeprom")
except OSError:
@ -121,8 +121,8 @@ def fstest(format=False):
print(uos.statvfs("/eeprom"))
def cptest(): # Assumes pre-existing filesystem of either type
eep = get_eep()
def cptest(eep=None): # Assumes pre-existing filesystem of either type
eep = eep if eep else get_eep()
if "eeprom" in uos.listdir("/"):
print("Device already mounted.")
else:
@ -139,13 +139,13 @@ def cptest(): # Assumes pre-existing filesystem of either type
# ***** TEST OF HARDWARE *****
def full_test():
eep = get_eep()
def full_test(eep=None, block_size = 128):
eep = eep if eep else get_eep()
page = 0
for sa in range(0, len(eep), 128):
data = uos.urandom(128)
eep[sa : sa + 128] = data
if eep[sa : sa + 128] == data:
for sa in range(0, len(eep), block_size):
data = uos.urandom(block_size)
eep[sa : sa + block_size] = data
if eep[sa : sa + block_size] == data:
print("Page {} passed".format(page))
else:
print("Page {} readback failed.".format(page))

Wyświetl plik

@ -8,21 +8,24 @@ from micropython import const
from bdevice import BlockDevice
_ADDR = const(0x50) # Base address of chip
_MAX_CHIPS_COUNT = const(8) # Max number of chips
T24C512 = const(65536) # 64KiB 512Kbits
T24C256 = const(32768) # 32KiB 256Kbits
T24C128 = const(16384) # 16KiB 128Kbits
T24C64 = const(8192) # 8KiB 64Kbits
T24C32 = const(4096) # 4KiB 32Kbits
# Logical EEPROM device consists of 1-8 physical chips. Chips must all be the
# same size, and must have contiguous addresses starting from 0x50.
# same size, and must have contiguous addresses.
class EEPROM(BlockDevice):
def __init__(self, i2c, chip_size=T24C512, verbose=True, block_size=9):
self._i2c = i2c
if chip_size not in (T24C64, T24C128, T24C256, T24C512):
if chip_size not in (T24C32, T24C64, T24C128, T24C256, T24C512):
print("Warning: possible unsupported chip. Size:", chip_size)
nchips = self.scan(verbose, chip_size) # No. of EEPROM chips
nchips, min_chip_address = self.scan(verbose, chip_size) # No. of EEPROM chips
super().__init__(block_size, nchips, chip_size)
self._min_chip_address = min_chip_address
self._i2c_addr = 0 # I2C address of current chip
self._buf1 = bytearray(1)
self._addrbuf = bytearray(2) # Memory offset into current chip
@ -30,16 +33,19 @@ class EEPROM(BlockDevice):
# Check for a valid hardware configuration
def scan(self, verbose, chip_size):
devices = self._i2c.scan() # All devices on I2C bus
eeproms = [d for d in devices if _ADDR <= d < _ADDR + 8] # EEPROM chips
eeproms = [d for d in devices if _ADDR <= d < _ADDR + _MAX_CHIPS_COUNT] # EEPROM chips
nchips = len(eeproms)
if nchips == 0:
raise RuntimeError("EEPROM not found.")
if min(eeproms) != _ADDR or (max(eeproms) - _ADDR) >= nchips:
raise RuntimeError("Non-contiguous chip addresses", eeproms)
eeproms = sorted(eeproms)
if len(set(eeproms)) != len(eeproms):
raise RuntimeError('Duplicate addresses were found', eeproms)
if (eeproms[-1] - eeproms[0] + 1) != len(eeproms):
raise RuntimeError('Non-contiguous chip addresses', eeproms)
if verbose:
s = "{} chips detected. Total EEPROM size {}bytes."
print(s.format(nchips, chip_size * nchips))
return nchips
return nchips, min(eeproms)
def _wait_rdy(self): # After a write, wait for device to become ready
self._buf1[0] = 0
@ -60,7 +66,7 @@ class EEPROM(BlockDevice):
ca, la = divmod(addr, self._c_bytes) # ca == chip no, la == offset into chip
self._addrbuf[0] = (la >> 8) & 0xFF
self._addrbuf[1] = la & 0xFF
self._i2c_addr = _ADDR + ca
self._i2c_addr = self._min_chip_address + ca
pe = (addr & ~0x7F) + 0x80 # byte 0 of next page
return min(nbytes, pe - la)