From a3a4c828e9034cc38207147f5147501f543eb930 Mon Sep 17 00:00:00 2001 From: chenjianqiang Date: Fri, 5 Jun 2020 21:06:21 +0800 Subject: [PATCH 1/2] psram: fix 16mbit psram id read error --- components/esp32/spiram_psram.c | 6 ++++++ components/esp32s2/spiram_psram.c | 11 +++++++++-- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/components/esp32/spiram_psram.c b/components/esp32/spiram_psram.c index a63069d0c..501642f3b 100644 --- a/components/esp32/spiram_psram.c +++ b/components/esp32/spiram_psram.c @@ -900,8 +900,14 @@ 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); + + /* 16Mbit psram ID read error + * workaround: Issue a pre-condition of dummy read id, then Read ID command + */ + psram_read_id(&s_psram_id); psram_read_id(&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; } diff --git a/components/esp32s2/spiram_psram.c b/components/esp32s2/spiram_psram.c index 3ba65ad03..a77b2e126 100644 --- a/components/esp32s2/spiram_psram.c +++ b/components/esp32s2/spiram_psram.c @@ -47,6 +47,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 @@ -150,7 +152,6 @@ typedef struct { .psram_spihd_sd2_io = PSRAM_SPIHD_SD2_IO, \ } -//static const char* TAG = "psram"; typedef enum { PSRAM_SPI_1 = 0x1, /* PSRAM_SPI_2, */ @@ -431,8 +432,14 @@ esp_err_t IRAM_ATTR psram_enable(psram_cache_mode_t mode, psram_vaddr_mode_t vad /* SPI1: set cs timing(hold time) in order to send commands on SPI1 */ psram_set_clk_mode(_SPI_FLASH_PORT, PSRAM_CLK_MODE_A1C); psram_set_spi1_cmd_cs_timing(PSRAM_CLK_MODE_A1C); - psram_read_id(&s_psram_id); + + /* 16Mbit psram ID read error + * workaround: Issue a pre-condition of dummy read id, then Read ID command + */ + psram_read_id(&s_psram_id); + psram_read_id(&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; } From 76c1be0d9434801ba40b60e20cfa07a0afff23b8 Mon Sep 17 00:00:00 2001 From: "Michael (XIAO Xufeng)" Date: Tue, 23 Jun 2020 11:12:08 +0800 Subject: [PATCH 2/2] spiram: fix the read id failure The issue is caused by: 1. The disable_qio_mode inside read_id may have side effects. 2. read_id twice may have side effects. Fix this issue by moving disable_qio_mode out of read_id and only do it once before read_id. And retry read_id only when the first one is failed. Issue introduced in 3ecbb59c15e0fd8209bd8921725d52cff3f0fb12. --- components/esp32/spiram_psram.c | 25 ++++++++++++++----------- components/esp32s2/spiram_psram.c | 25 ++++++++++++++----------- 2 files changed, 28 insertions(+), 22 deletions(-) diff --git a/components/esp32/spiram_psram.c b/components/esp32/spiram_psram.c index 501642f3b..442de5f1d 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; @@ -901,14 +899,19 @@ esp_err_t IRAM_ATTR psram_enable(psram_cache_mode_t mode, psram_vaddr_mode_t vad // GPIO related settings psram_gpio_config(&psram_io, mode); - /* 16Mbit psram ID read error - * workaround: Issue a pre-condition of dummy read id, then Read ID command - */ - psram_read_id(&s_psram_id); - 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)) { - ESP_EARLY_LOGE(TAG, "PSRAM ID read error: 0x%08x", (uint32_t)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/esp32s2/spiram_psram.c b/components/esp32s2/spiram_psram.c index a77b2e126..e45b67082 100644 --- a/components/esp32s2/spiram_psram.c +++ b/components/esp32s2/spiram_psram.c @@ -306,11 +306,9 @@ bool psram_support_wrap_size(uint32_t wrap_size) } -//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) { - int spi_num = PSRAM_SPI_1; - psram_disable_qio_mode(spi_num); psram_exec_cmd(spi_num, PSRAM_CMD_SPI, PSRAM_DEVICE_ID, 8, /* command and command bit len*/ 0, 24, /* address and address bit len*/ @@ -433,14 +431,19 @@ esp_err_t IRAM_ATTR psram_enable(psram_cache_mode_t mode, psram_vaddr_mode_t vad psram_set_clk_mode(_SPI_FLASH_PORT, PSRAM_CLK_MODE_A1C); psram_set_spi1_cmd_cs_timing(PSRAM_CLK_MODE_A1C); - /* 16Mbit psram ID read error - * workaround: Issue a pre-condition of dummy read id, then Read ID command - */ - psram_read_id(&s_psram_id); - 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)) { - ESP_EARLY_LOGE(TAG, "PSRAM ID read error: 0x%08x", 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; + } } psram_clk_mode_t clk_mode = PSRAM_CLK_MODE_MAX;