diff --git a/components/bootloader_support/bootloader_flash/include/bootloader_flash.h b/components/bootloader_support/bootloader_flash/include/bootloader_flash.h index 6a359e055f..b52553b03d 100644 --- a/components/bootloader_support/bootloader_flash/include/bootloader_flash.h +++ b/components/bootloader_support/bootloader_flash/include/bootloader_flash.h @@ -25,16 +25,6 @@ extern "C" { */ uint32_t bootloader_read_flash_id(void); -#if SOC_CACHE_SUPPORT_WRAP -/** - * @brief Set the burst mode setting command for specified wrap mode. - * - * @param mode The specified warp mode. - * @return always ESP_OK - */ -esp_err_t bootloader_flash_wrap_set(spi_flash_wrap_mode_t mode); -#endif - /** * @brief Startup flow recommended by XMC. Call at startup before any erase/write operation. * diff --git a/components/bootloader_support/bootloader_flash/include/bootloader_flash_priv.h b/components/bootloader_support/bootloader_flash/include/bootloader_flash_priv.h index dd1df35c70..f46b87f63b 100644 --- a/components/bootloader_support/bootloader_flash/include/bootloader_flash_priv.h +++ b/components/bootloader_support/bootloader_flash/include/bootloader_flash_priv.h @@ -49,7 +49,6 @@ extern "C" { #define CMD_RDSR3 0x15 /* Not all SPI flash uses this command */ #define CMD_OTPEN 0x3A /* Enable OTP mode, not all SPI flash uses this command */ #define CMD_RDSFDP 0x5A /* Read the SFDP of the flash */ -#define CMD_WRAP 0x77 /* Set burst with wrap command */ #define CMD_RESUME 0x7A /* Resume command to clear flash suspend bit */ #define CMD_RESETEN 0x66 #define CMD_RESET 0x99 diff --git a/components/bootloader_support/bootloader_flash/src/bootloader_flash.c b/components/bootloader_support/bootloader_flash/src/bootloader_flash.c index 914c0536fc..6cd8fbf0fd 100644 --- a/components/bootloader_support/bootloader_flash/src/bootloader_flash.c +++ b/components/bootloader_support/bootloader_flash/src/bootloader_flash.c @@ -606,38 +606,6 @@ void bootloader_spi_flash_reset(void) bootloader_execute_flash_command(CMD_RESET, 0, 0, 0); } -#if SOC_CACHE_SUPPORT_WRAP -esp_err_t bootloader_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 = CMD_WRAP; - 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; -} -#endif //SOC_CACHE_SUPPORT_WRAP - /******************************************************************************* * XMC startup flow ******************************************************************************/ diff --git a/components/bootloader_support/bootloader_flash/src/flash_qio_mode.c b/components/bootloader_support/bootloader_flash/src/flash_qio_mode.c index 7c846f9684..5b29186a02 100644 --- a/components/bootloader_support/bootloader_flash/src/flash_qio_mode.c +++ b/components/bootloader_support/bootloader_flash/src/flash_qio_mode.c @@ -17,6 +17,7 @@ #include "flash_qio_mode.h" #include "soc/efuse_periph.h" #include "soc/io_mux_reg.h" +#include "esp_private/spi_flash_os.h" static const char *TAG = "qio_mode"; @@ -96,7 +97,8 @@ void bootloader_enable_qio_mode(void) bootloader_flash_qe_support_list[i].write_status_fn, bootloader_flash_qe_support_list[i].status_qio_bit); #if SOC_CACHE_SUPPORT_WRAP - bootloader_flash_wrap_set(FLASH_WRAP_MODE_DISABLE); + spi_flash_wrap_probe(); + spi_flash_wrap_disable(); #endif } diff --git a/components/soc/esp32c2/include/soc/Kconfig.soc_caps.in b/components/soc/esp32c2/include/soc/Kconfig.soc_caps.in index 762cb5c059..9fd2448ae4 100644 --- a/components/soc/esp32c2/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32c2/include/soc/Kconfig.soc_caps.in @@ -443,6 +443,10 @@ config SOC_SPI_MEM_SUPPORT_CHECK_SUS bool default y +config SOC_SPI_MEM_SUPPORT_WRAP + bool + default y + config SOC_MEMSPI_SRC_FREQ_60M_SUPPORTED bool default y diff --git a/components/soc/esp32c2/include/soc/soc_caps.h b/components/soc/esp32c2/include/soc/soc_caps.h index 063fe10931..7c79d788b6 100644 --- a/components/soc/esp32c2/include/soc/soc_caps.h +++ b/components/soc/esp32c2/include/soc/soc_caps.h @@ -222,6 +222,7 @@ #define SOC_SPI_MEM_SUPPORT_IDLE_INTR (1) #define SOC_SPI_MEM_SUPPORT_SW_SUSPEND (1) #define SOC_SPI_MEM_SUPPORT_CHECK_SUS (1) +#define SOC_SPI_MEM_SUPPORT_WRAP (1) #define SOC_MEMSPI_SRC_FREQ_60M_SUPPORTED 1 #define SOC_MEMSPI_SRC_FREQ_30M_SUPPORTED 1 diff --git a/components/soc/esp32c3/include/soc/Kconfig.soc_caps.in b/components/soc/esp32c3/include/soc/Kconfig.soc_caps.in index 4952e6cc08..012351975d 100644 --- a/components/soc/esp32c3/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32c3/include/soc/Kconfig.soc_caps.in @@ -659,6 +659,10 @@ config SOC_SPI_MEM_SUPPORT_CONFIG_GPIO_BY_EFUSE bool default y +config SOC_SPI_MEM_SUPPORT_WRAP + bool + default y + config SOC_MEMSPI_SRC_FREQ_80M_SUPPORTED bool default y diff --git a/components/soc/esp32c3/include/soc/soc_caps.h b/components/soc/esp32c3/include/soc/soc_caps.h index 73169c38ce..80c5fbe88e 100644 --- a/components/soc/esp32c3/include/soc/soc_caps.h +++ b/components/soc/esp32c3/include/soc/soc_caps.h @@ -305,6 +305,7 @@ #define SOC_SPI_MEM_SUPPORT_SW_SUSPEND (1) #define SOC_SPI_MEM_SUPPORT_CHECK_SUS (1) #define SOC_SPI_MEM_SUPPORT_CONFIG_GPIO_BY_EFUSE (1) +#define SOC_SPI_MEM_SUPPORT_WRAP (1) #define SOC_MEMSPI_SRC_FREQ_80M_SUPPORTED 1 #define SOC_MEMSPI_SRC_FREQ_40M_SUPPORTED 1 diff --git a/components/soc/esp32c6/include/soc/Kconfig.soc_caps.in b/components/soc/esp32c6/include/soc/Kconfig.soc_caps.in index 35469a9b52..47ce9e63ea 100644 --- a/components/soc/esp32c6/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32c6/include/soc/Kconfig.soc_caps.in @@ -795,6 +795,10 @@ config SOC_SPI_MEM_SUPPORT_CHECK_SUS bool default y +config SOC_SPI_MEM_SUPPORT_WRAP + bool + default y + config SOC_MEMSPI_SRC_FREQ_80M_SUPPORTED bool default y diff --git a/components/soc/esp32c6/include/soc/soc_caps.h b/components/soc/esp32c6/include/soc/soc_caps.h index 211c0d3720..2d134951f7 100644 --- a/components/soc/esp32c6/include/soc/soc_caps.h +++ b/components/soc/esp32c6/include/soc/soc_caps.h @@ -340,6 +340,7 @@ #define SOC_SPI_MEM_SUPPORT_IDLE_INTR (1) #define SOC_SPI_MEM_SUPPORT_SW_SUSPEND (1) #define SOC_SPI_MEM_SUPPORT_CHECK_SUS (1) +#define SOC_SPI_MEM_SUPPORT_WRAP (1) #define SOC_MEMSPI_SRC_FREQ_80M_SUPPORTED 1 #define SOC_MEMSPI_SRC_FREQ_40M_SUPPORTED 1 diff --git a/components/soc/esp32h2/include/soc/Kconfig.soc_caps.in b/components/soc/esp32h2/include/soc/Kconfig.soc_caps.in index f1ba326885..617a81d1cb 100644 --- a/components/soc/esp32h2/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32h2/include/soc/Kconfig.soc_caps.in @@ -691,6 +691,10 @@ config SOC_SPI_MEM_SUPPORT_CHECK_SUS bool default y +config SOC_SPI_MEM_SUPPORT_WRAP + bool + default y + config SOC_MEMSPI_SRC_FREQ_48M_SUPPORTED bool default y diff --git a/components/soc/esp32h2/include/soc/soc_caps.h b/components/soc/esp32h2/include/soc/soc_caps.h index 77c38909f9..f41d557570 100644 --- a/components/soc/esp32h2/include/soc/soc_caps.h +++ b/components/soc/esp32h2/include/soc/soc_caps.h @@ -338,6 +338,7 @@ #define SOC_SPI_MEM_SUPPORT_IDLE_INTR (1) #define SOC_SPI_MEM_SUPPORT_SW_SUSPEND (1) #define SOC_SPI_MEM_SUPPORT_CHECK_SUS (1) +#define SOC_SPI_MEM_SUPPORT_WRAP (1) #define SOC_MEMSPI_SRC_FREQ_48M_SUPPORTED 1 diff --git a/components/soc/esp32h4/include/soc/Kconfig.soc_caps.in b/components/soc/esp32h4/include/soc/Kconfig.soc_caps.in index 69649712f5..cf3e41f10f 100644 --- a/components/soc/esp32h4/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32h4/include/soc/Kconfig.soc_caps.in @@ -627,6 +627,10 @@ config SOC_SPI_MEM_SUPPORT_CONFIG_GPIO_BY_EFUSE bool default y +config SOC_SPI_MEM_SUPPORT_WRAP + bool + default y + config SOC_MEMSPI_SRC_FREQ_48M_SUPPORTED bool default y diff --git a/components/soc/esp32h4/include/soc/soc_caps.h b/components/soc/esp32h4/include/soc/soc_caps.h index b80adba46a..0de78eb22c 100644 --- a/components/soc/esp32h4/include/soc/soc_caps.h +++ b/components/soc/esp32h4/include/soc/soc_caps.h @@ -310,6 +310,7 @@ #define SOC_SPI_MEM_SUPPORT_SW_SUSPEND (1) #define SOC_SPI_MEM_SUPPORT_CHECK_SUS (1) #define SOC_SPI_MEM_SUPPORT_CONFIG_GPIO_BY_EFUSE (1) +#define SOC_SPI_MEM_SUPPORT_WRAP (1) #define SOC_MEMSPI_SRC_FREQ_48M_SUPPORTED 1 #define SOC_MEMSPI_SRC_FREQ_24M_SUPPORTED 1 diff --git a/components/soc/esp32s2/include/soc/Kconfig.soc_caps.in b/components/soc/esp32s2/include/soc/Kconfig.soc_caps.in index 6c10d3f13d..6228cf67ff 100644 --- a/components/soc/esp32s2/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32s2/include/soc/Kconfig.soc_caps.in @@ -931,6 +931,10 @@ config SOC_SPI_MEM_SUPPORT_CONFIG_GPIO_BY_EFUSE bool default y +config SOC_SPI_MEM_SUPPORT_WRAP + bool + default y + config SOC_PM_SUPPORT_EXT_WAKEUP bool default y diff --git a/components/soc/esp32s2/include/soc/soc_caps.h b/components/soc/esp32s2/include/soc/soc_caps.h index 24cbf21252..bff583a243 100644 --- a/components/soc/esp32s2/include/soc/soc_caps.h +++ b/components/soc/esp32s2/include/soc/soc_caps.h @@ -407,6 +407,7 @@ #define SOC_SPI_MEM_SUPPORT_AUTO_SUSPEND (1) #define SOC_SPI_MEM_SUPPORT_SW_SUSPEND (1) #define SOC_SPI_MEM_SUPPORT_CONFIG_GPIO_BY_EFUSE (1) +#define SOC_SPI_MEM_SUPPORT_WRAP (1) /*-------------------------- Power Management CAPS ---------------------------*/ #define SOC_PM_SUPPORT_EXT_WAKEUP (1) diff --git a/components/soc/esp32s3/include/soc/Kconfig.soc_caps.in b/components/soc/esp32s3/include/soc/Kconfig.soc_caps.in index f9b143ec22..9f3d50b10a 100644 --- a/components/soc/esp32s3/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32s3/include/soc/Kconfig.soc_caps.in @@ -1143,6 +1143,10 @@ config SOC_SPI_MEM_SUPPORT_CONFIG_GPIO_BY_EFUSE bool default y +config SOC_SPI_MEM_SUPPORT_WRAP + bool + default y + config SOC_COEX_HW_PTI bool default y diff --git a/components/soc/esp32s3/include/soc/soc_caps.h b/components/soc/esp32s3/include/soc/soc_caps.h index 4bc7a63e99..f2d7072c7a 100644 --- a/components/soc/esp32s3/include/soc/soc_caps.h +++ b/components/soc/esp32s3/include/soc/soc_caps.h @@ -465,6 +465,7 @@ #define SOC_SPI_MEM_SUPPORT_OPI_MODE (1) #define SOC_SPI_MEM_SUPPORT_TIME_TUNING (1) #define SOC_SPI_MEM_SUPPORT_CONFIG_GPIO_BY_EFUSE (1) +#define SOC_SPI_MEM_SUPPORT_WRAP (1) /*-------------------------- COEXISTENCE HARDWARE PTI CAPS -------------------------------*/ #define SOC_COEX_HW_PTI (1) diff --git a/components/spi_flash/CMakeLists.txt b/components/spi_flash/CMakeLists.txt index edd09e5fda..e6242bd07f 100644 --- a/components/spi_flash/CMakeLists.txt +++ b/components/spi_flash/CMakeLists.txt @@ -4,7 +4,7 @@ if(${target} STREQUAL "linux") endif() if(BOOTLOADER_BUILD OR CONFIG_APP_BUILD_TYPE_PURE_RAM_APP) - set(cache_srcs "") + set(srcs "spi_flash_wrap.c") set(priv_requires bootloader_support soc) else() set(srcs "flash_brownout_hook.c") @@ -35,7 +35,7 @@ else() "cache_utils.c" "flash_mmap.c" "flash_ops.c" - "${target}/flash_ops_${target}.c" + "spi_flash_wrap.c" ) list(APPEND cache_srcs diff --git a/components/spi_flash/cache_utils.c b/components/spi_flash/cache_utils.c index a690e7f1f3..c473d4d6a7 100644 --- a/components/spi_flash/cache_utils.c +++ b/components/spi_flash/cache_utils.c @@ -55,6 +55,8 @@ #include "esp_memory_utils.h" #include "esp_intr_alloc.h" #include "spi_flash_mmap.h" +#include "spi_flash_override.h" +#include "esp_private/spi_flash_os.h" #include "esp_log.h" #include "esp_cpu.h" @@ -555,16 +557,16 @@ esp_err_t esp_enable_cache_wrap(bool icache_wrap_enable, bool dcache_wrap_enable if (icache_wrap_enable) { #if CONFIG_ESP32S2_INSTRUCTION_CACHE_LINE_16B || CONFIG_ESP32S3_INSTRUCTION_CACHE_LINE_16B - icache_wrap_size = 16; + icache_wrap_size = FLASH_WRAP_SIZE_16B; #else - icache_wrap_size = 32; + icache_wrap_size = FLASH_WRAP_SIZE_32B; #endif } if (dcache_wrap_enable) { #if CONFIG_ESP32S2_DATA_CACHE_LINE_16B || CONFIG_ESP32S3_DATA_CACHE_LINE_16B - dcache_wrap_size = 16; + dcache_wrap_size = FLASH_WRAP_SIZE_16B; #else - dcache_wrap_size = 32; + dcache_wrap_size = FLASH_WRAP_SIZE_32B; #endif } @@ -647,7 +649,6 @@ esp_err_t esp_enable_cache_wrap(bool icache_wrap_enable, bool dcache_wrap_enable #ifdef CONFIG_ESPTOOLPY_FLASHMODE_QIO flash_support_wrap = true; - extern bool spi_flash_support_wrap_size(uint32_t wrap_size); if (!spi_flash_support_wrap_size(flash_wrap_size)) { flash_support_wrap = false; ESP_EARLY_LOGW(TAG, "Flash do not support wrap size %d.", flash_wrap_size); @@ -669,10 +670,9 @@ esp_err_t esp_enable_cache_wrap(bool icache_wrap_enable, bool dcache_wrap_enable return ESP_FAIL; } - extern esp_err_t spi_flash_enable_wrap(uint32_t wrap_size); if (flash_support_wrap && flash_wrap_size > 0) { ESP_EARLY_LOGI(TAG, "Flash wrap enabled, size = %d.", flash_wrap_size); - spi_flash_enable_wrap(flash_wrap_size); + spI_flash_wrap_enable(flash_wrap_size); esp_enable_cache_flash_wrap((flash_wrap_sizes[0] > 0), (flash_wrap_sizes[1] > 0)); } #if (CONFIG_IDF_TARGET_ESP32S2 && CONFIG_SPIRAM) @@ -801,20 +801,20 @@ esp_err_t esp_enable_cache_wrap(bool icache_wrap_enable, bool dcache_wrap_enable if (icache_wrap_enable) { #if CONFIG_ESP32S3_INSTRUCTION_CACHE_LINE_16B - icache_wrap_size = 16; + icache_wrap_size = FLASH_WRAP_SIZE_16B; #elif CONFIG_ESP32S3_INSTRUCTION_CACHE_LINE_32B - icache_wrap_size = 32; + icache_wrap_size = FLASH_WRAP_SIZE_32B; #else - icache_wrap_size = 64; + icache_wrap_size = FLASH_WRAP_SIZE_64B; #endif } if (dcache_wrap_enable) { #if CONFIG_ESP32S3_DATA_CACHE_LINE_16B - dcache_wrap_size = 16; + dcache_wrap_size = FLASH_WRAP_SIZE_16B; #elif CONFIG_ESP32S3_DATA_CACHE_LINE_32B - dcache_wrap_size = 32; + dcache_wrap_size = FLASH_WRAP_SIZE_32B; #else - dcache_wrap_size = 64; + dcache_wrap_size = FLASH_WRAP_SIZE_64B; #endif } @@ -895,7 +895,6 @@ esp_err_t esp_enable_cache_wrap(bool icache_wrap_enable, bool dcache_wrap_enable #ifdef CONFIG_ESPTOOLPY_FLASHMODE_QIO flash_support_wrap = true; - extern bool spi_flash_support_wrap_size(uint32_t wrap_size); if (!spi_flash_support_wrap_size(flash_wrap_size)) { flash_support_wrap = false; ESP_EARLY_LOGW(TAG, "Flash do not support wrap size %d.", flash_wrap_size); @@ -918,10 +917,9 @@ esp_err_t esp_enable_cache_wrap(bool icache_wrap_enable, bool dcache_wrap_enable return ESP_FAIL; } - extern esp_err_t spi_flash_enable_wrap(uint32_t wrap_size); if (flash_support_wrap && flash_wrap_size > 0) { ESP_EARLY_LOGI(TAG, "Flash wrap enabled, size = %d.", flash_wrap_size); - spi_flash_enable_wrap(flash_wrap_size); + spI_flash_wrap_enable(flash_wrap_size); esp_enable_cache_flash_wrap((flash_wrap_sizes[0] > 0), (flash_wrap_sizes[1] > 0)); } #if (CONFIG_IDF_TARGET_ESP32S3 && CONFIG_SPIRAM) @@ -963,7 +961,6 @@ esp_err_t esp_enable_cache_wrap(bool icache_wrap_enable) #ifdef CONFIG_ESPTOOLPY_FLASHMODE_QIO flash_support_wrap = true; - extern bool spi_flash_support_wrap_size(uint32_t wrap_size); if (!spi_flash_support_wrap_size(flash_wrap_size)) { flash_support_wrap = false; ESP_EARLY_LOGW(TAG, "Flash do not support wrap size %d.", flash_wrap_size); @@ -972,10 +969,9 @@ esp_err_t esp_enable_cache_wrap(bool icache_wrap_enable) ESP_EARLY_LOGW(TAG, "Flash is not in QIO mode, do not support wrap."); #endif // CONFIG_ESPTOOLPY_FLASHMODE_QIO - extern esp_err_t spi_flash_enable_wrap(uint32_t wrap_size); if (flash_support_wrap && flash_wrap_size > 0) { ESP_EARLY_LOGI(TAG, "Flash wrap enabled, size = %d.", flash_wrap_size); - spi_flash_enable_wrap(flash_wrap_size); + spI_flash_wrap_enable(flash_wrap_size); esp_enable_cache_flash_wrap((flash_wrap_size > 0)); } return ESP_OK; diff --git a/components/spi_flash/esp32/flash_ops_esp32.c b/components/spi_flash/esp32/flash_ops_esp32.c deleted file mode 100644 index b2251506a4..0000000000 --- a/components/spi_flash/esp32/flash_ops_esp32.c +++ /dev/null @@ -1,5 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2018-2021 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ diff --git a/components/spi_flash/esp32c2/flash_ops_esp32c2.c b/components/spi_flash/esp32c2/flash_ops_esp32c2.c deleted file mode 100644 index b5761527fc..0000000000 --- a/components/spi_flash/esp32c2/flash_ops_esp32c2.c +++ /dev/null @@ -1,91 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include - -#include "spi_flash_mmap.h" -#include "soc/system_reg.h" -#include "soc/soc_memory_layout.h" -#include "esp32c2/rom/cache.h" -#include "hal/spi_flash_hal.h" -#include "esp_flash.h" -#include "esp_log.h" -#include "esp_attr.h" -#include "esp_rom_spiflash.h" -#include "esp_private/spi_flash_os.h" - -#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; - } -} diff --git a/components/spi_flash/esp32c3/flash_ops_esp32c3.c b/components/spi_flash/esp32c3/flash_ops_esp32c3.c deleted file mode 100644 index 3e74dc4b8c..0000000000 --- a/components/spi_flash/esp32c3/flash_ops_esp32c3.c +++ /dev/null @@ -1,91 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include - -#include "spi_flash_mmap.h" -#include "soc/system_reg.h" -#include "soc/soc_memory_layout.h" -#include "esp32c3/rom/cache.h" -#include "hal/spi_flash_hal.h" -#include "esp_flash.h" -#include "esp_log.h" -#include "esp_attr.h" -#include "esp_rom_spiflash.h" -#include "esp_private/spi_flash_os.h" - -#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; - } -} diff --git a/components/spi_flash/esp32c6/flash_ops_esp32c6.c b/components/spi_flash/esp32c6/flash_ops_esp32c6.c deleted file mode 100644 index e66ff56301..0000000000 --- a/components/spi_flash/esp32c6/flash_ops_esp32c6.c +++ /dev/null @@ -1,91 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include - -#include "spi_flash_mmap.h" -#include "soc/soc_memory_layout.h" -#include "esp32c6/rom/cache.h" -#include "hal/spi_flash_hal.h" -#include "esp_flash.h" -#include "esp_log.h" -#include "esp_attr.h" -#include "esp_rom_spiflash.h" -#include "esp_private/spi_flash_os.h" - -#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_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) -{ - // IDF-6198 TODO: support wrap on esp32-c6 - CLEAR_PERI_REG_MASK(SPI_MEM_CTRL2_REG(0), SPI_MEM_SPLIT_TRANS_EN_M); - 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; - } -} diff --git a/components/spi_flash/esp32h2/flash_ops_esp32h2.c b/components/spi_flash/esp32h2/flash_ops_esp32h2.c deleted file mode 100644 index 68acf738b4..0000000000 --- a/components/spi_flash/esp32h2/flash_ops_esp32h2.c +++ /dev/null @@ -1,8 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ - - -// TODO: IDF-6020 diff --git a/components/spi_flash/esp32h4/flash_ops_esp32h4.c b/components/spi_flash/esp32h4/flash_ops_esp32h4.c deleted file mode 100644 index e82552ab81..0000000000 --- a/components/spi_flash/esp32h4/flash_ops_esp32h4.c +++ /dev/null @@ -1,91 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include - -#include "spi_flash_mmap.h" -#include "soc/system_reg.h" -#include "soc/soc_memory_layout.h" -#include "esp32h4/rom/cache.h" -#include "hal/spi_flash_hal.h" -#include "esp_flash.h" -#include "esp_log.h" -#include "esp_attr.h" -#include "esp_rom_spiflash.h" -#include "esp_private/spi_flash_os.h" - -#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; - } -} diff --git a/components/spi_flash/esp32s2/flash_ops_esp32s2.c b/components/spi_flash/esp32s2/flash_ops_esp32s2.c deleted file mode 100644 index ef7a8eca25..0000000000 --- a/components/spi_flash/esp32s2/flash_ops_esp32s2.c +++ /dev/null @@ -1,64 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2018-2021 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include - -#include "spi_flash_mmap.h" -#include "soc/system_reg.h" -#include "soc/soc_memory_layout.h" -#include "esp32s2/rom/cache.h" -#include "bootloader_flash.h" -#include "hal/spi_flash_hal.h" -#include "esp_flash.h" -#include "esp_log.h" -#include "esp_rom_spiflash.h" - -#define SPICACHE SPIMEM0 -#define SPIFLASH SPIMEM1 - -esp_err_t spi_flash_wrap_set(spi_flash_wrap_mode_t mode) -{ - return bootloader_flash_wrap_set(mode); -} - -esp_err_t spi_flash_enable_wrap(uint32_t wrap_size) -{ - switch(wrap_size) { - case 8: - return bootloader_flash_wrap_set(FLASH_WRAP_MODE_8B); - case 16: - return bootloader_flash_wrap_set(FLASH_WRAP_MODE_16B); - case 32: - return bootloader_flash_wrap_set(FLASH_WRAP_MODE_32B); - case 64: - return bootloader_flash_wrap_set(FLASH_WRAP_MODE_64B); - default: - return ESP_FAIL; - } -} - -void spi_flash_disable_wrap(void) -{ - bootloader_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; - } -} diff --git a/components/spi_flash/esp32s3/flash_ops_esp32s3.c b/components/spi_flash/esp32s3/flash_ops_esp32s3.c deleted file mode 100644 index 2d114fa27f..0000000000 --- a/components/spi_flash/esp32s3/flash_ops_esp32s3.c +++ /dev/null @@ -1,64 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include - -#include "spi_flash_mmap.h" -#include "soc/system_reg.h" -#include "soc/soc_memory_layout.h" -#include "esp32s3/rom/cache.h" -#include "bootloader_flash.h" -#include "hal/spi_flash_hal.h" -#include "esp_flash.h" -#include "esp_log.h" -#include "esp_rom_spiflash.h" - -#define SPICACHE SPIMEM0 -#define SPIFLASH SPIMEM1 - -esp_err_t spi_flash_wrap_set(spi_flash_wrap_mode_t mode) -{ - return bootloader_flash_wrap_set(mode); -} - -esp_err_t spi_flash_enable_wrap(uint32_t wrap_size) -{ - switch (wrap_size) { - case 8: - return bootloader_flash_wrap_set(FLASH_WRAP_MODE_8B); - case 16: - return bootloader_flash_wrap_set(FLASH_WRAP_MODE_16B); - case 32: - return bootloader_flash_wrap_set(FLASH_WRAP_MODE_32B); - case 64: - return bootloader_flash_wrap_set(FLASH_WRAP_MODE_64B); - default: - return ESP_FAIL; - } -} - -void spi_flash_disable_wrap(void) -{ - bootloader_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; - } -} diff --git a/components/spi_flash/include/esp_private/spi_flash_os.h b/components/spi_flash/include/esp_private/spi_flash_os.h index 55c906b9ad..25273a2c70 100644 --- a/components/spi_flash/include/esp_private/spi_flash_os.h +++ b/components/spi_flash/include/esp_private/spi_flash_os.h @@ -135,23 +135,38 @@ const spi_flash_hpm_dummy_conf_t *spi_flash_hpm_get_dummy(void); */ bool spi_flash_hpm_dummy_adjust(void); -typedef enum { - FLASH_WRAP_MODE_8B = 0, - FLASH_WRAP_MODE_16B = 2, - FLASH_WRAP_MODE_32B = 4, - FLASH_WRAP_MODE_64B = 6, - FLASH_WRAP_MODE_DISABLE = 1 -} spi_flash_wrap_mode_t; - +#if SOC_SPI_MEM_SUPPORT_WRAP /** - * @brief set wrap mode of flash + * @brief set wrap size of flash * - * @param mode: wrap mode support disable, 16 32, 64 byte + * @param wrap_size: wrap mode support disable, 16 32, 64 byte * * @return esp_err_t : ESP_OK for successful. * */ -esp_err_t spi_flash_wrap_set(spi_flash_wrap_mode_t mode); +esp_err_t spI_flash_wrap_enable(spi_flash_wrap_size_t wrap_size); + +/** + * @brief Probe flash wrap method + * + * @return esp_err_t: ESP_OK for success + */ +esp_err_t spi_flash_wrap_probe(void); + +/** + * @brief disable cache wrap + */ +esp_err_t spi_flash_wrap_disable(void); + +/** + * @brief Check whether flash and esp chip supports wrap mode. + * + * @param wrap_size wrap size. + * @return true: wrap support, otherwise, false. + */ +bool spi_flash_support_wrap_size(uint32_t wrap_size); + +#endif //SOC_SPI_MEM_SUPPORT_WRAP /** * @brief SPI flash critical section enter function. diff --git a/components/spi_flash/include/spi_flash/spi_flash_defs.h b/components/spi_flash/include/spi_flash/spi_flash_defs.h index 724e8f9595..08247c619b 100644 --- a/components/spi_flash/include/spi_flash/spi_flash_defs.h +++ b/components/spi_flash/include/spi_flash/spi_flash_defs.h @@ -47,6 +47,8 @@ #define CMD_SUSPEND 0x75 #define CMD_RESUME 0x7A #define CMD_HPMEN 0xA3 /* Enable High Performance mode on flash */ +#define CMD_WRAP 0x77 +#define CMD_BURST_RD 0xC0 /* wrap(0x77) and burst read are functionally same. But commands and formats is different */ #define CMD_RST_EN 0x66 #define CMD_RST_DEV 0x99 diff --git a/components/spi_flash/include/spi_flash_override.h b/components/spi_flash/include/spi_flash_override.h index 7f01576dee..4384d629cf 100644 --- a/components/spi_flash/include/spi_flash_override.h +++ b/components/spi_flash/include/spi_flash_override.h @@ -50,6 +50,49 @@ typedef struct __attribute__((packed)) spi_flash_get_chip_dummy_fn_t flash_get_dummy; } spi_flash_hpm_info_t; +/** + * @brief Enum for user to select valid wrap size. + */ +typedef enum { + FLASH_WRAP_SIZE_8B = 8, + FLASH_WRAP_SIZE_16B = 16, + FLASH_WRAP_SIZE_32B = 32, + FLASH_WRAP_SIZE_64B = 64, +} spi_flash_wrap_size_t; + +/** + * @brief Probe flash wrap method + * + * @param flash_id Flash chip ID + * + * @return ESP_OK: If succeed + */ +typedef esp_err_t (*spi_flash_wrap_probe_fn_t)(uint32_t flash_id); + +/** + * @brief Set flash wrap + * + * @param wrap_size: wrap_size + * + * @return ESP_OK: If succeed + */ +typedef esp_err_t (*spi_flash_wrap_set_fn_t)(spi_flash_wrap_size_t wrap_size); + +/** + * @brief Clear flash wrap. + * + * @return ESP_OK: If succeed + */ +typedef esp_err_t (*spi_flash_wrap_clr_fn_t)(void); + +typedef struct __attribute__((packed)) +{ + const char *method; + spi_flash_wrap_probe_fn_t probe; + spi_flash_wrap_set_fn_t chip_wrap_set; + spi_flash_wrap_clr_fn_t chip_wrap_clr; +} spi_flash_wrap_info_t; + /** * Array of known flash chips and method to enable flash high performance mode. * diff --git a/components/spi_flash/linker.lf b/components/spi_flash/linker.lf index 1d9a112655..aae6bfa293 100644 --- a/components/spi_flash/linker.lf +++ b/components/spi_flash/linker.lf @@ -11,6 +11,7 @@ entries: spi_flash_chip_th (noflash) memspi_host_driver (noflash) flash_brownout_hook (noflash) + spi_flash_wrap (noflash) if IDF_TARGET_ESP32S3 = y: spi_flash_chip_mxic_opi (noflash) diff --git a/components/spi_flash/spi_flash_wrap.c b/components/spi_flash/spi_flash_wrap.c new file mode 100644 index 0000000000..447478ca19 --- /dev/null +++ b/components/spi_flash/spi_flash_wrap.c @@ -0,0 +1,175 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include "sdkconfig.h" +#include "esp_err.h" +#include "esp_log.h" +#include "spi_flash_defs.h" +#include "esp_rom_sys.h" +#include "esp_rom_spiflash.h" +#include "spi_flash_override.h" +#include "esp_private/spi_flash_os.h" + +// TODO: These dependencies will be removed after remove bootloader_flash to G0.IDF-4609 +#include "bootloader_flash_override.h" +#include "bootloader_flash_priv.h" + +/*********************************************************************************** + * Flash wrap feature (also called burst read on some flash chips) + * + * Different flash chips enter wrap (burst read) mode in different strategies. + * 1. Command 0xC0 + 8 Bytes. + * 2. Command 0x77 + 24 dummy + 8 Bytes. + **********************************************************************************/ + +#if SOC_SPI_MEM_SUPPORT_WRAP + +const static char *FLASH_WRAP_TAG = "flash wrap"; + +// TODO: This function will be changed after remove bootloader_flash to G0.IDF-4609 +extern uint32_t bootloader_flash_execute_command_common( + uint8_t command, + uint32_t addr_len, uint32_t address, + uint8_t dummy_len, + uint8_t mosi_len, uint32_t mosi_data, + uint8_t miso_len); + +esp_err_t spi_flash_wrap_probe_c0(uint32_t flash_id) +{ + esp_err_t ret = ESP_OK; + + switch (flash_id) { + /* The flash listed here should enter the wrap with command 0xC0 */ + case 0xC22018: + break; + default: + ret = ESP_ERR_NOT_FOUND; + break; + } + return ret; +} + +/** + * @brief Burst read with command 0xC0 + 8 Bytes + * + * |------------|-----------------------------| + * | data | wrap depth | + * | 00h | 8 | + * | 01h | 16 | + * | 02h | 32 | + * | 03h | 64 | + * |------------|-----------------------------| + */ +esp_err_t spi_flash_wrap_enable_c0(spi_flash_wrap_size_t wrap_size) +{ + uint8_t wrap_code = (uint8_t) (__builtin_ctz(wrap_size) - 3); + bootloader_flash_execute_command_common(CMD_BURST_RD, 0, 0, 0, 8, wrap_code, 0); + return ESP_OK; +} + +/** + * @brief Burst read with command 0x77 + 24 Dummy + 8 Bytes + * + * |-------------------|-----------------------------| + * | data(W6,W5) | wrap depth | + * | 00h | 8 | + * | 01h | 16 | + * | 02h | 32 | + * | 03h | 64 | + * |-------------------|-----------------------------| + */ +esp_err_t spi_flash_wrap_enable_77(spi_flash_wrap_size_t wrap_size) +{ + uint8_t wrap_code = (uint8_t) (((__builtin_ctz(wrap_size) - 3) * 2) << 4); + // According to the special format, we need enable QIO_FWRITE for command 77h and clear it after this command is done. + REG_SET_BIT(SPI_MEM_USER_REG(1), SPI_MEM_FWRITE_QIO); + bootloader_flash_execute_command_common(CMD_WRAP, 0, 0, 6, 8, wrap_code, 0); + REG_CLR_BIT(SPI_MEM_USER_REG(1), SPI_MEM_FWRITE_QIO); + return ESP_OK; +} + +/** + * @brief Burst read is cleared by setting 0x1xh, + * so we set 0x10 to disable this feature. + */ +esp_err_t spi_flash_wrap_clear_c0(void) +{ + bootloader_flash_execute_command_common(CMD_BURST_RD, 0, 0, 0, 8, 0x10, 0); + return ESP_OK; +} + +/** + * @brief Burst read is cleared by setting W4 bit 1, + * so we set 0x10 to disable this feature. + */ +esp_err_t spi_flash_wrap_clear_77(void) +{ + // According to the special format, we need enable QIO_FWRITE for command 77h and clear it after this command is done. + REG_SET_BIT(SPI_MEM_USER_REG(1), SPI_MEM_FWRITE_QIO); + bootloader_flash_execute_command_common(CMD_WRAP, 0, 0, 6, 8, 0x10, 0); + REG_CLR_BIT(SPI_MEM_USER_REG(1), SPI_MEM_FWRITE_QIO); + return ESP_OK; +} + +const spi_flash_wrap_info_t __attribute__((weak)) spi_flash_wrap_list[] = { + /* method probe chip wrap set chip wrap clear */ + {"C0H+8B", spi_flash_wrap_probe_c0, spi_flash_wrap_enable_c0, spi_flash_wrap_clear_c0}, + {"default", NULL, spi_flash_wrap_enable_77, spi_flash_wrap_clear_77}, +}; + +static const spi_flash_wrap_info_t *chip_wrap = NULL; + +esp_err_t spi_flash_wrap_probe(void) +{ + uint32_t flash_chip_id = g_rom_flashchip.device_id; + const spi_flash_wrap_info_t *chip = spi_flash_wrap_list; + esp_err_t ret = ESP_OK; + while (chip->probe) { + ret = chip->probe(flash_chip_id); + if (ret == ESP_OK) { + break; + } + chip++; + } + chip_wrap = chip; + return ret; +} + +esp_err_t spI_flash_wrap_enable(spi_flash_wrap_size_t wrap_size) +{ + // Calculate pre_code. pre_code equals log(2)(wrap_size) - 3 + // So the wrap_size:pre_code is 8:0, 16:1, 32:2, 64:3. + return chip_wrap->chip_wrap_set(wrap_size); +} + +esp_err_t spi_flash_wrap_disable(void) +{ + return chip_wrap->chip_wrap_clr(); +} + +bool spi_flash_support_wrap_size(uint32_t wrap_size) +{ + // Only QIO mode supports wrap. + if (!REG_GET_BIT(SPI_MEM_CTRL_REG(0), SPI_MEM_FREAD_QIO)) { + ESP_EARLY_LOGE(FLASH_WRAP_TAG, "flash wrap is only supported in QIO mode"); + abort(); + } + // Only following size can be wrapped. + switch (wrap_size) { + case 0: + case 8: + case 16: + case 32: + case 64: + return true; + default: + return false; + } +} + +#endif // SOC_SPI_MEM_SUPPORT_WRAP diff --git a/components/spi_flash/test_apps/esp_flash/main/test_esp_flash_drv.c b/components/spi_flash/test_apps/esp_flash/main/test_esp_flash_drv.c index 478c9bddc6..2e7e105a24 100644 --- a/components/spi_flash/test_apps/esp_flash/main/test_esp_flash_drv.c +++ b/components/spi_flash/test_apps/esp_flash/main/test_esp_flash_drv.c @@ -30,6 +30,7 @@ #include "esp_timer.h" #include "test_esp_flash_def.h" #include "spi_flash_mmap.h" +#include "esp_private/spi_flash_os.h" #if CONFIG_IDF_TARGET_ESP32S2 #include "esp32s2/rom/cache.h" @@ -533,6 +534,46 @@ static void test_write_protection(const esp_partition_t* part) TEST_CASE_FLASH("Test esp_flash can enable/disable write protetion", test_write_protection); TEST_CASE_MULTI_FLASH("Test esp_flash can enable/disable write protetion", test_write_protection); +#if CONFIG_ESPTOOLPY_FLASHMODE_QIO && SOC_SPI_MEM_SUPPORT_WRAP +// Only under QIO mode and mspi support wrap this feature makes sense. +static uint8_t wrap_buf[32]; + +void test_flash_wrap(const esp_partition_t* part) +{ + esp_flash_t* chip = part->flash_chip; + uint32_t offs = erase_test_region(part, 1); + + const int test_seed = 778; + srand(test_seed); + for (int i = 0 ; i < sizeof(wrap_buf); i++) { + wrap_buf[i] = rand(); + } + printf("Write %p...\n", (void *)offs); + TEST_ASSERT_EQUAL(ESP_OK, esp_flash_write(chip, wrap_buf, offs + 3, sizeof(wrap_buf)) ); + + bzero(wrap_buf, sizeof(wrap_buf)); + + printf("Read back...\n"); + spi_flash_wrap_probe(); + spI_flash_wrap_enable(FLASH_WRAP_SIZE_32B); + esp_flash_read(chip, wrap_buf, offs + 3, sizeof(wrap_buf)); + spi_flash_wrap_disable(); + + printf("Buffer starts 0x%02x 0x%02x 0x%02x 0x%02x\n", wrap_buf[0], wrap_buf[1], wrap_buf[2], wrap_buf[3]); + + srand(test_seed); + for (int i = 0; i < sizeof(wrap_buf) - 3; i++) { + uint8_t data = rand(); + TEST_ASSERT_EQUAL_HEX8(data, wrap_buf[i]); + } + for (int i = sizeof(wrap_buf) - 3; i < sizeof(wrap_buf); i++) { + TEST_ASSERT_EQUAL_HEX8(0xFF, wrap_buf[i]); + } +} + +TEST_CASE_FLASH("SPI flash wrap test", test_flash_wrap); +#endif + static const uint8_t large_const_buffer[16400] = { 203, // first byte 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,