espressif / esp-idf

Espressif IoT Development Framework. Official development framework for Espressif SoCs.
Apache License 2.0
13.45k stars 7.25k forks source link

[TW#22515] [Bug] Enabling QIO mode #1944

Closed loboris closed 6 years ago

loboris commented 6 years ago

After the latest changes in the bootloader component, some SPI Flash chips cannot be set to QIO mode.

Gigadevice GD25Q32 (ID: 0xc84016)

D (41) qio_mode: Probing for QIO mode enable...
D (46) qio_mode: Raw SPI flash chip id 0xc84016
D (50) qio_mode: Manufacturer ID 0xc8 chip ID 0x4016
I (55) qio_mode: Enabling default flash chip QIO
D (60) qio_mode: Initial flash chip status 0x0
D (67) qio_mode: Updated flash chip status 0x0
E (70) qio_mode: Failed to set QIE bit, not enabling QIO mode

Winbond W25Q64 (ID: 0xef4017)

D (47) qio_mode: Probing for QIO mode enable...
D (47) qio_mode: Raw SPI flash chip id 0xef4017
D (51) qio_mode: Manufacturer ID 0xef chip ID 0x4017
I (56) qio_mode: Enabling QIO for flash chip WinBond
D (61) qio_mode: Initial flash chip status 0x0
D (77) qio_mode: Updated flash chip status 0x0
E (77) qio_mode: Failed to set QIE bit, not enabling QIO mode

Winbond W25Q128 (ID: 0xef4018)

D (45) qio_mode: Probing for QIO mode enable...
D (46) qio_mode: Raw SPI flash chip id 0xef4018
D (50) qio_mode: Manufacturer ID 0xef chip ID 0x4018
I (55) qio_mode: Enabling QIO for flash chip WinBond
D (61) qio_mode: Initial flash chip status 0x0
D (76) qio_mode: Updated flash chip status 0x0
E (76) qio_mode: Failed to set QIE bit, not enabling QIO mode

Gigadevice GD25Q128 (ID: 0xc84018)

D (41) qio_mode: Probing for QIO mode enable...
D (45) qio_mode: Raw SPI flash chip id 0xc84018
D (50) qio_mode: Manufacturer ID 0xc8 chip ID 0x4018
I (55) qio_mode: Enabling default flash chip QIO
D (60) qio_mode: Initial flash chip status 0x0
D (67) qio_mode: Updated flash chip status 0x0
E (69) qio_mode: Failed to set QIE bit, not enabling QIO mode

Winbond W25Q64 (1.8V) (ID: 0xef6017) Enters QIO mode, but wrong status is read.

D (47) qio_mode: Probing for QIO mode enable...
D (48) qio_mode: Raw SPI flash chip id 0xef6017
D (52) qio_mode: Manufacturer ID 0xef chip ID 0x6017
I (57) qio_mode: Enabling default flash chip QIO
D (62) qio_mode: Initial flash chip status 0x57
D (67) qio_mode: QIO mode already enabled in flash
D (72) qio_mode: Enabling QIO mode...

Gigadevice GD25LQ32 (WROVER) (ID: 0xc86016) Enters QIO mode, but wrong status is read.

D (41) qio_mode: Probing for QIO mode enable...
D (46) qio_mode: Raw SPI flash chip id 0xc86016
D (50) qio_mode: Manufacturer ID 0xc8 chip ID 0x6016
I (55) qio_mode: Enabling QIO for flash chip GD
D (60) qio_mode: Initial flash chip status 0x5555
D (67) qio_mode: Updated flash chip status 0x7777
D (70) qio_mode: Enabling QIO mode...

Should be;

D (41) qio_mode: Probing for QIO mode enable...
D (46) qio_mode: Raw SPI flash chip id 0xc86016
D (50) qio_mode: Manufacturer ID 0xc8 chip ID 0x6016
I (55) qio_mode: Enabling QIO for flash chip GD
D (60) qio_mode: Initial flash chip status 0x1200
D (65) qio_mode: QIO mode already enabled in flash
D (70) qio_mode: Enabling QIO mode...

The source of the problem is in flash_qio_mode.c


The solution:

After adding:

    SPIFLASH.ctrl.val = SPI_WP_REG; // keep WP high while idle, otherwise leave DIO mode
    SPIFLASH.user.usr_dummy = 0;
    SPIFLASH.user.usr_addr = 0;
    SPIFLASH.user.usr_command = 1;
    SPIFLASH.user2.usr_command_bitlen = 7;

before line 149

    raw_flash_id = g_rom_flashchip.device_id;

, everything works as expected again.

void bootloader_enable_qio_mode(void)
{
    uint32_t old_ctrl_reg;
    uint32_t raw_flash_id;
    uint8_t mfg_id;
    uint16_t flash_id;
    int i;

    ESP_LOGD(TAG, "Probing for QIO mode enable...");
    esp_rom_spiflash_wait_idle(&g_rom_flashchip);

    /* Set up some of the SPIFLASH user/ctrl variables which don't change
       while we're probing using execute_flash_command() */
    old_ctrl_reg = SPIFLASH.ctrl.val;

    SPIFLASH.ctrl.val = SPI_WP_REG; // keep WP high while idle, otherwise leave DIO mode
    SPIFLASH.user.usr_dummy = 0;
    SPIFLASH.user.usr_addr = 0;
    SPIFLASH.user.usr_command = 1;
    SPIFLASH.user2.usr_command_bitlen = 7;

    raw_flash_id = g_rom_flashchip.device_id;
    ESP_LOGD(TAG, "Raw SPI flash chip id 0x%x", raw_flash_id);
...
...
jstoi commented 6 years ago

Thanks a lot. The solution works perfectly !

costaud commented 6 years ago

Thanks for your report, it issue will be merged soon.