From 653d8b5bdd128d0a9e3c569c06c855ada021c5fe Mon Sep 17 00:00:00 2001 From: wanglei Date: Thu, 22 Aug 2019 14:17:46 +0800 Subject: [PATCH] update cache and spiram related files and bug fixes 1. remove speed dependency of SPIRAM 2. support wrap mode of cache, flash and SPIRAM 3. fix some bugs on cache modes support --- components/esp32s2beta/Kconfig | 9 ++- components/esp32s2beta/spiram.c | 17 +++-- components/esp32s2beta/spiram_psram.c | 90 +++++++++++---------------- components/esp32s2beta/spiram_psram.h | 9 ++- components/spi_flash/cache_utils.c | 31 ++++----- components/spi_flash/flash_ops.c | 73 ++++++++++++++++++++++ 6 files changed, 141 insertions(+), 88 deletions(-) diff --git a/components/esp32s2beta/Kconfig b/components/esp32s2beta/Kconfig index 2f0b70adb7..ffc8d8e80e 100644 --- a/components/esp32s2beta/Kconfig +++ b/components/esp32s2beta/Kconfig @@ -209,11 +209,14 @@ menu "ESP32S2-specific" option to select 80MHz will only be visible if the flash SPI speed is also 80MHz. (ESPTOOLPY_FLASHFREQ_80M is true) - config SPIRAM_SPEED_40M - bool "40MHz clock speed" config SPIRAM_SPEED_80M - depends on ESPTOOLPY_FLASHFREQ_80M bool "80MHz clock speed" + config SPIRAM_SPEED_40M + bool "40Mhz clock speed" + config SPIRAM_SPEED_26M + bool "26Mhz clock speed" + config SPIRAM_SPEED_20M + bool "20Mhz clock speed" endchoice # insert non-chip-specific items here diff --git a/components/esp32s2beta/spiram.c b/components/esp32s2beta/spiram.c index 693ab702f1..3411102d2d 100644 --- a/components/esp32s2beta/spiram.c +++ b/components/esp32s2beta/spiram.c @@ -49,14 +49,12 @@ we add more types of external RAM memory, this can be made into a more intellige static const char* TAG = "spiram"; -#if CONFIG_SPIRAM_SPEED_40M && CONFIG_ESPTOOLPY_FLASHFREQ_40M -#define PSRAM_SPEED PSRAM_CACHE_F40M_S40M -#elif CONFIG_SPIRAM_SPEED_40M && CONFIG_ESPTOOLPY_FLASHFREQ_80M -#define PSRAM_SPEED PSRAM_CACHE_F80M_S40M -#elif CONFIG_SPIRAM_SPEED_80M && CONFIG_ESPTOOLPY_FLASHFREQ_80M -#define PSRAM_SPEED PSRAM_CACHE_F80M_S80M +#if CONFIG_SPIRAM_SPEED_40M +#define PSRAM_SPEED PSRAM_CACHE_S40M +#elif CONFIG_SPIRAM_SPEED_80M +#define PSRAM_SPEED PSRAM_CACHE_S80M #else -#define PSRAM_SPEED PSRAM_CACHE_F20M_S20M +#define PSRAM_SPEED PSRAM_CACHE_S20M #endif @@ -244,9 +242,8 @@ esp_err_t esp_spiram_init(void) return r; } - ESP_EARLY_LOGI(TAG, "SPI RAM mode: %s", PSRAM_SPEED == PSRAM_CACHE_F40M_S40M ? "flash 40m sram 40m" : \ - PSRAM_SPEED == PSRAM_CACHE_F80M_S40M ? "flash 80m sram 40m" : \ - PSRAM_SPEED == PSRAM_CACHE_F80M_S80M ? "flash 80m sram 80m" : "flash 20m sram 20m"); + ESP_EARLY_LOGI(TAG, "SPI RAM mode: %s", PSRAM_SPEED == PSRAM_CACHE_S40M ? "sram 40m" : \ + PSRAM_SPEED == PSRAM_CACHE_S80M ? "sram 80m" : "sram 20m"); ESP_EARLY_LOGI(TAG, "PSRAM initialized, cache is in %s mode.", \ (PSRAM_MODE==PSRAM_VADDR_MODE_EVENODD)?"even/odd (2-core)": \ (PSRAM_MODE==PSRAM_VADDR_MODE_LOWHIGH)?"low/high (2-core)": \ diff --git a/components/esp32s2beta/spiram_psram.c b/components/esp32s2beta/spiram_psram.c index 1aa036d105..ae3af8f0c4 100644 --- a/components/esp32s2beta/spiram_psram.c +++ b/components/esp32s2beta/spiram_psram.c @@ -320,10 +320,9 @@ static void psram_disable_qio_mode(psram_spi_num_t spi_num) ps_cmd.txDataBitLen = 8; if (s_clk_mode == PSRAM_CLK_MODE_DCLK) { switch (s_psram_mode) { - case PSRAM_CACHE_F80M_S80M: + case PSRAM_CACHE_S80M: break; - case PSRAM_CACHE_F80M_S40M: - case PSRAM_CACHE_F40M_S40M: + case PSRAM_CACHE_S40M: default: cmd_exit_qpi = PSRAM_EXIT_QMODE << 8; ps_cmd.txDataBitLen = 16; @@ -357,10 +356,9 @@ static void psram_read_id(uint32_t* dev_id) ps_cmd.cmdBitLen = 8; if (s_clk_mode == PSRAM_CLK_MODE_DCLK) { switch (s_psram_mode) { - case PSRAM_CACHE_F80M_S80M: + case PSRAM_CACHE_S80M: break; - case PSRAM_CACHE_F80M_S40M: - case PSRAM_CACHE_F40M_S40M: + case PSRAM_CACHE_S40M: default: ps_cmd.cmdBitLen = 2; //this two bits is used to delay 2 clock cycle ps_cmd.cmd = 0; @@ -391,10 +389,9 @@ static esp_err_t IRAM_ATTR psram_enable_qio_mode(psram_spi_num_t spi_num) ps_cmd.cmdBitLen = 0; if (s_clk_mode == PSRAM_CLK_MODE_DCLK) { switch (s_psram_mode) { - case PSRAM_CACHE_F80M_S80M: + case PSRAM_CACHE_S80M: break; - case PSRAM_CACHE_F80M_S40M: - case PSRAM_CACHE_F40M_S40M: + case PSRAM_CACHE_S40M: default: ps_cmd.cmdBitLen = 2; break; @@ -519,13 +516,12 @@ static void psram_read_id(uint32_t* dev_id) uint32_t addr = 0; psram_cmd_t ps_cmd; switch (s_psram_mode) { - case PSRAM_CACHE_F80M_S80M: + case PSRAM_CACHE_S80M: dummy_bits = 0 + extra_dummy; break; - case PSRAM_CACHE_F80M_S40M: - case PSRAM_CACHE_F40M_S40M: - case PSRAM_CACHE_F26M_S26M: - case PSRAM_CACHE_F20M_S20M: + case PSRAM_CACHE_S40M: + case PSRAM_CACHE_S26M: + case PSRAM_CACHE_S20M: default: dummy_bits = 0 + extra_dummy; break; @@ -588,7 +584,7 @@ void IRAM_ATTR psram_spi_init(psram_spi_num_t spi_num, psram_cache_mode_t mode) CLEAR_PERI_REG_MASK(SPI_MEM_SLAVE_REG(spi_num), SPI_MEM_SLAVE_MODE); #endif // Set SPI speed for non-80M mode. (80M mode uses APB clock directly.) - if (mode!=PSRAM_CACHE_F80M_S80M) { + if (mode!=PSRAM_CACHE_S80M) { k = 2; //Main divider. Divide by 2 so we get 40MHz //clear bit 31, set SPI clock div CLEAR_PERI_REG_MASK(SPI_MEM_CLOCK_REG(spi_num), SPI_MEM_CLK_EQU_SYSCLK); @@ -632,15 +628,17 @@ static void IRAM_ATTR psram_gpio_config(psram_cache_mode_t mode) #warning "psram_gpio_config: parts not implemented for esp32s2beta" switch (mode) { - case PSRAM_CACHE_F80M_S40M: + case PSRAM_CACHE_S40M: extra_dummy = PSRAM_IO_MATRIX_DUMMY_40M; - g_rom_spiflash_dummy_len_plus[_SPI_CACHE_PORT] = PSRAM_IO_MATRIX_DUMMY_80M; - g_rom_spiflash_dummy_len_plus[_SPI_FLASH_PORT] = PSRAM_IO_MATRIX_DUMMY_40M; - SET_PERI_REG_BITS(SPI_MEM_USER1_REG(_SPI_CACHE_PORT), SPI_MEM_USR_DUMMY_CYCLELEN_V, spi_cache_dummy + PSRAM_IO_MATRIX_DUMMY_80M, SPI_MEM_USR_DUMMY_CYCLELEN_S); //DUMMY - esp_rom_spiflash_config_clk(_SPI_80M_CLK_DIV, _SPI_CACHE_PORT); - esp_rom_spiflash_config_clk(_SPI_40M_CLK_DIV, _SPI_FLASH_PORT); +#if CONFIG_ESPTOOLPY_FLASHFREQ_80M + g_rom_spiflash_dummy_len_plus[_SPI_CACHE_PORT] = PSRAM_IO_MATRIX_DUMMY_80M; + g_rom_spiflash_dummy_len_plus[_SPI_FLASH_PORT] = PSRAM_IO_MATRIX_DUMMY_40M; + SET_PERI_REG_BITS(SPI_MEM_USER1_REG(_SPI_CACHE_PORT), SPI_MEM_USR_DUMMY_CYCLELEN_V, spi_cache_dummy + PSRAM_IO_MATRIX_DUMMY_80M, SPI_MEM_USR_DUMMY_CYCLELEN_S); //DUMMY + esp_rom_spiflash_config_clk(_SPI_80M_CLK_DIV, _SPI_CACHE_PORT); + esp_rom_spiflash_config_clk(_SPI_40M_CLK_DIV, _SPI_FLASH_PORT); +#endif break; - case PSRAM_CACHE_F80M_S80M: + case PSRAM_CACHE_S80M: extra_dummy = PSRAM_IO_MATRIX_DUMMY_80M; #if 0 g_rom_spiflash_dummy_len_plus[_SPI_CACHE_PORT] = PSRAM_IO_MATRIX_DUMMY_80M; @@ -654,23 +652,8 @@ static void IRAM_ATTR psram_gpio_config(psram_cache_mode_t mode) #endif break; - case PSRAM_CACHE_F40M_S40M: - extra_dummy = PSRAM_IO_MATRIX_DUMMY_40M; -#if 0 - g_rom_spiflash_dummy_len_plus[_SPI_CACHE_PORT] = PSRAM_IO_MATRIX_DUMMY_40M; - g_rom_spiflash_dummy_len_plus[_SPI_FLASH_PORT] = PSRAM_IO_MATRIX_DUMMY_40M; - SET_PERI_REG_BITS(SPI_MEM_USER1_REG(_SPI_CACHE_PORT), SPI_MEM_USR_DUMMY_CYCLELEN_V, spi_cache_dummy + PSRAM_IO_MATRIX_DUMMY_40M, SPI_MEM_USR_DUMMY_CYCLELEN_S); //DUMMY - - CLEAR_PERI_REG_MASK(PERIPHS_SPI_FLASH_CTRL, SPI_MEM_FREAD_QIO | SPI_MEM_FREAD_QUAD | SPI_MEM_FREAD_DIO | SPI_MEM_FREAD_DUAL | SPI_MEM_FASTRD_MODE); - esp_rom_spiflash_config_clk(_SPI_40M_CLK_DIV, _SPI_CACHE_PORT); - - CLEAR_PERI_REG_MASK(PERIPHS_SPI_FLASH_CTRL, SPI_MEM_FREAD_QIO | SPI_MEM_FREAD_QUAD | SPI_MEM_FREAD_DIO | SPI_MEM_FREAD_DUAL | SPI_MEM_FASTRD_MODE); - esp_rom_spiflash_config_clk(_SPI_40M_CLK_DIV, _SPI_FLASH_PORT); -#endif - - break; - case PSRAM_CACHE_F26M_S26M: - case PSRAM_CACHE_F20M_S20M: + case PSRAM_CACHE_S26M: + case PSRAM_CACHE_S20M: extra_dummy = PSRAM_IO_MATRIX_DUMMY_20M; #if 0 g_rom_spiflash_dummy_len_plus[_SPI_CACHE_PORT] = PSRAM_IO_MATRIX_DUMMY_20M; @@ -726,11 +709,10 @@ esp_err_t IRAM_ATTR psram_enable(psram_cache_mode_t mode, psram_vaddr_mode_t vad switch (mode) { - case PSRAM_CACHE_F80M_S80M: - case PSRAM_CACHE_F80M_S40M: - case PSRAM_CACHE_F40M_S40M: - case PSRAM_CACHE_F26M_S26M: - case PSRAM_CACHE_F20M_S20M: + case PSRAM_CACHE_S80M: + case PSRAM_CACHE_S40M: + case PSRAM_CACHE_S26M: + case PSRAM_CACHE_S20M: default: psram_spi_init(PSRAM_SPI_1, mode); CLEAR_PERI_REG_MASK(SPI_MEM_USER_REG(PSRAM_SPI_1), SPI_MEM_CS_HOLD); @@ -792,7 +774,7 @@ esp_err_t IRAM_ATTR psram_enable(psram_cache_mode_t mode, psram_vaddr_mode_t vad REG_SET_FIELD(SPI_MEM_CTRL1_REG(1), SPI_MEM_CLK_MODE, 0); } else if (PSRAM_IS_32MBIT_VER0(s_psram_id)) { s_clk_mode = PSRAM_CLK_MODE_DCLK; - if (mode == PSRAM_CACHE_F80M_S80M) { + if (mode == PSRAM_CACHE_S80M) { } } psram_reset_mode(PSRAM_SPI_1); @@ -829,19 +811,18 @@ static void IRAM_ATTR psram_cache_init(psram_cache_mode_t psram_cache_mode, psra SPI_MEM_SRAM_RDUMMY_CYCLELEN_S); //dummy, psram cache : 40m--+1dummy,80m--+2dummy switch (psram_cache_mode) { - case PSRAM_CACHE_F80M_S80M: + case PSRAM_CACHE_S80M: psram_clock_set(0, 1); break; - case PSRAM_CACHE_F80M_S40M: + case PSRAM_CACHE_S40M: psram_clock_set(0, 2); break; - case PSRAM_CACHE_F26M_S26M: + case PSRAM_CACHE_S26M: psram_clock_set(0, 3); break; - case PSRAM_CACHE_F20M_S20M: + case PSRAM_CACHE_S20M: psram_clock_set(0, 4); break; - case PSRAM_CACHE_F40M_S40M: default: psram_clock_set(0, 2); break; @@ -853,12 +834,11 @@ static void IRAM_ATTR psram_cache_init(psram_cache_mode_t psram_cache_mode, psra //config sram cache r/w command switch (psram_cache_mode) { - case PSRAM_CACHE_F80M_S80M: //in this mode , no delay is needed + case PSRAM_CACHE_S80M: //in this mode , no delay is needed break; - case PSRAM_CACHE_F80M_S40M: //is sram is @40M, need 2 cycles of delay - case PSRAM_CACHE_F40M_S40M: - case PSRAM_CACHE_F26M_S26M: - case PSRAM_CACHE_F20M_S20M: + case PSRAM_CACHE_S40M: //is sram is @40M, need 2 cycles of delay + case PSRAM_CACHE_S26M: + case PSRAM_CACHE_S20M: default: #ifdef FAKE_QPI SET_PERI_REG_BITS(SPI_MEM_SRAM_DRD_CMD_REG(0), SPI_MEM_CACHE_SRAM_USR_RD_CMD_BITLEN_V, 15, diff --git a/components/esp32s2beta/spiram_psram.h b/components/esp32s2beta/spiram_psram.h index 53d6500ff9..b357b8807e 100644 --- a/components/esp32s2beta/spiram_psram.h +++ b/components/esp32s2beta/spiram_psram.h @@ -20,11 +20,10 @@ #include "sdkconfig.h" typedef enum { - PSRAM_CACHE_F80M_S40M = 0, - PSRAM_CACHE_F80M_S80M, - PSRAM_CACHE_F40M_S40M, - PSRAM_CACHE_F26M_S26M, - PSRAM_CACHE_F20M_S20M, + PSRAM_CACHE_S80M = 1, + PSRAM_CACHE_S40M, + PSRAM_CACHE_S26M, + PSRAM_CACHE_S20M, PSRAM_CACHE_MAX, } psram_cache_mode_t; diff --git a/components/spi_flash/cache_utils.c b/components/spi_flash/cache_utils.c index d206bbd7ce..909369abb8 100644 --- a/components/spi_flash/cache_utils.c +++ b/components/spi_flash/cache_utils.c @@ -352,19 +352,19 @@ IRAM_ATTR void esp_config_instruction_cache_mode(void) Cache_Allocate_SRAM(CACHE_MEMORY_ICACHE_LOW, CACHE_MEMORY_ICACHE_HIGH, CACHE_MEMORY_INVALID, CACHE_MEMORY_INVALID); cache_size = CACHE_SIZE_16KB; #endif -#if CONFIG_INSTRUCTION_CACHE_4WAYS +#if CONFIG_ESP32S2_INSTRUCTION_CACHE_4WAYS cache_ways = CACHE_4WAYS_ASSOC; #else cache_ways = CACHE_8WAYS_ASSOC; #endif -#if CONFIG_INSTRUCTION_CACHE_LINE_16B +#if CONFIG_ESP32S2_INSTRUCTION_CACHE_LINE_16B cache_line_size = CACHE_LINE_SIZE_16B; -#elif CONFIG_INSTRUCTION_CACHE_LINE_32B +#elif CONFIG_ESP32S2_INSTRUCTION_CACHE_LINE_32B cache_line_size = CACHE_LINE_SIZE_32B; #else cache_line_size = CACHE_LINE_SIZE_64B; #endif - ESP_EARLY_LOGI(TAG, "Instruction cache \t: size %dKB, %dWays, cache line size %dByte", cache_size == CACHE_SIZE_8KB ? 8 : 16,cache_ways == CACHE_4WAYS_ASSOC ? 4: 8, cache_line_size == CACHE_LINE_SIZE_16B ? 16 : (cache_line_size == CACHE_LINE_SIZE_32B ? 2 : 64)); + ESP_EARLY_LOGI(TAG, "Instruction cache \t: size %dKB, %dWays, cache line size %dByte", cache_size == CACHE_SIZE_8KB ? 8 : 16,cache_ways == CACHE_4WAYS_ASSOC ? 4: 8, cache_line_size == CACHE_LINE_SIZE_16B ? 16 : (cache_line_size == CACHE_LINE_SIZE_32B ? 32 : 64)); Cache_Suspend_ICache(); Cache_Set_ICache_Mode(cache_size, cache_ways, cache_line_size); Cache_Invalidate_ICache_All(); @@ -407,7 +407,7 @@ IRAM_ATTR void esp_config_data_cache_mode(void) #else cache_line_size = CACHE_LINE_SIZE_64B; #endif - ESP_EARLY_LOGI(TAG, "Data cache \t\t: size %dKB, %dWays, cache line size %dByte", cache_size == CACHE_SIZE_8KB ? 8 : 16, cache_ways == CACHE_4WAYS_ASSOC ? 4: 8, cache_line_size == CACHE_LINE_SIZE_16B ? 16 : (cache_line_size == CACHE_LINE_SIZE_32B ? 2 : 64)); + ESP_EARLY_LOGI(TAG, "Data cache \t\t: size %dKB, %dWays, cache line size %dByte", cache_size == CACHE_SIZE_8KB ? 8 : 16, cache_ways == CACHE_4WAYS_ASSOC ? 4: 8, cache_line_size == CACHE_LINE_SIZE_16B ? 16 : (cache_line_size == CACHE_LINE_SIZE_32B ? 32 : 64)); Cache_Set_DCache_Mode(cache_size, cache_ways, cache_line_size); Cache_Invalidate_DCache_All(); } @@ -439,7 +439,7 @@ static IRAM_ATTR void esp_enable_cache_flash_wrap(bool icache, bool dcache) } } -#if CONFIG_SPIRAM_SUPPORT +#if CONFIG_ESP32S2_SPIRAM_SUPPORT static IRAM_ATTR void esp_enable_cache_spiram_wrap(bool icache, bool dcache) { uint32_t i_autoload, d_autoload; @@ -468,18 +468,18 @@ esp_err_t esp_enable_cache_wrap(bool icache_wrap_enable, bool dcache_wrap_enable int i; bool flash_spiram_wrap_together, flash_support_wrap = true, spiram_support_wrap = true; if (icache_wrap_enable) { -#if CONFIG_INSTRUCTION_CACHE_LINE_16B +#if CONFIG_ESP32S2_INSTRUCTION_CACHE_LINE_16B icache_wrap_size = 16; -#elif CONFIG_INSTRUCTION_CACHE_LINE_32B +#elif CONFIG_ESP32S2_INSTRUCTION_CACHE_LINE_32B icache_wrap_size = 32; #else icache_wrap_size = 64; #endif } if (dcache_wrap_enable) { -#if CONFIG_DATA_CACHE_LINE_16B +#if CONFIG_ESP32S2_DATA_CACHE_LINE_16B dcache_wrap_size = 16; -#elif CONFIG_DATA_CACHE_LINE_32B +#elif CONFIG_ESP32S2_DATA_CACHE_LINE_32B dcache_wrap_size = 32; #else dcache_wrap_size = 64; @@ -488,11 +488,11 @@ esp_err_t esp_enable_cache_wrap(bool icache_wrap_enable, bool dcache_wrap_enable uint32_t instruction_use_spiram = 0; uint32_t rodata_use_spiram = 0; -#if CONFIG_INSTRUCTION_USE_SPIRAM +#if CONFIG_SPIRAM_FETCH_INSTRUCTIONS extern uint32_t esp_spiram_instruction_access_enabled(); instruction_use_spiram = esp_spiram_instruction_access_enabled(); #endif -#if CONFIG_RODATA_USE_SPIRAM +#if CONFIG_SPIRAM_RODATA extern uint32_t esp_spiram_rodata_access_enabled(); rodata_use_spiram = esp_spiram_rodata_access_enabled(); #endif @@ -521,7 +521,7 @@ extern uint32_t esp_spiram_rodata_access_enabled(); flash_wrap_sizes[1] = dcache_wrap_size; #endif } -#ifdef CONFIG_SPIRAM_SUPPORT +#ifdef CONFIG_ESP32S2_SPIRAM_SUPPORT spiram_wrap_sizes[1] = dcache_wrap_size; #endif for (i = 0; i < 2; i++) { @@ -541,6 +541,7 @@ extern uint32_t esp_spiram_rodata_access_enabled(); } else { flash_spiram_wrap_together = true; } + ESP_EARLY_LOGI(TAG, "flash_count=%d, size=%d, spiram_count=%d, size=%d,together=%d", flash_count, flash_wrap_size, spiram_count, spiram_wrap_size, flash_spiram_wrap_together); if (flash_count > 1 && flash_wrap_sizes[0] != flash_wrap_sizes[1]) { ESP_EARLY_LOGW(TAG, "Flash wrap with different length %d and %d, abort wrap.", flash_wrap_sizes[0], flash_wrap_sizes[1]); if (spiram_wrap_size == 0) { @@ -573,7 +574,7 @@ extern bool spi_flash_support_wrap_size(uint32_t wrap_size); ESP_EARLY_LOGW(TAG, "Flash do not support wrap size %d.", flash_wrap_size); } -#ifdef CONFIG_SPIRAM_SUPPORT +#ifdef CONFIG_ESP32S2_SPIRAM_SUPPORT extern bool psram_support_wrap_size(uint32_t wrap_size); if (!psram_support_wrap_size(spiram_wrap_size)) { spiram_support_wrap = false; @@ -592,7 +593,7 @@ extern esp_err_t spi_flash_enable_wrap(uint32_t wrap_size); spi_flash_enable_wrap(flash_wrap_size); esp_enable_cache_flash_wrap((flash_wrap_sizes[0] > 0), (flash_wrap_sizes[1] > 0)); } -#if CONFIG_SPIRAM_SUPPORT +#if CONFIG_ESP32S2_SPIRAM_SUPPORT extern esp_err_t psram_enable_wrap(uint32_t wrap_size); if (spiram_support_wrap && spiram_wrap_size > 0) { ESP_EARLY_LOGI(TAG, "SPIRAM wrap enabled."); diff --git a/components/spi_flash/flash_ops.c b/components/spi_flash/flash_ops.c index 99b2db2371..a57e630397 100644 --- a/components/spi_flash/flash_ops.c +++ b/components/spi_flash/flash_ops.c @@ -36,6 +36,7 @@ #elif CONFIG_IDF_TARGET_ESP32S2BETA #include "esp32s2beta/clk.h" #include "soc/spi_mem_reg.h" +#include "soc/spi_mem_struct.h" #endif #include "esp_flash_partitions.h" #include "cache_utils.h" @@ -701,6 +702,78 @@ void spi_flash_dump_counters(void) #endif //CONFIG_SPI_FLASH_ENABLE_COUNTERS +#if CONFIG_IDF_TARGET_ESP32S2BETA +#define SPICACHE SPIMEM0 +#define SPIFLASH SPIMEM1 +#define FLASH_WRAP_CMD 0x77 +esp_err_t spi_flash_wrap_set(spi_flash_wrap_mode_t mode) +{ + uint32_t reg_bkp_ctrl = SPIFLASH.ctrl.val; + uint32_t reg_bkp_usr = SPIFLASH.user.val; + SPIFLASH.user.fwrite_dio = 0; + SPIFLASH.user.fwrite_dual = 0; + SPIFLASH.user.fwrite_qio = 1; + SPIFLASH.user.fwrite_quad = 0; + SPIFLASH.ctrl.fcmd_dual = 0; + SPIFLASH.ctrl.fcmd_quad = 0; + SPIFLASH.user.usr_dummy = 0; + SPIFLASH.user.usr_addr = 1; + SPIFLASH.user.usr_command = 1; + SPIFLASH.user2.usr_command_bitlen = 7; + SPIFLASH.user2.usr_command_value = FLASH_WRAP_CMD; + SPIFLASH.user1.usr_addr_bitlen = 23; + SPIFLASH.addr = 0; + SPIFLASH.user.usr_miso = 0; + SPIFLASH.user.usr_mosi = 1; + SPIFLASH.mosi_dlen.usr_mosi_bit_len = 7; + SPIFLASH.data_buf[0] = (uint32_t) mode << 4;; + SPIFLASH.cmd.usr = 1; + while(SPIFLASH.cmd.usr != 0) + { } + + SPIFLASH.ctrl.val = reg_bkp_ctrl; + SPIFLASH.user.val = reg_bkp_usr; + return ESP_OK; +} + +esp_err_t spi_flash_enable_wrap(uint32_t wrap_size) +{ + switch(wrap_size) { + case 8: + return spi_flash_wrap_set(FLASH_WRAP_MODE_8B); + case 16: + return spi_flash_wrap_set(FLASH_WRAP_MODE_16B); + case 32: + return spi_flash_wrap_set(FLASH_WRAP_MODE_32B); + case 64: + return spi_flash_wrap_set(FLASH_WRAP_MODE_64B); + default: + return ESP_FAIL; + } +} + +void spi_flash_disable_wrap(void) +{ + spi_flash_wrap_set(FLASH_WRAP_MODE_DISABLE); +} + +bool spi_flash_support_wrap_size(uint32_t wrap_size) +{ + if (!REG_GET_BIT(SPI_MEM_CTRL_REG(0), SPI_MEM_FREAD_QIO) || !REG_GET_BIT(SPI_MEM_CTRL_REG(0), SPI_MEM_FASTRD_MODE)){ + return ESP_FAIL; + } + switch(wrap_size) { + case 0: + case 8: + case 16: + case 32: + case 64: + return true; + default: + return false; + } +} +#endif #if defined(CONFIG_SPI_FLASH_USE_LEGACY_IMPL) && defined(CONFIG_IDF_TARGET_ESP32S2BETA) // TODO esp32s2beta: Remove once ESP32S2Beta has new SPI Flash API support esp_flash_t *esp_flash_default_chip = NULL;