Flash DIO to QIO Mode - mhightower83/Arduino-ESP8266-misc GitHub Wiki

Configuring Flash DIO to QIO Mode

In favor of more IRAM space, this NONOS SDK option was not utilized by the Arduino ESP8266 Core.

Most SPI Flash memory, that supports a QE (Quad Enable) bit at S9 and 16-bit Write Status Register-1 should work. For QIO support with these devices, select the Arduino IDE → Tools → SPI Flash Mode: "QIO" build option.

What is this user_spi_flash_dio_to_qio_pre_init

Introduced with NONOS SDK Release Version 2.1.0 - Release Notes System.5

  1. Reduce iRAM usage by transferring some functions to flash;
    • add weak function void user_spi_flash_dio_to_qio_pre_init(void). If the DIO to QIO flash mode is not used, users can add an empty user_spi_flash_dio_to_qio_pre_init on the application side to reduce iRAM usage;

What does that mean?

I cannot find a list of the SPI Flash memory supported by the ESP8266. However, from what I have deciphered to use QIO or QOUT Flash, the ESP8266 expects the Flash memory to have a QE (Quad Enable) bit at S9 and support for 16-bit Write Status Register-1. Some non-compliant Flash memory can be supported through the callback function user_spi_flash_dio_to_qio_pre_init().

Using the build-in (weak link) user_spi_flash_dio_to_qio_pre_init, the NONOS SDK supports non-S9 QE bit Flash Vendors ISSI, MXIC, and GigaDevice's GD25Q16C and GD25Q32C. For user_spi_flash_dio_to_qio_pre_init to be called, this method also required setting some bits in blank.bin.

My guess, is this was viewed as too much complication for a beginner and it was opted to specify an empty function to free up the IRAM. With my limited sample of ESP modules, the Flash memory used seldom supports the ESP8266 requirements for QIO. Some have to be used with DOUT In the current GIT for Arduino ESP8266, an empty user_spi_flash_dio_to_qio_pre_init() can be found in core_esp8266_phy.cpp.

In NON-OS SDK version 3.0.5 the bits are reset after the first boot. (?) With v2.2.1, this does not happen. Configuring Flash DIO to QIO Mode

Pseudo code for user_spi_flash_dio_to_qio_pre_init

extern "C" void user_spi_flash_dio_to_qio_pre_init(void) {
  const uint32_t _flash_id = spi_flash_get_id();
  const uint32_t _id = 0xFFu & _flash_id;

  bool to_qio;
  if (/* ISSI */ 0x9Du == _id || /* Macronix */ 0xC2u == _id) {
    // Enable Flash QIO with QE=1, BIT6 on Status Register-1
    to_qio = spi_flash_issi_enable_QIO_mode();
  } else if (0x1640C8u == _flash_id || 0x1840C8u == _flash_id)) { 
    // 4M and 16M GigaDevice
    // Enable Flash QIO with QE=1, BIT1 on Status Register-2
    to_qio = flash_gd25q32c_enable_QIO_mode();
  } else {
    // Assume the Flash supports 16-bit Write Status Register-1 
    // and QE bit is at S9
    to_qio = (0 == spi_flash_enable_qmode());
  }

  if (to_qio) {
    SPI0C &= ~(SPICQIO | SPICDIO | SPICQOUT | SPICDOUT | SPICFASTRD);
    SPI0C |= (SPICQIO | SPICFASTRD);
  }
}