diff --git a/components/esp_hw_support/include/esp_private/esp_pmu.h b/components/esp_hw_support/include/esp_private/esp_pmu.h index c416b3adf3..6200249da1 100644 --- a/components/esp_hw_support/include/esp_private/esp_pmu.h +++ b/components/esp_hw_support/include/esp_private/esp_pmu.h @@ -114,8 +114,10 @@ typedef enum { #if SOC_LP_CORE_SUPPORTED #define RTC_LP_CORE_TRIG_EN PMU_LP_CORE_WAKEUP_EN //!< LP core wakeup +#define RTC_LP_CORE_TRAP_TRIG_EN PMU_LP_CORE_TRAP_WAKEUP_EN //!< LP core trap (exception) wakeup #else #define RTC_LP_CORE_TRIG_EN 0 +#define RTC_LP_CORE_TRAP_TRIG_EN 0 #endif //SOC_LP_CORE_SUPPORTED #if SOC_LP_VAD_SUPPORTED diff --git a/components/esp_hw_support/port/esp32c5/private_include/pmu_bit_defs.h b/components/esp_hw_support/port/esp32c5/private_include/pmu_bit_defs.h index 390499371b..334b88c63e 100644 --- a/components/esp_hw_support/port/esp32c5/private_include/pmu_bit_defs.h +++ b/components/esp_hw_support/port/esp32c5/private_include/pmu_bit_defs.h @@ -20,6 +20,7 @@ extern "C" { #define PMU_UART1_WAKEUP_EN BIT(7) #define PMU_BLE_SOC_WAKEUP_EN BIT(10) #define PMU_LP_CORE_WAKEUP_EN BIT(11) +#define PMU_LP_CORE_TRAP_WAKEUP_EN BIT(12) #define PMU_USB_WAKEUP_EN BIT(14) #ifdef __cplusplus diff --git a/components/esp_hw_support/port/esp32c6/private_include/pmu_bit_defs.h b/components/esp_hw_support/port/esp32c6/private_include/pmu_bit_defs.h index df1a7fddfd..e36c152092 100644 --- a/components/esp_hw_support/port/esp32c6/private_include/pmu_bit_defs.h +++ b/components/esp_hw_support/port/esp32c6/private_include/pmu_bit_defs.h @@ -21,6 +21,7 @@ extern "C" { #define PMU_SDIO_WAKEUP_EN BIT(8) #define PMU_BLE_SOC_WAKEUP_EN BIT(10) #define PMU_LP_CORE_WAKEUP_EN BIT(11) +#define PMU_LP_CORE_TRAP_WAKEUP_EN BIT(12) #define PMU_USB_WAKEUP_EN BIT(14) #ifdef __cplusplus diff --git a/components/esp_hw_support/sleep_modes.c b/components/esp_hw_support/sleep_modes.c index 0b786e06e7..39d7fb5bd5 100644 --- a/components/esp_hw_support/sleep_modes.c +++ b/components/esp_hw_support/sleep_modes.c @@ -1052,7 +1052,7 @@ static esp_err_t SLEEP_FN_ATTR esp_sleep_start(uint32_t sleep_flags, uint32_t cl #elif CONFIG_ULP_COPROC_TYPE_RISCV if (s_config.wakeup_triggers & (RTC_COCPU_TRIG_EN | RTC_COCPU_TRAP_TRIG_EN)) { #elif CONFIG_ULP_COPROC_TYPE_LP_CORE - if (s_config.wakeup_triggers & RTC_LP_CORE_TRIG_EN) { + if (s_config.wakeup_triggers & (RTC_LP_CORE_TRIG_EN | RTC_LP_CORE_TRAP_TRIG_EN)) { #endif #ifdef CONFIG_IDF_TARGET_ESP32 rtc_hal_ulp_wakeup_enable(); @@ -1752,7 +1752,11 @@ esp_err_t esp_sleep_enable_ulp_wakeup(void) s_config.wakeup_triggers |= (RTC_COCPU_TRIG_EN | RTC_COCPU_TRAP_TRIG_EN); return ESP_OK; #elif CONFIG_ULP_COPROC_TYPE_LP_CORE - s_config.wakeup_triggers |= RTC_LP_CORE_TRIG_EN; + #if CONFIG_ULP_TRAP_WAKEUP + s_config.wakeup_triggers |= RTC_LP_CORE_TRIG_EN | RTC_LP_CORE_TRAP_TRIG_EN; + #else + s_config.wakeup_triggers |= RTC_LP_CORE_TRIG_EN; + #endif return ESP_OK; #else return ESP_ERR_NOT_SUPPORTED; @@ -2339,6 +2343,8 @@ esp_sleep_wakeup_cause_t esp_sleep_get_wakeup_cause(void) #if SOC_LP_CORE_SUPPORTED } else if (wakeup_cause & RTC_LP_CORE_TRIG_EN) { return ESP_SLEEP_WAKEUP_ULP; + } else if (wakeup_cause & RTC_LP_CORE_TRAP_TRIG_EN) { + return ESP_SLEEP_WAKEUP_COCPU_TRAP_TRIG; #endif #if SOC_LP_VAD_SUPPORTED } else if (wakeup_cause & RTC_LP_VAD_TRIG_EN) { @@ -2427,6 +2433,9 @@ uint32_t esp_sleep_get_wakeup_causes(void) if (wakeup_cause_raw & RTC_LP_CORE_TRIG_EN) { wakeup_cause |= BIT(ESP_SLEEP_WAKEUP_ULP); } + if (wakeup_cause_raw & RTC_LP_CORE_TRAP_TRIG_EN) { + wakeup_cause |= BIT(ESP_SLEEP_WAKEUP_COCPU_TRAP_TRIG); + } #endif #if SOC_LP_VAD_SUPPORTED if (wakeup_cause_raw & RTC_LP_VAD_TRIG_EN) { diff --git a/components/esp_rom/esp32c5/include/esp32c5/rom/rtc.h b/components/esp_rom/esp32c5/include/esp32c5/rom/rtc.h index 3c5d3750b8..a1cbfccc9e 100644 --- a/components/esp_rom/esp32c5/include/esp32c5/rom/rtc.h +++ b/components/esp_rom/esp32c5/include/esp32c5/rom/rtc.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -126,8 +126,8 @@ typedef enum { SAR_TRIG = BIT9, BT_TRIG = BIT10, RISCV_TRIG = BIT11, - XTAL_DEAD_TRIG = BIT12, - RISCV_TRAP_TRIG = BIT13, + RISCV_TRAP_TRIG = BIT12, + XTAL_DEAD_TRIG = BIT13, USB_TRIG = BIT14 } WAKEUP_REASON; @@ -144,8 +144,8 @@ typedef enum { SAR_TRIG_EN = SAR_TRIG, BT_TRIG_EN = BT_TRIG, RISCV_TRIG_EN = RISCV_TRIG, - XTAL_DEAD_TRIG_EN = XTAL_DEAD_TRIG, RISCV_TRAP_TRIG_EN = RISCV_TRAP_TRIG, + XTAL_DEAD_TRIG_EN = XTAL_DEAD_TRIG, USB_TRIG_EN = USB_TRIG } WAKEUP_ENABLE; diff --git a/components/esp_rom/esp32c6/include/esp32c6/rom/rtc.h b/components/esp_rom/esp32c6/include/esp32c6/rom/rtc.h index a94fd96c88..70a868df41 100644 --- a/components/esp_rom/esp32c6/include/esp32c6/rom/rtc.h +++ b/components/esp_rom/esp32c6/include/esp32c6/rom/rtc.h @@ -131,8 +131,8 @@ typedef enum { SAR_TRIG = BIT9, BT_TRIG = BIT10, RISCV_TRIG = BIT11, - XTAL_DEAD_TRIG = BIT12, - RISCV_TRAP_TRIG = BIT13, + RISCV_TRAP_TRIG = BIT12, + XTAL_DEAD_TRIG = BIT13, USB_TRIG = BIT14 } WAKEUP_REASON; @@ -150,8 +150,8 @@ typedef enum { SAR_TRIG_EN = SAR_TRIG, BT_TRIG_EN = BT_TRIG, RISCV_TRIG_EN = RISCV_TRIG, - XTAL_DEAD_TRIG_EN = XTAL_DEAD_TRIG, RISCV_TRAP_TRIG_EN = RISCV_TRAP_TRIG, + XTAL_DEAD_TRIG_EN = XTAL_DEAD_TRIG, USB_TRIG_EN = USB_TRIG } WAKEUP_ENABLE; diff --git a/components/ulp/Kconfig b/components/ulp/Kconfig index f4728ad835..2fbb436130 100644 --- a/components/ulp/Kconfig +++ b/components/ulp/Kconfig @@ -92,12 +92,21 @@ menu "Ultra Low Power (ULP) Co-processor" Note: For LP ROM prints to work properly, make sure that the LP core boots from the LP ROM. + config ULP_TRAP_WAKEUP + depends on ULP_COPROC_TYPE_LP_CORE + bool + prompt "Enable wakeup of HP-CPU when LP-core encounters an exception" + default "y" + help + Set this option to also trigger a wakeup signal to the HP-CPU when + the LP-core encounters an exception. + menu "ULP Debugging Options" config ULP_PANIC_OUTPUT_ENABLE depends on ULP_COPROC_TYPE_LP_CORE && SOC_ULP_LP_UART_SUPPORTED bool prompt "Enable panic handler which outputs over LP UART" - default "y" if SOC_LP_CORE_SUPPORT_STORE_LOAD_EXCEPTIONS + default "n" help Set this option to enable panic handler functionality. If this option is enabled then the LP Core will output a panic dump over LP UART, diff --git a/components/ulp/test_apps/lp_core/lp_core_basic_tests/main/CMakeLists.txt b/components/ulp/test_apps/lp_core/lp_core_basic_tests/main/CMakeLists.txt index b15fe5c4a5..2c9e9222f2 100644 --- a/components/ulp/test_apps/lp_core/lp_core_basic_tests/main/CMakeLists.txt +++ b/components/ulp/test_apps/lp_core/lp_core_basic_tests/main/CMakeLists.txt @@ -100,3 +100,5 @@ endif() ulp_embed_binary(lp_core_test_app_prefix1 "lp_core/test_main_prefix1.c" "${lp_core_exp_dep_srcs}" PREFIX "ulp1_") ulp_embed_binary(lp_core_test_app_prefix2 "lp_core/test_main_prefix2.c" "${lp_core_exp_dep_srcs}" PREFIX "ulp2_") + +ulp_embed_binary(lp_core_test_app_exception "lp_core/test_main_exception.c" "${lp_core_exp_dep_srcs}") diff --git a/components/ulp/test_apps/lp_core/lp_core_basic_tests/main/lp_core/test_main_exception.c b/components/ulp/test_apps/lp_core/lp_core_basic_tests/main/lp_core/test_main_exception.c new file mode 100644 index 0000000000..fc6b14ad0a --- /dev/null +++ b/components/ulp/test_apps/lp_core/lp_core_basic_tests/main/lp_core/test_main_exception.c @@ -0,0 +1,10 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +int main(void) +{ + asm volatile("unimp"); +} diff --git a/components/ulp/test_apps/lp_core/lp_core_basic_tests/main/test_lp_core.c b/components/ulp/test_apps/lp_core/lp_core_basic_tests/main/test_lp_core.c index 8de43884c4..74d3db790f 100644 --- a/components/ulp/test_apps/lp_core/lp_core_basic_tests/main/test_lp_core.c +++ b/components/ulp/test_apps/lp_core/lp_core_basic_tests/main/test_lp_core.c @@ -46,6 +46,9 @@ extern const uint8_t lp_core_main_gpio_bin_end[] asm("_binary_lp_core_test_app extern const uint8_t lp_core_main_isr_bin_start[] asm("_binary_lp_core_test_app_isr_bin_start"); extern const uint8_t lp_core_main_isr_bin_end[] asm("_binary_lp_core_test_app_isr_bin_end"); +extern const uint8_t lp_core_main_exception_bin_start[] asm("_binary_lp_core_test_app_exception_bin_start"); +extern const uint8_t lp_core_main_exception_bin_end[] asm("_binary_lp_core_test_app_exception_bin_end"); + static void load_and_start_lp_core_firmware(ulp_lp_core_cfg_t* cfg, const uint8_t* firmware_start, const uint8_t* firmware_end) { TEST_ASSERT(ulp_lp_core_load_binary(firmware_start, @@ -383,3 +386,32 @@ TEST_CASE("LP core ISR tests", "[ulp]") TEST_ASSERT_EQUAL(ISR_TEST_ITERATIONS, ulp_io_isr_counter); #endif //SOC_RTCIO_PIN_COUNT > 0 } + +#if SOC_DEEP_SLEEP_SUPPORTED + +void lp_core_prep_exception_wakeup(void) +{ + /* Load ULP firmware and start the coprocessor */ + ulp_lp_core_cfg_t cfg = { + .wakeup_source = ULP_LP_CORE_WAKEUP_SOURCE_HP_CPU, + }; + + load_and_start_lp_core_firmware(&cfg, lp_core_main_exception_bin_start, lp_core_main_exception_bin_end); + + TEST_ASSERT(esp_sleep_enable_ulp_wakeup() == ESP_OK); + /* Setup test data */ + + /* Enter Deep Sleep */ + esp_deep_sleep_start(); +} + +static void check_reset_reason_ulp_trap_wakeup(void) +{ + printf("Wakeup cause: 0x%"PRIx32"\n", esp_sleep_get_wakeup_causes()); + TEST_ASSERT(esp_sleep_get_wakeup_causes() & BIT(ESP_SLEEP_WAKEUP_COCPU_TRAP_TRIG)); +} + +TEST_CASE_MULTIPLE_STAGES("LP-core exception can wakeup main cpu", "[ulp]", + lp_core_prep_exception_wakeup, + check_reset_reason_ulp_trap_wakeup); +#endif //SOC_DEEP_SLEEP_SUPPORTED diff --git a/components/ulp/test_apps/lp_core/lp_core_basic_tests/sdkconfig.ci.defaults b/components/ulp/test_apps/lp_core/lp_core_basic_tests/sdkconfig.ci.defaults index c7626f4733..79776d7ef1 100644 --- a/components/ulp/test_apps/lp_core/lp_core_basic_tests/sdkconfig.ci.defaults +++ b/components/ulp/test_apps/lp_core/lp_core_basic_tests/sdkconfig.ci.defaults @@ -3,4 +3,3 @@ CONFIG_ESP_TASK_WDT_INIT=n CONFIG_ULP_COPROC_ENABLED=y CONFIG_ULP_COPROC_TYPE_LP_CORE=y CONFIG_ULP_COPROC_RESERVE_MEM=12000 -CONFIG_ULP_PANIC_OUTPUT_ENABLE=y diff --git a/components/ulp/test_apps/lp_core/lp_core_basic_tests/sdkconfig.defaults b/components/ulp/test_apps/lp_core/lp_core_basic_tests/sdkconfig.defaults index c7626f4733..79776d7ef1 100644 --- a/components/ulp/test_apps/lp_core/lp_core_basic_tests/sdkconfig.defaults +++ b/components/ulp/test_apps/lp_core/lp_core_basic_tests/sdkconfig.defaults @@ -3,4 +3,3 @@ CONFIG_ESP_TASK_WDT_INIT=n CONFIG_ULP_COPROC_ENABLED=y CONFIG_ULP_COPROC_TYPE_LP_CORE=y CONFIG_ULP_COPROC_RESERVE_MEM=12000 -CONFIG_ULP_PANIC_OUTPUT_ENABLE=y diff --git a/docs/en/migration-guides/release-6.x/6.0/system.rst b/docs/en/migration-guides/release-6.x/6.0/system.rst index 2472d7acbf..354f377f10 100644 --- a/docs/en/migration-guides/release-6.x/6.0/system.rst +++ b/docs/en/migration-guides/release-6.x/6.0/system.rst @@ -235,3 +235,8 @@ System Console (STDIO) ``esp_vfs_cdcacm.h`` has been moved to the new component ``esp_usb_cdc_rom_console``, you will now have to add an explicit ``REQUIRES`` for ``esp_usb_cdc_rom_console`` if using any functions from this header. +ULP +--- + +The LP-Core will now wake-up the main CPU when it encounters an exception during deep sleep. This feature is enabled by default but can be disabled via the :ref:`CONFIG_ULP_TRAP_WAKEUP` Kconfig option is this behavior is not desired. +