Upgrading Flash Chips - mhightower83/Arduino-ESP8266-misc GitHub Wiki
Upgrading Flash Chips
ESP8266EX BootROM Expectations
Based on the SPI Flash Mode
found in the Firmware Image Header, the BootROM tries to set or clear the non-volatile QE bit in the SPI Flash Status Register-2. Some ESP8266 module providers do not pair the ESP8266EX with a compatible SPI Flash Chip. And, the BootROM's attempt to update the QE bit fails. While some Flash Chips are QIO capable, they are not compatible because they do not support 16-bit status register-1 writes (or don't have a QE bit at S9). If the Status Register WEL
bit is still set after a Write Status Register, this is a good indicator that the 16-bit transfer failed.
This may explain why some ESP8266 Modules have silkscreen marks of DIO or QIO on the back of the antenna area. The ones marked with DIO had flash chips that appeared to support QIO. At least, according to the datasheets. However, they only worked when using DIO.
In the NONOS SDK, a bug exists that needlessly turns on the
WEL
bit when the SDK callsflash_gd25q32c_read_status()
.
The Winbond W25Q128JVSIQ and others support both 8-bit and legacy 16-bit writes to Status Register-1. Other vendors like GigaDevice GD25Q32E only support the 8-bit Write Status Register-1 option and the BootROM initialization will fail to change it.
However, for the GD25Q32E, the esptool.py
write_flash_status option can set the non-volatile status register and turn on the QE bit. Once the QE bit is set, it stays set. The BootROM is unable to change it. Each Flash Chip vendor appears to have its own set of nuances.
Example for setting QE bit on GigaDevice, or mystery vendor 0xD8:
esptool.py --chip esp8266 write_flash_status 0x0200 --non-volatile
An example for additionally setting driver strength to 25% on GigaDevice. Different vendors have different defaults and different bit values for a given percentage. If you are changing this check the respective datasheet. Unless you know you need this for now, it would be best to ignore this example.
esptool.py --chip esp8266 write_flash_status 0x600200 --bytes 3 --non-volatile
Flash Memory for ESP8266
For Winbond, there is no concern for ordering parts with QE preset. The BootROM can successfully update the QE bit as specified by the SPI Flash Mode
setting.
- W25Q128JVSIQ - This has the status flag QE preset.
- W25Q128FVSG - This does not have QE set
Backup flash notes
Example get Flash Chip info
./esptool.py --port /dev/ttyUSB0 flash_id
Example of backing up 4MB External Flash
cd tools/esptool/
./esptool.py --port /dev/ttyUSB0 read_flash 0x00000 0x400000 image.bin
How to Use GPIO9 and GPIO10
See Pins GPIO9 and GPIO10 for how to safely use GPIO9 and GPIO10. Note, that this is very SPI Flash vendor-specific.
Other Notes
Flash DIO to QIO
If reclaiming GPIO9 and GPIO10, this topic is of no use.
This is more of an academic topic that captures my understanding of how user_spi_flash_dio_to_qio_pre_init()
would have worked. Because I know I will forget the details.
What is user_spi_flash_dio_to_qio_pre_init()
about?
Occasional Crashes - speculations
The possibilities here are endless. However, poor quality flash or noisy board could contribute.
After reviewing some flash datasheets, that discuss the use of /WP signal for preventing flash corruption due to SPI bus data errors, I am left with the question, are some of these occasional crashes possible due to noise and flash quality?
The SPI bus cannot be too unreliable, or we would frequently crash as the iCache hardware has no error detection/recovery process unless you count the HWDT reset. Could higher-quality flash memory and/or a quiet board design help?
I have a sketch, that has been running on one device for 141 days without crashing. The same build on a different device may stay up for 2 weeks, 4 at the most. On the latter, I have had crashes that cannot occur unless the instruction was misread. It is rare to have an event that can be identified with confidence.
Don't forget the noise left by poor bus capacitors, ringing on long traces/wires, etc.
flashchip->deviceId
not updated by NONOS SDK
flashchip->deviceId
is preset by the Boot ROM and the NONOS SDK does not update to match the actual Flash Chip ID.
Use spi_flash_get_id()
or ESP.getFlashChipId()
to get the "real" Flash Chip ID.
extern uint32_t spi_flash_get_id (void); // <user_interface.h>
However, the NONOS SDK does set flashchip->chip_size
to the configured size of Flash Chip as supplied by the Firmware Image Header. Byte 3, SPI Flash Info, at the beginning of the flashed image.
Booting from blank flash Looks like this:
└─▶ pyserial-miniterm /dev/ttyUSB0 74880
--- Miniterm on /dev/ttyUSB0 74880,8,N,1 ---
--- Quit: Ctrl+] | Menu: Ctrl+T | Help: Ctrl+T followed by Ctrl+H ---
--- DTR inactive ---
--- DTR active ---
ets Jan 8 2013,rst cause:2, boot mode:(3,7)
ets_main.c
Setting Flash QE Bit
When you use an ESP8266 module with compatible Flash memory, the "Boot ROM" knows how to change the QE bit in the Flash Status Register.
However, this is limited to flash memory that supports the QE bit at S9 (BIT9) of a 16-bit Status Register-1.
The BootROM expects the flash memory to support the QE bit at S9 (BIT9) of a 16-bit Status Register-1.
Functions Enable_QMode()
and Disable_QMode()
handle setting and clearing the QE bit.
The BootROM's function Enable_QMode()
will fail when the flash memory does not support 16-bit Status Register-1 writes.
A clear indicator that you have a compatible Flash Chip is building with Tools->Flash Mode: "QIO"
and having it work.
err_t Enable_QMode(uint8_t FlashMode); // sub_44c0, 0x400044c0
err_t Disable_QMode(); // sub_4508, 0x40004508