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 Winbond W25Q128FVSIG chip. There’s no great sources I could find for these in the UK, so got them off aliexpress, 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.
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 = Winbond
- 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.
For more detail: ESP8266 16MB Flash Handling