From cea7dfbe90469938b95cf162350a0e7458f616c5 Mon Sep 17 00:00:00 2001 From: Wangjialin Date: Fri, 3 Nov 2017 15:10:47 +0800 Subject: [PATCH] psram: improve clock signal generation, increase drive strength Also check the chip type when initializing. --- components/esp32/spiram_psram.c | 56 ++++++++++++++++++++++++--------- 1 file changed, 41 insertions(+), 15 deletions(-) diff --git a/components/esp32/spiram_psram.c b/components/esp32/spiram_psram.c index 6be905d141..5d87a0a2b6 100644 --- a/components/esp32/spiram_psram.c +++ b/components/esp32/spiram_psram.c @@ -22,6 +22,7 @@ #include "esp_attr.h" #include "esp_err.h" #include "esp_types.h" +#include "esp_log.h" #include "spiram_psram.h" #include "rom/ets_sys.h" #include "rom/spi_flash.h" @@ -30,6 +31,7 @@ #include "soc/io_mux_reg.h" #include "soc/dport_reg.h" #include "soc/gpio_sig_map.h" +#include "soc/efuse_reg.h" #include "driver/gpio.h" #include "driver/spi_common.h" @@ -71,6 +73,8 @@ #define PSRAM_SPIWP_IO 10 #define PSRAM_SPIHD_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 @@ -84,7 +88,7 @@ #define SPI_CACHE_DUMMY SPI0_R_FAST_DUMMY_CYCLELEN //dout 7 #endif - +static const char* TAG = "psram"; typedef enum { PSRAM_SPI_1 = 0x1, PSRAM_SPI_2, @@ -418,7 +422,6 @@ void IRAM_ATTR psram_spi_init(psram_spi_num_t spi_num, psram_cache_mode_t mode) static void IRAM_ATTR psram_gpio_config(psram_cache_mode_t mode) { - gpio_matrix_out(FLASH_CLK_IO, SPICLK_OUT_IDX, 0, 0); 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); @@ -434,16 +437,25 @@ static void IRAM_ATTR psram_gpio_config(psram_cache_mode_t mode) extra_dummy = PSRAM_IO_MATRIX_DUMMY_40M; g_rom_spiflash_dummy_len_plus[1] = PSRAM_IO_MATRIX_DUMMY_40M; SET_PERI_REG_BITS(SPI_USER1_REG(0), SPI_USR_DUMMY_CYCLELEN_V, SPI_CACHE_DUMMY + PSRAM_IO_MATRIX_DUMMY_80M, SPI_USR_DUMMY_CYCLELEN_S); //DUMMY + //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[PSRAM_CLK_IO], FUN_DRV, 2, FUN_DRV_S); break; case PSRAM_CACHE_F80M_S80M: extra_dummy = PSRAM_IO_MATRIX_DUMMY_80M; g_rom_spiflash_dummy_len_plus[1] = PSRAM_IO_MATRIX_DUMMY_80M; SET_PERI_REG_BITS(SPI_USER1_REG(0), SPI_USR_DUMMY_CYCLELEN_V, SPI_CACHE_DUMMY + PSRAM_IO_MATRIX_DUMMY_80M, SPI_USR_DUMMY_CYCLELEN_S); //DUMMY + //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[PSRAM_CLK_IO], FUN_DRV, 3, FUN_DRV_S); break; case PSRAM_CACHE_F40M_S40M: extra_dummy = PSRAM_IO_MATRIX_DUMMY_40M; g_rom_spiflash_dummy_len_plus[1] = PSRAM_IO_MATRIX_DUMMY_40M; SET_PERI_REG_BITS(SPI_USER1_REG(0), SPI_USR_DUMMY_CYCLELEN_V, SPI_CACHE_DUMMY + PSRAM_IO_MATRIX_DUMMY_40M, SPI_USR_DUMMY_CYCLELEN_S); //DUMMY + //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[PSRAM_CLK_IO], FUN_DRV, 2, FUN_DRV_S); break; default: break; @@ -451,17 +463,31 @@ 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, 2); - PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_DATA1_U, 2); - PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_DATA2_U, 2); - PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_DATA3_U, 2); - PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_CLK_U, 2); - PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_CMD_U, 2); + 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); + //flash clock signal should come from IO MUX. + PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_CLK_U, FUNC_SD_CLK_SPICLK); } //psram gpio init , different working frequency we have different solutions esp_err_t IRAM_ATTR psram_enable(psram_cache_mode_t mode, psram_vaddr_mode_t vaddrmode) //psram init { + uint32_t chip_ver = REG_GET_FIELD(EFUSE_BLK0_RDATA3_REG, EFUSE_RD_CHIP_VER_PKG); + uint32_t pkg_ver = chip_ver & 0x7; + if (pkg_ver == EFUSE_RD_CHIP_VER_PKG_ESP32D2WDQ5) { + ESP_EARLY_LOGE(TAG, "ESP32D2WD do not support psram yet"); + return ESP_FAIL; + } else if (pkg_ver == EFUSE_RD_CHIP_VER_PKG_ESP32PICOD2) { + ESP_EARLY_LOGE(TAG, "ESP32PICOD2 do not support psram yet"); + return ESP_FAIL; + } else if (pkg_ver == EFUSE_RD_CHIP_VER_PKG_ESP32PICOD4) { + ESP_EARLY_LOGE(TAG, "ESP32PICOD4 do not support psram yet"); + return ESP_FAIL; + } + /* note: If the third mode(80Mhz+80Mhz) is enabled, VSPI port will be occupied by the system, Application code should never touch VSPI hardware in this case. We try to stop applications from doing this using the drivers by claiming the port for ourselves*/ @@ -515,20 +541,20 @@ esp_err_t IRAM_ATTR psram_enable(psram_cache_mode_t mode, psram_vaddr_mode_t vad We do this by routing it signal to signal 224/225, which are used as a loopback; the extra run through the GPIO matrix causes the delay. We use GPIO20 (which is not in any package but has pad logic in silicon) as a temporary pad for this. So the signal path is: - GPIO6(SPI CLK) --> signal224(in then out) --> internal GPIO20 --> signal225(in then out) --> GPIO17(PSRAM CLK) + SPI CLK --> GPIO28 --> signal224(in then out) --> internal GPIO29 --> signal225(in then out) --> GPIO17(PSRAM CLK) */ - gpio_matrix_in(FLASH_CLK_IO, SIG_IN_FUNC224_IDX, 0); - gpio_matrix_out(20, SIG_IN_FUNC224_IDX, 0, 0); - gpio_matrix_in(20, SIG_IN_FUNC225_IDX, 0); + gpio_matrix_out(PSRAM_INTERNAL_IO_28, SPICLK_OUT_IDX, 0, 0); + gpio_matrix_in(PSRAM_INTERNAL_IO_28, SIG_IN_FUNC224_IDX, 0); + gpio_matrix_out(PSRAM_INTERNAL_IO_29, SIG_IN_FUNC224_IDX, 0, 0); + gpio_matrix_in(PSRAM_INTERNAL_IO_29, SIG_IN_FUNC225_IDX, 0); gpio_matrix_out(PSRAM_CLK_IO, SIG_IN_FUNC225_IDX, 0, 0); break; } CLEAR_PERI_REG_MASK(SPI_USER_REG(PSRAM_SPI_1), SPI_CS_SETUP_M); - psram_gpio_config(mode); WRITE_PERI_REG(GPIO_ENABLE_W1TS_REG, BIT(PSRAM_CS_IO)| BIT(PSRAM_CLK_IO)); - PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[PSRAM_CS_IO], 2); - PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[PSRAM_CLK_IO], 2); + PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[PSRAM_CS_IO], PIN_FUNC_GPIO); + PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[PSRAM_CLK_IO], PIN_FUNC_GPIO); uint32_t id; psram_read_id(&id); if (((id >> PSRAM_MFG_ID_S) & PSRAM_MFG_ID_M) != PSRAM_MFG_ID_V) { -- 2.40.0