diff --git a/components/esp_hw_support/sleep_modes.c b/components/esp_hw_support/sleep_modes.c index 4138fa6a5b..e0387e30f4 100644 --- a/components/esp_hw_support/sleep_modes.c +++ b/components/esp_hw_support/sleep_modes.c @@ -81,6 +81,9 @@ #endif #include "hal/temperature_sensor_hal.h" #include "hal/mspi_ll.h" +#if SOC_LP_CORE_HW_AUTO_CLRWAKEUPCAUSE +#include "hal/lp_aon_hal.h" +#endif #include "sdkconfig.h" #include "esp_rom_serial_output.h" @@ -2533,6 +2536,15 @@ uint32_t esp_sleep_get_wakeup_causes(void) uint32_t wakeup_cause_raw = rtc_cntl_ll_get_wakeup_cause(); #endif +#if SOC_LP_CORE_HW_AUTO_CLRWAKEUPCAUSE + /* LP store register to read wakeup cause saved by LP core. + * Must match the register used in lp_core_utils.c */ + uint32_t lp_core_wakeup_cause_status0 = lp_aon_hal_load_wakeup_cause(); + if ((wakeup_cause_raw == 0) && (lp_core_wakeup_cause_status0 != 0)) { + wakeup_cause_raw = lp_core_wakeup_cause_status0; + } +#endif + if (wakeup_cause_raw & RTC_TIMER_TRIG_EN) { wakeup_cause |= BIT(ESP_SLEEP_WAKEUP_TIMER); } diff --git a/components/esp_rom/esp32c5/include/esp32c5/rom/rtc.h b/components/esp_rom/esp32c5/include/esp32c5/rom/rtc.h index a1cbfccc9e..be177cebdd 100644 --- a/components/esp_rom/esp32c5/include/esp32c5/rom/rtc.h +++ b/components/esp_rom/esp32c5/include/esp32c5/rom/rtc.h @@ -51,7 +51,8 @@ extern "C" { * LP_AON_STORE6_REG FAST_RTC_MEMORY_ENTRY * LP_AON_STORE7_REG FAST_RTC_MEMORY_CRC * LP_AON_STORE8_REG Store light sleep wake stub addr - * LP_AON_STORE9_REG Store the sleep mode at bit[0] (0:light sleep 1:deep sleep) + * LP_AON_STORE8_REG Store the sleep mode at bit[0] (0:light sleep 1:deep sleep) + * LP_AON_STORE9_REG LP core store wakeup cause ************************************************************************************* */ @@ -64,6 +65,7 @@ extern "C" { #define RTC_MEMORY_CRC_REG LP_AON_STORE7_REG #define RTC_SLEEP_WAKE_STUB_ADDR_REG LP_AON_STORE8_REG #define RTC_SLEEP_MODE_REG LP_AON_STORE8_REG +#define RTC_LP_CORE_STORE_WAKEUP_REG LP_AON_STORE9_REG #define RTC_DISABLE_ROM_LOG ((1 << 0) | (1 << 16)) //!< Disable logging from the ROM code. diff --git a/components/esp_rom/esp32c6/include/esp32c6/rom/rtc.h b/components/esp_rom/esp32c6/include/esp32c6/rom/rtc.h index 70a868df41..38c3ac3c35 100644 --- a/components/esp_rom/esp32c6/include/esp32c6/rom/rtc.h +++ b/components/esp_rom/esp32c6/include/esp32c6/rom/rtc.h @@ -53,6 +53,7 @@ extern "C" { * LP_AON_STORE7_REG FAST_RTC_MEMORY_CRC * LP_AON_STORE8_REG Store light sleep wake stub addr * LP_AON_STORE9_REG Store the sleep mode at bit[0] (0:light sleep 1:deep sleep) + * LP_AON_STORE10_REG LP core store wakeup cause at bit[31:2] ************************************************************************************* */ @@ -66,6 +67,7 @@ extern "C" { #define RTC_MEMORY_CRC_REG LP_AON_STORE7_REG #define RTC_SLEEP_WAKE_STUB_ADDR_REG LP_AON_STORE8_REG #define RTC_SLEEP_MODE_REG LP_AON_STORE9_REG +#define RTC_LP_CORE_STORE_WAKEUP_REG LP_AON_STORE9_REG #define RTC_DISABLE_ROM_LOG ((1 << 0) | (1 << 16)) //!< Disable logging from the ROM code. diff --git a/components/esp_rom/esp32p4/include/esp32p4/rom/rtc.h b/components/esp_rom/esp32p4/include/esp32p4/rom/rtc.h index 6eccaa9ba5..d3c39b0e1e 100644 --- a/components/esp_rom/esp32p4/include/esp32p4/rom/rtc.h +++ b/components/esp_rom/esp32p4/include/esp32p4/rom/rtc.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -53,17 +53,19 @@ extern "C" { * LP_SYS_LP_STORE8_REG sleep mode and wake stub address * LP_SYS_LP_STORE9_REG LP_UART_INIT_CTRL * LP_SYS_LP_STORE10_REG LP_ROM_LOG_CTRL + * LP_SYS_LP_STORE11_REG LP core store wakeup cause ************************************************************************************* */ -#define RTC_SLOW_CLK_CAL_REG LP_SYSTEM_REG_LP_STORE1_REG -#define RTC_BOOT_TIME_LOW_REG LP_SYSTEM_REG_LP_STORE2_REG -#define RTC_BOOT_TIME_HIGH_REG LP_SYSTEM_REG_LP_STORE3_REG -#define RTC_XTAL_FREQ_REG LP_SYSTEM_REG_LP_STORE4_REG -#define RTC_APB_FREQ_REG LP_SYSTEM_REG_LP_STORE5_REG -#define RTC_ENTRY_ADDR_REG LP_SYSTEM_REG_LP_STORE6_REG -#define RTC_RESET_CAUSE_REG LP_SYSTEM_REG_LP_STORE6_REG -#define RTC_MEMORY_CRC_REG LP_SYSTEM_REG_LP_STORE7_REG +#define RTC_SLOW_CLK_CAL_REG LP_SYSTEM_REG_LP_STORE1_REG +#define RTC_BOOT_TIME_LOW_REG LP_SYSTEM_REG_LP_STORE2_REG +#define RTC_BOOT_TIME_HIGH_REG LP_SYSTEM_REG_LP_STORE3_REG +#define RTC_XTAL_FREQ_REG LP_SYSTEM_REG_LP_STORE4_REG +#define RTC_APB_FREQ_REG LP_SYSTEM_REG_LP_STORE5_REG +#define RTC_ENTRY_ADDR_REG LP_SYSTEM_REG_LP_STORE6_REG +#define RTC_RESET_CAUSE_REG LP_SYSTEM_REG_LP_STORE6_REG +#define RTC_MEMORY_CRC_REG LP_SYSTEM_REG_LP_STORE7_REG +#define RTC_LP_CORE_STORE_WAKEUP_REG LP_SYSTEM_REG_LP_STORE11_REG #define RTC_DISABLE_ROM_LOG ((1 << 0) | (1 << 16)) //!< Disable logging from the ROM code. diff --git a/components/esp_rom/esp32s31/include/esp32s31/rom/rtc.h b/components/esp_rom/esp32s31/include/esp32s31/rom/rtc.h index b3d74f4c08..c263ded86b 100644 --- a/components/esp_rom/esp32s31/include/esp32s31/rom/rtc.h +++ b/components/esp_rom/esp32s31/include/esp32s31/rom/rtc.h @@ -46,6 +46,7 @@ extern "C" { * RTC_CNTL_STORE5_REG FAST_RTC_MEMORY_LENGTH * RTC_CNTL_STORE6_REG FAST_RTC_MEMORY_ENTRY * RTC_CNTL_STORE7_REG FAST_RTC_MEMORY_CRC + * RTC_CNTL_STORE9_REG LP core store wakeup cause ************************************************************************************* */ @@ -56,6 +57,7 @@ extern "C" { #define RTC_ENTRY_ADDR_REG LP_SYSTEM_REG_LP_STORE6_REG #define RTC_RESET_CAUSE_REG LP_SYSTEM_REG_LP_STORE6_REG #define RTC_MEMORY_CRC_REG LP_SYSTEM_REG_LP_STORE7_REG +#define RTC_LP_CORE_STORE_WAKEUP_REG LP_SYSTEM_REG_LP_STORE9_REG // light sleep /* use LP_SYS_LP_STORE8_REG to store light sleep wake stub addr and sleep mode for dualcore diff --git a/components/hal/esp32c5/include/hal/lp_aon_hal.h b/components/hal/esp32c5/include/hal/lp_aon_hal.h index 2090a64928..9854ef3b0e 100644 --- a/components/hal/esp32c5/include/hal/lp_aon_hal.h +++ b/components/hal/esp32c5/include/hal/lp_aon_hal.h @@ -15,3 +15,6 @@ #define rtc_hal_ext1_get_wakeup_pins() lp_aon_ll_ext1_get_wakeup_pins() #define lp_aon_hal_inform_wakeup_type(dslp) lp_aon_ll_inform_wakeup_type(dslp) + +#define lp_aon_hal_store_wakeup_cause(wakeup_cause) lp_aon_ll_store_wakeup_cause(wakeup_cause) +#define lp_aon_hal_load_wakeup_cause() lp_aon_ll_load_wakeup_cause() diff --git a/components/hal/esp32c5/include/hal/lp_aon_ll.h b/components/hal/esp32c5/include/hal/lp_aon_ll.h index e36779941a..f077dc59c8 100644 --- a/components/hal/esp32c5/include/hal/lp_aon_ll.h +++ b/components/hal/esp32c5/include/hal/lp_aon_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -85,6 +85,24 @@ static inline void lp_aon_ll_inform_wakeup_type(bool dslp) } } +/** + * @brief Set the wakeup cause stored by LP core + * @param wakeup_cause The wakeup cause in PMU register + */ +static inline void lp_aon_ll_store_wakeup_cause(uint32_t wakeup_cause) +{ + REG_WRITE(RTC_LP_CORE_STORE_WAKEUP_REG, wakeup_cause); +} + +/** + * @brief Get the wakeup cause stored by LP core + * @return The wakeup cause cleared before LP core sleep + */ +static inline uint32_t lp_aon_ll_load_wakeup_cause(void) +{ + return REG_READ(RTC_LP_CORE_STORE_WAKEUP_REG); +} + #ifdef __cplusplus } #endif diff --git a/components/hal/esp32c6/include/hal/lp_aon_hal.h b/components/hal/esp32c6/include/hal/lp_aon_hal.h index 86a8849239..d409cdbb22 100644 --- a/components/hal/esp32c6/include/hal/lp_aon_hal.h +++ b/components/hal/esp32c6/include/hal/lp_aon_hal.h @@ -13,6 +13,8 @@ extern "C" { #endif #define lp_aon_hal_inform_wakeup_type(dslp) lp_aon_ll_inform_wakeup_type(dslp) +#define lp_aon_hal_store_wakeup_cause(wakeup_cause) lp_aon_ll_store_wakeup_cause(wakeup_cause) +#define lp_aon_hal_load_wakeup_cause() lp_aon_ll_load_wakeup_cause() #ifdef __cplusplus } diff --git a/components/hal/esp32c6/include/hal/lp_aon_ll.h b/components/hal/esp32c6/include/hal/lp_aon_ll.h index 2283a0dff6..d2ce851402 100644 --- a/components/hal/esp32c6/include/hal/lp_aon_ll.h +++ b/components/hal/esp32c6/include/hal/lp_aon_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -85,6 +85,24 @@ static inline void lp_aon_ll_inform_wakeup_type(bool dslp) } } +/** + * @brief Set the wakeup cause stored by LP core + * @param wakeup_cause The wakeup cause in PMU register + */ +static inline void lp_aon_ll_store_wakeup_cause(uint32_t wakeup_cause) +{ + REG_WRITE(RTC_LP_CORE_STORE_WAKEUP_REG, (REG_READ(RTC_LP_CORE_STORE_WAKEUP_REG) & 0x1) | ((wakeup_cause << 1) & 0xFFFFFFFE)); +} + +/** + * @brief Get the wakeup cause stored by LP core + * @return The wakeup cause cleared before LP core sleep + */ +static inline uint32_t lp_aon_ll_load_wakeup_cause(void) +{ + return (REG_READ(RTC_LP_CORE_STORE_WAKEUP_REG) & 0xFFFFFFFE) >> 1; +} + #ifdef __cplusplus } #endif diff --git a/components/hal/esp32p4/include/hal/lp_aon_hal.h b/components/hal/esp32p4/include/hal/lp_aon_hal.h index 31d7c57485..6152d3b952 100644 --- a/components/hal/esp32p4/include/hal/lp_aon_hal.h +++ b/components/hal/esp32p4/include/hal/lp_aon_hal.h @@ -13,6 +13,8 @@ extern "C" { #endif #define lp_aon_hal_inform_wakeup_type(dslp) lp_sys_ll_inform_wakeup_type(dslp) +#define lp_aon_hal_store_wakeup_cause(wakeup_cause) lp_sys_ll_store_wakeup_cause(wakeup_cause) +#define lp_aon_hal_load_wakeup_cause() lp_sys_ll_load_wakeup_cause() #ifdef __cplusplus } diff --git a/components/hal/esp32p4/include/hal/lp_sys_ll.h b/components/hal/esp32p4/include/hal/lp_sys_ll.h index 366edbd4d5..71d5371e9a 100644 --- a/components/hal/esp32p4/include/hal/lp_sys_ll.h +++ b/components/hal/esp32p4/include/hal/lp_sys_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -81,6 +81,25 @@ FORCE_INLINE_ATTR void lp_sys_ll_set_lp_mem_lowpower_mode(uint32_t mode) LP_SYS.lp_mem_aux_ctrl.lp_mem_lowpower_mode = mode; } #endif + +/** + * @brief Set the wakeup cause stored by LP core + * @param wakeup_cause The wakeup cause in PMU register + */ +static inline void lp_sys_ll_store_wakeup_cause(uint32_t wakeup_cause) +{ + REG_WRITE(RTC_LP_CORE_STORE_WAKEUP_REG, wakeup_cause); +} + +/** + * @brief Get the wakeup cause stored by LP core + * @return The wakeup cause cleared before LP core sleep + */ +static inline uint32_t lp_sys_ll_load_wakeup_cause(void) +{ + return REG_READ(RTC_LP_CORE_STORE_WAKEUP_REG); +} + #ifdef __cplusplus } #endif diff --git a/components/hal/esp32s31/include/hal/lp_aon_hal.h b/components/hal/esp32s31/include/hal/lp_aon_hal.h index e996c5d567..31b61e522d 100644 --- a/components/hal/esp32s31/include/hal/lp_aon_hal.h +++ b/components/hal/esp32s31/include/hal/lp_aon_hal.h @@ -13,6 +13,8 @@ extern "C" { #endif #define lp_aon_hal_inform_wakeup_type(dslp) lp_sys_ll_inform_wakeup_type(dslp) +#define lp_aon_hal_store_wakeup_cause(wakeup_cause) lp_sys_ll_store_wakeup_cause(wakeup_cause) +#define lp_aon_hal_load_wakeup_cause() lp_sys_ll_load_wakeup_cause() #ifdef __cplusplus } diff --git a/components/hal/esp32s31/include/hal/lp_sys_ll.h b/components/hal/esp32s31/include/hal/lp_sys_ll.h index bee101c9e9..3b78f818eb 100644 --- a/components/hal/esp32s31/include/hal/lp_sys_ll.h +++ b/components/hal/esp32s31/include/hal/lp_sys_ll.h @@ -65,6 +65,24 @@ static inline void lp_sys_set_regdma_link_count(int count) HAL_FORCE_MODIFY_U32_REG_FIELD(LP_SYS.backup_dma_cfg1, branch_link_length_aon, count); } +/** + * @brief Set the wakeup cause stored by LP core + * @param wakeup_cause The wakeup cause in PMU register + */ +static inline void lp_sys_ll_store_wakeup_cause(uint32_t wakeup_cause) +{ + REG_WRITE(RTC_LP_CORE_STORE_WAKEUP_REG, wakeup_cause); +} + +/** + * @brief Get the wakeup cause stored by LP core + * @return The wakeup cause cleared before LP core sleep + */ +static inline uint32_t lp_sys_ll_load_wakeup_cause(void) +{ + return REG_READ(RTC_LP_CORE_STORE_WAKEUP_REG); +} + #ifdef __cplusplus } #endif diff --git a/components/soc/esp32c5/include/soc/Kconfig.soc_caps.in b/components/soc/esp32c5/include/soc/Kconfig.soc_caps.in index 06f6153eee..f32b8cb592 100644 --- a/components/soc/esp32c5/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32c5/include/soc/Kconfig.soc_caps.in @@ -1614,3 +1614,7 @@ config SOC_LP_CORE_SUPPORT_STORE_LOAD_EXCEPTIONS config SOC_LP_CORE_SUPPORT_I2C bool default y + +config SOC_LP_CORE_HW_AUTO_CLRWAKEUPCAUSE + bool + default y diff --git a/components/soc/esp32c5/include/soc/soc_caps.h b/components/soc/esp32c5/include/soc/soc_caps.h index 3bd4e6c93a..dfb1e5755c 100644 --- a/components/soc/esp32c5/include/soc/soc_caps.h +++ b/components/soc/esp32c5/include/soc/soc_caps.h @@ -645,3 +645,4 @@ #define SOC_LP_CORE_SUPPORT_ETM (1) /*!< LP Core supports ETM */ #define SOC_LP_CORE_SUPPORT_STORE_LOAD_EXCEPTIONS (1) /*!< LP Core will raise exceptions if accessing invalid addresses */ #define SOC_LP_CORE_SUPPORT_I2C (1) /*!< LP Core supports I2C */ +#define SOC_LP_CORE_HW_AUTO_CLRWAKEUPCAUSE (1) /*!< LP core requests sleep, PMU clears both HP and LP wakeup causes */ diff --git a/components/soc/esp32c6/include/soc/Kconfig.soc_caps.in b/components/soc/esp32c6/include/soc/Kconfig.soc_caps.in index c67adadfb8..b2863279a6 100644 --- a/components/soc/esp32c6/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32c6/include/soc/Kconfig.soc_caps.in @@ -1363,6 +1363,10 @@ config SOC_LP_CORE_SUPPORT_I2C bool default y +config SOC_LP_CORE_HW_AUTO_CLRWAKEUPCAUSE + bool + default y + config SOC_DEBUG_HAVE_OCD_STUB_BINS bool default y diff --git a/components/soc/esp32c6/include/soc/soc_caps.h b/components/soc/esp32c6/include/soc/soc_caps.h index 2ba2685ec0..2f84c538d4 100644 --- a/components/soc/esp32c6/include/soc/soc_caps.h +++ b/components/soc/esp32c6/include/soc/soc_caps.h @@ -554,6 +554,7 @@ #define SOC_LP_CORE_SINGLE_INTERRUPT_VECTOR (1) /*!< LP Core interrupts all map to a single entry in vector table */ #define SOC_LP_CORE_SUPPORT_ETM (1) /*!< LP Core supports ETM */ #define SOC_LP_CORE_SUPPORT_I2C (1) /*!< LP Core supports I2C */ +#define SOC_LP_CORE_HW_AUTO_CLRWAKEUPCAUSE (1) /*!< LP core requests sleep, PMU clears both HP and LP wakeup causes */ /*------------------------------------- DEBUG CAPS -------------------------------------*/ #define SOC_DEBUG_HAVE_OCD_STUB_BINS (1) diff --git a/components/soc/esp32p4/include/soc/Kconfig.soc_caps.in b/components/soc/esp32p4/include/soc/Kconfig.soc_caps.in index 346fb42b51..5cc4fdd166 100644 --- a/components/soc/esp32p4/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32p4/include/soc/Kconfig.soc_caps.in @@ -1922,3 +1922,7 @@ config SOC_LP_CORE_SUPPORT_STORE_LOAD_EXCEPTIONS config SOC_LP_CORE_SUPPORT_I2C bool default y + +config SOC_LP_CORE_HW_AUTO_CLRWAKEUPCAUSE + bool + default y diff --git a/components/soc/esp32p4/include/soc/soc_caps.h b/components/soc/esp32p4/include/soc/soc_caps.h index d2eb31aad4..d90ea26e28 100644 --- a/components/soc/esp32p4/include/soc/soc_caps.h +++ b/components/soc/esp32p4/include/soc/soc_caps.h @@ -736,3 +736,4 @@ #define SOC_LP_CORE_SUPPORT_LP_ADC (1) /*!< LP ADC can be accessed from the LP-Core */ #define SOC_LP_CORE_SUPPORT_STORE_LOAD_EXCEPTIONS (1) /*!< LP Core will raise exceptions if accessing invalid addresses */ #define SOC_LP_CORE_SUPPORT_I2C (1) /*!< LP Core supports I2C */ +#define SOC_LP_CORE_HW_AUTO_CLRWAKEUPCAUSE (1) /*!< LP core requests sleep, PMU clears both HP and LP wakeup causes */ diff --git a/components/soc/esp32s31/include/soc/Kconfig.soc_caps.in b/components/soc/esp32s31/include/soc/Kconfig.soc_caps.in index 00d406c870..b43e50da93 100644 --- a/components/soc/esp32s31/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32s31/include/soc/Kconfig.soc_caps.in @@ -1091,6 +1091,10 @@ config SOC_LP_CORE_CONFIGURABLE_BOOT_ADDR bool default y +config SOC_LP_CORE_HW_AUTO_CLRWAKEUPCAUSE + bool + default y + config SOC_LP_TIMER_BIT_WIDTH_LO int default 32 diff --git a/components/soc/esp32s31/include/soc/soc_caps.h b/components/soc/esp32s31/include/soc/soc_caps.h index 0cd971d731..ed639b11d0 100644 --- a/components/soc/esp32s31/include/soc/soc_caps.h +++ b/components/soc/esp32s31/include/soc/soc_caps.h @@ -457,6 +457,7 @@ #define SOC_LP_CORE_SUPPORT_ETM (1) /*!< LP Core supports ETM wakeup */ #define SOC_LP_CORE_CONFIGURABLE_BOOT_ADDR (1) /*!< LP Core has no LP ROM; HP must write the reset_vector address (LP_RAM_BASE+0x80) to LP_SYS.lp_core_boot_addr before triggering LP wake */ //#define SOC_LP_CORE_SUPPORT_I2C (1) /*!< LP Core supports I2C */ TODO IDF-14635 +#define SOC_LP_CORE_HW_AUTO_CLRWAKEUPCAUSE (1) /*!< LP core requests sleep, PMU clears both HP and LP wakeup causes */ /*-------------------------- LP_TIMER CAPS ----------------------------------*/ #define SOC_LP_TIMER_BIT_WIDTH_LO 32 // Bit width of lp_timer low part diff --git a/components/ulp/lp_core/lp_core.c b/components/ulp/lp_core/lp_core.c index dafd947fe4..52bd762e38 100644 --- a/components/ulp/lp_core/lp_core.c +++ b/components/ulp/lp_core/lp_core.c @@ -30,6 +30,11 @@ extern uint8_t _rtc_ulp_memory_start[]; #endif //ESP_ROM_HAS_LP_ROM +#if SOC_LP_CORE_HW_AUTO_CLRWAKEUPCAUSE +#include "hal/lp_aon_hal.h" +#include "rom/rtc.h" +#endif + const static char* TAG = "ulp-lp-core"; #define WAKEUP_SOURCE_MAX_NUMBER 6 @@ -178,6 +183,19 @@ esp_err_t ulp_lp_core_load_binary(const uint8_t* program_binary, size_t program_ return ESP_OK; } +void ulp_lp_core_sleep_start(void) +{ +#if SOC_LP_CORE_HW_AUTO_CLRWAKEUPCAUSE + /* LP store register to save wakeup cause for HP core to query. + * Using a hardware register avoids symbol linking issues between + * the independently compiled HP and LP core binaries. + * Save PMU wakeup cause to LP store register for HP core to query */ + lp_aon_hal_store_wakeup_cause(pmu_ll_hp_get_wakeup_cause(&PMU)); +#endif + + lp_core_ll_request_sleep(); +} + void ulp_lp_core_stop(void) { if (esp_cpu_dbgr_is_attached()) { @@ -191,7 +209,7 @@ void ulp_lp_core_stop(void) } /* Disable wake-up source and put lp core to sleep */ lp_core_ll_set_wakeup_source(0); - lp_core_ll_request_sleep(); + ulp_lp_core_sleep_start(); } void ulp_lp_core_sw_intr_to_lp_trigger(void) diff --git a/components/ulp/lp_core/lp_core/lp_core_utils.c b/components/ulp/lp_core/lp_core/lp_core_utils.c index ff3fe34c7f..f1739d8e96 100644 --- a/components/ulp/lp_core/lp_core/lp_core_utils.c +++ b/components/ulp/lp_core/lp_core/lp_core_utils.c @@ -25,6 +25,10 @@ #include "esp_cpu.h" #include "ulp_lp_core_cpu_freq_shared.h" +#if SOC_LP_CORE_HW_AUTO_CLRWAKEUPCAUSE +#include "hal/lp_aon_hal.h" +#include "rom/rtc.h" +#endif static uint32_t lp_wakeup_cause = 0; @@ -142,9 +146,22 @@ void ulp_lp_core_lp_uart_reset_wakeup_en(void) } #endif +void ulp_lp_core_sleep_start_lp_core(void) +{ +#if SOC_LP_CORE_HW_AUTO_CLRWAKEUPCAUSE + /* LP store register to save wakeup cause for HP core to query. + * Using a hardware register avoids symbol linking issues between + * the independently compiled HP and LP core binaries. + * Save PMU wakeup cause to LP store register for HP core to query */ + lp_aon_hal_store_wakeup_cause(pmu_ll_hp_get_wakeup_cause(&PMU)); +#endif + + lp_core_ll_request_sleep(); +} + void ulp_lp_core_halt(void) { - lp_core_ll_request_sleep(); + ulp_lp_core_sleep_start_lp_core(); while (1); } @@ -153,7 +170,7 @@ void ulp_lp_core_stop_lp_core(void) { /* Disable wake-up source and put lp core to sleep */ lp_core_ll_set_wakeup_source(0); - lp_core_ll_request_sleep(); + ulp_lp_core_sleep_start_lp_core(); } void __attribute__((noreturn)) abort(void)