diff --git a/components/esp32/spiram_psram.c b/components/esp32/spiram_psram.c index a63069d0cc..442de5f1de 100644 --- a/components/esp32/spiram_psram.c +++ b/components/esp32/spiram_psram.c @@ -397,11 +397,9 @@ static void psram_disable_qio_mode(psram_spi_num_t spi_num) psram_cmd_end(spi_num); } -//read psram id -static void psram_read_id(uint64_t* dev_id) +//read psram id, should issue `psram_disable_qio_mode` before calling this +static void psram_read_id(psram_spi_num_t spi_num, uint64_t* dev_id) { - psram_spi_num_t spi_num = PSRAM_SPI_1; - psram_disable_qio_mode(spi_num); uint32_t dummy_bits = 0 + extra_dummy; uint32_t psram_id[2] = {0}; psram_cmd_t ps_cmd; @@ -900,9 +898,20 @@ esp_err_t IRAM_ATTR psram_enable(psram_cache_mode_t mode, psram_vaddr_mode_t vad bootloader_common_vddsdio_configure(); // GPIO related settings psram_gpio_config(&psram_io, mode); - psram_read_id(&s_psram_id); + + psram_spi_num_t spi_num = PSRAM_SPI_1; + psram_disable_qio_mode(spi_num); + psram_read_id(spi_num, &s_psram_id); if (!PSRAM_IS_VALID(s_psram_id)) { - return ESP_FAIL; + /* 16Mbit psram ID read error workaround: + * treat the first read id as a dummy one as the pre-condition, + * Send Read ID command again + */ + psram_read_id(spi_num, &s_psram_id); + if (!PSRAM_IS_VALID(s_psram_id)) { + ESP_EARLY_LOGE(TAG, "PSRAM ID read error: 0x%08x", (uint32_t)s_psram_id); + return ESP_FAIL; + } } if (psram_is_32mbit_ver0()) { diff --git a/components/esp32s2beta/spiram_psram.c b/components/esp32s2beta/spiram_psram.c index ae3af8f0c4..33bed7ba81 100644 --- a/components/esp32s2beta/spiram_psram.c +++ b/components/esp32s2beta/spiram_psram.c @@ -40,6 +40,8 @@ #if CONFIG_SPIRAM #include "soc/rtc.h" +static const char* TAG = "psram"; + //Commands for PSRAM chip #define PSRAM_READ 0x03 #define PSRAM_FAST_READ 0x0B @@ -99,7 +101,6 @@ typedef enum { #define _SPI_40M_CLK_DIV 2 #define _SPI_20M_CLK_DIV 4 -static const char* TAG = "psram"; typedef enum { PSRAM_SPI_1 = 0x1, PSRAM_SPI_2, @@ -342,11 +343,9 @@ static void psram_disable_qio_mode(psram_spi_num_t spi_num) psram_cmd_end(spi_num); } -//read psram id -static void psram_read_id(uint32_t* dev_id) +//read psram id, should issue `psram_disable_qio_mode` before calling this +static void psram_read_id(int spi_num, uint32_t* dev_id) { - psram_spi_num_t spi_num = PSRAM_SPI_1; - psram_disable_qio_mode(spi_num); uint32_t dummy_bits = 0 + extra_dummy; psram_cmd_t ps_cmd; @@ -508,10 +507,9 @@ bool psram_support_wrap_size(uint32_t wrap_size) } -static void psram_read_id(uint32_t* dev_id) +//read psram id, should issue `psram_disable_qio_mode` before calling this +static void psram_read_id(int spi_num, uint32_t* dev_id) { - psram_spi_num_t spi_num = PSRAM_SPI_1; - psram_disable_qio_mode(spi_num); uint32_t dummy_bits = 0; uint32_t addr = 0; psram_cmd_t ps_cmd; @@ -752,9 +750,20 @@ esp_err_t IRAM_ATTR psram_enable(psram_cache_mode_t mode, psram_vaddr_mode_t vad CLEAR_PERI_REG_MASK(SPI_MEM_USER_REG(PSRAM_SPI_1), SPI_MEM_CS_SETUP_M); psram_gpio_config(mode); PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[PSRAM_CS_IO], PIN_FUNC_GPIO); - psram_read_id(&s_psram_id); + + int spi_num = PSRAM_SPI_1; + psram_disable_qio_mode(spi_num); + psram_read_id(spi_num, &s_psram_id); if (!PSRAM_IS_VALID(s_psram_id)) { - return ESP_FAIL; + /* 16Mbit psram ID read error workaround: + * treat the first read id as a dummy one as the pre-condition, + * Send Read ID command again + */ + psram_read_id(spi_num, &s_psram_id); + if (!PSRAM_IS_VALID(s_psram_id)) { + ESP_EARLY_LOGE(TAG, "PSRAM ID read error: 0x%08x", s_psram_id); + return ESP_FAIL; + } } uint32_t flash_id = g_rom_flashchip.device_id; if (flash_id == FLASH_ID_GD25LQ32C) {