From 07def0505c0f5921fadfa6a248e880a9c49bbf12 Mon Sep 17 00:00:00 2001 From: Peter Hinch Date: Sat, 21 Dec 2019 09:25:32 +0000 Subject: [PATCH] Tested with 256KiB STM chip. SPI bug fixed. --- README.md | 2 -- i2c/eeprom_i2c.py | 1 + spi/SPI.md | 2 -- spi/eeprom_spi.py | 75 ++++++++++++++++++++++++++--------------------- 4 files changed, 42 insertions(+), 38 deletions(-) diff --git a/README.md b/README.md index ffdf55e..219e263 100644 --- a/README.md +++ b/README.md @@ -59,8 +59,6 @@ In the table below the Interface column includes page size in bytes. | Microchip | 24xx64 | I2C 128 | 8KiB | EEPROM | [I2C.md](./i2c/I2C.md) | | Adafruit | 1895 | I2C n/a | 32KiB | FRAM | [FRAM.md](./fram/FRAM.md) | -**STM chip support under development** - Documentation: [SPI.md](./spi/SPI.md) [I2C.md](./i2c/I2C.md) diff --git a/i2c/eeprom_i2c.py b/i2c/eeprom_i2c.py index 8d6fdc9..6d177f0 100644 --- a/i2c/eeprom_i2c.py +++ b/i2c/eeprom_i2c.py @@ -82,3 +82,4 @@ class EEPROM(BlockDevice): nbytes -= npage start += npage addr += npage + return buf diff --git a/spi/SPI.md b/spi/SPI.md index 5db3537..cce76c1 100644 --- a/spi/SPI.md +++ b/spi/SPI.md @@ -4,8 +4,6 @@ This driver supports the Microchip 25xx1024 series of 128KiB SPI EEPROMs and the STM M95M02-DR 256KiB device. These have 1M and 4M cycles of write endurance respectively (compared to 10K for Pyboard Flash memory). -**NOTE: STM chip not yet tested** - Multiple chips may be used to construct a single logical nonvolatile memory module. The driver allows the memory either to be mounted in the target filesystem as a disk device or to be addressed as an array of bytes. diff --git a/spi/eeprom_spi.py b/spi/eeprom_spi.py index 77ade0a..60ae343 100644 --- a/spi/eeprom_spi.py +++ b/spi/eeprom_spi.py @@ -9,19 +9,21 @@ import time from micropython import const from bdevice import BlockDevice -# Supported instruction set +# Supported instruction set - common to both chips: _READ = const(3) _WRITE = const(2) _WREN = const(6) # Write enable _RDSR = const(5) # Read status register +# Microchip only: _RDID = const(0xab) # Read chip ID -_CE = const(0xc7) # Chip erase (Microchip only) +_CE = const(0xc7) # Chip erase +# STM only: +_RDID_STM = const(0x83) # Read ID page +_WRID_STM = const(0x82) +_STM_ID = const(0x30) # Arbitrary ID for STM chip # Not implemented: Write disable and Write status register # _WRDI = const(4) # _WRSR = const(1) -#_RDID_STM = const(0x83) # STM only read ID page -#_WRID_STM = const(0x82) -#_STM_ID = const(0x30) # Arbitrary ID for STM chip # Logical EEPROM device comprising one or more physical chips sharing an SPI bus. class EEPROM(BlockDevice): @@ -39,37 +41,41 @@ class EEPROM(BlockDevice): self._mvp = memoryview(self._bufp) # cost-free slicing self.scan(verbose) -# STM Datasheet too vague about the ID block. Do we need _WREN? Do we need to poll ready? - #def _stm_rdid(self): - #mvp = self._mvp - #mvp[:] = b'\0\0\0\0\0' - #mvp[0] = _RDID_STM - #cs(0) - #self._spi.write_readinto(mvp, mvp) - #cs(1) - #return mvp[4] + # Read ID block ID[0] + def _stm_rdid(self, n): + cs = self._cspins[n] + mvp = self._mvp + mvp[:] = b'\0\0\0\0\0' + mvp[0] = _RDID_STM + cs(0) + self._spi.write_readinto(mvp, mvp) + cs(1) + return mvp[4] - #def _stm_wrid(self): - #mvp = self._mvp - #mvp[:] = b'\0\0\0\0\0' - #mvp[0] = _WRID_STM - #mvp[5] = _STM_ID - #cs(0) - #self._spi.write(mvp) - #cs(1) + # Write a fixed value to ID[0] + def _stm_wrid(self, n): + cs = self._ccs + mvp = self._mvp + mvp[0] = _WREN + cs(0) + self._spi.write(mvp[:1]) # Enable write + cs(1) + mvp[:] = b'\0\0\0\0\0' + mvp[0] = _WRID_STM + mvp[4] = _STM_ID + cs(0) + self._spi.write(mvp) + cs(1) + self._wait_rdy() - # Check for a valid hardware configuration: just see if we can write to offset 0 - # Tested (on Microchip), but probably better to use ID block + # Check for valid hardware on each CS pin: use ID block def _stm_scan(self): - for n in range(len(self._cspins)): - ta = n * self._c_bytes - v = self[ta] - vx = v^0xff - self[ta] = vx - if self[ta] == vx: # Wrote OK, put back - self[ta] = v - else: - raise RuntimeError('EEPROM not found at cs[{}].'.format(n)) + for n, cs in enumerate(self._cspins): + self._ccs = cs + if self._stm_rdid(n) != _STM_ID: + self._stm_wrid(n) + if self._stm_rdid(n) != _STM_ID: + raise RuntimeError('M95M02 chip not found at cs[{}].'.format(n)) return n # Scan for Microchip devices: read manf ID @@ -82,7 +88,7 @@ class EEPROM(BlockDevice): self._spi.write_readinto(mvp, mvp) cs(1) if mvp[4] != 0x29: - raise RuntimeError('EEPROM not found at cs[{}].'.format(n)) + raise RuntimeError('25xx1024 chip not found at cs[{}].'.format(n)) return n # Check for a valid hardware configuration @@ -163,3 +169,4 @@ class EEPROM(BlockDevice): nbytes -= npage start += npage addr += npage + return buf