-
Notifications
You must be signed in to change notification settings - Fork 0
Upgrading Flash Chips
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
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
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
See Pins GPIO9 and GPIO10 for how to safely use GPIO9 and GPIO10. Note, that this is very SPI Flash vendor-specific.
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?
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
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.
└─▶ 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
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
- Keeping the Lights On - how to manage GPIO state across reboots and crashes
- Boot fails when SPI Bus used
- GPIO Drive Strength and Ringing
- LDO Regulators WIP
- ESP8266 Power Considerations This is only a rough outline, needs a lot of development.
- Upgrading Flash Chips, QIO, and DIO
- Dodgy Extra 2K of DRAM or CONT - WIP
- WDTracks - Print last call before WDT
- 5V Tolerant I/O?
Arduino IDE specific
Misc.
- Exception Causes
- ESP8266 will not boot
- Stacks sys and cont
- WIP Boot ROM and SDK Notes
- Multi-segment Boot ROM Loader, notes
- Cache_Read_Enable How to turn off and on instruction cache execution.