kopia lustrzana https://github.com/peterhinch/micropython_eeprom
flash_spi.py: Can specify size where auto-detect fails.
rodzic
7d804c5b59
commit
6b42d58b8c
|
@ -12,8 +12,8 @@ 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.
|
||||
to be able to support hardware I don't possess. See
|
||||
[Section 6](./FLASH.md#6-unsupported-chips) for recommendations on settings.
|
||||
|
||||
## 1.2 The driver
|
||||
|
||||
|
@ -34,9 +34,9 @@ an inevitable price for the large capacity of flash chips.
|
|||
|
||||
FAT and littlefs filesystems are supported but the latter is preferred owing to
|
||||
its resilience and wear levelling characteristics. Please note that this driver
|
||||
has been tested on LFS2 only. Users requiring a driver with minimum code size
|
||||
may want to consider [this driver](https://github.com/robert-hh/SPI_Flash) with
|
||||
LFS1.
|
||||
has been tested on LFS2 only. Users requiring a driver with minimum RAM use
|
||||
may want to consider [this driver](https://github.com/robert-hh/SPI_Flash).
|
||||
This supports an LFS1 filesystem on a single flash chip.
|
||||
|
||||
Arguably byte level access on such large devices has few use cases other than
|
||||
for facilitating effective hardware tests and for diagnostics.
|
||||
|
@ -149,21 +149,22 @@ Arguments. In most cases only the first two mandatory args are required:
|
|||
1. `spi` An initialised SPI bus created by `machine`.
|
||||
2. `cspins` A list or tuple of `Pin` instances. Each `Pin` must be initialised
|
||||
as an output (`Pin.OUT`) and with `value=1` and be created by `machine`.
|
||||
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 of chips tested to date.
|
||||
3. `size=None` Chip size in KiB. By default the size is read from the chip; a
|
||||
`ValueError` will occur if chips in the array have differing sizes. See table
|
||||
below for values of chips tested to date. If a `size` is specified, the driver
|
||||
will assume that the value given is correct. If no `size` is specified and the
|
||||
chip returns an unexpected value, a `ValueError` will be raised.
|
||||
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.
|
||||
7. `cmd5=None` Flash chips can support two low level command sets, an old 4
|
||||
byte set and a newer 5 byte set capable of supporting a larger address
|
||||
space. By default if the size read from the chip's ID is <= 4096KiB the 4 byte
|
||||
set is used oterwise the 5 byte set is adopted. This works for supported
|
||||
chips. Setting `cmd5` `True` forces 5 byte commands, `False` forces 4 byte.
|
||||
This override is necessary for certain chip types (e.g. WinBond W25Q64FV).
|
||||
7. `cmd5=None` Flash chips can support two low level command sets, a 4 byte
|
||||
set and a 5 byte set. By default if the size read from the chip's ID is
|
||||
<= 4096KiB the 4 byte set is used oterwise the 5 byte set is adopted. This
|
||||
works for supported chips. Setting `cmd5` `True` forces 5 byte commands,
|
||||
`False` forces 4 byte. This override is necessary for certain chip types
|
||||
(e.g. WinBond W25Q64FV).
|
||||
|
||||
Size values (KiB):
|
||||
| Chip | Size |
|
||||
|
@ -173,6 +174,9 @@ Size values (KiB):
|
|||
| Cypress S25FL064L | 8192 |
|
||||
| Winbond W25Q32JV | 4096 |
|
||||
|
||||
See [main readme](../README.md#141-chips-tested-by-users) for updates to the
|
||||
list of supported chips.
|
||||
|
||||
### 4.1.2 Methods providing byte level access
|
||||
|
||||
It is possible to read and write individual bytes or arrays of arbitrary size.
|
||||
|
@ -319,3 +323,21 @@ cp('/flash/main.py','/fl_ext/')
|
|||
|
||||
See `upysh` in [micropython-lib](https://github.com/micropython/micropython-lib.git)
|
||||
for other filesystem tools for use at the REPL.
|
||||
|
||||
# 6. Unsupported chips
|
||||
|
||||
Flash chips have fairly standard commands so there is a good chance that
|
||||
unsupported chips will work so long as they are specified correctly.
|
||||
|
||||
Automatic size detection for unsupported chips is not guaranteed: some chips
|
||||
produce nonstandard output on the relevant byte. Specifying the `size`
|
||||
constructor arg is highly recommended.
|
||||
|
||||
It is also best to establish whether it uses 4 or 5 byte commands. This can be
|
||||
determined from the datasheet. Look up the code for `READ MEMORY`. If it is
|
||||
`03H` the device uses 4 byte instructions; if `13H` it uses 5-byte instructions.
|
||||
|
||||
Instantiate with `cmd5` set `True` or `False` appropriately.
|
||||
|
||||
If you have success with a new chip please raise an issue with the part no. and
|
||||
the `cmd5` setting and I will update the docs.
|
||||
|
|
|
@ -9,7 +9,7 @@ from bdevice import FlashDevice
|
|||
|
||||
# Supported instruction set:
|
||||
# 3 and 4 byte address commands
|
||||
_READ = const(0)
|
||||
_READ = const(0) # Index of _CMDSxBA
|
||||
_PP = const(1)
|
||||
_SE = const(2)
|
||||
_CMDS3BA = b"\x03\x02\x20"
|
||||
|
@ -25,14 +25,7 @@ _SEC_SIZE = const(4096) # Flash sector size 0x1000
|
|||
# Logical Flash device comprising one or more physical chips sharing an SPI bus.
|
||||
class FLASH(FlashDevice):
|
||||
def __init__(
|
||||
self,
|
||||
spi,
|
||||
cspins,
|
||||
size=None,
|
||||
verbose=True,
|
||||
sec_size=_SEC_SIZE,
|
||||
block_size=9,
|
||||
cmd5=None,
|
||||
self, spi, cspins, size=None, verbose=True, sec_size=_SEC_SIZE, block_size=9, cmd5=None
|
||||
):
|
||||
self._spi = spi
|
||||
self._cspins = cspins
|
||||
|
@ -46,6 +39,7 @@ class FLASH(FlashDevice):
|
|||
cs(1)
|
||||
time.sleep_ms(1) # Meet Tpu 300μs
|
||||
|
||||
if size is None: # Get from chip
|
||||
size = self.scan(verbose, size) # KiB
|
||||
super().__init__(block_size, len(cspins), size * 1024, sec_size)
|
||||
|
||||
|
@ -73,11 +67,10 @@ class FLASH(FlashDevice):
|
|||
if size is None:
|
||||
size = scansize # Save size of 1st chip
|
||||
if size != scansize: # Mismatch passed size or 1st chip.
|
||||
raise ValueError(
|
||||
"Flash size mismatch: expected {}KiB, found {}KiB".format(
|
||||
size, scansize
|
||||
)
|
||||
)
|
||||
raise ValueError(f"Flash size mismatch: expected {size}KiB, found {scansize}KiB")
|
||||
if not 0x10 < mvp[3] < 0x22:
|
||||
raise ValueError(f"Invalid chip size {size}KiB. Specify size arg.")
|
||||
|
||||
if verbose:
|
||||
s = "{} chips detected. Total flash size {}MiB."
|
||||
n += 1
|
||||
|
|
Ładowanie…
Reference in New Issue