From ae50c7122274a1c84fe0ba3a4d7b1bf387bae3c7 Mon Sep 17 00:00:00 2001 From: "C.S.M" Date: Fri, 7 Mar 2025 11:18:39 +0800 Subject: [PATCH 1/3] fix(spi_flash): Return false directly in suspend caps check --- components/spi_flash/esp_flash_api.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/components/spi_flash/esp_flash_api.c b/components/spi_flash/esp_flash_api.c index 79188e971c..d5c3105f53 100644 --- a/components/spi_flash/esp_flash_api.c +++ b/components/spi_flash/esp_flash_api.c @@ -1442,10 +1442,12 @@ esp_err_t esp_flash_suspend_cmd_init(esp_flash_t* chip) ESP_EARLY_LOGW(TAG, "Flash suspend feature is enabled"); if (chip->chip_drv->get_chip_caps == NULL) { // chip caps get failed, pass the flash capability check. - ESP_EARLY_LOGW(TAG, "get_chip_caps function pointer hasn't been initialized"); + ESP_EARLY_LOGE(TAG, "get_chip_caps function pointer hasn't been initialized"); + return ESP_ERR_INVALID_ARG; } else { if ((chip->chip_drv->get_chip_caps(chip) & SPI_FLASH_CHIP_CAP_SUSPEND) == 0) { - ESP_EARLY_LOGW(TAG, "Suspend and resume may not supported for this flash model yet."); + ESP_EARLY_LOGE(TAG, "Suspend and resume may not supported for this flash model yet."); + return ESP_ERR_NOT_SUPPORTED; } } return chip->chip_drv->sus_setup(chip); From 6c3d67b2342d023f44ec668004c6998bb66cbd9c Mon Sep 17 00:00:00 2001 From: "C.S.M" Date: Fri, 7 Mar 2025 14:55:11 +0800 Subject: [PATCH 2/3] fix(spi_flash): Add suspend check on esp32c6 and esp32h2 for some reason --- components/spi_flash/Kconfig | 11 +++++++++++ components/spi_flash/esp_flash_api.c | 16 ++++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/components/spi_flash/Kconfig b/components/spi_flash/Kconfig index edf2076826..7ea89c70fe 100644 --- a/components/spi_flash/Kconfig +++ b/components/spi_flash/Kconfig @@ -120,6 +120,17 @@ menu "Main Flash configuration" For new users, DO NOT enable this config. + config SPI_FLASH_FORCE_ENABLE_C6_H2_SUSPEND + bool "Enable chip suspend feature on c6 or h2 anyway (DO NOT ENABLE FOR NEW USERS OR APPLICATIONS)" + default n + help + Flash suspend has defect on ESP32C6 until v0.2 and ESP32H2 until v1.2. If you already use suspend + feature for massive protection, you can enable this for bypassing check after knowing the risk. + But if you are new users, or developing new applications, or producing a new batch, + please DO NOT enable this config option. + + For more information, please refer to errata or connect to Espressif business support team. + config SPI_FLASH_SOFTWARE_RESUME bool "Resume flash program/erase form suspend state by software control" default n diff --git a/components/spi_flash/esp_flash_api.c b/components/spi_flash/esp_flash_api.c index d5c3105f53..bb7084f7fe 100644 --- a/components/spi_flash/esp_flash_api.c +++ b/components/spi_flash/esp_flash_api.c @@ -22,6 +22,8 @@ #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" #if CONFIG_IDF_TARGET_ESP32S2 #include "esp_crypto_lock.h" // for locking flash encryption peripheral @@ -1439,6 +1441,20 @@ restore_cache: //init suspend mode cmd, uses internal. esp_err_t esp_flash_suspend_cmd_init(esp_flash_t* chip) { +#if !CONFIG_SPI_FLASH_FORCE_ENABLE_C6_H2_SUSPEND +#if CONFIG_IDF_TARGET_ESP32H2 + if (!ESP_CHIP_REV_ABOVE(efuse_hal_chip_revision(), 102)) { + ESP_LOGE(TAG, "ESP32H2 chips lower than v1.2 are not recommended to suspend the Flash"); + return ESP_ERR_NOT_SUPPORTED; + } +#endif +#if CONFIG_IDF_TARGET_ESP32C6 + if (!ESP_CHIP_REV_ABOVE(efuse_hal_chip_revision(), 2)) { + ESP_LOGE(TAG, "ESP32C6 chips lower than v0.2 are not recommended to suspend the Flash"); + return ESP_ERR_NOT_SUPPORTED; + } +#endif +#endif ESP_EARLY_LOGW(TAG, "Flash suspend feature is enabled"); if (chip->chip_drv->get_chip_caps == NULL) { // chip caps get failed, pass the flash capability check. From 9aba44a2d90f25eb4377ed316c57730714bcf4d4 Mon Sep 17 00:00:00 2001 From: "C.S.M" Date: Fri, 7 Mar 2025 15:13:56 +0800 Subject: [PATCH 3/3] test(spi_flash): Flash suspend test evolution --- .../test_apps/i2c_test_apps/main/CMakeLists.txt | 4 ++++ .../i2c_test_apps}/main/idf_component.yml | 0 .../i2c_test_apps}/main/test_i2c_flash_text.c | 4 ++-- .../test_apps/i2c_test_apps/pytest_i2c.py | 17 +++++++++++++++++ .../i2c_test_apps/sdkconfig.ci.i2c_isr_flash | 4 ++++ components/spi_flash/Kconfig | 4 ++-- .../sdkconfig.ci.esp32c3_suspend | 2 ++ .../test_apps/flash_suspend/main/CMakeLists.txt | 6 ------ .../flash_suspend/main/test_app_main.c | 2 +- .../flash_suspend/sdkconfig.ci.i2c_isr_flash | 1 - .../flash_suspend/sdkconfig.ci.release | 4 +++- .../sdkconfig.ci.text_in_flash_when_suspend | 2 ++ .../test_apps/flash_suspend/sdkconfig.defaults | 4 +++- .../flash_suspend/sdkconfig.ci.flash_suspend | 2 ++ 14 files changed, 42 insertions(+), 14 deletions(-) rename components/{spi_flash/test_apps/flash_suspend => esp_driver_i2c/test_apps/i2c_test_apps}/main/idf_component.yml (100%) rename components/{spi_flash/test_apps/flash_suspend => esp_driver_i2c/test_apps/i2c_test_apps}/main/test_i2c_flash_text.c (97%) create mode 100644 components/esp_driver_i2c/test_apps/i2c_test_apps/sdkconfig.ci.i2c_isr_flash delete mode 100644 components/spi_flash/test_apps/flash_suspend/sdkconfig.ci.i2c_isr_flash diff --git a/components/esp_driver_i2c/test_apps/i2c_test_apps/main/CMakeLists.txt b/components/esp_driver_i2c/test_apps/i2c_test_apps/main/CMakeLists.txt index 7187dd3907..eeb0e10d19 100644 --- a/components/esp_driver_i2c/test_apps/i2c_test_apps/main/CMakeLists.txt +++ b/components/esp_driver_i2c/test_apps/i2c_test_apps/main/CMakeLists.txt @@ -34,6 +34,10 @@ if(CONFIG_SOC_I2C_SUPPORT_SLAVE) endif() endif() +if(NOT CONFIG_I2C_MASTER_ISR_HANDLER_IN_IRAM) + list(APPEND srcs "test_i2c_flash_text.c") +endif() + idf_component_register(SRCS ${srcs} PRIV_REQUIRES unity driver test_utils WHOLE_ARCHIVE) diff --git a/components/spi_flash/test_apps/flash_suspend/main/idf_component.yml b/components/esp_driver_i2c/test_apps/i2c_test_apps/main/idf_component.yml similarity index 100% rename from components/spi_flash/test_apps/flash_suspend/main/idf_component.yml rename to components/esp_driver_i2c/test_apps/i2c_test_apps/main/idf_component.yml diff --git a/components/spi_flash/test_apps/flash_suspend/main/test_i2c_flash_text.c b/components/esp_driver_i2c/test_apps/i2c_test_apps/main/test_i2c_flash_text.c similarity index 97% rename from components/spi_flash/test_apps/flash_suspend/main/test_i2c_flash_text.c rename to components/esp_driver_i2c/test_apps/i2c_test_apps/main/test_i2c_flash_text.c index e5d68175e7..9c3f094a2c 100644 --- a/components/spi_flash/test_apps/flash_suspend/main/test_i2c_flash_text.c +++ b/components/esp_driver_i2c/test_apps/i2c_test_apps/main/test_i2c_flash_text.c @@ -32,7 +32,7 @@ void spi_flash_suspend_test_task(void *arg) { spi_flash_test_context_t *context = (spi_flash_test_context_t *)arg; - uint32_t cnt = 200; + uint32_t cnt = 20; while (cnt--) { if (context->flash_handle->suspend_times != 0) { break; @@ -120,7 +120,7 @@ TEST_CASE("Flash suspend support on i2c", "[i2c]") // Quit when suspend is triggered. xTaskCreatePinnedToCore(spi_flash_suspend_test_task, "flash_task", 4096, context, 2, NULL, 0); - xSemaphoreTake(context->sem, pdMS_TO_TICKS(5000)); // We don't always wait the semaphore + xSemaphoreTake(context->sem, portMAX_DELAY); printf("test finishes, suspend for %ld times\n", context->flash_handle->suspend_times); TEST_ASSERT_NOT_EQUAL(0, context->flash_handle->suspend_times); diff --git a/components/esp_driver_i2c/test_apps/i2c_test_apps/pytest_i2c.py b/components/esp_driver_i2c/test_apps/i2c_test_apps/pytest_i2c.py index de7106b1fe..eaf1f87d0d 100644 --- a/components/esp_driver_i2c/test_apps/i2c_test_apps/pytest_i2c.py +++ b/components/esp_driver_i2c/test_apps/i2c_test_apps/pytest_i2c.py @@ -51,3 +51,20 @@ def test_i2c_multi_device(case_tester) -> None: # type: ignore for case in case_tester.test_menu: if case.attributes.get('test_env', 'generic_multi_device') == 'generic_multi_device': case_tester.run_multi_dev_case(case=case, reset=True) + + +@pytest.mark.flash_suspend +@pytest.mark.parametrize( + 'config', + [ + 'i2c_isr_flash', + ], + indirect=True, +) +@idf_parametrize( + 'target', + ['esp32c3'], + indirect=['target'], +) +def test_flash_auto_suspend_for_i2c(dut: Dut) -> None: + dut.run_all_single_board_cases(timeout=30) diff --git a/components/esp_driver_i2c/test_apps/i2c_test_apps/sdkconfig.ci.i2c_isr_flash b/components/esp_driver_i2c/test_apps/i2c_test_apps/sdkconfig.ci.i2c_isr_flash new file mode 100644 index 0000000000..ded782e5c9 --- /dev/null +++ b/components/esp_driver_i2c/test_apps/i2c_test_apps/sdkconfig.ci.i2c_isr_flash @@ -0,0 +1,4 @@ +CONFIG_I2C_MASTER_ISR_HANDLER_IN_IRAM=n +CONFIG_SPI_FLASH_AUTO_SUSPEND=y +# Now the runners are massively using xmc-c chips, to be removed when xmc-d goes massive production. +CONFIG_SPI_FLASH_FORCE_ENABLE_XMC_C_SUSPEND=y diff --git a/components/spi_flash/Kconfig b/components/spi_flash/Kconfig index 7ea89c70fe..50b9a0beb6 100644 --- a/components/spi_flash/Kconfig +++ b/components/spi_flash/Kconfig @@ -124,8 +124,8 @@ menu "Main Flash configuration" bool "Enable chip suspend feature on c6 or h2 anyway (DO NOT ENABLE FOR NEW USERS OR APPLICATIONS)" default n help - Flash suspend has defect on ESP32C6 until v0.2 and ESP32H2 until v1.2. If you already use suspend - feature for massive protection, you can enable this for bypassing check after knowing the risk. + Flash suspend has a defect on ESP32C6 until v0.2 and ESP32H2 until v1.2. If you already use suspend + feature for mass production, you can enable this for bypassing check after knowing the risk. But if you are new users, or developing new applications, or producing a new batch, please DO NOT enable this config option. diff --git a/components/spi_flash/test_apps/esp_flash_stress/sdkconfig.ci.esp32c3_suspend b/components/spi_flash/test_apps/esp_flash_stress/sdkconfig.ci.esp32c3_suspend index 0addf025a2..3375e2ad83 100644 --- a/components/spi_flash/test_apps/esp_flash_stress/sdkconfig.ci.esp32c3_suspend +++ b/components/spi_flash/test_apps/esp_flash_stress/sdkconfig.ci.esp32c3_suspend @@ -2,3 +2,5 @@ CONFIG_IDF_TARGET="esp32c3" CONFIG_SPI_FLASH_AUTO_SUSPEND=y +# Now the runners are massively using xmc-c chips, to be removed when xmc-d goes massive production. +CONFIG_SPI_FLASH_FORCE_ENABLE_XMC_C_SUSPEND=y diff --git a/components/spi_flash/test_apps/flash_suspend/main/CMakeLists.txt b/components/spi_flash/test_apps/flash_suspend/main/CMakeLists.txt index 432ac51904..07ff2ece51 100644 --- a/components/spi_flash/test_apps/flash_suspend/main/CMakeLists.txt +++ b/components/spi_flash/test_apps/flash_suspend/main/CMakeLists.txt @@ -1,12 +1,6 @@ set(srcs "test_app_main.c" "test_flash_suspend.c") - -if(NOT CONFIG_I2C_MASTER_ISR_HANDLER_IN_IRAM) - list(APPEND srcs "test_i2c_flash_text.c") -endif() - - # In order for the cases defined by `TEST_CASE` to be linked into the final elf, # the component can be registered as WHOLE_ARCHIVE idf_component_register(SRCS ${srcs} diff --git a/components/spi_flash/test_apps/flash_suspend/main/test_app_main.c b/components/spi_flash/test_apps/flash_suspend/main/test_app_main.c index a626f5e8cd..c72d87cead 100644 --- a/components/spi_flash/test_apps/flash_suspend/main/test_app_main.c +++ b/components/spi_flash/test_apps/flash_suspend/main/test_app_main.c @@ -9,7 +9,7 @@ #include "esp_heap_caps.h" // Some resources are lazy allocated, the threshold is left for that case -#define TEST_MEMORY_LEAK_THRESHOLD (1000) +#define TEST_MEMORY_LEAK_THRESHOLD (1200) static size_t before_free_8bit; static size_t before_free_32bit; diff --git a/components/spi_flash/test_apps/flash_suspend/sdkconfig.ci.i2c_isr_flash b/components/spi_flash/test_apps/flash_suspend/sdkconfig.ci.i2c_isr_flash deleted file mode 100644 index b80d56a297..0000000000 --- a/components/spi_flash/test_apps/flash_suspend/sdkconfig.ci.i2c_isr_flash +++ /dev/null @@ -1 +0,0 @@ -CONFIG_I2C_MASTER_ISR_HANDLER_IN_IRAM=n diff --git a/components/spi_flash/test_apps/flash_suspend/sdkconfig.ci.release b/components/spi_flash/test_apps/flash_suspend/sdkconfig.ci.release index b451578520..fba9378c3d 100644 --- a/components/spi_flash/test_apps/flash_suspend/sdkconfig.ci.release +++ b/components/spi_flash/test_apps/flash_suspend/sdkconfig.ci.release @@ -1,5 +1,7 @@ -CONFIG_ESP_TASK_WDT=n +CONFIG_ESP_TASK_WDT_EN=n CONFIG_SPI_FLASH_AUTO_SUSPEND=y CONFIG_COMPILER_OPTIMIZATION_SIZE=y CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_SIZE=y CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_SILENT=y +# Now the runners are massively using xmc-c chips, to be removed when xmc-d goes massive production. +CONFIG_SPI_FLASH_FORCE_ENABLE_XMC_C_SUSPEND=y diff --git a/components/spi_flash/test_apps/flash_suspend/sdkconfig.ci.text_in_flash_when_suspend b/components/spi_flash/test_apps/flash_suspend/sdkconfig.ci.text_in_flash_when_suspend index 1ef7b73f05..7727aa7589 100644 --- a/components/spi_flash/test_apps/flash_suspend/sdkconfig.ci.text_in_flash_when_suspend +++ b/components/spi_flash/test_apps/flash_suspend/sdkconfig.ci.text_in_flash_when_suspend @@ -1,2 +1,4 @@ CONFIG_SPI_FLASH_AUTO_SUSPEND=y CONFIG_SPI_FLASH_PLACE_FUNCTIONS_IN_IRAM=n +# Now the runners are massively using xmc-c chips, to be removed when xmc-d goes massive production. +CONFIG_SPI_FLASH_FORCE_ENABLE_XMC_C_SUSPEND=y diff --git a/components/spi_flash/test_apps/flash_suspend/sdkconfig.defaults b/components/spi_flash/test_apps/flash_suspend/sdkconfig.defaults index cdb818d6f9..b1c381e888 100644 --- a/components/spi_flash/test_apps/flash_suspend/sdkconfig.defaults +++ b/components/spi_flash/test_apps/flash_suspend/sdkconfig.defaults @@ -1,4 +1,6 @@ -CONFIG_ESP_TASK_WDT=n +CONFIG_ESP_TASK_WDT_EN=n CONFIG_SPI_FLASH_AUTO_SUSPEND=y CONFIG_PARTITION_TABLE_CUSTOM=y CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv" +# Now the runners are massively using xmc-c chips, to be removed when xmc-d goes massive production. +CONFIG_SPI_FLASH_FORCE_ENABLE_XMC_C_SUSPEND=y diff --git a/examples/system/flash_suspend/sdkconfig.ci.flash_suspend b/examples/system/flash_suspend/sdkconfig.ci.flash_suspend index 8c84ea2be2..07e726c01e 100644 --- a/examples/system/flash_suspend/sdkconfig.ci.flash_suspend +++ b/examples/system/flash_suspend/sdkconfig.ci.flash_suspend @@ -2,3 +2,5 @@ CONFIG_SPI_FLASH_AUTO_SUSPEND=y CONFIG_PARTITION_TABLE_CUSTOM=y CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv" CONFIG_PARTITION_TABLE_FILENAME="partitions.csv" +# Now the runners are massively using xmc-c chips, to be removed when xmc-d goes massive production. +CONFIG_SPI_FLASH_FORCE_ENABLE_XMC_C_SUSPEND=y