Просмотр исходного кода

Merge branch 'bugfix/fix_16mbit_psram_id_read_error_v4.2' into 'release/v4.2'

psram: fix 16mbit psram id read error (backport v4.2)

See merge request espressif/esp-idf!9424
Jiang Jiang Jian 5 лет назад
Родитель
Сommit
f52c35258c
2 измененных файлов с 32 добавлено и 13 удалено
  1. 15 6
      components/esp32/spiram_psram.c
  2. 17 7
      components/esp32s2/spiram_psram.c

+ 15 - 6
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()) {

+ 17 - 7
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, */
@@ -305,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*/
@@ -431,9 +430,20 @@ 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);    
+
+    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;
+        }
     }
 
     psram_clk_mode_t clk_mode = PSRAM_CLK_MODE_MAX;