ESP8266 16MB Flash Handling

In recent weeks a number of ESP8266 devices have become available offering more than the previous defacto maximum of 4MB of flash memory. Wemos’s D1 mini pro offers 16MB of flash, and the ESP-100 claims to offer 8MB.
To put this in context, the original ESP8266 modules (such as the ESP-01) offered 512KB of flash, with the more recent ones (ESP-07) 1MB and then 4MB. The maximum addressable flash memory of the ESP8266 is 16MB according to the datasheet. (The ESP32 offers up to 4 x 16MB of flash.)
I don’t have a particular need for > 4MB flash (otb-iot currently only requires and supports 4MB) but my interest was tweaked in the larger flash chips, so I thought I’d give it a go. I’ve experience of replacing flash chips from older modules to upgrade them from 1MB to 4MB, so figured 16MB would be the same.

Butchering a D1 mini

From a hardware perspective I was right – this was simple. I ripped the PCB EMI shield off a Wemos D1 mini of which I have tons, took off the old flash chip with a cheapo hot air station, and replaced with a Win bond W25Q128FVSIG chip. There’s no great sources I could find for these in the UK, so got them off ali express, at £3.20 for 5 inc shipping. They arrived quickly (couple of weeks).
The good thing about this particular flash chip variant is that it’s the same package as the original so doesn’t require any bending of pins to try and get it to fit – it’s just a drop in replacement. The 128 in the part number is the size – 128Mbits, 16MBytes.

First tests

So, first thing to do was run a quick test with esptool.py and check that the right device ID was returned.
Here’s the output from an original D1 mini (not the pro!):

$ esptool.py flash_id
Connecting...
Manufacturer: ef
Device: 4016

And here’s the output from the modified D1 mini:

$ esptool.py flash_id
Connecting...
Manufacturer: ef
Device: 4018

To break this down:

  • ef = Win bond
  • Device is 2 hex bytes – so 0x4016 or 0x4018. The low order byte actually indicates the size – so 0x16 or 0x18.
    • 0x16 = 22 decimal so the size is 2 ^ 22 = 4,194,304 = 4MB.
    • 0x18 = 24 decimal so the size is 2 ^ 24 = 16,777,216 = 16MB.

Reading/writing to > 4MB flash

Things went a bit downhill at this point. It turns out that most of the various tools to read/write to the flash over serial don’t support reading/writing from > 4MB space. Some fail obviously, some fail silently.
This led me on a merry investigation, during which I concluded the ESP8266 SPI flash functions don’t natively support > 4MB flash. This isn’t just the SDK functions, but also as far as I can tell the ROM based access methods upon which the SDK (and other tools) rely. This isn’t quite the same as saying the chip doesn’t support > 4MB flash (it does) but makes accessing this extra space trickier.

If you simply try and access data beyond 4MB on the flash from code running on the chip using one of the usual functions:

  • spi_flash_erase_sector
  • spi_flash_write
  • spi_flash_read

it’ll fail.
Read More: ESP8266 16MB Flash Handling

Leave a Comment

Your email address will not be published. Required fields are marked *