]> granicus.if.org Git - esp-idf/commitdiff
bugfix(psram): fix psram size acquisition method
authorchenjianqiang <chenjianqiang@espressif.com>
Tue, 20 Nov 2018 12:39:47 +0000 (20:39 +0800)
committerWangjialin <wangjialin@espressif.com>
Wed, 28 Nov 2018 09:05:37 +0000 (17:05 +0800)
1. Use BIT[7:5] of EID to determine psram size
2. Add ID support for 16Mbit psram
3. Remove module reset on SPI1
4. Confirmed with the vendor that only the old 32Mbit psram need special clock timing. For other psram chips, we should use standard QPI mode.

components/esp32/include/esp_spiram.h
components/esp32/spiram.c
components/esp32/spiram_psram.c
components/esp32/spiram_psram.h

index ab76f3b56d859d7d61fdf88ef75e74011afc610a..a55872cd4deb05d729c8e7bdaf9f52b0f4c9e3a0 100644 (file)
@@ -22,8 +22,9 @@
 #include "esp_err.h"
 
 typedef enum {
-    ESP_SPIRAM_SIZE_32MBITS = 0,   /*!< SPI RAM size is 32 MBits */
-    ESP_SPIRAM_SIZE_64MBITS = 1,   /*!< SPI RAM size is 64 MBits */
+    ESP_SPIRAM_SIZE_16MBITS = 0,   /*!< SPI RAM size is 16 MBits */
+    ESP_SPIRAM_SIZE_32MBITS = 1,   /*!< SPI RAM size is 32 MBits */
+    ESP_SPIRAM_SIZE_64MBITS = 2,   /*!< SPI RAM size is 64 MBits */
     ESP_SPIRAM_SIZE_INVALID,       /*!< SPI RAM size is invalid */
 } esp_spiram_size_t;
 
index ecd95dcdb13f5999b5c47d137f9ad6e0e9665676..e2d3f170c810310f6c530ef54299bae0f4b008f6 100644 (file)
@@ -131,6 +131,8 @@ esp_spiram_size_t esp_spiram_get_chip_size()
     }
     psram_size_t psram_size = psram_get_size();
     switch (psram_size) {
+        case PSRAM_SIZE_16MBITS:
+            return ESP_SPIRAM_SIZE_16MBITS;
         case PSRAM_SIZE_32MBITS:
             return ESP_SPIRAM_SIZE_32MBITS;
         case PSRAM_SIZE_64MBITS:
@@ -214,6 +216,7 @@ esp_err_t esp_spiram_reserve_dma_pool(size_t size) {
 size_t esp_spiram_get_size()
 {
     psram_size_t size=esp_spiram_get_chip_size();
+    if (size==PSRAM_SIZE_16MBITS) return 2*1024*1024;
     if (size==PSRAM_SIZE_32MBITS) return 4*1024*1024;
     if (size==PSRAM_SIZE_64MBITS) return 8*1024*1024;
     return CONFIG_SPIRAM_SIZE;
index 4bef607dad73763db38ca8793ea05b9386852132..c36b83258aca232b0e4fcde5921ae498cba332ca 100644 (file)
@@ -65,38 +65,59 @@ typedef enum {
 #define PSRAM_ID_EID_M          0xff
 #define PSRAM_ID_EID_S            16
 
-#define PSRAM_KGD(id)          (((id) >> PSRAM_ID_KGD_S) & PSRAM_ID_KGD_M)
-#define PSRAM_EID(id)          (((id) >> PSRAM_ID_EID_S) & PSRAM_ID_EID_M)
-#define PSRAM_IS_VALID(id)     (PSRAM_KGD(id) == PSRAM_ID_KGD)
+// Use the [7:5](bit7~bit5) of EID to distinguish the psram size:
+//
+//   BIT7  |  BIT6  |  BIT5  |  SIZE(MBIT)
+//   -------------------------------------
+//    0    |   0    |   0    |     16
+//    0    |   0    |   1    |     32
+//    0    |   1    |   0    |     64
+#define PSRAM_EID_SIZE_M         0x07
+#define PSRAM_EID_SIZE_S            5
+
+typedef enum {
+    PSRAM_EID_SIZE_16MBITS = 0,
+    PSRAM_EID_SIZE_32MBITS = 1,
+    PSRAM_EID_SIZE_64MBITS = 2,
+} psram_eid_size_t;
 
-// PSRAM_EID = 0x26 or 0x4x ----> 64MBit psram
-// PSRAM_EID = 0x20 ------------> 32MBit psram
-#define PSRAM_IS_64MBIT(id)       ((PSRAM_EID(id) == 0x26) || ((PSRAM_EID(id) & 0xf0) == 0x40))
+#define PSRAM_KGD(id)         (((id) >> PSRAM_ID_KGD_S) & PSRAM_ID_KGD_M)
+#define PSRAM_EID(id)         (((id) >> PSRAM_ID_EID_S) & PSRAM_ID_EID_M)
+#define PSRAM_SIZE_ID(id)     ((PSRAM_EID(id) >> PSRAM_EID_SIZE_S) & PSRAM_EID_SIZE_M)
+#define PSRAM_IS_VALID(id)    (PSRAM_KGD(id) == PSRAM_ID_KGD)
+
+// For the old version 32Mbit psram, using the spicial driver */
 #define PSRAM_IS_32MBIT_VER0(id)  (PSRAM_EID(id) == 0x20)
+#define PSRAM_IS_64MBIT_TRIAL(id) (PSRAM_EID(id) == 0x26)
 
 // IO-pins for PSRAM. These need to be in the VDD_SIO power domain because all chips we
 // currently support are 1.8V parts.
 // WARNING: PSRAM shares all but the CS and CLK pins with the flash, so these defines
 // hardcode the flash pins as well, making this code incompatible with either a setup
 // that has the flash on non-standard pins or ESP32s with built-in flash.
-#define FLASH_CLK_IO      6  //Psram clock is a delayed version of this in 40MHz mode
-#define FLASH_CS_IO       11
-#define PSRAM_CLK_IO      17
-#define PSRAM_CS_IO       16
-#define PSRAM_SPIQ_IO     7
-#define PSRAM_SPID_IO     8
-#define PSRAM_SPIWP_IO    10
-#define PSRAM_SPIHD_IO    9
+#define FLASH_CLK_IO                6  //Psram clock is a delayed version of this in 40MHz mode
+#define FLASH_CS_IO                11
+#define FLASH_SPIQ_SD0_IO           7
+#define FLASH_SPID_SD1_IO           8
+#define FLASH_SPIWP_SD3_IO         10
+#define FLASH_SPIHD_SD2_IO          9
+
+#define PSRAM_CLK_IO               17
+#define PSRAM_CS_IO                16
+#define PSRAM_SPIQ_SD0_IO           7
+#define PSRAM_SPID_SD1_IO           8
+#define PSRAM_SPIWP_SD3_IO         10
+#define PSRAM_SPIHD_SD2_IO          9
 
 #define PSRAM_INTERNAL_IO_28       28
 #define PSRAM_INTERNAL_IO_29       29
 #define PSRAM_IO_MATRIX_DUMMY_40M   1
 #define PSRAM_IO_MATRIX_DUMMY_80M   2
 
-#define _SPI_CACHE_PORT   0
-#define _SPI_FLASH_PORT   1
-#define _SPI_80M_CLK_DIV  1
-#define _SPI_40M_CLK_DIV  2
+#define _SPI_CACHE_PORT             0
+#define _SPI_FLASH_PORT             1
+#define _SPI_80M_CLK_DIV            1
+#define _SPI_40M_CLK_DIV            2
 
 //For 4MB PSRAM, we need one more SPI host, select which one to use by kconfig
 #ifdef CONFIG_SPIRAM_OCCUPY_HSPI_HOST
@@ -479,14 +500,14 @@ static void IRAM_ATTR psram_gpio_config(psram_cache_mode_t mode)
     // In bootloader, all the signals are already configured,
     // We keep the following code in case the bootloader is some older version.
     gpio_matrix_out(FLASH_CS_IO, SPICS0_OUT_IDX, 0, 0);
-    gpio_matrix_out(PSRAM_SPIQ_IO, SPIQ_OUT_IDX, 0, 0);
-    gpio_matrix_in(PSRAM_SPIQ_IO, SPIQ_IN_IDX, 0);
-    gpio_matrix_out(PSRAM_SPID_IO, SPID_OUT_IDX, 0, 0);
-    gpio_matrix_in(PSRAM_SPID_IO, SPID_IN_IDX, 0);
-    gpio_matrix_out(PSRAM_SPIWP_IO, SPIWP_OUT_IDX, 0, 0);
-    gpio_matrix_in(PSRAM_SPIWP_IO, SPIWP_IN_IDX, 0);
-    gpio_matrix_out(PSRAM_SPIHD_IO, SPIHD_OUT_IDX, 0, 0);
-    gpio_matrix_in(PSRAM_SPIHD_IO, SPIHD_IN_IDX, 0);
+    gpio_matrix_out(PSRAM_SPIQ_SD0_IO, SPIQ_OUT_IDX, 0, 0);
+    gpio_matrix_in(PSRAM_SPIQ_SD0_IO, SPIQ_IN_IDX, 0);
+    gpio_matrix_out(PSRAM_SPID_SD1_IO, SPID_OUT_IDX, 0, 0);
+    gpio_matrix_in(PSRAM_SPID_SD1_IO, SPID_IN_IDX, 0);
+    gpio_matrix_out(PSRAM_SPIWP_SD3_IO, SPIWP_OUT_IDX, 0, 0);
+    gpio_matrix_in(PSRAM_SPIWP_SD3_IO, SPIWP_IN_IDX, 0);
+    gpio_matrix_out(PSRAM_SPIHD_SD2_IO, SPIHD_OUT_IDX, 0, 0);
+    gpio_matrix_in(PSRAM_SPIHD_SD2_IO, SPIHD_IN_IDX, 0);
 
     switch (mode) {
         case PSRAM_CACHE_F80M_S40M:
@@ -497,7 +518,7 @@ static void IRAM_ATTR psram_gpio_config(psram_cache_mode_t mode)
             esp_rom_spiflash_config_clk(_SPI_80M_CLK_DIV, _SPI_CACHE_PORT);
             esp_rom_spiflash_config_clk(_SPI_40M_CLK_DIV, _SPI_FLASH_PORT);
             //set drive ability for clock
-            SET_PERI_REG_BITS(PERIPHS_IO_MUX_SD_CLK_U, FUN_DRV, 3, FUN_DRV_S);
+            SET_PERI_REG_BITS(GPIO_PIN_MUX_REG[FLASH_CLK_IO], FUN_DRV, 3, FUN_DRV_S);
             SET_PERI_REG_BITS(GPIO_PIN_MUX_REG[PSRAM_CLK_IO], FUN_DRV, 2, FUN_DRV_S);
             break;
         case PSRAM_CACHE_F80M_S80M:
@@ -508,7 +529,7 @@ static void IRAM_ATTR psram_gpio_config(psram_cache_mode_t mode)
             esp_rom_spiflash_config_clk(_SPI_80M_CLK_DIV, _SPI_CACHE_PORT);
             esp_rom_spiflash_config_clk(_SPI_80M_CLK_DIV, _SPI_FLASH_PORT);
             //set drive ability for clock
-            SET_PERI_REG_BITS(PERIPHS_IO_MUX_SD_CLK_U, FUN_DRV, 3, FUN_DRV_S);
+            SET_PERI_REG_BITS(GPIO_PIN_MUX_REG[FLASH_CLK_IO], FUN_DRV, 3, FUN_DRV_S);
             SET_PERI_REG_BITS(GPIO_PIN_MUX_REG[PSRAM_CLK_IO], FUN_DRV, 3, FUN_DRV_S);
             break;
         case PSRAM_CACHE_F40M_S40M:
@@ -519,7 +540,7 @@ static void IRAM_ATTR psram_gpio_config(psram_cache_mode_t mode)
             esp_rom_spiflash_config_clk(_SPI_40M_CLK_DIV, _SPI_CACHE_PORT);
             esp_rom_spiflash_config_clk(_SPI_40M_CLK_DIV, _SPI_FLASH_PORT);
             //set drive ability for clock
-            SET_PERI_REG_BITS(PERIPHS_IO_MUX_SD_CLK_U, FUN_DRV, 2, FUN_DRV_S);
+            SET_PERI_REG_BITS(GPIO_PIN_MUX_REG[FLASH_CLK_IO], FUN_DRV, 2, FUN_DRV_S);
             SET_PERI_REG_BITS(GPIO_PIN_MUX_REG[PSRAM_CLK_IO], FUN_DRV, 2, FUN_DRV_S);
             break;
         default:
@@ -528,21 +549,24 @@ static void IRAM_ATTR psram_gpio_config(psram_cache_mode_t mode)
     SET_PERI_REG_MASK(SPI_USER_REG(0), SPI_USR_DUMMY); // dummy en
 
     //select pin function gpio
-    PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_DATA0_U, PIN_FUNC_GPIO);
-    PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_DATA1_U, PIN_FUNC_GPIO);
-    PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_DATA2_U, PIN_FUNC_GPIO);
-    PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_DATA3_U, PIN_FUNC_GPIO);
-    PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_CMD_U, PIN_FUNC_GPIO);
+    PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[FLASH_SPIQ_SD0_IO], PIN_FUNC_GPIO);
+    PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[FLASH_SPID_SD1_IO], PIN_FUNC_GPIO);
+    PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[FLASH_SPIHD_SD2_IO], PIN_FUNC_GPIO);
+    PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[FLASH_SPIWP_SD3_IO], PIN_FUNC_GPIO);
+
+    PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[FLASH_CS_IO], PIN_FUNC_GPIO);
     //flash clock signal should come from IO MUX.
-    PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_CLK_U, FUNC_SD_CLK_SPICLK);
+    PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[PSRAM_CLK_IO], FUNC_SD_CLK_SPICLK);
 }
 
 psram_size_t psram_get_size()
 {
-    if (PSRAM_IS_32MBIT_VER0(s_psram_id)) {
-        return PSRAM_SIZE_32MBITS;
-    } else if (PSRAM_IS_64MBIT(s_psram_id)) {
+    if ((PSRAM_SIZE_ID(s_psram_id) == PSRAM_EID_SIZE_64MBITS) || PSRAM_IS_64MBIT_TRIAL(s_psram_id)) {
         return PSRAM_SIZE_64MBITS;
+    } else if (PSRAM_SIZE_ID(s_psram_id) == PSRAM_EID_SIZE_32MBITS) {
+        return PSRAM_SIZE_32MBITS;
+    } else if (PSRAM_SIZE_ID(s_psram_id) == PSRAM_EID_SIZE_16MBITS) {
+        return PSRAM_SIZE_16MBITS;
     } else {
         return PSRAM_SIZE_MAX;
     }
@@ -568,8 +592,6 @@ esp_err_t IRAM_ATTR psram_enable(psram_cache_mode_t mode, psram_vaddr_mode_t vad
     assert(mode < PSRAM_CACHE_MAX && "we don't support any other mode for now.");
     s_psram_mode = mode;
 
-    periph_module_enable(PERIPH_SPI_MODULE);
-
     WRITE_PERI_REG(SPI_EXT3_REG(0), 0x1);
     CLEAR_PERI_REG_MASK(SPI_USER_REG(PSRAM_SPI_1), SPI_USR_PREP_HOLD_M);
 
@@ -624,22 +646,17 @@ esp_err_t IRAM_ATTR psram_enable(psram_cache_mode_t mode, psram_vaddr_mode_t vad
     uint32_t flash_id = g_rom_flashchip.device_id;
     if (flash_id == FLASH_ID_GD25LQ32C) {
         // Set drive ability for 1.8v flash in 80Mhz.
-        SET_PERI_REG_BITS(PERIPHS_IO_MUX_SD_DATA0_U,      FUN_DRV_V, 3, FUN_DRV_S);
-        SET_PERI_REG_BITS(PERIPHS_IO_MUX_SD_DATA1_U,      FUN_DRV_V, 3, FUN_DRV_S);
-        SET_PERI_REG_BITS(PERIPHS_IO_MUX_SD_DATA2_U,      FUN_DRV_V, 3, FUN_DRV_S);
-        SET_PERI_REG_BITS(PERIPHS_IO_MUX_SD_DATA3_U,      FUN_DRV_V, 3, FUN_DRV_S);
-        SET_PERI_REG_BITS(PERIPHS_IO_MUX_SD_CMD_U,        FUN_DRV_V, 3, FUN_DRV_S);
-        SET_PERI_REG_BITS(PERIPHS_IO_MUX_SD_CLK_U,        FUN_DRV_V, 3, FUN_DRV_S);
-        SET_PERI_REG_BITS(GPIO_PIN_MUX_REG[PSRAM_CS_IO],  FUN_DRV_V, 3, FUN_DRV_S);
-        SET_PERI_REG_BITS(GPIO_PIN_MUX_REG[PSRAM_CLK_IO], FUN_DRV_V, 3, FUN_DRV_S);
+        SET_PERI_REG_BITS(GPIO_PIN_MUX_REG[FLASH_SPIQ_SD0_IO],  FUN_DRV_V, 3, FUN_DRV_S);
+        SET_PERI_REG_BITS(GPIO_PIN_MUX_REG[FLASH_SPID_SD1_IO],  FUN_DRV_V, 3, FUN_DRV_S);
+        SET_PERI_REG_BITS(GPIO_PIN_MUX_REG[FLASH_SPIHD_SD2_IO], FUN_DRV_V, 3, FUN_DRV_S);
+        SET_PERI_REG_BITS(GPIO_PIN_MUX_REG[FLASH_SPIWP_SD3_IO], FUN_DRV_V, 3, FUN_DRV_S);
+        SET_PERI_REG_BITS(GPIO_PIN_MUX_REG[FLASH_CS_IO],        FUN_DRV_V, 3, FUN_DRV_S);
+        SET_PERI_REG_BITS(GPIO_PIN_MUX_REG[FLASH_CLK_IO],       FUN_DRV_V, 3, FUN_DRV_S);
+        SET_PERI_REG_BITS(GPIO_PIN_MUX_REG[PSRAM_CS_IO],        FUN_DRV_V, 3, FUN_DRV_S);
+        SET_PERI_REG_BITS(GPIO_PIN_MUX_REG[PSRAM_CLK_IO],       FUN_DRV_V, 3, FUN_DRV_S);
     }
-    if (PSRAM_IS_64MBIT(s_psram_id)) {
-        // For this psram, we don't need any extra clock cycles after cs get back to high level
-        s_clk_mode = PSRAM_CLK_MODE_NORM;
-        gpio_matrix_out(PSRAM_INTERNAL_IO_28, SIG_GPIO_OUT_IDX, 0, 0);
-        gpio_matrix_out(PSRAM_INTERNAL_IO_29, SIG_GPIO_OUT_IDX, 0, 0);
-        gpio_matrix_out(PSRAM_CLK_IO, SPICLK_OUT_IDX, 0, 0);
-    } else if (PSRAM_IS_32MBIT_VER0(s_psram_id)) {
+    
+    if (PSRAM_IS_32MBIT_VER0(s_psram_id)) {
         s_clk_mode = PSRAM_CLK_MODE_DCLK;
         if (mode == PSRAM_CACHE_F80M_S80M) {
             /*   note: If the third mode(80Mhz+80Mhz) is enabled for 32MBit 1V8 psram, one of HSPI/VSPI port will be
@@ -667,7 +684,14 @@ esp_err_t IRAM_ATTR psram_enable(psram_cache_mode_t mode, psram_vaddr_mode_t vad
                 }
             }
         }
+    } else {
+        // For other psram, we don't need any extra clock cycles after cs get back to high level
+        s_clk_mode = PSRAM_CLK_MODE_NORM;
+        gpio_matrix_out(PSRAM_INTERNAL_IO_28, SIG_GPIO_OUT_IDX, 0, 0);
+        gpio_matrix_out(PSRAM_INTERNAL_IO_29, SIG_GPIO_OUT_IDX, 0, 0);
+        gpio_matrix_out(PSRAM_CLK_IO, SPICLK_OUT_IDX, 0, 0);
     }
+    
     psram_enable_qio_mode(PSRAM_SPI_1);
     psram_cache_init(mode, vaddrmode);
     return ESP_OK;
index 226a213dd58dba3a6de2337009f670d7c5b5efb2..34c6e9f380278881abbfef72f669f7d63caa9fb1 100644 (file)
@@ -27,8 +27,9 @@ typedef enum {
 } psram_cache_mode_t;
 
 typedef enum {
-    PSRAM_SIZE_32MBITS = 0,
-    PSRAM_SIZE_64MBITS = 1,
+    PSRAM_SIZE_16MBITS = 0,
+    PSRAM_SIZE_32MBITS = 1,
+    PSRAM_SIZE_64MBITS = 2,
     PSRAM_SIZE_MAX,
 } psram_size_t;