micropython_eeprom icon indicating copy to clipboard operation
micropython_eeprom copied to clipboard

Understanding Nomenclature for Flash Sector, Blocks, Pages

Open thestumbler opened this issue 5 months ago • 5 comments

I'm struggling to get a larger 1GB NAND flash working with the library.

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

thestumbler avatar Sep 03 '24 05:09 thestumbler