micropython_eeprom
micropython_eeprom copied to clipboard
Understanding Nomenclature for Flash Sector, Blocks, Pages
I'm struggling to get a larger 1GB NAND flash working with the library.
- Micron MT29F1G01
- Datasheet
I first figured out that the READ_ID command didn't follow the same rule as the code was expecting, and memory size was being scanned incorrectly. Put a temporary patch in for that (see below) and now I'm simply not able to get it to work. Similar to reports from others here who have tried adding unknown flash chips -- it seems to read and write, but it doesn't persist across a reset nor power cycle.
But before I get deeper into that, I'm struggling to match the terminology of Micron with that of the library / block driver / VFSLFS2. Specifically, Micron describes the memory organization as:
- Plane size: 1Gb (1 plane, 1024 blocks per plane)
- Block size: 64 pages (128K + 8K bytes)
- Page size x1: 2176 bytes (2048 + 128 bytes)
The library code manages four categories of sizes:
- SIZE, presumably the whole flash (array) size
- SEC_SIZE, a sector size, defaults to 4KiB
- BLOCK_SIZE, defaults to 512 B
- PAGE_SIZE, hard coded to 256 B
I'd appreciate any guidance for sorting out these seemingly different naming conventions. I've tried too many combinations of the above, all without success.
Here's the snippet where I patched the scan function to try to get started
# **** API SPECIAL METHODS ****
# Scan: return chip size in KiB as read from ID.
def scan(self, verbose, size):
mvp = self._mvp
for n, cs in enumerate(self._cspins):
mvp[:] = b"\0\0\0\0\0\0"
mvp[0] = _RDID
cs(0)
self._spi.write_readinto(mvp[:4], mvp[:4])
cs(1)
print( f'0x{mvp[0]:02x} ' \
f'0x{mvp[1]:02x} ' \
f'0x{mvp[2]:02x} ' \
f'0x{mvp[3]:02x} ' \
)
if mvp[2]==0x2c: # exception for Micron 1G/2G/4G/8G NAND
# MFR byte = 0x2c = Micron MT29F1G01 (1Gb version P/N)
# e2
# size=1Gb, ID byte = 14h 30
# size=2Gb, ID byte = 24h 31
# size=4Gb, ID byte = 36h 32
# size=8Gb, ID byte = 46h 33
e2 = 29 + ((mvp[3] & 0xf0) >> 4)
scansize = (1 << e2)
print(f'power of two {e2}, size {scansize:,}')
else:
scansize = 1 << (mvp[3] - 10)
if size is None:
size = scansize # Save size of 1st chip
if size != scansize: # Mismatch passed size or 1st chip.
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
print(s.format(n, (n * size) // 1024))
return size