Tested with 256KiB STM chip. SPI bug fixed.

pull/1/head
Peter Hinch 2019-12-21 09:25:32 +00:00
rodzic 4624fb41c6
commit 07def0505c
4 zmienionych plików z 42 dodań i 38 usunięć

Wyświetl plik

@ -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) | | Microchip | 24xx64 | I2C 128 | 8KiB | EEPROM | [I2C.md](./i2c/I2C.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) |
**STM chip support under development**
Documentation: Documentation:
[SPI.md](./spi/SPI.md) [SPI.md](./spi/SPI.md)
[I2C.md](./i2c/I2C.md) [I2C.md](./i2c/I2C.md)

Wyświetl plik

@ -82,3 +82,4 @@ class EEPROM(BlockDevice):
nbytes -= npage nbytes -= npage
start += npage start += npage
addr += npage addr += npage
return buf

Wyświetl plik

@ -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 the STM M95M02-DR 256KiB device. These have 1M and 4M cycles of write endurance
respectively (compared to 10K for Pyboard Flash memory). 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 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 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. filesystem as a disk device or to be addressed as an array of bytes.

Wyświetl plik

@ -9,19 +9,21 @@ import time
from micropython import const from micropython import const
from bdevice import BlockDevice from bdevice import BlockDevice
# Supported instruction set # Supported instruction set - common to both chips:
_READ = const(3) _READ = const(3)
_WRITE = const(2) _WRITE = const(2)
_WREN = const(6) # Write enable _WREN = const(6) # Write enable
_RDSR = const(5) # Read status register _RDSR = const(5) # Read status register
# Microchip only:
_RDID = const(0xab) # Read chip ID _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 # Not implemented: Write disable and Write status register
# _WRDI = const(4) # _WRDI = const(4)
# _WRSR = const(1) # _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. # Logical EEPROM device comprising one or more physical chips sharing an SPI bus.
class EEPROM(BlockDevice): class EEPROM(BlockDevice):
@ -39,37 +41,41 @@ class EEPROM(BlockDevice):
self._mvp = memoryview(self._bufp) # cost-free slicing self._mvp = memoryview(self._bufp) # cost-free slicing
self.scan(verbose) self.scan(verbose)
# STM Datasheet too vague about the ID block. Do we need _WREN? Do we need to poll ready? # Read ID block ID[0]
#def _stm_rdid(self): def _stm_rdid(self, n):
#mvp = self._mvp cs = self._cspins[n]
#mvp[:] = b'\0\0\0\0\0' mvp = self._mvp
#mvp[0] = _RDID_STM mvp[:] = b'\0\0\0\0\0'
#cs(0) mvp[0] = _RDID_STM
#self._spi.write_readinto(mvp, mvp) cs(0)
#cs(1) self._spi.write_readinto(mvp, mvp)
#return mvp[4] cs(1)
return mvp[4]
#def _stm_wrid(self): # Write a fixed value to ID[0]
#mvp = self._mvp def _stm_wrid(self, n):
#mvp[:] = b'\0\0\0\0\0' cs = self._ccs
#mvp[0] = _WRID_STM mvp = self._mvp
#mvp[5] = _STM_ID mvp[0] = _WREN
#cs(0) cs(0)
#self._spi.write(mvp) self._spi.write(mvp[:1]) # Enable write
#cs(1) 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 # Check for valid hardware on each CS pin: use ID block
# Tested (on Microchip), but probably better to use ID block
def _stm_scan(self): def _stm_scan(self):
for n in range(len(self._cspins)): for n, cs in enumerate(self._cspins):
ta = n * self._c_bytes self._ccs = cs
v = self[ta] if self._stm_rdid(n) != _STM_ID:
vx = v^0xff self._stm_wrid(n)
self[ta] = vx if self._stm_rdid(n) != _STM_ID:
if self[ta] == vx: # Wrote OK, put back raise RuntimeError('M95M02 chip not found at cs[{}].'.format(n))
self[ta] = v
else:
raise RuntimeError('EEPROM not found at cs[{}].'.format(n))
return n return n
# Scan for Microchip devices: read manf ID # Scan for Microchip devices: read manf ID
@ -82,7 +88,7 @@ class EEPROM(BlockDevice):
self._spi.write_readinto(mvp, mvp) self._spi.write_readinto(mvp, mvp)
cs(1) cs(1)
if mvp[4] != 0x29: 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 return n
# Check for a valid hardware configuration # Check for a valid hardware configuration
@ -163,3 +169,4 @@ class EEPROM(BlockDevice):
nbytes -= npage nbytes -= npage
start += npage start += npage
addr += npage addr += npage
return buf