diff --git a/components/app_update/esp_ota_ops.c b/components/app_update/esp_ota_ops.c index 0e9575be109..22420b016fe 100644 --- a/components/app_update/esp_ota_ops.c +++ b/components/app_update/esp_ota_ops.c @@ -31,7 +31,7 @@ #include "esp_attr.h" #include "esp_bootloader_desc.h" #include "esp_flash.h" -#include "esp_flash_internal.h" +#include "esp_private/esp_flash_internal.h" //For dangerous write protection #define OTA_SLOT(i) (i & 0x0F) #define ALIGN_UP(num, align) (((num) + ((align) - 1)) & ~((align) - 1)) diff --git a/components/app_update/test_apps/test_app_update/main/test_bootloader_update.c b/components/app_update/test_apps/test_app_update/main/test_bootloader_update.c index f4009f01ce7..8bc23790370 100644 --- a/components/app_update/test_apps/test_app_update/main/test_bootloader_update.c +++ b/components/app_update/test_apps/test_app_update/main/test_bootloader_update.c @@ -10,7 +10,7 @@ #include "unity.h" #include "esp_log.h" #include "esp_efuse.h" -#include "esp_flash_internal.h" +#include "esp_private/esp_flash_internal.h" //For dangerous write protection #include "esp_rom_sys.h" #include "utils_update.h" #include "sdkconfig.h" diff --git a/components/app_update/test_apps/test_app_update/main/test_ota_partitions.c b/components/app_update/test_apps/test_app_update/main/test_ota_partitions.c index c6f9f09ef02..73809aca79c 100644 --- a/components/app_update/test_apps/test_app_update/main/test_ota_partitions.c +++ b/components/app_update/test_apps/test_app_update/main/test_ota_partitions.c @@ -6,7 +6,7 @@ #include "esp_ota_ops.h" #include "esp_partition.h" #include "esp_flash_partitions.h" -#include "esp_flash_internal.h" +#include "esp_flash.h" #include "spi_flash_mmap.h" #include "esp_image_format.h" #include "esp_system.h" @@ -34,12 +34,9 @@ static uint32_t find_unused_space(size_t required_size) esp_partition_iterator_release(it); TEST_ASSERT_NOT_NULL(latest_partition); -#if CONFIG_IDF_TARGET_LINUX uint32_t flash_chip_size; - esp_flash_get_size(NULL, &flash_chip_size); -#else - uint32_t flash_chip_size = esp_flash_default_chip->size; -#endif // CONFIG_IDF_TARGET_LINUX + esp_err_t ret = esp_flash_get_size(esp_flash_default_chip, &flash_chip_size); + TEST_ASSERT_EQUAL(ESP_OK, ret); uint32_t unused_offset = latest_partition->address + latest_partition->size; TEST_ASSERT_GREATER_OR_EQUAL_UINT32(required_size, flash_chip_size - unused_offset); return unused_offset; diff --git a/components/bootloader_support/bootloader_flash/src/bootloader_flash.c b/components/bootloader_support/bootloader_flash/src/bootloader_flash.c index 1dcd8ff0503..938e175cd9e 100644 --- a/components/bootloader_support/bootloader_flash/src/bootloader_flash.c +++ b/components/bootloader_support/bootloader_flash/src/bootloader_flash.c @@ -131,7 +131,7 @@ esp_err_t bootloader_flash_erase_range(uint32_t start_addr, uint32_t size) #elif CONFIG_IDF_TARGET_ESP32C5 #include "esp32c5/rom/opi_flash.h" #endif -#include "spi_flash/spi_flash_defs.h" +#include "esp_flash_chips/spi_flash_defs.h" #if ESP_TEE_BUILD #include "esp_fault.h" diff --git a/components/esp_hal_mspi/esp32c5/include/hal/mspi_ll.h b/components/esp_hal_mspi/esp32c5/include/hal/mspi_ll.h index c05190d42bb..5fb863600fc 100644 --- a/components/esp_hal_mspi/esp32c5/include/hal/mspi_ll.h +++ b/components/esp_hal_mspi/esp32c5/include/hal/mspi_ll.h @@ -38,6 +38,9 @@ extern "C" { #define MSPI_LL_CORE_CLOCK_120_MHZ 120 #define MSPI_TIMING_LL_CORE_CLOCK_MHZ_DEFAULT MSPI_LL_CORE_CLOCK_80_MHZ +// PSRAM frequency should be constrained by AXI frequency to avoid FIFO underflow. +#define MSPI_TIMING_LL_PSRAM_FREQ_AXI_CONSTRAINED 1 + /*--------------------------------------------------------------- MSPI ---------------------------------------------------------------*/ diff --git a/components/esp_hal_mspi/esp32c61/include/hal/mspi_ll.h b/components/esp_hal_mspi/esp32c61/include/hal/mspi_ll.h index 3a8a52275f9..2e8aee7c26d 100644 --- a/components/esp_hal_mspi/esp32c61/include/hal/mspi_ll.h +++ b/components/esp_hal_mspi/esp32c61/include/hal/mspi_ll.h @@ -38,6 +38,9 @@ extern "C" { #define MSPI_LL_CORE_CLOCK_120_MHZ 120 #define MSPI_TIMING_LL_CORE_CLOCK_MHZ_DEFAULT MSPI_LL_CORE_CLOCK_80_MHZ +// PSRAM frequency should be constrained by AXI frequency to avoid FIFO underflow. +#define MSPI_TIMING_LL_PSRAM_FREQ_AXI_CONSTRAINED 1 + /************************** MSPI pll clock configurations **************************/ /* diff --git a/components/esp_hal_mspi/esp32h4/include/hal/mspi_ll.h b/components/esp_hal_mspi/esp32h4/include/hal/mspi_ll.h index 9ac94c7d136..a408f0415a6 100644 --- a/components/esp_hal_mspi/esp32h4/include/hal/mspi_ll.h +++ b/components/esp_hal_mspi/esp32h4/include/hal/mspi_ll.h @@ -28,6 +28,9 @@ //TODO: [ESP32H4] IDF-12390 inherited from verification branch, need check +// PSRAM frequency should be constrained by AXI frequency to avoid FIFO underflow. +#define MSPI_TIMING_LL_PSRAM_FREQ_AXI_CONSTRAINED 1 + #ifdef __cplusplus extern "C" { #endif diff --git a/components/esp_hal_mspi/esp32p4/include/hal/mspi_ll.h b/components/esp_hal_mspi/esp32p4/include/hal/mspi_ll.h index 9743b9fb12f..eaf65e85472 100644 --- a/components/esp_hal_mspi/esp32p4/include/hal/mspi_ll.h +++ b/components/esp_hal_mspi/esp32p4/include/hal/mspi_ll.h @@ -48,6 +48,9 @@ extern "C" { #define MSPI_TIMING_LL_MSPI_ID_0 0 #define MSPI_TIMING_LL_MSPI_ID_1 1 +// PSRAM frequency should be constrained by AXI frequency to avoid FIFO underflow. +#define MSPI_TIMING_LL_PSRAM_FREQ_AXI_CONSTRAINED 1 + #define MSPI_TIMING_LL_HP_FLASH_CORE_CLK_DIV 4 #define MSPI_TIMING_LL_LP_FLASH_CORE_CLK_DIV 6 #define MSPI_TIMING_LL_FLASH_FDUMMY_RIN_SUPPORTED 1 diff --git a/components/esp_hw_support/clk_utils.c b/components/esp_hw_support/clk_utils.c index 99eabf816ef..efd3939cbdd 100644 --- a/components/esp_hw_support/clk_utils.c +++ b/components/esp_hw_support/clk_utils.c @@ -11,7 +11,6 @@ #include "sdkconfig.h" #include "esp_check.h" #include "esp_log.h" -#include "soc/soc_caps.h" #include "soc/rtc.h" #include "hal/mspi_ll.h" #include "hal/clk_tree_ll.h" @@ -36,7 +35,7 @@ void esp_clk_utils_mspi_speed_mode_sync_before_cpu_freq_switching(uint32_t targe if (target_cpu_src_freq <= clk_ll_xtal_load_freq_mhz()) { mspi_timing_change_speed_mode_cache_safe(true); } -#elif SOC_SPI_MEM_PSRAM_FREQ_AXI_CONSTRAINED && CONFIG_SPIRAM +#elif MSPI_TIMING_LL_PSRAM_FREQ_AXI_CONSTRAINED && CONFIG_SPIRAM /* On chips with AXI bus, currently there is a restriction that AXI frequency (usually equals to a portion of CPU * frequency) needs to be greater than or equal to MSPI PSRAM frequency to avoid writing MSPI FIFO overflow. */ @@ -58,7 +57,7 @@ void esp_clk_utils_mspi_speed_mode_sync_after_cpu_freq_switching(uint32_t target if (target_cpu_src_freq > clk_ll_xtal_load_freq_mhz()) { mspi_timing_change_speed_mode_cache_safe(false); } -#elif SOC_SPI_MEM_PSRAM_FREQ_AXI_CONSTRAINED && CONFIG_SPIRAM +#elif MSPI_TIMING_LL_PSRAM_FREQ_AXI_CONSTRAINED && CONFIG_SPIRAM /* On chips with AXI bus, currently there is a restriction that AXI frequency (usually equals to a portion of CPU * frequency) needs to be greater than or equal to MSPI PSRAM frequency to avoid writing MSPI FIFO overflow. */ diff --git a/components/esp_partition/partition.c b/components/esp_partition/partition.c index aee1d6ab25c..9baeda5a5c3 100644 --- a/components/esp_partition/partition.c +++ b/components/esp_partition/partition.c @@ -478,7 +478,12 @@ esp_err_t esp_partition_register_external(esp_flash_t *flash_chip, size_t offset if (flash_chip == NULL) { flash_chip = esp_flash_default_chip; } - if (offset + size > flash_chip->size) { + uint32_t flash_size = 0; + esp_err_t ret = esp_flash_get_size(flash_chip, &flash_size); + if (ret != ESP_OK) { + return ret; + } + if (offset + size > flash_size) { return ESP_ERR_INVALID_SIZE; } #endif // CONFIG_IDF_TARGET_LINUX diff --git a/components/esp_pm/CMakeLists.txt b/components/esp_pm/CMakeLists.txt index 0db3e2dea7a..8d54bde2eca 100644 --- a/components/esp_pm/CMakeLists.txt +++ b/components/esp_pm/CMakeLists.txt @@ -19,3 +19,8 @@ idf_component_register(SRCS ${srcs} INCLUDE_DIRS include PRIV_REQUIRES "${priv_requires}" LDFRAGMENTS linker.lf) + +if(CONFIG_PM_WORKAROUND_FREQ_LIMIT_ENABLED) + # Force linking init_flash ESP_SYSTEM_INIT_FN to ensure it's not discarded by linker + target_link_libraries(${COMPONENT_LIB} INTERFACE "-u pm_c5_flash_freq_limit_init_include_func") +endif() diff --git a/components/esp_pm/include/esp_private/pm_impl.h b/components/esp_pm/include/esp_private/pm_impl.h index 56fab2fec98..9ef9abcee78 100644 --- a/components/esp_pm/include/esp_private/pm_impl.h +++ b/components/esp_pm/include/esp_private/pm_impl.h @@ -140,15 +140,6 @@ esp_err_t esp_pm_register_skip_light_sleep_callback(skip_light_sleep_cb_t cb); */ esp_err_t esp_pm_unregister_skip_light_sleep_callback(skip_light_sleep_cb_t cb); - -/** - * @brief Initialize flash frequency limit - * - * This function initializes the flash frequency limit. - * @note This function is only available when CONFIG_PM_WORKAROUND_FREQ_LIMIT_ENABLED is enabled. - */ -void esp_pm_flash_freq_limit_init(void); - #ifdef CONFIG_PM_PROFILING #define WITH_PROFILING #include "esp_timer.h" diff --git a/components/esp_pm/pm_c5_flash_freq_limit.c b/components/esp_pm/pm_c5_flash_freq_limit.c index f0770156503..1f56f854a39 100644 --- a/components/esp_pm/pm_c5_flash_freq_limit.c +++ b/components/esp_pm/pm_c5_flash_freq_limit.c @@ -16,6 +16,7 @@ #include "soc/rtc.h" #include "hal/efuse_hal.h" +#include "esp_private/startup_internal.h" #include "esp_private/pm_impl_freq_limit.h" #include "esp_private/spi_flash_freq_limit_cbs.h" #include "esp_private/esp_clk_utils.h" @@ -39,18 +40,6 @@ static uint32_t IRAM_ATTR get_encrypt_lock_freq_limit(void) } } -void esp_pm_flash_freq_limit_init(void) -{ - uint32_t limit_freq_mhz = get_encrypt_lock_freq_limit(); - ESP_EARLY_LOGW("spi_flash", "CPU frequency is set to 240MHz. esp_flash_write_encrypted() will automatically limit CPU frequency to %dMHz during execution.", limit_freq_mhz); -#ifdef CONFIG_PM_ENABLE - /* Pre-calculate and store forced frequency configuration during initialization. - * This is done here to avoid runtime calculation overhead in lock/unlock functions. - */ - esp_pm_impl_cpu_max_freq_force_init(limit_freq_mhz); -#endif -} - #if !CONFIG_PM_ENABLE /* Saved original frequency for !PM_ENABLE case (0 means no change was made) */ static uint32_t s_saved_freq_mhz = 0; @@ -136,6 +125,24 @@ static void IRAM_ATTR unlimit_cpu_freq(void) } #endif // !CONFIG_PM_ENABLE +ESP_SYSTEM_INIT_FN(init_pm_flash_freq_limit, SECONDARY, BIT(0), 202) +{ + uint32_t limit_freq_mhz = get_encrypt_lock_freq_limit(); + ESP_EARLY_LOGW("spi_flash", "CPU frequency is set to 240MHz. esp_flash_write_encrypted() will automatically limit CPU frequency to %dMHz during execution.", limit_freq_mhz); +#ifdef CONFIG_PM_ENABLE + /* Pre-calculate and store forced frequency configuration during initialization. + * This is done here to avoid runtime calculation overhead in lock/unlock functions. + */ + esp_pm_impl_cpu_max_freq_force_init(limit_freq_mhz); +#endif + return ESP_OK; +} + +void pm_c5_flash_freq_limit_init_include_func(void) +{ + // Linker hook function, exists to make the linker examine this file +} + void IRAM_ATTR esp_flash_freq_limit_cb(void) { /* Limit the frequency */ diff --git a/components/esp_rom/esp32c2/include/esp32c2/rom/esp_flash.h b/components/esp_rom/esp32c2/include/esp32c2/rom/esp_flash.h index 85b4ae8755a..9e0705032a4 100644 --- a/components/esp_rom/esp32c2/include/esp32c2/rom/esp_flash.h +++ b/components/esp_rom/esp32c2/include/esp32c2/rom/esp_flash.h @@ -16,7 +16,6 @@ extern "C" { just adds ROM-specific parts */ -struct spi_flash_chip_t; typedef struct esp_flash_t esp_flash_t; /* Structure to wrap "global" data used by esp_flash in ROM */ diff --git a/components/esp_rom/esp32c3/include/esp32c3/rom/esp_flash.h b/components/esp_rom/esp32c3/include/esp32c3/rom/esp_flash.h index 3b1c97b2e84..f03d507bda5 100644 --- a/components/esp_rom/esp32c3/include/esp32c3/rom/esp_flash.h +++ b/components/esp_rom/esp32c3/include/esp32c3/rom/esp_flash.h @@ -16,7 +16,6 @@ extern "C" { just adds ROM-specific parts */ -struct spi_flash_chip_t; typedef struct esp_flash_t esp_flash_t; /* Structure to wrap "global" data used by esp_flash in ROM */ diff --git a/components/esp_rom/esp32c5/include/esp32c5/rom/esp_flash.h b/components/esp_rom/esp32c5/include/esp32c5/rom/esp_flash.h index c063a30adc9..2d3fe0432e3 100644 --- a/components/esp_rom/esp32c5/include/esp32c5/rom/esp_flash.h +++ b/components/esp_rom/esp32c5/include/esp32c5/rom/esp_flash.h @@ -16,7 +16,6 @@ extern "C" { just adds ROM-specific parts */ -struct spi_flash_chip_t; typedef struct esp_flash_t esp_flash_t; /* Structure to wrap "global" data used by esp_flash in ROM */ diff --git a/components/esp_rom/esp32c6/include/esp32c6/rom/esp_flash.h b/components/esp_rom/esp32c6/include/esp32c6/rom/esp_flash.h index d975036fc27..a456863424a 100644 --- a/components/esp_rom/esp32c6/include/esp32c6/rom/esp_flash.h +++ b/components/esp_rom/esp32c6/include/esp32c6/rom/esp_flash.h @@ -16,7 +16,6 @@ extern "C" { just adds ROM-specific parts */ -struct spi_flash_chip_t; typedef struct esp_flash_t esp_flash_t; /* Structure to wrap "global" data used by esp_flash in ROM */ diff --git a/components/esp_rom/esp32c61/include/esp32c61/rom/esp_flash.h b/components/esp_rom/esp32c61/include/esp32c61/rom/esp_flash.h index 6d48e4be2cc..886d938272f 100644 --- a/components/esp_rom/esp32c61/include/esp32c61/rom/esp_flash.h +++ b/components/esp_rom/esp32c61/include/esp32c61/rom/esp_flash.h @@ -16,7 +16,6 @@ extern "C" { just adds ROM-specific parts */ -struct spi_flash_chip_t; typedef struct esp_flash_t esp_flash_t; /* Structure to wrap "global" data used by esp_flash in ROM */ diff --git a/components/esp_rom/esp32h2/include/esp32h2/rom/esp_flash.h b/components/esp_rom/esp32h2/include/esp32h2/rom/esp_flash.h index d975036fc27..a456863424a 100644 --- a/components/esp_rom/esp32h2/include/esp32h2/rom/esp_flash.h +++ b/components/esp_rom/esp32h2/include/esp32h2/rom/esp_flash.h @@ -16,7 +16,6 @@ extern "C" { just adds ROM-specific parts */ -struct spi_flash_chip_t; typedef struct esp_flash_t esp_flash_t; /* Structure to wrap "global" data used by esp_flash in ROM */ diff --git a/components/esp_rom/esp32h21/include/esp32h21/rom/esp_flash.h b/components/esp_rom/esp32h21/include/esp32h21/rom/esp_flash.h index 6d48e4be2cc..886d938272f 100644 --- a/components/esp_rom/esp32h21/include/esp32h21/rom/esp_flash.h +++ b/components/esp_rom/esp32h21/include/esp32h21/rom/esp_flash.h @@ -16,7 +16,6 @@ extern "C" { just adds ROM-specific parts */ -struct spi_flash_chip_t; typedef struct esp_flash_t esp_flash_t; /* Structure to wrap "global" data used by esp_flash in ROM */ diff --git a/components/esp_rom/esp32h4/include/esp32h4/rom/esp_flash.h b/components/esp_rom/esp32h4/include/esp32h4/rom/esp_flash.h index 0177e1e62ae..1d8926a5a1c 100644 --- a/components/esp_rom/esp32h4/include/esp32h4/rom/esp_flash.h +++ b/components/esp_rom/esp32h4/include/esp32h4/rom/esp_flash.h @@ -16,7 +16,6 @@ extern "C" { just adds ROM-specific parts */ -struct spi_flash_chip_t; typedef struct esp_flash_t esp_flash_t; /* Structure to wrap "global" data used by esp_flash in ROM */ diff --git a/components/esp_rom/esp32p4/include/esp32p4/rom/esp_flash.h b/components/esp_rom/esp32p4/include/esp32p4/rom/esp_flash.h index 56f052198af..d4e386708d3 100644 --- a/components/esp_rom/esp32p4/include/esp32p4/rom/esp_flash.h +++ b/components/esp_rom/esp32p4/include/esp32p4/rom/esp_flash.h @@ -16,7 +16,6 @@ extern "C" { just adds ROM-specific parts */ -struct spi_flash_chip_t; typedef struct esp_flash_t esp_flash_t; /* Structure to wrap "global" data used by esp_flash in ROM */ diff --git a/components/esp_system/startup_funcs.c b/components/esp_system/startup_funcs.c index c3e9de4734d..86578e6148c 100644 --- a/components/esp_system/startup_funcs.c +++ b/components/esp_system/startup_funcs.c @@ -12,20 +12,16 @@ #include "esp_err.h" #include "esp_check.h" #include "esp_system.h" -#include "esp_private/log_util.h" #include "esp_log.h" -#include "esp_private/cache_utils.h" -#include "spi_flash_mmap.h" -#include "esp_flash_internal.h" #include "esp_newlib.h" #include "esp_xt_wdt.h" #include "esp_cpu.h" #include "esp_private/startup_internal.h" +#include "freertos/FreeRTOS.h" #include "soc/soc_caps.h" #include "hal/wdt_hal.h" #include "hal/uart_types.h" #include "hal/uart_ll.h" -#include "freertos/FreeRTOS.h" #if CONFIG_SW_COEXIST_ENABLE || CONFIG_EXTERNAL_COEX_ENABLE #include "private/esp_coexist_internal.h" @@ -37,7 +33,6 @@ #endif #include "esp_private/esp_clk.h" -#include "esp_private/spi_flash_os.h" #include "esp_private/brownout.h" #include "esp_private/vbat.h" @@ -104,29 +99,6 @@ ESP_SYSTEM_INIT_FN(init_newlib_time, CORE, BIT(0), 105) return ESP_OK; } -#if !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP -ESP_SYSTEM_INIT_FN(init_flash, CORE, BIT(0), 130) -{ -#if CONFIG_SPI_FLASH_ROM_IMPL - spi_flash_rom_impl_init(); -#endif - - esp_flash_app_init(); - esp_err_t flash_ret = esp_flash_init_default_chip(); - assert(flash_ret == ESP_OK); - (void)flash_ret; -#if CONFIG_SPI_FLASH_BROWNOUT_RESET - spi_flash_needs_reset_check(); -#endif // CONFIG_SPI_FLASH_BROWNOUT_RESET - // The log library will call the registered callback function to check if the cache is disabled. - esp_log_util_set_cache_enabled_cb(spi_flash_cache_enabled); -#if CONFIG_PM_WORKAROUND_FREQ_LIMIT_ENABLED - esp_pm_flash_freq_limit_init(); -#endif // CONFIG_PM_WORKAROUND_FREQ_LIMIT_ENABLED - return ESP_OK; -} -#endif // !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP - #if CONFIG_ESP_XT_WDT ESP_SYSTEM_INIT_FN(init_xt_wdt, CORE, BIT(0), 170) { diff --git a/components/esp_system/system_init_fn.txt b/components/esp_system/system_init_fn.txt index 0e049104786..f3f0fe1f1a2 100644 --- a/components/esp_system/system_init_fn.txt +++ b/components/esp_system/system_init_fn.txt @@ -60,7 +60,7 @@ CORE: 118: init_vfs_nullfs in components/vfs/nullfs.c on BIT(0) CORE: 119: init_vfs_console in components/esp_stdio/stdio_vfs.c on BIT(0) CORE: 120: init_libc_stdio in components/esp_libc/src/init.c on BIT(0) -CORE: 130: init_flash in components/esp_system/startup_funcs.c on BIT(0) +CORE: 130: init_flash in components/spi_flash/esp_flash_spi_init.c on BIT(0) CORE: 140: init_efuse in components/efuse/src/esp_efuse_startup.c on BIT(0) CORE: 170: init_xt_wdt in components/esp_system/startup_funcs.c on BIT(0) @@ -112,6 +112,7 @@ SECONDARY: 151: nvs_sec_provider_register_hmac_scheme in components/nvs_sec_prov # the rest of the components which are initialized from startup_funcs.c # [refactor-todo]: move init calls into respective components SECONDARY: 201: init_pm in components/esp_system/startup_funcs.c on BIT(0) +SECONDARY: 202: init_pm_flash_freq_limit in components/esp_pm/pm_c5_flash_freq_limit.c on BIT(0) SECONDARY: 203: init_apb_dma in components/esp_system/startup_funcs.c on BIT(0) SECONDARY: 204: init_coexist in components/esp_system/startup_funcs.c on BIT(0) SECONDARY: 205: init_bootloader_offset in components/esp_system/startup_funcs.c on BIT(0) diff --git a/components/esp_tee/subproject/main/core/esp_secure_services_iram.c b/components/esp_tee/subproject/main/core/esp_secure_services_iram.c index 0413e147b7c..dc3437acac1 100644 --- a/components/esp_tee/subproject/main/core/esp_secure_services_iram.c +++ b/components/esp_tee/subproject/main/core/esp_secure_services_iram.c @@ -16,8 +16,8 @@ #include "hal/spi_flash_hal.h" #include "hal/spi_flash_types.h" -#include "spi_flash_chip_generic.h" -#include "memspi_host_driver.h" +#include "esp_flash_chips/spi_flash_chip_generic.h" +#include "esp_private/memspi_host_driver.h" #include "esp_private/mspi_timing_tuning.h" #include "esp_flash.h" #include "riscv/rv_utils.h" diff --git a/components/espcoredump/src/core_dump_flash.c b/components/espcoredump/src/core_dump_flash.c index 2873b48a195..95e6e26a4c2 100644 --- a/components/espcoredump/src/core_dump_flash.c +++ b/components/espcoredump/src/core_dump_flash.c @@ -10,7 +10,7 @@ #include "esp_log.h" #include "esp_core_dump_types.h" #include "core_dump_checksum.h" -#include "esp_flash_internal.h" +#include "esp_private/esp_flash_internal.h" #include "esp_flash_encrypt.h" #include "esp_rom_crc.h" #include "esp_private/spi_flash_os.h" diff --git a/components/soc/esp32c5/include/soc/Kconfig.soc_caps.in b/components/soc/esp32c5/include/soc/Kconfig.soc_caps.in index 03aa2d342b0..820f9bcd2f1 100644 --- a/components/soc/esp32c5/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32c5/include/soc/Kconfig.soc_caps.in @@ -1063,10 +1063,6 @@ config SOC_SPI_MEM_SUPPORT_TSUS_TRES_SEPERATE_CTR bool default y -config SOC_SPI_MEM_PSRAM_FREQ_AXI_CONSTRAINED - bool - default y - config SOC_MEMSPI_TIMING_TUNING_BY_MSPI_DELAY bool default y diff --git a/components/soc/esp32c5/include/soc/soc_caps.h b/components/soc/esp32c5/include/soc/soc_caps.h index f58cdb40f64..2c4a59982bd 100644 --- a/components/soc/esp32c5/include/soc/soc_caps.h +++ b/components/soc/esp32c5/include/soc/soc_caps.h @@ -435,7 +435,6 @@ #define SOC_SPI_MEM_SUPPORT_CACHE_32BIT_ADDR_MAP (1) #define SOC_SPI_MEM_SUPPORT_TIMING_TUNING (1) #define SOC_SPI_MEM_SUPPORT_TSUS_TRES_SEPERATE_CTR (1) -#define SOC_SPI_MEM_PSRAM_FREQ_AXI_CONSTRAINED (1) #define SOC_MEMSPI_TIMING_TUNING_BY_MSPI_DELAY (1) #define SOC_MEMSPI_SRC_FREQ_120M_SUPPORTED 1 diff --git a/components/soc/esp32c61/include/soc/Kconfig.soc_caps.in b/components/soc/esp32c61/include/soc/Kconfig.soc_caps.in index 8a09636d608..1cbdfadb5c3 100644 --- a/components/soc/esp32c61/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32c61/include/soc/Kconfig.soc_caps.in @@ -799,10 +799,6 @@ config SOC_SPI_MEM_SUPPORT_TSUS_TRES_SEPERATE_CTR bool default y -config SOC_SPI_MEM_PSRAM_FREQ_AXI_CONSTRAINED - bool - default y - config SOC_MEMSPI_TIMING_TUNING_BY_MSPI_DELAY bool default y diff --git a/components/soc/esp32c61/include/soc/soc_caps.h b/components/soc/esp32c61/include/soc/soc_caps.h index b8ffd6a5787..e890ed20c73 100644 --- a/components/soc/esp32c61/include/soc/soc_caps.h +++ b/components/soc/esp32c61/include/soc/soc_caps.h @@ -338,7 +338,6 @@ #define SOC_SPI_MEM_SUPPORT_WRAP (1) #define SOC_SPI_MEM_SUPPORT_TIMING_TUNING (1) #define SOC_SPI_MEM_SUPPORT_TSUS_TRES_SEPERATE_CTR (1) -#define SOC_SPI_MEM_PSRAM_FREQ_AXI_CONSTRAINED (1) #define SOC_MEMSPI_TIMING_TUNING_BY_MSPI_DELAY (1) #define SOC_MEMSPI_SRC_FREQ_80M_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 d812acf1b57..4f8e7ef7ffc 100644 --- a/components/soc/esp32h4/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32h4/include/soc/Kconfig.soc_caps.in @@ -687,10 +687,6 @@ config SOC_SPI_MEM_SUPPORT_WRAP bool default y -config SOC_SPI_MEM_PSRAM_FREQ_AXI_CONSTRAINED - bool - default y - config SOC_SYSTIMER_COUNTER_NUM int default 2 diff --git a/components/soc/esp32h4/include/soc/soc_caps.h b/components/soc/esp32h4/include/soc/soc_caps.h index 2beb8e89cb4..b0cec5dd6f3 100644 --- a/components/soc/esp32h4/include/soc/soc_caps.h +++ b/components/soc/esp32h4/include/soc/soc_caps.h @@ -384,7 +384,6 @@ #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_SPI_MEM_PSRAM_FREQ_AXI_CONSTRAINED (1) /*-------------------------- SYSTIMER CAPS ----------------------------------*/ #define SOC_SYSTIMER_COUNTER_NUM 2 // Number of counter units diff --git a/components/soc/esp32p4/include/soc/Kconfig.soc_caps.in b/components/soc/esp32p4/include/soc/Kconfig.soc_caps.in index ef7001be0f1..6ef04bd20e8 100644 --- a/components/soc/esp32p4/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32p4/include/soc/Kconfig.soc_caps.in @@ -1427,10 +1427,6 @@ config SOC_SPI_MEM_SUPPORT_CACHE_32BIT_ADDR_MAP bool default y -config SOC_SPI_MEM_PSRAM_FREQ_AXI_CONSTRAINED - bool - default y - config SOC_SPI_MEM_SUPPORT_TSUS_TRES_SEPERATE_CTR bool default y diff --git a/components/soc/esp32p4/include/soc/soc_caps.h b/components/soc/esp32p4/include/soc/soc_caps.h index bf5864120db..074a98424ac 100644 --- a/components/soc/esp32p4/include/soc/soc_caps.h +++ b/components/soc/esp32p4/include/soc/soc_caps.h @@ -547,7 +547,6 @@ #define SOC_MEMSPI_TIMING_TUNING_BY_DQS (1) #define SOC_MEMSPI_TIMING_TUNING_BY_FLASH_DELAY (1) #define SOC_SPI_MEM_SUPPORT_CACHE_32BIT_ADDR_MAP (1) -#define SOC_SPI_MEM_PSRAM_FREQ_AXI_CONSTRAINED (1) #define SOC_SPI_MEM_SUPPORT_TSUS_TRES_SEPERATE_CTR (1) #define SOC_SPI_PERIPH_SUPPORT_CONTROL_DUMMY_OUT (1) diff --git a/components/spi_flash/CMakeLists.txt b/components/spi_flash/CMakeLists.txt index 24c39d15c46..037608a8af0 100644 --- a/components/spi_flash/CMakeLists.txt +++ b/components/spi_flash/CMakeLists.txt @@ -7,8 +7,7 @@ if(${target} STREQUAL "linux") "linux/flash_mmap.c" "spi_flash_blockdev.c" INCLUDE_DIRS include - REQUIRES esp_hal_mspi esp_blockdev - PRIV_INCLUDE_DIRS include/spi_flash) + REQUIRES esp_hal_mspi esp_blockdev) return() endif() @@ -55,7 +54,7 @@ else() "spi_flash_os_func_noos.c") list(APPEND srcs ${cache_srcs}) - set(priv_requires bootloader_support soc esp_hal_gpio esp_mm) + set(priv_requires bootloader_support soc esp_hal_gpio esp_driver_gpio esp_mm) if(${target} STREQUAL "esp32s2") list(APPEND priv_requires esp_security) @@ -66,7 +65,6 @@ idf_component_register(SRCS "${srcs}" REQUIRES hal esp_hal_mspi esp_blockdev PRIV_REQUIRES "${priv_requires}" INCLUDE_DIRS include - PRIV_INCLUDE_DIRS include/spi_flash LDFRAGMENTS linker.lf) # Avoid cache miss by unexpected inlineing when built by -Os @@ -83,4 +81,6 @@ if(NOT non_os_build AND NOT CONFIG_APP_BUILD_TYPE_PURE_RAM_APP) # will be replaced with MMU requirements idf_component_optional_requires(PRIVATE esp_psram) endif() + # Force linking init_flash ESP_SYSTEM_INIT_FN to ensure it's not discarded by linker + target_link_libraries(${COMPONENT_LIB} INTERFACE "-u esp_flash_spi_init_include_func") endif() diff --git a/components/spi_flash/cache_utils.c b/components/spi_flash/cache_utils.c index 38ce2444efe..a02ef5716b9 100644 --- a/components/spi_flash/cache_utils.c +++ b/components/spi_flash/cache_utils.c @@ -32,7 +32,6 @@ #include "esp_attr.h" #include "esp_memory_utils.h" #include "esp_intr_alloc.h" -#include "spi_flash_override.h" #include "esp_private/esp_cache_private.h" #include "esp_private/cache_utils.h" #include "esp_private/spi_flash_os.h" diff --git a/components/spi_flash/esp32s3/opi_flash_cmd_format_mxic.h b/components/spi_flash/esp32s3/opi_flash_cmd_format_mxic.h index 0fabe0afa84..6be9b51ec08 100644 --- a/components/spi_flash/esp32s3/opi_flash_cmd_format_mxic.h +++ b/components/spi_flash/esp32s3/opi_flash_cmd_format_mxic.h @@ -5,7 +5,7 @@ */ #include -#include "spi_flash_defs.h" +#include "esp_flash_chips/spi_flash_defs.h" //MXIC OPI mode needs two bytes of command - 2nd byte is the inversion of the command (1st) byte. S3 HW send LSB first #define MXIC_CMD16(cmd8) ( (uint8_t)(cmd8) | ((uint8_t)(~(cmd8)) << 8) ) diff --git a/components/spi_flash/esp_flash_api.c b/components/spi_flash/esp_flash_api.c index bf31ca9a240..91a4b521924 100644 --- a/components/spi_flash/esp_flash_api.c +++ b/components/spi_flash/esp_flash_api.c @@ -9,22 +9,23 @@ #include #include +#include "esp_cpu.h" #include "esp_memory_utils.h" -#include "spi_flash_chip_driver.h" -#include "memspi_host_driver.h" #include "esp_log.h" #include "sdkconfig.h" -#include "esp_flash_internal.h" -#include "spi_flash_defs.h" -#include "spi_flash_mmap.h" #include "esp_rom_caps.h" #include "esp_rom_spiflash.h" #include "esp_private/esp_clk.h" -#include "esp_spi_flash_counters.h" #include "esp_check.h" -#include "hal/efuse_hal.h" #include "soc/chip_revision.h" -#include "esp_cpu.h" +#include "hal/efuse_hal.h" + +#include "esp_spi_flash_counters.h" +#include "esp_flash_chips/spi_flash_chip_driver.h" +#include "esp_private/memspi_host_driver.h" +#include "esp_private/esp_flash_internal.h" +#include "esp_flash_chips/spi_flash_defs.h" +#include "spi_flash_mmap.h" #if CONFIG_IDF_TARGET_ESP32S2 #include "esp_crypto_lock.h" // for locking flash encryption peripheral @@ -152,8 +153,8 @@ extern rom_spiflash_api_func_t *esp_flash_api_funcs; #define rom_spiflash_api_funcs esp_flash_api_funcs_patched_ptr #endif -#if !CONFIG_SPI_FLASH_ROM_IMPL || ESP_ROM_HAS_ENCRYPTED_WRITES_USING_LEGACY_DRV -// API funcs case 1 & 2 +#if !CONFIG_SPI_FLASH_ROM_IMPL +// API funcs case 1: Not using ROM - define our own pointer and all functions static esp_err_t spiflash_start_default(esp_flash_t *chip); static esp_err_t spiflash_end_default(esp_flash_t *chip, esp_err_t err); static esp_err_t check_chip_pointer_default(esp_flash_t **inout_chip); @@ -167,25 +168,13 @@ DRAM_ATTR static rom_spiflash_api_func_t esp_flash_api_funcs_patched = { .flash_end_flush_cache = flash_end_flush_cache, }; -# if !CONFIG_SPI_FLASH_ROM_IMPL -// API funcs case 1: Not using ROM - define our own pointer and all functions DRAM_ATTR static rom_spiflash_api_func_t *esp_flash_api_funcs_patched_ptr = &esp_flash_api_funcs_patched; -# else // CONFIG_SPI_FLASH_ROM_IMPL -// API funcs case 2: Using ROM APIs but patch all api_funcs by updating esp_flash_api_funcs from ROM -void esp_flash_rom_api_funcs_init(void) -{ - // Point esp_flash_api_funcs to our default structure - esp_flash_api_funcs = &esp_flash_api_funcs_patched; -} - -# endif // CONFIG_SPI_FLASH_ROM_IMPL - -#else // CONFIG_SPI_FLASH_ROM_IMPL && !ESP_ROM_HAS_ENCRYPTED_WRITES_USING_LEGACY_DRV +#else // CONFIG_SPI_FLASH_ROM_IMPL // Using ROM implementation # if CONFIG_SPI_FLASH_FREQ_LIMIT_C5_240MHZ -// API funcs case 3: Using ROM APIs but patch start function to support flags parameter +// API funcs case 2: Using ROM APIs but patch start function to support flags parameter static esp_err_t spiflash_start_default(esp_flash_t *chip); DRAM_ATTR static rom_spiflash_api_func_t esp_flash_api_funcs_patched; @@ -198,6 +187,21 @@ void esp_flash_rom_api_funcs_init(void) esp_flash_api_funcs = &esp_flash_api_funcs_patched; } +# elif ESP_ROM_HAS_ENCRYPTED_WRITES_USING_LEGACY_DRV +// API funcs case 3: Using ROM APIs but patch flash_end_flush_cache function +// When ESP_ROM_HAS_ENCRYPTED_WRITES_USING_LEGACY_DRV, the api_funcs provided by ROM does not have flash_end_flush_cache member. +static esp_err_t flash_end_flush_cache(esp_flash_t* chip, esp_err_t err, bool bus_acquired, uint32_t address, uint32_t length); +DRAM_ATTR static rom_spiflash_api_func_t esp_flash_api_funcs_patched; + +// Copy ROM structure to RAM and patch flash_end_flush_cache function +void esp_flash_rom_api_funcs_init(void) +{ + rom_spiflash_api_func_t *rom_ptr = esp_flash_api_funcs; + memcpy(&esp_flash_api_funcs_patched, rom_ptr, sizeof(rom_spiflash_api_func_t)); + esp_flash_api_funcs_patched.flash_end_flush_cache = flash_end_flush_cache; + esp_flash_api_funcs = &esp_flash_api_funcs_patched; +} + # else // API funcs case 4: Using All ROM APIs directly void esp_flash_rom_api_funcs_init(void) @@ -206,14 +210,14 @@ void esp_flash_rom_api_funcs_init(void) } # endif // CONFIG_SPI_FLASH_FREQ_LIMIT_C5_240MHZ -#endif // !CONFIG_SPI_FLASH_ROM_IMPL || ESP_ROM_HAS_ENCRYPTED_WRITES_USING_LEGACY_DRV +#endif // !CONFIG_SPI_FLASH_ROM_IMPL /* Static function to notify OS of a new SPI flash operation. If returns an error result, caller must abort. If returns ESP_OK, caller must call rom_spiflash_api_funcs->end() before returning. */ -#if !CONFIG_SPI_FLASH_ROM_IMPL || ESP_ROM_HAS_ENCRYPTED_WRITES_USING_LEGACY_DRV || CONFIG_SPI_FLASH_FREQ_LIMIT_C5_240MHZ +#if !CONFIG_SPI_FLASH_ROM_IMPL || CONFIG_SPI_FLASH_FREQ_LIMIT_C5_240MHZ //Avoid constprop issue that place this function into flash. __attribute__((optimize("O0"))) //IDF-14941 static esp_err_t spiflash_start_core(esp_flash_t *chip, uint32_t flags) @@ -232,9 +236,9 @@ static esp_err_t spiflash_start_default(esp_flash_t *chip) { return spiflash_start_core(chip, 0); } -#endif //!CONFIG_SPI_FLASH_ROM_IMPL || ESP_ROM_HAS_ENCRYPTED_WRITES_USING_LEGACY_DRV || CONFIG_SPI_FLASH_FREQ_LIMIT_C5_240MHZ +#endif //!CONFIG_SPI_FLASH_ROM_IMPL || CONFIG_SPI_FLASH_FREQ_LIMIT_C5_240MHZ -#if !CONFIG_SPI_FLASH_ROM_IMPL || ESP_ROM_HAS_ENCRYPTED_WRITES_USING_LEGACY_DRV +#if !CONFIG_SPI_FLASH_ROM_IMPL /* Static function to notify OS that SPI flash operation is complete. */ static esp_err_t spiflash_end_default(esp_flash_t *chip, esp_err_t err) @@ -262,7 +266,13 @@ static esp_err_t check_chip_pointer_default(esp_flash_t **inout_chip) } return ESP_OK; } +#endif // !CONFIG_SPI_FLASH_ROM_IMPL +#if !CONFIG_SPI_FLASH_ROM_IMPL || ESP_ROM_HAS_ENCRYPTED_WRITES_USING_LEGACY_DRV +/* ROM and patch information + * Latest: No change + * V1 (!ESP_ROM_HAS_ENCRYPTED_WRITES_USING_LEGACY_DRV): Added to ROM + */ static esp_err_t flash_end_flush_cache(esp_flash_t* chip, esp_err_t err, bool bus_acquired, uint32_t address, uint32_t length) { if (!bus_acquired) { @@ -769,7 +779,7 @@ esp_err_t esp_flash_erase_region(esp_flash_t *chip, uint32_t start, uint32_t len if (len == 0) { return ESP_OK; } - if (len > chip->size - start) { + if (start > chip->size || len > chip->size - start) { return ESP_ERR_INVALID_ARG; } return rom_esp_flash_erase_region(chip, start, len); @@ -782,7 +792,7 @@ esp_err_t IRAM_ATTR esp_flash_erase_region(esp_flash_t *chip, uint32_t start, ui if (err != ESP_OK) { return err; } - if (len > chip->size - start) { + if (start > chip->size || len > chip->size - start) { return ESP_ERR_INVALID_ARG; } return rom_esp_flash_erase_region(chip, start, len); @@ -1286,7 +1296,7 @@ esp_err_t esp_flash_set_io_mode(esp_flash_t* chip, bool qe) } #endif //CONFIG_SPI_FLASH_ROM_IMPL -#if !(CONFIG_SPI_FLASH_ROM_IMPL && !ESP_ROM_HAS_ENCRYPTED_WRITES_USING_LEGACY_DRV) || CONFIG_SPI_FLASH_FREQ_LIMIT_C5_240MHZ +#if !CONFIG_SPI_FLASH_ROM_IMPL || ESP_ROM_HAS_ENCRYPTED_WRITES_USING_LEGACY_DRV || CONFIG_SPI_FLASH_FREQ_LIMIT_C5_240MHZ // use `esp_flash_write_encrypted` ROM version on chips later than C3, S3 // For ESP32-C5, use IDF implementation when CPU frequency is 240MHz (calling start() with arg is required) FORCE_INLINE_ATTR esp_err_t s_encryption_write_lock(esp_flash_t *chip) @@ -1546,12 +1556,12 @@ esp_err_t IRAM_ATTR esp_flash_write_encrypted(esp_flash_t *chip, uint32_t addres if (err != ESP_OK) { return err; } - if (length > chip->size - address) { + if (buffer == NULL || address > chip->size || length > chip->size - address) { return ESP_ERR_INVALID_ARG; } return rom_esp_flash_write_encrypted(chip, address, buffer, length); } -#endif // !(CONFIG_SPI_FLASH_ROM_IMPL && !ESP_ROM_HAS_ENCRYPTED_WRITES_USING_LEGACY_DRV) || CONFIG_SPI_FLASH_FREQ_LIMIT_C5_240MHZ +#endif // !CONFIG_SPI_FLASH_ROM_IMPL || ESP_ROM_HAS_ENCRYPTED_WRITES_USING_LEGACY_DRV || CONFIG_SPI_FLASH_FREQ_LIMIT_C5_240MHZ //init suspend mode cmd, uses internal. esp_err_t esp_flash_suspend_cmd_init(esp_flash_t* chip) @@ -1592,3 +1602,11 @@ esp_err_t esp_flash_app_disable_protect(bool disable) return esp_flash_app_enable_os_functions(esp_flash_default_chip); } } + +bool esp_flash_is_quad_mode(const esp_flash_t *chip) +{ + if (chip == NULL) { + chip = esp_flash_default_chip; + } + return (chip->read_mode == SPI_FLASH_QIO) || (chip->read_mode == SPI_FLASH_QOUT); +} diff --git a/components/spi_flash/esp_flash_spi_init.c b/components/spi_flash/esp_flash_spi_init.c index 8beb9425375..97b08e8590c 100644 --- a/components/spi_flash/esp_flash_spi_init.c +++ b/components/spi_flash/esp_flash_spi_init.c @@ -1,13 +1,11 @@ /* - * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ #include "sdkconfig.h" -#include "esp_flash.h" -#include "memspi_host_driver.h" -#include "esp_flash_spi_init.h" +#include "driver/gpio.h" #include "esp_rom_gpio.h" #include "esp_rom_efuse.h" #include "esp_log.h" @@ -15,13 +13,11 @@ #include "hal/spi_types.h" #include "esp_private/spi_share_hw_ctrl.h" #include "esp_ldo_regulator.h" -#include "hal/spi_flash_hal.h" -#include "spi_flash_chip_driver.h" #include "hal/gpio_hal.h" -#include "esp_flash_internal.h" #include "esp_rom_gpio.h" -#include "esp_private/spi_flash_os.h" #include "esp_private/cache_utils.h" +#include "esp_private/log_util.h" +#include "esp_private/startup_internal.h" #include "esp_spi_flash_counters.h" #include "esp_rom_spiflash.h" #include "bootloader_flash.h" @@ -29,6 +25,15 @@ #include "esp_private/esp_clk_tree_common.h" #include "clk_ctrl_os.h" #include "soc/soc_caps.h" +#include "hal/spi_flash_hal.h" +#include "hal/mspi_ll.h" + +#include "esp_flash.h" +#include "esp_flash_spi_init.h" +#include "esp_flash_chips/spi_flash_chip_driver.h" +#include "esp_private/memspi_host_driver.h" +#include "esp_private/esp_flash_internal.h" +#include "esp_private/spi_flash_os.h" __attribute__((unused)) static const char TAG[] = "spi_flash"; @@ -149,7 +154,7 @@ esp_flash_t *esp_flash_default_chip = NULL; // 1. Frequency limit workaround is enabled (CONFIG_SPI_FLASH_FREQ_LIMIT_C5_240MHZ) // 2. Flash frequency requires timing tuning (80MHz or 120MHz, i.e., > 40MHz) // 3. CPU frequency reduction will trigger MSPI timing tuning to enter low speed mode -// This happens when: SOC_SPI_MEM_PSRAM_FREQ_AXI_CONSTRAINED && CONFIG_SPIRAM && +// This happens when: MSPI_TIMING_LL_PSRAM_FREQ_AXI_CONSTRAINED && CONFIG_SPIRAM && // (target_cpu_freq < CONFIG_SPIRAM_SPEED) // Note: The runtime check for CPU freq < PSRAM speed is done in clk_utils.c, // which calls mspi_timing_change_speed_mode_cache_safe(true) to enter low speed mode. @@ -359,12 +364,10 @@ static void deinit_gpspi_clock(esp_flash_t *chip) // Disable the clock source esp_clk_tree_enable_src(chip->clock_source, false); -#if SOC_SPI_SUPPORT_CLK_RC_FAST // Disable RC_FAST clock if it was used - if (chip->clock_source == SPI_CLK_SRC_RC_FAST) { + if ((soc_module_clk_t)chip->clock_source == SOC_MOD_CLK_RC_FAST) { periph_rtc_dig_clk8m_disable(); } -#endif #endif // !CONFIG_IDF_TARGET_ESP32 } @@ -649,3 +652,28 @@ esp_err_t esp_flash_app_init(void) err = esp_flash_app_enable_os_functions(&default_chip); return err; } + +#if !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP +ESP_SYSTEM_INIT_FN(init_flash, CORE, BIT(0), 130) +{ +#if CONFIG_SPI_FLASH_ROM_IMPL + spi_flash_rom_impl_init(); +#endif + + esp_flash_app_init(); + esp_err_t flash_ret = esp_flash_init_default_chip(); + assert(flash_ret == ESP_OK); + (void)flash_ret; +#if CONFIG_SPI_FLASH_BROWNOUT_RESET + spi_flash_needs_reset_check(); +#endif // CONFIG_SPI_FLASH_BROWNOUT_RESET + // The log library will call the registered callback function to check if the cache is disabled. + esp_log_util_set_cache_enabled_cb(spi_flash_cache_enabled); + return ESP_OK; +} +#endif // !CONFIG_APP_BUILD_TYPE_PURE_RAM_APP + +void esp_flash_spi_init_include_func(void) +{ + // Linker hook function, exists to make the linker examine this file +} diff --git a/components/spi_flash/include/esp_flash.h b/components/spi_flash/include/esp_flash.h index c3b29269efe..8d1bef07b3c 100644 --- a/components/spi_flash/include/esp_flash.h +++ b/components/spi_flash/include/esp_flash.h @@ -10,14 +10,12 @@ #include #include "hal/spi_flash_types.h" #include "esp_blockdev.h" +#include "esp_bit_defs.h" #ifdef __cplusplus extern "C" { #endif -struct spi_flash_chip_t; -typedef struct spi_flash_chip_t spi_flash_chip_t; - /** @cond */ typedef struct esp_flash_t esp_flash_t; /** @endcond */ @@ -28,91 +26,6 @@ typedef struct { uint32_t size; ///< Size of the region } esp_flash_region_t; -/** @brief OS-level integration hooks for accessing flash chips inside a running OS - * - * It's in the public header because some instances should be allocated statically in the startup - * code. May be updated according to hardware version and new flash chip feature requirements, - * shouldn't be treated as public API. - * - * For advanced developers, you may replace some of them with your implementations at your own - * risk. -*/ -typedef struct { - /** - * Flags for start function - */ - /** Limit CPU frequency during flash operations (ESP32-C5 only, 240MHz). - */ - #define ESP_FLASH_START_FLAG_LIMIT_CPU_FREQ BIT(0) - /** - * Called before commencing any flash operation. Does not need to be - * recursive (ie is called at most once for each call to 'end'). - */ - esp_err_t (*start)(void *arg, uint32_t flags); - - /** Called after completing any flash operation. */ - esp_err_t (*end)(void *arg); - - /** Called before any erase/write operations to check whether the region is limited by the OS */ - esp_err_t (*region_protected)(void* arg, size_t start_addr, size_t size); - - /** Delay for at least 'us' microseconds. Called in between 'start' and 'end'. */ - esp_err_t (*delay_us)(void *arg, uint32_t us); - - /** Called for get temp buffer when buffer from application cannot be directly read into/write from. */ - void *(*get_temp_buffer)(void* arg, size_t reqest_size, size_t* out_size); - - /** Called for release temp buffer. */ - void (*release_temp_buffer)(void* arg, void *temp_buf); - - #define SPI_FLASH_YIELD_REQ_YIELD BIT(0) - #define SPI_FLASH_YIELD_REQ_SUSPEND BIT(1) - - /** Yield to other tasks. Called during erase operations. - * @return ESP_OK means yield needs to be called (got an event to handle), while ESP_ERR_TIMEOUT means skip yield.*/ - esp_err_t (*check_yield)(void *arg, uint32_t chip_status, uint32_t* out_request); - - #define SPI_FLASH_YIELD_STA_RESUME BIT(2) - - /** Yield to other tasks. Called during erase operations. */ - esp_err_t (*yield)(void *arg, uint32_t* out_status); - - /** Called for get system time. */ - int64_t (*get_system_time)(void *arg); - - #define SPI_FLASH_OS_IS_ERASING_STATUS_FLAG BIT(0) - - /** Call to set flash operation status */ - void (*set_flash_op_status)(uint32_t op_status); - -} esp_flash_os_functions_t; - -/** @brief Structure to describe a SPI flash chip connected to the system. - - Structure must be initialized before use (passed to esp_flash_init()). It's in the public - header because some instances should be allocated statically in the startup code. May be - updated according to hardware version and new flash chip feature requirements, shouldn't be - treated as public API. - - For advanced developers, you may replace some of them with your implementations at your own - risk. -*/ -struct esp_flash_t { - spi_flash_host_inst_t* host; ///< Pointer to hardware-specific "host_driver" structure. Must be initialized before used. - const spi_flash_chip_t *chip_drv; ///< Pointer to chip-model-specific "adapter" structure. If NULL, will be detected during initialisation. - - const esp_flash_os_functions_t *os_func; ///< Pointer to os-specific hook structure. Call ``esp_flash_init_os_functions()`` to setup this field, after the host is properly initialized. - void *os_func_data; ///< Pointer to argument for os-specific hooks. Left NULL and will be initialized with ``os_func``. - - esp_flash_io_mode_t read_mode; ///< Configured SPI flash read mode. Set before ``esp_flash_init`` is called. - uint32_t size; ///< Size of SPI flash in bytes. If 0, size will be detected during initialisation. Note: this stands for the size in the binary image header. If you want to get the flash physical size, please call `esp_flash_get_physical_size`. - uint32_t chip_id; ///< Detected chip id. - uint32_t busy :1; ///< This flag is used to verify chip's status. - uint32_t hpm_dummy_ena :1; ///< This flag is used to verify whether flash works under HPM status. - uint32_t reserved_flags :30; ///< reserved. - int clock_source; ///< Clock source for GPSPI. -}; - /** @brief Initialise SPI flash chip interface. * @@ -384,10 +297,7 @@ extern esp_flash_t *esp_flash_default_chip; * * @return true if flash works in quad mode, otherwise false */ -static inline bool esp_flash_is_quad_mode(const esp_flash_t *chip) -{ - return (chip->read_mode == SPI_FLASH_QIO) || (chip->read_mode == SPI_FLASH_QOUT); -} +bool esp_flash_is_quad_mode(const esp_flash_t *chip); /******************************************************************************* * BDL Functions diff --git a/components/spi_flash/include/esp_flash_chips/README.md b/components/spi_flash/include/esp_flash_chips/README.md new file mode 100644 index 00000000000..1816358e98b --- /dev/null +++ b/components/spi_flash/include/esp_flash_chips/README.md @@ -0,0 +1,50 @@ +# ESP Flash Chips Directory + +## Overview + +This directory contains header files for implementing custom SPI flash chip drivers. These headers are **semi-public** - they are intended for expert users who need to implement custom chip drivers for unsupported flash chips, but they are **not considered stable API** and may change without notice. + +## Intended Use + +These headers are provided for: + +- **Expert users** who need to implement custom chip drivers for flash chips not supported by ESP-IDF +- **Advanced developers** who need to extend or modify existing chip driver behavior +- **Internal ESP-IDF development** for implementing official chip drivers + +## Important Warnings + +⚠️ **These headers are NOT stable API** + +- The structure and content of these headers may change in any ESP-IDF release +- No backward compatibility is guaranteed +- These headers are not part of the public API contract +- Changes may break custom chip driver implementations without notice + +⚠️ **Use at your own risk** + +- Custom chip drivers using these headers may break when upgrading ESP-IDF +- Thorough testing is required after each ESP-IDF version upgrade +- Consider contributing your chip driver to ESP-IDF or [3rd party flash drivers repo](https://github.com/espressif/esp-flash-drivers) instead of maintaining it separately + +## Directory Contents + +- `spi_flash_chip_driver.h` - Core chip driver interface definitions +- `esp_flash_types.h` - Internal flash type definitions +- `spi_flash_chip_*.h` - Header files for specific chip driver implementations that you may reuse (especially the generic driver) +- `spi_flash_override.h` - Flash override configuration structures for those parts outside the scope of esp_flash driver, usually used in the startup code + +## When to Use These Headers + +✅ **Appropriate use cases:** + +- Implementing a driver for a new flash chip model +- Extending functionality of an existing chip driver +- Debugging chip-specific flash issues + +See [example](examples/storage/custom_flash_driver) on how to implement the driver for a custom flash chip. + +❌ **Not appropriate for:** + +- Regular application development (use public APIs in `esp_flash.h` instead) +- Production code that needs stable API guarantees diff --git a/components/spi_flash/include/esp_flash_chips/esp_flash_types.h b/components/spi_flash/include/esp_flash_chips/esp_flash_types.h new file mode 100644 index 00000000000..ab99ded3efe --- /dev/null +++ b/components/spi_flash/include/esp_flash_chips/esp_flash_types.h @@ -0,0 +1,100 @@ +/* + * SPDX-FileCopyrightText: 2015-2026 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include "esp_err.h" +#include +#include +#include "esp_bit_defs.h" +#include "hal/spi_flash_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct spi_flash_chip_t; +typedef struct spi_flash_chip_t spi_flash_chip_t; + +/** @brief OS-level integration hooks for accessing flash chips inside a running OS + * + * This structure is used internally by the SPI flash driver and should not be used directly by applications. + * It's defined here because some instances need to be allocated statically in the startup code. + */ +typedef struct esp_flash_os_functions_t { + /** + * Flags for start function + */ + /** Limit CPU frequency during flash operations (ESP32-C5 only, 240MHz). + */ + #define ESP_FLASH_START_FLAG_LIMIT_CPU_FREQ BIT(0) + /** + * Called before commencing any flash operation. Does not need to be + * recursive (ie is called at most once for each call to 'end'). + */ + esp_err_t (*start)(void *arg, uint32_t flags); + + /** Called after completing any flash operation. */ + esp_err_t (*end)(void *arg); + + /** Called before any erase/write operations to check whether the region is limited by the OS */ + esp_err_t (*region_protected)(void* arg, size_t start_addr, size_t size); + + /** Delay for at least 'us' microseconds. Called in between 'start' and 'end'. */ + esp_err_t (*delay_us)(void *arg, uint32_t us); + + /** Called for get temp buffer when buffer from application cannot be directly read into/write from. */ + void *(*get_temp_buffer)(void* arg, size_t reqest_size, size_t* out_size); + + /** Called for release temp buffer. */ + void (*release_temp_buffer)(void *arg, void *temp_buf); + + #define SPI_FLASH_YIELD_REQ_YIELD BIT(0) + #define SPI_FLASH_YIELD_REQ_SUSPEND BIT(1) + + /** Yield to other tasks. Called during erase operations. + * @return ESP_OK means yield needs to be called (got an event to handle), while ESP_ERR_TIMEOUT means skip yield.*/ + esp_err_t (*check_yield)(void *arg, uint32_t chip_status, uint32_t* out_request); + + #define SPI_FLASH_YIELD_STA_RESUME BIT(2) + + /** Yield to other tasks. Called during erase operations. */ + esp_err_t (*yield)(void *arg, uint32_t* out_status); + + /** Called for get system time. */ + int64_t (*get_system_time)(void *arg); + + #define SPI_FLASH_OS_IS_ERASING_STATUS_FLAG BIT(0) + + /** Call to set flash operation status */ + void (*set_flash_op_status)(uint32_t op_status); + +} esp_flash_os_functions_t; + +/** @brief Structure to describe a SPI flash chip connected to the system. + * + * This structure is used internally by the SPI flash driver and should not be used directly by applications. + * It's defined here because some instances need to be allocated statically in the startup code. + */ +struct esp_flash_t { + spi_flash_host_inst_t* host; ///< Pointer to hardware-specific "host_driver" structure. Must be initialized before used. + const spi_flash_chip_t *chip_drv; ///< Pointer to chip-model-specific "adapter" structure. If NULL, will be detected during initialisation. + + const esp_flash_os_functions_t *os_func; ///< Pointer to os-specific hook structure. Call ``esp_flash_init_os_functions()`` to setup this field, after the host is properly initialized. + void *os_func_data; ///< Pointer to argument for os-specific hooks. Left NULL and will be initialized with ``os_func``. + + esp_flash_io_mode_t read_mode; ///< Configured SPI flash read mode. Set before ``esp_flash_init`` is called. + uint32_t size; ///< Size of SPI flash in bytes. If 0, size will be detected during initialisation. Note: this stands for the size in the binary image header. If you want to get the flash physical size, please call `esp_flash_get_physical_size`. + uint32_t chip_id; ///< Detected chip id. + uint32_t busy :1; ///< This flag is used to verify chip's status. + uint32_t hpm_dummy_ena :1; ///< This flag is used to verify whether flash works under HPM status. + uint32_t reserved_flags :30; ///< reserved. + int clock_source; ///< Clock source for GPSPI. +}; + +#ifdef __cplusplus +} +#endif diff --git a/components/spi_flash/include/spi_flash_chip_boya.h b/components/spi_flash/include/esp_flash_chips/spi_flash_chip_boya.h similarity index 76% rename from components/spi_flash/include/spi_flash_chip_boya.h rename to components/spi_flash/include/esp_flash_chips/spi_flash_chip_boya.h index 02fd05c6b10..3af25f7763d 100644 --- a/components/spi_flash/include/spi_flash_chip_boya.h +++ b/components/spi_flash/include/esp_flash_chips/spi_flash_chip_boya.h @@ -8,11 +8,19 @@ #include #include "esp_flash.h" -#include "spi_flash_chip_driver.h" +#include "esp_flash_chips/spi_flash_chip_driver.h" #include "sdkconfig.h" +#ifdef __cplusplus +extern "C" { +#endif + #ifdef CONFIG_SPI_FLASH_SUPPORT_BOYA_CHIP extern const spi_flash_chip_t esp_flash_chip_boya; #else extern __attribute__((weak)) const spi_flash_chip_t esp_flash_chip_boya; #endif + +#ifdef __cplusplus +} +#endif diff --git a/components/spi_flash/include/spi_flash_chip_driver.h b/components/spi_flash/include/esp_flash_chips/spi_flash_chip_driver.h similarity index 98% rename from components/spi_flash/include/spi_flash_chip_driver.h rename to components/spi_flash/include/esp_flash_chips/spi_flash_chip_driver.h index 5e769aa2e01..46853cfdb5e 100644 --- a/components/spi_flash/include/spi_flash_chip_driver.h +++ b/components/spi_flash/include/esp_flash_chips/spi_flash_chip_driver.h @@ -7,9 +7,11 @@ #pragma once #include "esp_flash.h" #include "esp_attr.h" +#include "esp_flash_chips/esp_flash_types.h" -struct esp_flash_t; -typedef struct esp_flash_t esp_flash_t; +#ifdef __cplusplus +extern "C" { +#endif typedef struct spi_flash_chip_t spi_flash_chip_t; @@ -224,3 +226,7 @@ extern const spi_flash_chip_t **esp_flash_registered_chips; * This ID is used to match the chip against known drivers. */ void spi_flash_chip_list_check(esp_flash_t *chip, uint32_t device_id); + +#ifdef __cplusplus +} +#endif diff --git a/components/spi_flash/include/spi_flash_chip_gd.h b/components/spi_flash/include/esp_flash_chips/spi_flash_chip_gd.h similarity index 90% rename from components/spi_flash/include/spi_flash_chip_gd.h rename to components/spi_flash/include/esp_flash_chips/spi_flash_chip_gd.h index 34b84f841dc..49c276451d9 100644 --- a/components/spi_flash/include/spi_flash_chip_gd.h +++ b/components/spi_flash/include/esp_flash_chips/spi_flash_chip_gd.h @@ -8,9 +8,12 @@ #include #include "esp_flash.h" -#include "spi_flash_chip_driver.h" +#include "esp_flash_chips/spi_flash_chip_driver.h" #include "sdkconfig.h" +#ifdef __cplusplus +extern "C" { +#endif /** * GD (GigaDevice) SPI flash chip_drv, uses all the above functions for its operations. In @@ -31,3 +34,7 @@ extern const spi_flash_chip_t esp_flash_chip_gd; #else extern __attribute__((weak)) const spi_flash_chip_t esp_flash_chip_gd; #endif + +#ifdef __cplusplus +} +#endif diff --git a/components/spi_flash/include/spi_flash_chip_generic.h b/components/spi_flash/include/esp_flash_chips/spi_flash_chip_generic.h similarity index 95% rename from components/spi_flash/include/spi_flash_chip_generic.h rename to components/spi_flash/include/esp_flash_chips/spi_flash_chip_generic.h index 019a6966a40..50cfc07f326 100644 --- a/components/spi_flash/include/spi_flash_chip_generic.h +++ b/components/spi_flash/include/esp_flash_chips/spi_flash_chip_generic.h @@ -1,23 +1,18 @@ -// Copyright 2015-2019 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +/* + * SPDX-FileCopyrightText: 2015-2026 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ #pragma once #include #include "esp_flash.h" -#include "spi_flash_chip_driver.h" +#include "esp_flash_chips/spi_flash_chip_driver.h" +#ifdef __cplusplus +extern "C" { +#endif /* * The 'chip_generic' SPI flash operations are a lowest common subset of SPI @@ -346,7 +341,7 @@ esp_err_t spi_flash_common_write_status_8b_wrsr2(esp_flash_t* chip, uint32_t sr) * Most chip QE enable follows a common pattern, though commands to read/write * the status register may be different, as well as the position of QE bit. * - * Registers to actually do Quad transtions and command to be sent in reading + * Registers to actually do Quad transitions and command to be sent in reading * should also be configured via * spi_flash_chip_generic_config_host_io_mode(). * @@ -409,3 +404,7 @@ esp_err_t spi_flash_chip_generic_read_unique_id_none(esp_flash_t *chip, uint64_t /// Default timeout configuration used by most chips extern const flash_chip_op_timeout_t spi_flash_chip_generic_timeout; + +#ifdef __cplusplus +} +#endif diff --git a/components/spi_flash/include/spi_flash_chip_issi.h b/components/spi_flash/include/esp_flash_chips/spi_flash_chip_issi.h similarity index 87% rename from components/spi_flash/include/spi_flash_chip_issi.h rename to components/spi_flash/include/esp_flash_chips/spi_flash_chip_issi.h index 58a8aac2227..ba1947985e8 100644 --- a/components/spi_flash/include/spi_flash_chip_issi.h +++ b/components/spi_flash/include/esp_flash_chips/spi_flash_chip_issi.h @@ -8,9 +8,12 @@ #include #include "esp_flash.h" -#include "spi_flash_chip_driver.h" +#include "esp_flash_chips/spi_flash_chip_driver.h" #include "sdkconfig.h" +#ifdef __cplusplus +extern "C" { +#endif /** * ISSI SPI flash chip_drv, uses all the above functions for its operations. In @@ -26,3 +29,7 @@ extern const spi_flash_chip_t esp_flash_chip_issi; #else extern __attribute__((weak)) const spi_flash_chip_t esp_flash_chip_issi; #endif + +#ifdef __cplusplus +} +#endif diff --git a/components/spi_flash/include/spi_flash_chip_mxic.h b/components/spi_flash/include/esp_flash_chips/spi_flash_chip_mxic.h similarity index 88% rename from components/spi_flash/include/spi_flash_chip_mxic.h rename to components/spi_flash/include/esp_flash_chips/spi_flash_chip_mxic.h index cf77ad92d85..74e55e6d9d5 100644 --- a/components/spi_flash/include/spi_flash_chip_mxic.h +++ b/components/spi_flash/include/esp_flash_chips/spi_flash_chip_mxic.h @@ -8,9 +8,13 @@ #include #include "esp_flash.h" -#include "spi_flash_chip_driver.h" +#include "esp_flash_chips/spi_flash_chip_driver.h" #include "sdkconfig.h" +#ifdef __cplusplus +extern "C" { +#endif + /** * MXIC SPI flash chip_drv, uses all the above functions for its operations. In * default autodetection, this is used as a catchall if a more specific chip_drv @@ -32,3 +36,7 @@ extern const spi_flash_chip_t esp_flash_chip_mxic_opi; #else extern __attribute__((weak)) const spi_flash_chip_t esp_flash_chip_mxic_opi; #endif + +#ifdef __cplusplus +} +#endif diff --git a/components/spi_flash/include/spi_flash_chip_th.h b/components/spi_flash/include/esp_flash_chips/spi_flash_chip_th.h similarity index 75% rename from components/spi_flash/include/spi_flash_chip_th.h rename to components/spi_flash/include/esp_flash_chips/spi_flash_chip_th.h index bdab41ee56b..e96d0756aa4 100644 --- a/components/spi_flash/include/spi_flash_chip_th.h +++ b/components/spi_flash/include/esp_flash_chips/spi_flash_chip_th.h @@ -8,11 +8,19 @@ #include #include "esp_flash.h" -#include "spi_flash_chip_driver.h" +#include "esp_flash_chips/spi_flash_chip_driver.h" #include "sdkconfig.h" +#ifdef __cplusplus +extern "C" { +#endif + #ifdef CONFIG_SPI_FLASH_SUPPORT_TH_CHIP extern const spi_flash_chip_t esp_flash_chip_th; #else extern __attribute__((weak)) const spi_flash_chip_t esp_flash_chip_th; #endif + +#ifdef __cplusplus +} +#endif diff --git a/components/spi_flash/include/spi_flash_chip_winbond.h b/components/spi_flash/include/esp_flash_chips/spi_flash_chip_winbond.h similarity index 82% rename from components/spi_flash/include/spi_flash_chip_winbond.h rename to components/spi_flash/include/esp_flash_chips/spi_flash_chip_winbond.h index b6b4287c196..d0a41881a2d 100644 --- a/components/spi_flash/include/spi_flash_chip_winbond.h +++ b/components/spi_flash/include/esp_flash_chips/spi_flash_chip_winbond.h @@ -8,9 +8,13 @@ #include #include "esp_flash.h" -#include "spi_flash_chip_driver.h" +#include "esp_flash_chips/spi_flash_chip_driver.h" #include "sdkconfig.h" +#ifdef __cplusplus +extern "C" { +#endif + /** * Winbond SPI flash chip_drv, uses all the above functions for its operations. In * default autodetection, this is used as a catchall if a more specific chip_drv @@ -22,3 +26,7 @@ extern const spi_flash_chip_t esp_flash_chip_winbond; #else extern __attribute__((weak)) const spi_flash_chip_t esp_flash_chip_winbond; #endif + +#ifdef __cplusplus +} +#endif diff --git a/components/spi_flash/include/spi_flash/spi_flash_defs.h b/components/spi_flash/include/esp_flash_chips/spi_flash_defs.h similarity index 100% rename from components/spi_flash/include/spi_flash/spi_flash_defs.h rename to components/spi_flash/include/esp_flash_chips/spi_flash_defs.h diff --git a/components/spi_flash/include/spi_flash_override.h b/components/spi_flash/include/esp_flash_chips/spi_flash_override.h similarity index 100% rename from components/spi_flash/include/spi_flash_override.h rename to components/spi_flash/include/esp_flash_chips/spi_flash_override.h diff --git a/components/spi_flash/include/esp_flash_internal.h b/components/spi_flash/include/esp_private/esp_flash_internal.h similarity index 98% rename from components/spi_flash/include/esp_flash_internal.h rename to components/spi_flash/include/esp_private/esp_flash_internal.h index b3a87206bfb..14e9169a0a7 100644 --- a/components/spi_flash/include/esp_flash_internal.h +++ b/components/spi_flash/include/esp_private/esp_flash_internal.h @@ -12,6 +12,7 @@ #include "sdkconfig.h" #include "esp_flash.h" +#include "esp_flash_chips/esp_flash_types.h" /** Internal API, don't use in the applications */ diff --git a/components/spi_flash/include/memspi_host_driver.h b/components/spi_flash/include/esp_private/memspi_host_driver.h similarity index 99% rename from components/spi_flash/include/memspi_host_driver.h rename to components/spi_flash/include/esp_private/memspi_host_driver.h index 269ea554c38..7fc34554184 100644 --- a/components/spi_flash/include/memspi_host_driver.h +++ b/components/spi_flash/include/esp_private/memspi_host_driver.h @@ -7,6 +7,10 @@ #pragma once #include "hal/spi_flash_hal.h" +#ifdef __cplusplus +extern "C" { +#endif + /** Default configuration for the memspi (high speed version) */ #define ESP_FLASH_DEFAULT_HOST_DRIVER() (spi_flash_host_driver_t) { \ .dev_config = spi_flash_hal_device_config, \ @@ -183,3 +187,7 @@ int memspi_host_read_data_slicer(spi_flash_host_inst_t *host, uint32_t address, * @return Length that can actually be written in one `program_page` call in `spi_flash_host_driver_t`. */ int memspi_host_write_data_slicer(spi_flash_host_inst_t *host, uint32_t address, uint32_t len, uint32_t *align_address, uint32_t page_size); + +#ifdef __cplusplus +} +#endif 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 22954c17830..5dc1669d9c4 100644 --- a/components/spi_flash/include/esp_private/spi_flash_os.h +++ b/components/spi_flash/include/esp_private/spi_flash_os.h @@ -14,12 +14,15 @@ #include "sdkconfig.h" #include "esp_rom_spiflash.h" #include "esp_err.h" -#include "esp_flash.h" -#include "hal/spi_flash_hal.h" -#include "spi_flash_override.h" #include "soc/soc_caps.h" #include "soc/clk_tree_defs.h" +#include "hal/spi_flash_hal.h" + +#include "esp_flash.h" +#include "esp_flash_chips/esp_flash_types.h" +#include "esp_flash_chips/spi_flash_override.h" + #ifdef __cplusplus extern "C" { #endif diff --git a/components/spi_flash/linker.lf b/components/spi_flash/linker.lf index 201a2257cbc..055be7e3512 100644 --- a/components/spi_flash/linker.lf +++ b/components/spi_flash/linker.lf @@ -18,6 +18,7 @@ entries: esp_flash_api: esp_flash_chip_driver_initialized (noflash) esp_flash_api: esp_flash_init (noflash) esp_flash_api: esp_flash_init_main (noflash) + esp_flash_api: esp_flash_is_quad_mode (noflash) esp_flash_api: read_unique_id (noflash) esp_flash_api: detect_spi_flash_chip (noflash) esp_flash_api: esp_flash_get_physical_size (noflash) @@ -46,16 +47,18 @@ entries: esp_flash_api: s_verify_write (noflash) if SPI_FLASH_ROM_IMPL = n || ESP_ROM_HAS_ENCRYPTED_WRITES_USING_LEGACY_DRV = y || SPI_FLASH_FREQ_LIMIT_C5_240MHZ = y: - esp_flash_api: spiflash_start_default (noflash) - esp_flash_api: spiflash_start_core (noflash) esp_flash_api: esp_flash_write_encrypted (noflash) + if SPI_FLASH_ROM_IMPL = n || SPI_FLASH_FREQ_LIMIT_C5_240MHZ = y: + esp_flash_api: spiflash_start_default (noflash) + esp_flash_api: spiflash_start_core (noflash) + if SPI_FLASH_ROM_IMPL = n || ESP_ROM_HAS_ENCRYPTED_WRITES_USING_LEGACY_DRV = y: - esp_flash_api: spiflash_end_default (noflash) - esp_flash_api: check_chip_pointer_default (noflash) esp_flash_api: flash_end_flush_cache (noflash) if SPI_FLASH_ROM_IMPL = n: + esp_flash_api: spiflash_end_default (noflash) + esp_flash_api: check_chip_pointer_default (noflash) esp_flash_api: esp_flash_get_size (noflash) esp_flash_api: esp_flash_erase_chip (noflash) esp_flash_api: esp_flash_get_chip_write_protect (noflash) diff --git a/components/spi_flash/memspi_host_driver.c b/components/spi_flash/memspi_host_driver.c index 8f690ad084b..9f2cae834b5 100644 --- a/components/spi_flash/memspi_host_driver.c +++ b/components/spi_flash/memspi_host_driver.c @@ -6,15 +6,15 @@ #include "sdkconfig.h" #include "soc/soc_caps.h" -#include "spi_flash_defs.h" -#include "memspi_host_driver.h" #include "string.h" #include "esp_log.h" -#include "esp_private/cache_utils.h" -#include "esp_flash_partitions.h" #include "esp_memory_utils.h" #include "hal/mspi_ll.h" +#include "esp_flash_partitions.h" +#include "esp_flash_chips/spi_flash_defs.h" +#include "esp_private/cache_utils.h" +#include "esp_private/memspi_host_driver.h" #define SPI_FLASH_HAL_MAX_WRITE_BYTES 64 #define SPI_FLASH_HAL_MAX_READ_BYTES 64 diff --git a/components/spi_flash/spi_flash_blockdev.c b/components/spi_flash/spi_flash_blockdev.c index 9b9c5e0298f..526ce55dda6 100644 --- a/components/spi_flash/spi_flash_blockdev.c +++ b/components/spi_flash/spi_flash_blockdev.c @@ -6,11 +6,12 @@ #include #include -#include "esp_flash.h" -#include "spi_flash_chip_driver.h" #include "esp_heap_caps.h" #include "esp_blockdev.h" +#include "esp_flash.h" +#include "esp_flash_chips/spi_flash_chip_driver.h" + static inline esp_err_t esp_flash_blockdev_read(esp_blockdev_handle_t handle, uint8_t* dst_buf, size_t dst_buf_size, uint64_t src_addr, size_t data_read_len) { if (handle == NULL || dst_buf_size < data_read_len) { diff --git a/components/spi_flash/spi_flash_chip_boya.c b/components/spi_flash/spi_flash_chip_boya.c index c2d3bd2ac5e..18c130ecece 100644 --- a/components/spi_flash/spi_flash_chip_boya.c +++ b/components/spi_flash/spi_flash_chip_boya.c @@ -1,21 +1,13 @@ -// Copyright 2015-2021 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +/* + * SPDX-FileCopyrightText: 2015-2026 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ #include -#include "spi_flash_chip_generic.h" -#include "spi_flash_chip_gd.h" -#include "spi_flash_defs.h" +#include "esp_flash_chips/spi_flash_defs.h" +#include "esp_flash_chips/spi_flash_chip_generic.h" +#include "esp_flash_chips/spi_flash_chip_gd.h" esp_err_t spi_flash_chip_boya_probe(esp_flash_t *chip, uint32_t flash_id) { diff --git a/components/spi_flash/spi_flash_chip_drivers.c b/components/spi_flash/spi_flash_chip_drivers.c index d866d72954d..24f81b1d04a 100644 --- a/components/spi_flash/spi_flash_chip_drivers.c +++ b/components/spi_flash/spi_flash_chip_drivers.c @@ -5,18 +5,19 @@ */ #include -#include "spi_flash_chip_driver.h" -#include "spi_flash_chip_generic.h" -#include "spi_flash_chip_issi.h" -#include "spi_flash_chip_mxic.h" -#include "spi_flash_chip_gd.h" -#include "spi_flash_chip_winbond.h" -#include "spi_flash_chip_boya.h" -#include "spi_flash_chip_th.h" -#include "spi_flash_defs.h" #include "sdkconfig.h" #include "esp_log.h" +#include "esp_flash_chips/spi_flash_defs.h" +#include "esp_flash_chips/spi_flash_chip_driver.h" +#include "esp_flash_chips/spi_flash_chip_generic.h" +#include "esp_flash_chips/spi_flash_chip_issi.h" +#include "esp_flash_chips/spi_flash_chip_mxic.h" +#include "esp_flash_chips/spi_flash_chip_gd.h" +#include "esp_flash_chips/spi_flash_chip_winbond.h" +#include "esp_flash_chips/spi_flash_chip_boya.h" +#include "esp_flash_chips/spi_flash_chip_th.h" + ESP_LOG_ATTR_TAG(TAG, "spi_flash"); #define FORMAT_STR "Detected %s flash chip but using generic driver. For optimal functionality, enable `SPI_FLASH_SUPPORT_%s_CHIP` in menuconfig" diff --git a/components/spi_flash/spi_flash_chip_gd.c b/components/spi_flash/spi_flash_chip_gd.c index 46ac61ab32b..4948a192b22 100644 --- a/components/spi_flash/spi_flash_chip_gd.c +++ b/components/spi_flash/spi_flash_chip_gd.c @@ -8,11 +8,12 @@ #include #include // For MIN/MAX #include "esp_log.h" -#include "spi_flash_chip_generic.h" -#include "spi_flash_chip_gd.h" -#include "spi_flash_defs.h" #include "sdkconfig.h" +#include "esp_flash_chips/spi_flash_defs.h" +#include "esp_flash_chips/spi_flash_chip_generic.h" +#include "esp_flash_chips/spi_flash_chip_gd.h" + #define ADDR_32BIT(addr) (addr >= (1<<24)) #define REGION_32BIT(start, len) ((start) + (len) > (1<<24)) diff --git a/components/spi_flash/spi_flash_chip_generic.c b/components/spi_flash/spi_flash_chip_generic.c index 019644a8ab2..78caec83b94 100644 --- a/components/spi_flash/spi_flash_chip_generic.c +++ b/components/spi_flash/spi_flash_chip_generic.c @@ -7,14 +7,15 @@ #include #include #include // For MIN/MAX -#include "spi_flash_chip_generic.h" -#include "spi_flash_defs.h" -#include "hal/spi_flash_encrypt_hal.h" #include "esp_log.h" #include "esp_attr.h" -#include "esp_private/spi_flash_os.h" #include "esp_rom_caps.h" +#include "hal/spi_flash_encrypt_hal.h" +#include "esp_flash_chips/spi_flash_defs.h" +#include "esp_flash_chips/spi_flash_chip_generic.h" +#include "esp_private/spi_flash_os.h" + #define IS_REGION_32BIT(start, len) ((start) + (len) > (1<<24)) #define IS_ADDR_32BIT(addr) (addr >= (1<<24)) diff --git a/components/spi_flash/spi_flash_chip_issi.c b/components/spi_flash/spi_flash_chip_issi.c index 56f29743b6a..20b84e71f5b 100644 --- a/components/spi_flash/spi_flash_chip_issi.c +++ b/components/spi_flash/spi_flash_chip_issi.c @@ -1,21 +1,13 @@ -// Copyright 2015-2019 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +/* + * SPDX-FileCopyrightText: 2015-2026 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ #include -#include "spi_flash_chip_generic.h" -#include "spi_flash_chip_issi.h" -#include "spi_flash_defs.h" +#include "esp_flash_chips/spi_flash_defs.h" +#include "esp_flash_chips/spi_flash_chip_generic.h" +#include "esp_flash_chips/spi_flash_chip_issi.h" /* Driver for ISSI flash chip, as used in ESP32 D2WD */ diff --git a/components/spi_flash/spi_flash_chip_mxic.c b/components/spi_flash/spi_flash_chip_mxic.c index 3d31469d25c..cd49f8052e6 100644 --- a/components/spi_flash/spi_flash_chip_mxic.c +++ b/components/spi_flash/spi_flash_chip_mxic.c @@ -5,10 +5,11 @@ */ #include -#include "spi_flash_chip_generic.h" -#include "spi_flash_defs.h" #include "esp_log.h" + #include "hal/spi_flash_hal.h" +#include "esp_flash_chips/spi_flash_defs.h" +#include "esp_flash_chips/spi_flash_chip_generic.h" /* Driver for MXIC flash chip */ diff --git a/components/spi_flash/spi_flash_chip_mxic_opi.c b/components/spi_flash/spi_flash_chip_mxic_opi.c index 417b67799c1..e5fb38757f3 100644 --- a/components/spi_flash/spi_flash_chip_mxic_opi.c +++ b/components/spi_flash/spi_flash_chip_mxic_opi.c @@ -5,12 +5,13 @@ */ #include -#include "spi_flash_chip_generic.h" -#include "spi_flash_defs.h" #include "esp_log.h" #include "string.h" #include // For MIN/MAX + #include "hal/spi_flash_hal.h" +#include "esp_flash_chips/spi_flash_defs.h" +#include "esp_flash_chips/spi_flash_chip_generic.h" #define CMD_OPI_FLASH_MXIC(cmd) ((((~(cmd) & 0xff) << 8)) | ((cmd) & 0xff)) #define CMD_OPI_FLASH_MXIC_CHIP_ERASE 0x9F60 diff --git a/components/spi_flash/spi_flash_chip_th.c b/components/spi_flash/spi_flash_chip_th.c index cc8001b7721..80342fe76db 100644 --- a/components/spi_flash/spi_flash_chip_th.c +++ b/components/spi_flash/spi_flash_chip_th.c @@ -5,8 +5,8 @@ */ #include -#include "spi_flash_chip_generic.h" -#include "spi_flash_defs.h" +#include "esp_flash_chips/spi_flash_defs.h" +#include "esp_flash_chips/spi_flash_chip_generic.h" esp_err_t spi_flash_chip_th_probe(esp_flash_t *chip, uint32_t flash_id) { diff --git a/components/spi_flash/spi_flash_chip_winbond.c b/components/spi_flash/spi_flash_chip_winbond.c index 1f2516537b5..3f826e5656d 100644 --- a/components/spi_flash/spi_flash_chip_winbond.c +++ b/components/spi_flash/spi_flash_chip_winbond.c @@ -8,8 +8,9 @@ #include #include // For MIN/MAX #include "esp_log.h" -#include "spi_flash_chip_generic.h" -#include "spi_flash_defs.h" + +#include "esp_flash_chips/spi_flash_defs.h" +#include "esp_flash_chips/spi_flash_chip_generic.h" #define REGION_32BIT(start, len) ((start) + (len) > (1<<24)) diff --git a/components/spi_flash/spi_flash_hpm_enable.c b/components/spi_flash/spi_flash_hpm_enable.c index 7013840b76a..880f4cf3fc6 100644 --- a/components/spi_flash/spi_flash_hpm_enable.c +++ b/components/spi_flash/spi_flash_hpm_enable.c @@ -8,10 +8,11 @@ #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_flash_chips/spi_flash_defs.h" +#include "esp_flash_chips/spi_flash_override.h" // TODO: These dependencies will be removed after remove bootloader_flash to G0.IDF-4609 #include "bootloader_flash_override.h" diff --git a/components/spi_flash/spi_flash_os_func_app.c b/components/spi_flash/spi_flash_os_func_app.c index 073b102df01..8e6f28e1d35 100644 --- a/components/spi_flash/spi_flash_os_func_app.c +++ b/components/spi_flash/spi_flash_os_func_app.c @@ -9,8 +9,6 @@ #include //For max/min #include "esp_attr.h" #include "esp_private/system_internal.h" -#include "esp_flash.h" -#include "esp_flash_partitions.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "hal/spi_types.h" @@ -18,6 +16,11 @@ #include "esp_log.h" #include "esp_compiler.h" #include "esp_rom_sys.h" + +#include "esp_flash.h" +#include "esp_flash_chips/esp_flash_types.h" +#include "esp_flash_partitions.h" + #include "esp_private/spi_flash_os.h" #include "esp_private/cache_utils.h" #include "esp_private/spi_share_hw_ctrl.h" diff --git a/components/spi_flash/spi_flash_os_func_noos.c b/components/spi_flash/spi_flash_os_func_noos.c index 0ba7c006c5f..9e0096b35c4 100644 --- a/components/spi_flash/spi_flash_os_func_noos.c +++ b/components/spi_flash/spi_flash_os_func_noos.c @@ -6,14 +6,16 @@ #include #include "sdkconfig.h" -#include "esp_flash.h" #include "esp_attr.h" #include "esp_rom_sys.h" #include "esp_cpu.h" #include "rom/cache.h" +#include "soc/soc_caps.h" #include "hal/cache_hal.h" #include "hal/cache_ll.h" -#include "soc/soc_caps.h" + +#include "esp_flash.h" +#include "esp_flash_chips/esp_flash_types.h" static IRAM_ATTR esp_err_t start(void *arg, uint32_t flags) { diff --git a/components/spi_flash/spi_flash_wrap.c b/components/spi_flash/spi_flash_wrap.c index e43f8d31b7a..edf32e609f5 100644 --- a/components/spi_flash/spi_flash_wrap.c +++ b/components/spi_flash/spi_flash_wrap.c @@ -9,11 +9,12 @@ #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 "rom/spi_flash.h" -#include "spi_flash_override.h" + +#include "esp_flash_chips/spi_flash_defs.h" +#include "esp_flash_chips/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 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 ea1eace63c1..d32ee9649b7 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 @@ -14,7 +14,7 @@ #include "esp_flash.h" #include "esp_private/spi_common_internal.h" #include "esp_flash_spi_init.h" -#include "memspi_host_driver.h" +#include "esp_private/memspi_host_driver.h" #include #include "esp_log.h" #include "test_utils.h" diff --git a/components/spi_flash/test_apps/esp_flash_blockdev/main/test_spi_flash.c b/components/spi_flash/test_apps/esp_flash_blockdev/main/test_spi_flash.c index 3bb408426ff..96ce3589730 100644 --- a/components/spi_flash/test_apps/esp_flash_blockdev/main/test_spi_flash.c +++ b/components/spi_flash/test_apps/esp_flash_blockdev/main/test_spi_flash.c @@ -9,7 +9,7 @@ #include "esp_log.h" #include "unity.h" -#include "spi_flash_chip_driver.h" +#include "esp_flash_chips/spi_flash_chip_driver.h" #include "test_flash_utils.h" TEST_CASE("spi_flash BDL test", "[esp_flash]") diff --git a/components/spi_flash/test_apps/esp_flash_freq_limit/CMakeLists.txt b/components/spi_flash/test_apps/esp_flash_freq_limit/CMakeLists.txt index b888fea1ba9..614e10ca1cd 100644 --- a/components/spi_flash/test_apps/esp_flash_freq_limit/CMakeLists.txt +++ b/components/spi_flash/test_apps/esp_flash_freq_limit/CMakeLists.txt @@ -1,8 +1,6 @@ # This is the project CMakeLists.txt file for the test subproject cmake_minimum_required(VERSION 3.22) -set(EXTRA_COMPONENT_DIRS "$ENV{IDF_PATH}/tools/test_apps/components") - # "Trim" the build. Include the minimal set of components, main, and anything it depends on. We also depend on # esptool_py as we set CONFIG_ESPTOOLPY_... options. set(COMPONENTS main esptool_py) diff --git a/components/spi_flash/test_apps/esp_flash_freq_limit/main/idf_component.yml b/components/spi_flash/test_apps/esp_flash_freq_limit/main/idf_component.yml new file mode 100644 index 00000000000..d5f58e5fa9a --- /dev/null +++ b/components/spi_flash/test_apps/esp_flash_freq_limit/main/idf_component.yml @@ -0,0 +1,3 @@ +dependencies: + test_utils: + path: ${IDF_PATH}/tools/test_apps/components/test_utils diff --git a/components/spi_flash/test_apps/esp_flash_freq_limit/main/test_esp_flash_freq_limit.c b/components/spi_flash/test_apps/esp_flash_freq_limit/main/test_esp_flash_freq_limit.c index c76fa625082..47c4790368c 100644 --- a/components/spi_flash/test_apps/esp_flash_freq_limit/main/test_esp_flash_freq_limit.c +++ b/components/spi_flash/test_apps/esp_flash_freq_limit/main/test_esp_flash_freq_limit.c @@ -14,6 +14,7 @@ #include #include "unity.h" #include "esp_flash.h" +#include "esp_flash_chips/esp_flash_types.h" #include "soc/rtc.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" diff --git a/docs/en/api-reference/peripherals/spi_flash/index.rst b/docs/en/api-reference/peripherals/spi_flash/index.rst index 72dab9451bf..2badb657b1c 100644 --- a/docs/en/api-reference/peripherals/spi_flash/index.rst +++ b/docs/en/api-reference/peripherals/spi_flash/index.rst @@ -175,6 +175,10 @@ Note that since memory mapping happens in pages, it may be possible to read data SPI Flash Implementation ------------------------ +.. note:: + + The header files in ``components/spi_flash/include/esp_flash_chips/`` directory are **semi-public** - they are intended for expert users who need to implement custom chip drivers for unsupported flash chips, but they are **not considered stable API** and may change without notice. For most use cases, you should use the public APIs in ``esp_flash.h`` instead. + The ``esp_flash_t`` structure holds chip data as well as three important parts of this API: 1. The host driver, which provides the hardware support to access the chip; @@ -193,7 +197,7 @@ You can also implement your own host driver, even with the GPIO. As long as all Chip Driver ^^^^^^^^^^^ -The chip driver, defined in ``spi_flash_chip_driver.h``, wraps basic functions provided by the host driver for the API layer to use. +The chip driver, defined in ``esp_flash_chips/spi_flash_chip_driver.h``, wraps basic functions provided by the host driver for the API layer to use. Some operations need some commands to be sent first, or read some status afterwards. Some chips need different commands or values, or need special communication ways. diff --git a/docs/en/api-reference/peripherals/spi_flash/spi_flash_override_driver.rst b/docs/en/api-reference/peripherals/spi_flash/spi_flash_override_driver.rst index cf8e2d6dfd9..390ae0c7cdd 100644 --- a/docs/en/api-reference/peripherals/spi_flash/spi_flash_override_driver.rst +++ b/docs/en/api-reference/peripherals/spi_flash/spi_flash_override_driver.rst @@ -149,7 +149,12 @@ Generic Flash Driver The flash driver in the application is used to read, write, erase, and save data. It also supports some advanced features like OTA. Below is a guide on how to customize the driver for your specific flash model. - Step 1: The last item of `default_registered_chips` should be the `generic chip driver `_. If your flash chip does not match any of the chip drivers listed above, it will use the generic driver. Check for any differences in behavior between your flash and the generic driver, including but not limited to different commands, dummy cycles, data bytes, and status registers. -- Step 2: If you have found something different from the generic driver, you need to implement your own chip driver. Create a new file named ``spi_flash_chip_.c`` to implement the specific behavior, and copy the ``esp_flash_chip_generic`` structure into it as a starting point. Remember to include ``spi_flash_chip_generic.h``. Here is an example `esp_flash_nor `_. +- Step 2: If you have found something different from the generic driver, you need to implement your own chip driver. Create a new file named ``spi_flash_chip_.c`` to implement the specific behavior, and copy the ``esp_flash_chip_generic`` structure into it as a starting point. Remember to include ``esp_flash_chips/spi_flash_chip_generic.h``. Here is an example `esp_flash_nor `_. + + .. note:: + + The chip driver header files are located in the ``esp_flash_chips/`` directory (e.g., ``components/spi_flash/include/esp_flash_chips/``). These headers are **semi-public** - they are intended for expert users who need to implement custom chip drivers, but they are **not considered stable API** and may change without notice. + - Step 3: Implement the functions with difference and point to them from the ``spi_flash_chip_t``. Note: if some behavior of your flash is the same as the generic one, retain the generic driver functions without customization. Only implement the parts that differ. Here is an example: .. important:: diff --git a/docs/en/migration-guides/release-6.x/6.0/peripherals.rst b/docs/en/migration-guides/release-6.x/6.0/peripherals.rst index d7ce411ca51..87efad70b07 100644 --- a/docs/en/migration-guides/release-6.x/6.0/peripherals.rst +++ b/docs/en/migration-guides/release-6.x/6.0/peripherals.rst @@ -374,9 +374,28 @@ SPI Flash Driver - New argument ``flags`` is added to ``esp_flash_os_functions_t::start``. Caller and implementer should handle this argument properly. - Kconfig option ``CONFIG_SPI_FLASH_ROM_DRIVER_PATCH`` has been removed. Considering that this option is unlikely to be widely used by users and may cause serious issues if misused, it has been decided to remove it. -.. note:: +Header File Reorganization +~~~~~~~~~~~~~~~~~~~~~~~~~~~ - Note that enabling :ref:`CONFIG_FREERTOS_IN_IRAM` will increase IRAM usage. Consider this trade-off when optimizing for SPI performance. +Several internal header files have been reorganized to better reflect their visibility and intended usage: + +- **Flash chip driver related headers** have been moved to ``esp_flash_chips/`` directory: + - ``spi_flash_chip_driver.h`` + - ``spi_flash_chip_*.h`` + - ``spi_flash_defs.h`` + - ``spi_flash_override.h`` + - ``esp_flash_types.h`` + - The ``esp_flash_t`` structure definition has been moved from ``esp_flash.h`` to ``esp_flash_chips/esp_flash_types.h``. Applications should not access structure members directly; use the public APIs instead (e.g., use :cpp:func:`esp_flash_get_size` instead of accessing ``chip->size`` directly). + - The ``esp_flash_os_functions_t`` structure definition has been moved from ``esp_flash.h`` to ``esp_flash_chips/esp_flash_types.h``. + - The ``spi_flash_chip_t`` type forward declaration has been removed from ``esp_flash.h`` and all ROM headers (``components/esp_rom/esp32xx/include/esp32xx/rom/esp_flash.h``). The type is now only defined in ``esp_flash_chips/esp_flash_types.h``. Applications should not use this type directly; it is only intended for custom chip driver implementations. + + .. note:: + + The headers in ``esp_flash_chips/`` are **semi-public** - they are intended for expert users who need to implement custom chip drivers for unsupported flash chips, but they are **not considered stable API** and may change without notice. For most use cases, you should use the public APIs in ``esp_flash.h`` instead. See :doc:`Override Driver for SPI Flash <../../../api-reference/peripherals/spi_flash/spi_flash_override_driver>` for more details. + +- **Internal headers** have been moved to ``esp_private/`` directory and not included in the public (stable) header files: + - ``esp_flash_internal.h`` + - ``memspi_host_driver.h`` Touch Element ------------- diff --git a/docs/zh_CN/api-reference/peripherals/spi_flash/index.rst b/docs/zh_CN/api-reference/peripherals/spi_flash/index.rst index 5a0017103ac..b69e06e1065 100644 --- a/docs/zh_CN/api-reference/peripherals/spi_flash/index.rst +++ b/docs/zh_CN/api-reference/peripherals/spi_flash/index.rst @@ -175,6 +175,10 @@ flash 在 {IDF_TARGET_CACHE_SIZE} 页进行映射。内存映射硬件既可将 SPI flash 实现 -------------- +.. note:: + + 实现部分的头文件(例如 ``esp_flash_chips/``、``esp_private/``)是**内部**的 - 它们面向需要为不支持的 flash 芯片实现自定义芯片驱动的专家用户,但**不被视为稳定 API**,可能会在不通知的情况下更改。对于大多数用例,您应该使用 ``esp_flash.h`` 中的公共 API。 + ``esp_flash_t`` 结构体包含芯片数据和该 API 的三个重要部分: 1. 主机驱动,为访问芯片提供硬件支持; @@ -193,7 +197,7 @@ SPI flash 实现 芯片驱动 ^^^^^^^^^^^ -芯片驱动在 ``spi_flash_chip_driver.h`` 中进行定义,并将主机驱动提供的基本函数进行封装以供 API 层使用。 +芯片驱动在 ``esp_flash_chips/spi_flash_chip_driver.h`` 中进行定义,并将主机驱动提供的基本函数进行封装以供 API 层使用。 有些操作需在执行前先发送命令,或在执行后读取状态,因此有些芯片需要不同的命令或值以及通信方式。 diff --git a/docs/zh_CN/api-reference/peripherals/spi_flash/spi_flash_override_driver.rst b/docs/zh_CN/api-reference/peripherals/spi_flash/spi_flash_override_driver.rst index 073d039746a..38111d7e4a1 100644 --- a/docs/zh_CN/api-reference/peripherals/spi_flash/spi_flash_override_driver.rst +++ b/docs/zh_CN/api-reference/peripherals/spi_flash/spi_flash_override_driver.rst @@ -149,7 +149,12 @@ 应用程序中的 flash 驱动程序用于读取、写入、擦除、保存数据等操作,且支持 OTA 等高级功能。可参考下列指南,为你的 flash 芯片自定义驱动程序。 - 步骤 1:`default_registered_chips` 的最后一项应为 `通用芯片驱动程序 `_。如果你的 flash 芯片无法匹配以上列出的任何一个芯片驱动程序,则将使用通用驱动。请检查你的 flash 芯片行为与通用驱动是否存在差异,包括但不限于不同的命令、dummy 周期、数据字节以及状态寄存器。 -- 步骤 2:如果你的 flash 芯片行为与通用驱动存在差异,则需要实现自定义的芯片驱动程序。请创建一个名为 ``spi_flash_chip_.c`` 的新文件,在其中实现特定行为。可以将 ``esp_flash_chip_generic`` 结构体复制到文件中进行修改。记得在文件中包含 ``spi_flash_chip_generic.h``。详情请参阅示例 `esp_flash_nor `_。 +- 步骤 2:如果你的 flash 芯片行为与通用驱动存在差异,则需要实现自定义的芯片驱动程序。请创建一个名为 ``spi_flash_chip_.c`` 的新文件,在其中实现特定行为。可以将 ``esp_flash_chip_generic`` 结构体复制到文件中进行修改。记得在文件中包含 ``esp_flash_chips/spi_flash_chip_generic.h``。详情请参阅示例 `esp_flash_nor `_。 + + .. note:: + + 芯片驱动程序头文件位于 ``esp_flash_chips/`` 目录中(例如 ``components/spi_flash/include/esp_flash_chips/``)。这些头文件是**半公开的** - 它们面向需要实现自定义芯片驱动程序的高级用户,但**不被视为稳定的 API**,可能会在未通知的情况下更改。 + - 步骤 3:实现与通用驱动程序存在差异的函数,并从 ``spi_flash_chip_t`` 结构体中指向这些函数。注意:如果 flash 芯片的某些行为与通用驱动相同,那么可以保留通用驱动程序的函数,无需自定义,只要为与通用驱动不同的部分编写自定义函数即可。请参考以下示例: .. important:: diff --git a/docs/zh_CN/migration-guides/release-6.x/6.0/peripherals.rst b/docs/zh_CN/migration-guides/release-6.x/6.0/peripherals.rst index 0952332d1a8..5cc32524f16 100644 --- a/docs/zh_CN/migration-guides/release-6.x/6.0/peripherals.rst +++ b/docs/zh_CN/migration-guides/release-6.x/6.0/peripherals.rst @@ -374,9 +374,28 @@ SPI flash 驱动 - ``esp_flash_os_functions_t::start`` 新增了一个参数 ``flags``。调用者和实现者应正确处理此参数。 - Kconfig 选项 ``CONFIG_SPI_FLASH_ROM_DRIVER_PATCH`` 已被移除,考虑到这个选项不会被广泛被用户使用,且有因误用而导致出现严重的问题,遂决定移除。 -.. note:: +头文件重组 +~~~~~~~~~~ - 启用 :ref:`CONFIG_FREERTOS_IN_IRAM` 会显著增加 IRAM 使用量。在优化 SPI 性能时,需进行权衡。 +为了更好地反映其可见性和预期用途,多个内部头文件已重新组织: + +- **Flash 芯片驱动相关头文件** 已移至 ``esp_flash_chips/`` 目录: + - ``spi_flash_chip_driver.h`` + - ``spi_flash_chip_*.h`` + - ``spi_flash_defs.h`` + - ``spi_flash_override.h`` + - ``esp_flash_types.h`` + - ``esp_flash_t`` 结构体定义已从 ``esp_flash.h`` 移至 ``esp_flash_chips/esp_flash_types.h``。应用程序不应直接访问结构体成员;请改用公开 API(例如,使用 :cpp:func:`esp_flash_get_size` 而不是直接访问 ``chip->size``)。 + - ``esp_flash_os_functions_t`` 结构体定义已从 ``esp_flash.h`` 移至 ``esp_flash_chips/esp_flash_types.h``。 + - ``spi_flash_chip_t`` 类型的前向声明已从 ``esp_flash.h`` 和所有 ROM 头文件(``components/esp_rom/esp32xx/include/esp32xx/rom/esp_flash.h``)中移除。该类型现在仅在 ``esp_flash_chips/esp_flash_types.h`` 中定义。应用程序不应直接使用此类型;它仅用于自定义芯片驱动实现。 + + .. note:: + + ``esp_flash_chips/`` 中的头文件是**半公开的** - 它们面向需要为不支持的 flash 芯片实现自定义芯片驱动的专家用户,但**不被视为稳定 API**,可能会在不通知的情况下更改。对于大多数用例,您应该改用 ``esp_flash.h`` 中的公开 API。更多详情请参阅 :doc:`SPI Flash 驱动覆盖 <../../../api-reference/peripherals/spi_flash/spi_flash_override_driver>`。 + +- **内部头文件** 已移至 ``esp_private/`` 目录,且不包含在公共(稳定)头文件中: + - ``esp_flash_internal.h`` + - ``memspi_host_driver.h`` Touch Element ------------- diff --git a/examples/storage/.build-test-rules.yml b/examples/storage/.build-test-rules.yml index b758826c23d..c6779e2bbf8 100644 --- a/examples/storage/.build-test-rules.yml +++ b/examples/storage/.build-test-rules.yml @@ -3,6 +3,10 @@ examples/storage/custom_flash_driver: depends_components: - spi_flash + disable: + - if: 1 == 1 + temporary: true + reason: breaking change needs external component to fix first (IDF-15134) examples/storage/emmc: depends_components: diff --git a/examples/storage/custom_flash_driver/components/custom_chip_driver/chip_drivers.c b/examples/storage/custom_flash_driver/components/custom_chip_driver/chip_drivers.c index 7ad469573bc..b4a4b58d7f4 100644 --- a/examples/storage/custom_flash_driver/components/custom_chip_driver/chip_drivers.c +++ b/examples/storage/custom_flash_driver/components/custom_chip_driver/chip_drivers.c @@ -12,13 +12,13 @@ CONDITIONS OF ANY KIND, either express or implied. */ -#include "spi_flash_chip_driver.h" -#include "spi_flash_chip_generic.h" -#include "spi_flash_chip_issi.h" -#include "spi_flash_chip_mxic.h" -#include "spi_flash_chip_gd.h" -#include "spi_flash_chip_winbond.h" -#include "spi_flash_chip_boya.h" +#include "esp_flash_chips/spi_flash_chip_driver.h" +#include "esp_flash_chips/spi_flash_chip_generic.h" +#include "esp_flash_chips/spi_flash_chip_issi.h" +#include "esp_flash_chips/spi_flash_chip_mxic.h" +#include "esp_flash_chips/spi_flash_chip_gd.h" +#include "esp_flash_chips/spi_flash_chip_winbond.h" +#include "esp_flash_chips/spi_flash_chip_boya.h" // `spi_flash_chip_custom.h` is the header for the structure of customize flash driver, // in this example is `esp_flash_chip_eon`. #include "spi_flash_chip_custom.h" diff --git a/examples/storage/fatfs/ext_flash/main/fatfs_ext_flash_example_main.c b/examples/storage/fatfs/ext_flash/main/fatfs_ext_flash_example_main.c index 4e10057d10f..77e6c708e5c 100644 --- a/examples/storage/fatfs/ext_flash/main/fatfs_ext_flash_example_main.c +++ b/examples/storage/fatfs/ext_flash/main/fatfs_ext_flash_example_main.c @@ -161,22 +161,26 @@ static esp_flash_t* example_init_ext_flash(void) // Print out the ID and size uint32_t id; + uint32_t size; ESP_ERROR_CHECK(esp_flash_read_id(ext_flash, &id)); - ESP_LOGI(TAG, "Initialized external Flash, size=%" PRIu32 " KB, ID=0x%" PRIx32, ext_flash->size / 1024, id); + ESP_ERROR_CHECK(esp_flash_get_size(ext_flash, &size)); + ESP_LOGI(TAG, "Initialized external Flash, size=%" PRIu32 " KB, ID=0x%" PRIx32, size / 1024, id); return ext_flash; } static const esp_partition_t* example_add_partition(esp_flash_t* ext_flash, const char* partition_label) { - ESP_LOGI(TAG, "Adding external Flash as a partition, label=\"%s\", size=%" PRIu32 " KB", partition_label, ext_flash->size / 1024); + uint32_t size; + ESP_ERROR_CHECK(esp_flash_get_size(ext_flash, &size)); + ESP_LOGI(TAG, "Adding external Flash as a partition, label=\"%s\", size=%" PRIu32 " KB", partition_label, size / 1024); const esp_partition_t* fat_partition; const size_t offset = 0; - ESP_ERROR_CHECK(esp_partition_register_external(ext_flash, offset, ext_flash->size, partition_label, ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_DATA_FAT, &fat_partition)); + ESP_ERROR_CHECK(esp_partition_register_external(ext_flash, offset, size, partition_label, ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_DATA_FAT, &fat_partition)); // Erase space of partition on the external flash chip - ESP_LOGI(TAG, "Erasing partition range, offset=%u size=%" PRIu32 " KB", offset, ext_flash->size / 1024); - ESP_ERROR_CHECK(esp_partition_erase_range(fat_partition, offset, ext_flash->size)); + ESP_LOGI(TAG, "Erasing partition range, offset=%u size=%" PRIu32 " KB", offset, size / 1024); + ESP_ERROR_CHECK(esp_partition_erase_range(fat_partition, offset, size)); return fat_partition; } diff --git a/examples/system/ota/partitions_ota/main/partition_utils.c b/examples/system/ota/partitions_ota/main/partition_utils.c index c6dbfe18c94..731684067c6 100644 --- a/examples/system/ota/partitions_ota/main/partition_utils.c +++ b/examples/system/ota/partitions_ota/main/partition_utils.c @@ -10,7 +10,6 @@ #include #include #include "esp_flash_partitions.h" -#include "esp_flash_internal.h" #include "esp_image_format.h" #include "esp_flash.h" #include "esp_partition.h" @@ -103,7 +102,13 @@ esp_err_t partition_utils_find_unallocated(esp_flash_t *flash_chip, size_t requi // Check for unallocated space after the last partition last_end_address = MAX(last_end_address, start_offset); - size_t unallocated_size = flash_chip->size - last_end_address; + uint32_t flash_size = 0; + esp_err_t ret = esp_flash_get_size(flash_chip, &flash_size); + if (ret != ESP_OK) { + free(sorted_partitions); + return ret; + } + size_t unallocated_size = flash_size - last_end_address; if (unallocated_size >= required_size) { *found_offset = last_end_address; if (found_size != NULL) { diff --git a/tools/ci/check_copyright_ignore.txt b/tools/ci/check_copyright_ignore.txt index b532452594a..b4e556183ac 100644 --- a/tools/ci/check_copyright_ignore.txt +++ b/tools/ci/check_copyright_ignore.txt @@ -492,9 +492,6 @@ components/soc/esp32s2/include/soc/fe_reg.h components/soc/esp32s2/include/soc/memprot_defs.h components/soc/esp32s2/include/soc/nrx_reg.h components/soc/esp32s2/include/soc/soc_ulp.h -components/spi_flash/include/spi_flash_chip_generic.h -components/spi_flash/spi_flash_chip_boya.c -components/spi_flash/spi_flash_chip_issi.c components/tcp_transport/include/esp_transport_ws.h components/wpa_supplicant/esp_supplicant/src/esp_wpa_err.h components/wpa_supplicant/include/utils/wpa_debug.h diff --git a/tools/ci/check_public_headers_exceptions.txt b/tools/ci/check_public_headers_exceptions.txt index 2d510902fd1..1648d78309e 100644 --- a/tools/ci/check_public_headers_exceptions.txt +++ b/tools/ci/check_public_headers_exceptions.txt @@ -26,15 +26,6 @@ components/lwip/lwip/src/include/netif/ppp/ components/lwip/lwip/src/include/lwip/apps/tftp_server.h components/lwip/lwip/src/include/lwip/apps/tftp_client.h -components/spi_flash/include/spi_flash_chip_issi.h -components/spi_flash/include/spi_flash_chip_mxic.h -components/spi_flash/include/spi_flash_chip_gd.h -components/spi_flash/include/spi_flash_chip_winbond.h -components/spi_flash/include/spi_flash_chip_boya.h -components/spi_flash/include/spi_flash_chip_th.h -components/spi_flash/include/memspi_host_driver.h -components/spi_flash/include/spi_flash_chip_driver.h -components/spi_flash/include/spi_flash_chip_generic.h components/wpa_supplicant/include/ diff --git a/tools/test_apps/system/g1_components/check_dependencies.py b/tools/test_apps/system/g1_components/check_dependencies.py index abb6ff6d230..482af9cd048 100644 --- a/tools/test_apps/system/g1_components/check_dependencies.py +++ b/tools/test_apps/system/g1_components/check_dependencies.py @@ -54,7 +54,7 @@ g1_g0_components = g1_g0_components_base + get_all_esp_hal_components() # Global expected dependency violations that apply to all targets expected_dep_violations = { 'esp_system': ['esp_timer', 'bootloader_support', 'esp_pm', 'esp_usb_cdc_rom_console'], - 'spi_flash': ['bootloader_support', 'esp_blockdev'], + 'spi_flash': ['bootloader_support', 'esp_blockdev', 'esp_driver_gpio'], 'esp_hw_support': ['efuse', 'bootloader_support', 'esp_driver_gpio', 'esp_timer', 'esp_pm'], 'cxx': ['pthread'], }