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 calls flash_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