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 edf2076826..50b9a0beb6 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 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. + + 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 79188e971c..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,13 +1441,29 @@ 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. - 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); 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