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;