kopia lustrzana https://github.com/peterhinch/micropython_eeprom
commit
7c1496783e
|
@ -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 | 24xx256 | I2C 128 | 32KiB | EEPROM | [I2C.md](./eeprom/i2c/I2C.md) |
|
||||||
| Microchip | 24xx128 | I2C 128 | 16KiB | 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 | 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 | 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 | 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) |
|
| Adafruit | 1895 | I2C n/a | 32KiB | FRAM | [FRAM.md](./fram/FRAM.md) |
|
||||||
|
|
|
@ -124,7 +124,8 @@ is detected or if device address lines are not wired as described in
|
||||||
Arguments:
|
Arguments:
|
||||||
1. `i2c` Mandatory. An initialised master mode I2C bus created by `machine`.
|
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
|
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
|
3. `verbose=True` If `True`, the constructor issues information on the EEPROM
|
||||||
devices it has detected.
|
devices it has detected.
|
||||||
4. `block_size=9` The block size reported to the filesystem. The size in bytes
|
4. `block_size=9` The block size reported to the filesystem. The size in bytes
|
||||||
|
|
|
@ -60,8 +60,8 @@ def _testblock(eep, bs):
|
||||||
return "Block test fail 3:" + str(list(res))
|
return "Block test fail 3:" + str(list(res))
|
||||||
|
|
||||||
|
|
||||||
def test():
|
def test(eep=None):
|
||||||
eep = get_eep()
|
eep = eep if eep else get_eep()
|
||||||
sa = 1000
|
sa = 1000
|
||||||
for v in range(256):
|
for v in range(256):
|
||||||
eep[sa + v] = v
|
eep[sa + v] = v
|
||||||
|
@ -99,8 +99,8 @@ def test():
|
||||||
|
|
||||||
|
|
||||||
# ***** TEST OF FILESYSTEM MOUNT *****
|
# ***** TEST OF FILESYSTEM MOUNT *****
|
||||||
def fstest(format=False):
|
def fstest(eep=None, format=False):
|
||||||
eep = get_eep()
|
eep = eep if eep else get_eep()
|
||||||
try:
|
try:
|
||||||
uos.umount("/eeprom")
|
uos.umount("/eeprom")
|
||||||
except OSError:
|
except OSError:
|
||||||
|
@ -121,8 +121,8 @@ def fstest(format=False):
|
||||||
print(uos.statvfs("/eeprom"))
|
print(uos.statvfs("/eeprom"))
|
||||||
|
|
||||||
|
|
||||||
def cptest(): # Assumes pre-existing filesystem of either type
|
def cptest(eep=None): # Assumes pre-existing filesystem of either type
|
||||||
eep = get_eep()
|
eep = eep if eep else get_eep()
|
||||||
if "eeprom" in uos.listdir("/"):
|
if "eeprom" in uos.listdir("/"):
|
||||||
print("Device already mounted.")
|
print("Device already mounted.")
|
||||||
else:
|
else:
|
||||||
|
@ -139,13 +139,13 @@ def cptest(): # Assumes pre-existing filesystem of either type
|
||||||
|
|
||||||
|
|
||||||
# ***** TEST OF HARDWARE *****
|
# ***** TEST OF HARDWARE *****
|
||||||
def full_test():
|
def full_test(eep=None, block_size = 128):
|
||||||
eep = get_eep()
|
eep = eep if eep else get_eep()
|
||||||
page = 0
|
page = 0
|
||||||
for sa in range(0, len(eep), 128):
|
for sa in range(0, len(eep), block_size):
|
||||||
data = uos.urandom(128)
|
data = uos.urandom(block_size)
|
||||||
eep[sa : sa + 128] = data
|
eep[sa : sa + block_size] = data
|
||||||
if eep[sa : sa + 128] == data:
|
if eep[sa : sa + block_size] == data:
|
||||||
print("Page {} passed".format(page))
|
print("Page {} passed".format(page))
|
||||||
else:
|
else:
|
||||||
print("Page {} readback failed.".format(page))
|
print("Page {} readback failed.".format(page))
|
||||||
|
|
|
@ -8,21 +8,24 @@ from micropython import const
|
||||||
from bdevice import BlockDevice
|
from bdevice import BlockDevice
|
||||||
|
|
||||||
_ADDR = const(0x50) # Base address of chip
|
_ADDR = const(0x50) # Base address of chip
|
||||||
|
_MAX_CHIPS_COUNT = const(8) # Max number of chips
|
||||||
|
|
||||||
T24C512 = const(65536) # 64KiB 512Kbits
|
T24C512 = const(65536) # 64KiB 512Kbits
|
||||||
T24C256 = const(32768) # 32KiB 256Kbits
|
T24C256 = const(32768) # 32KiB 256Kbits
|
||||||
T24C128 = const(16384) # 16KiB 128Kbits
|
T24C128 = const(16384) # 16KiB 128Kbits
|
||||||
T24C64 = const(8192) # 8KiB 64Kbits
|
T24C64 = const(8192) # 8KiB 64Kbits
|
||||||
|
T24C32 = const(4096) # 4KiB 32Kbits
|
||||||
|
|
||||||
# Logical EEPROM device consists of 1-8 physical chips. Chips must all be the
|
# 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):
|
class EEPROM(BlockDevice):
|
||||||
def __init__(self, i2c, chip_size=T24C512, verbose=True, block_size=9):
|
def __init__(self, i2c, chip_size=T24C512, verbose=True, block_size=9):
|
||||||
self._i2c = i2c
|
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)
|
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)
|
super().__init__(block_size, nchips, chip_size)
|
||||||
|
self._min_chip_address = min_chip_address
|
||||||
self._i2c_addr = 0 # I2C address of current chip
|
self._i2c_addr = 0 # I2C address of current chip
|
||||||
self._buf1 = bytearray(1)
|
self._buf1 = bytearray(1)
|
||||||
self._addrbuf = bytearray(2) # Memory offset into current chip
|
self._addrbuf = bytearray(2) # Memory offset into current chip
|
||||||
|
@ -30,16 +33,19 @@ class EEPROM(BlockDevice):
|
||||||
# Check for a valid hardware configuration
|
# Check for a valid hardware configuration
|
||||||
def scan(self, verbose, chip_size):
|
def scan(self, verbose, chip_size):
|
||||||
devices = self._i2c.scan() # All devices on I2C bus
|
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)
|
nchips = len(eeproms)
|
||||||
if nchips == 0:
|
if nchips == 0:
|
||||||
raise RuntimeError("EEPROM not found.")
|
raise RuntimeError("EEPROM not found.")
|
||||||
if min(eeproms) != _ADDR or (max(eeproms) - _ADDR) >= nchips:
|
eeproms = sorted(eeproms)
|
||||||
raise RuntimeError("Non-contiguous chip addresses", 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:
|
if verbose:
|
||||||
s = "{} chips detected. Total EEPROM size {}bytes."
|
s = "{} chips detected. Total EEPROM size {}bytes."
|
||||||
print(s.format(nchips, chip_size * nchips))
|
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
|
def _wait_rdy(self): # After a write, wait for device to become ready
|
||||||
self._buf1[0] = 0
|
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
|
ca, la = divmod(addr, self._c_bytes) # ca == chip no, la == offset into chip
|
||||||
self._addrbuf[0] = (la >> 8) & 0xFF
|
self._addrbuf[0] = (la >> 8) & 0xFF
|
||||||
self._addrbuf[1] = la & 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
|
pe = (addr & ~0x7F) + 0x80 # byte 0 of next page
|
||||||
return min(nbytes, pe - la)
|
return min(nbytes, pe - la)
|
||||||
|
|
||||||
|
|
Ładowanie…
Reference in New Issue