Document support for extra flash chips.

pull/13/head
Peter Hinch 2020-02-13 14:01:02 +00:00
rodzic cb1c33303e
commit 33f4dc0658
6 zmienionych plików z 76 dodań i 48 usunięć

Wyświetl plik

@ -57,19 +57,30 @@ M95M02-DRMN6TP and M95M02-DWMN3TP/K. The latter has a wider temperature range.
In the table below the Interface column includes page size in bytes.
| Manufacturer | Part | Interface | Bytes | Technology | Docs |
|:------------:|:---------:|:---------:|:------:|:----------:|:-----------------------------:|
| Cypress | S25FL256L | SPI 4096 | 32MiB | Flash | [FLASH.md](./flash/FLASH.md) |
| Cypress | S25FL128L | SPI 4096 | 16MiB | Flash | [FLASH.md](./flash/FLASH.md) |
| STM | M95M02-DR | SPI 256 | 256KiB | EEPROM | [SPI.md](./eeprom/spi/SPI.md) |
| Microchip | 25xx1024 | SPI 256 | 128KiB | EEPROM | [SPI.md](./eeprom/SPI.md) |
| Microchip | 24xx512 | I2C 128 | 64KiB | 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 | 24xx64 | I2C 128 | 8KiB | EEPROM | [I2C.md](./eeprom/i2c/I2C.md) |
| Adafruit | 1895 | I2C n/a | 32KiB | FRAM | [FRAM.md](./fram/FRAM.md) |
| Manufacturer | Part | Interface | Bytes | Technology | Docs |
|:------------:|:---------:|:---------:|:-------:|:----------:|:-----------------------------:|
| Various | Various | SPI 4096 | <=32MiB | Flash | [FLASH.md](./flash/FLASH.md) |
| STM | M95M02-DR | SPI 256 | 256KiB | EEPROM | [SPI.md](./eeprom/spi/SPI.md) |
| Microchip | 25xx1024 | SPI 256 | 128KiB | EEPROM | [SPI.md](./eeprom/SPI.md) |
| Microchip | 24xx512 | I2C 128 | 64KiB | 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 | 24xx64 | I2C 128 | 8KiB | EEPROM | [I2C.md](./eeprom/i2c/I2C.md) |
| Adafruit | 1895 | I2C n/a | 32KiB | FRAM | [FRAM.md](./fram/FRAM.md) |
The flash driver now has the capability to support smaller chips.
The flash driver now has the capability to support a variety of chips. The
following have been tested to date:
| Chip | Size (MiB) |
|:-----------------:|:----------:|
| Cypress S25FL256L | 32 |
| Cypress S25FL128L | 16 |
| Cypress S25FL064L | 8 |
| Winbond W25Q32JV | 4 |
It is likely that other chips with 4096 byte blocks will work but I am unlikely
to be able to support hardware I don't possess. Users should check datasheets
for compatibility.
## 1.5 Performance

Wyświetl plik

@ -63,10 +63,7 @@ class BlockDevice:
return
def readblocks(self, blocknum, buf, offset=0):
if blocknum < 0 or (offset + (blocknum << self._nbits)) > self._a_bytes:
print('rb', hex(blocknum), offset, hex(offset + (blocknum << self._nbits)))
else:
self.readwrite(offset + (blocknum << self._nbits), buf, True)
self.readwrite(offset + (blocknum << self._nbits), buf, True)
def writeblocks(self, blocknum, buf, offset=0):
self.readwrite(offset + (blocknum << self._nbits), buf, False)

Wyświetl plik

@ -1,13 +1,21 @@
# 1. A MicroPython Flash memory driver
## 1.1 Device support
This driver supports the Cypress S25FL256L and S25FL128L chips, providing 32MiB
and 16MiB respectively. These have 100K cycles of write endurance (compared to
10K for Pyboard Flash memory). These were the largest capacity available with a
sector size small enough for microcontroller use.
Thanks to a patch from Daniel Thompson this now has the capability to support
smaller NOR Flash chips with 24-bit addressing. I lack the chips to test this
so am unable to support such use. The author tested on an XPX XT25F32B.
Thanks to a patch from Daniel Thompson this now supports a variety of NOR Flash
chips including those with 24-bit addressing. He tested an XPX XT25F32B; I
tested Winbond W25Q32JV 4MiB and Cypress S25FL064L 8MiB devices.
It is likely that other chips with 4096 byte blocks will work but I am unlikely
to be able to support hardware I don't possess. Users should check datasheets
for compatibility.
## 1.2 The driver
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
@ -36,8 +44,8 @@ for facilitating effective hardware tests and for diagnostics.
Any SPI interface may be used. The table below assumes a Pyboard running SPI(2)
as per the test program. To wire up a single flash chip, connect to a Pyboard
as below. Pin numbers an 8 pin SOIC or WSON package. Inputs marked `nc` may be
connected to 3V3 or left unconnected.
as below. Pin numbers relate to an 8 pin SOIC or WSON package. Inputs marked
`nc` may be connected to 3V3 or left unconnected.
| Flash | Signal | PB | Signal |
|:-----:|:-------:|:---:|:------:|
@ -50,7 +58,7 @@ connected to 3V3 or left unconnected.
| 7 | RESET/ | nc | - |
| 8 | Vcc | 3V3 | 3V3 |
For multiple chips a separate CS pin must be assigned to each chip: each one
For multiple chips a separate CS pin must be assigned to each chip, each one
being wired to a single chip's CS line. The test program assumes a second chip
with CS connected to Y4. Multiple chips should have 3V3, Gnd, SCL, MOSI and
MISO lines wired in parallel.
@ -61,7 +69,7 @@ to enable the voltage rail by issuing:
machine.Pin.board.EN_3V3.value(1)
time.sleep(0.1) # Allow decouplers to charge
```
Other platforms may vary but the Cypress chips require a 3.3V supply.
Other devices may vary but the Cypress chips require a 3.3V supply.
It is wise to add a pullup resistor (say 10KΩ) from each CS/ line to 3.3V. This
ensures that chips are deselected at initial power up when the microcontroller
@ -85,9 +93,10 @@ Bus lines should be short and direct.
5. `wemos_flash.py` Test program running on a Wemos D1 Mini ESP8266 board.
Installation: copy files 1 and 2 (3 - 5 are optional) to the target filesystem.
The `flash_test` script assumes two S25FL256L chips connected to SPI(2) with
CS/ pins wired to Pyboard pins Y4 and Y5. The `get_device` function may be
adapted for other setups and is shared with `littlefs_test`.
The `flash_test` script assumes two chips connected to SPI(2) with CS/ pins
wired to Pyboard pins Y4 and Y5. Device size is detected at runtime. The
`get_device` function may be adapted for other setups and is shared with
`littlefs_test`.
For a quick check of hardware issue:
```python
@ -140,18 +149,20 @@ Arguments. In most cases only the first two mandatory args are required:
3. `size=None` Chip size in KiB. The size is read from the chip. If a value
is passed, the actual size is compared with the passed value: a mismatch will
raise a `ValueError`. A `ValueError` will also occur if chips in the array
have differing sizes. See table below for values.
have differing sizes. See table below for values of chips tested to date.
4. `verbose=True` If `True`, the constructor issues information on the flash
devices it has detected.
5. `sec_size=4096` Chip sector size.
6. `block_size=9` The block size reported to the filesystem. The size in bytes
is `2**block_size` so is 512 bytes by default.
Size values:
| Chip | Size |
|:---------:|:-----:|
| S25FL256L | 32768 |
| S25FL128L | 16384 |
Size values (KiB):
| Chip | Size |
|:-----------------:|:-----:|
| Cypress S25FL256L | 32768 |
| Cypress S25FL128L | 16384 |
| Cypress S25FL064L | 8192 |
| Winbond W25Q32JV | 4096 |
### 4.1.2 Methods providing byte level access
@ -195,8 +206,7 @@ print(flash[2000:2002]) # Returns a bytearray
```
Three argument slices are not supported: a third arg (other than 1) will cause
an exception. One argument slices (`flash[:5]` or `flash[13100:]`) and negative
args are supported. See [section 4.2](./SPI.md#42-byte-addressing-usage-example)
for a typical application.
args are supported.
#### 4.1.2.2 readwrite
@ -224,13 +234,18 @@ where `flash` is the `FLASH` instance.
#### scan
Activate each chip select in turn checking for a valid device and returns the
number of flash devices detected. A `RuntimeError` will be raised if any CS
pin does not correspond to a valid chip.
Args:
1. `verbose` `bool`. If `True` print information on chips detected.
2. `size` `int` or `None`. If an `int` is passed a `ValueError` is thrown if
the detected chip size does not match the passed value.
Other than for debugging there is no need to call `scan()`: the constructor
will throw a `RuntimeError` if it fails to communicate with and correctly
identify each chip.
Activate each chip select in turn checking for a valid device and returns the
size in KiB of one instance of the flash devices detected. A `RuntimeError`
will be raised if any CS pin does not correspond to a valid chip. A
`ValueError` is thrown if the detected chips are not of the same size.
Other than for debugging there is no need to call `scan()`: it is called by the
constructor.
#### erase
@ -246,7 +261,7 @@ also [here](http://docs.micropython.org/en/latest/reference/filesystem.html#cust
`writeblocks()`
`ioctl()`
# 5. Test program flash_spi.py
# 5. Test program flash_test.py
This assumes a Pyboard 1.x or Pyboard D with two chips wired to SPI(2) as
above with chip selects connected to pins `Y4` and `Y5`. It provides the

Wyświetl plik

@ -152,16 +152,10 @@ class FLASH(FlashDevice):
# Given an address, set current chip select and address buffer.
# Return the number of bytes that can be processed in the current chip.
def _getaddr(self, addr, nbytes):
# print(hex(addr), hex(self._a_bytes), hex(self._c_bytes), self._nbits, self._block_size, divmod(addr, self._c_bytes))
if addr >= self._a_bytes:
# print(hex(addr), hex(self._a_bytes), hex(self._c_bytes), self._nbits, self._block_size, divmod(addr, self._c_bytes))
raise RuntimeError("Flash Address is out of range")
ca, la = divmod(addr, self._c_bytes) # ca == chip no, la == offset into chip
try:
self._ccs = self._cspins[ca] # Current chip select
except:
print(ca, la)
raise
self._ccs = self._cspins[ca] # Current chip select
cmdlen = self._cmdlen
mvp = self._mvp[:cmdlen]
if cmdlen > 3:

Wyświetl plik

@ -159,3 +159,12 @@ def full_test(count=10):
if g != data[n]:
print('{} {:2x} {:2x} {:2x}'.format(n, data[n], g, got1[n]))
break
helpstr = '''Available tests:
test() Basic hardware test.
full_test(count=10) Full hardware test, count is no. of passes.
fstest(format=False) Check or create littlefs filesystem.
cptest() Copy 2 files to filesystem.
cp() Primitive copy routine. See docs.
'''
print(helpstr)

Wyświetl plik

@ -73,3 +73,5 @@ def main():
print('Rewrote', n, length)
check_all()
remove_all()
print('main() to run littlefs test. Filesystem must exist.')