From 7635a54b1ed73c110e2096de3300b2d76e36562d Mon Sep 17 00:00:00 2001 From: wuzhenghui Date: Tue, 26 Aug 2025 10:37:51 +0800 Subject: [PATCH] feat(esp_hw_support): add new API to get all wakeup sources --- .../include/esp_private/esp_pmu.h | 6 ++ components/esp_hw_support/include/esp_sleep.h | 13 ++- components/esp_hw_support/sleep_modes.c | 86 +++++++++++++++++++ 3 files changed, 104 insertions(+), 1 deletion(-) 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 8284ca5f75..91b414a129 100644 --- a/components/esp_hw_support/include/esp_private/esp_pmu.h +++ b/components/esp_hw_support/include/esp_private/esp_pmu.h @@ -86,9 +86,15 @@ typedef enum { #if SOC_UART_SUPPORT_WAKEUP_INT #define RTC_UART0_TRIG_EN PMU_UART0_WAKEUP_EN //!< UART0 wakeup (light sleep only) #define RTC_UART1_TRIG_EN PMU_UART1_WAKEUP_EN //!< UART1 wakeup (light sleep only) +#if SOC_UART_HP_NUM > 2 +#define RTC_UART2_TRIG_EN PMU_UART2_WAKEUP_EN //!< UART2 wakeup (light sleep only) +#else +#define RTC_UART2_TRIG_EN 0 +#endif #else #define RTC_UART0_TRIG_EN 0 #define RTC_UART1_TRIG_EN 0 +#define RTC_UART2_TRIG_EN 0 #endif #if SOC_BT_SUPPORTED diff --git a/components/esp_hw_support/include/esp_sleep.h b/components/esp_hw_support/include/esp_sleep.h index 8f8f1a6a67..dee094ef7f 100644 --- a/components/esp_hw_support/include/esp_sleep.h +++ b/components/esp_hw_support/include/esp_sleep.h @@ -113,7 +113,9 @@ typedef enum { ESP_SLEEP_WAKEUP_TOUCHPAD, //!< Wakeup caused by touchpad ESP_SLEEP_WAKEUP_ULP, //!< Wakeup caused by ULP program ESP_SLEEP_WAKEUP_GPIO, //!< Wakeup caused by GPIO (light sleep only on ESP32, S2 and S3) - ESP_SLEEP_WAKEUP_UART, //!< Wakeup caused by UART (light sleep only) + ESP_SLEEP_WAKEUP_UART, //!< Wakeup caused by UART0 (light sleep only) + ESP_SLEEP_WAKEUP_UART1, //!< Wakeup caused by UART1 (light sleep only) + ESP_SLEEP_WAKEUP_UART2, //!< Wakeup caused by UART2 (light sleep only) ESP_SLEEP_WAKEUP_WIFI, //!< Wakeup caused by WIFI (light sleep only) ESP_SLEEP_WAKEUP_COCPU, //!< Wakeup caused by COCPU int ESP_SLEEP_WAKEUP_COCPU_TRAP_TRIG, //!< Wakeup caused by COCPU crash @@ -678,10 +680,19 @@ void esp_deep_sleep_deregister_hook(esp_deep_sleep_cb_t old_dslp_cb); /** * @brief Get the wakeup source which caused wakeup from sleep * + * @note !!! This API will only return one wakeup source. If multiple wakeup sources + * wake up at the same time, the wakeup source information may be lost. + * * @return cause of wake up from last sleep (deep sleep or light sleep) */ esp_sleep_wakeup_cause_t esp_sleep_get_wakeup_cause(void); +/** + * @brief Get all wakeup sources bitmap which caused wakeup from sleep. + * + * @return The bitmap of the wakeup sources of the last wakeup from sleep. (deep sleep or light sleep) + */ +uint32_t esp_sleep_get_wakeup_causes(void); /** * @brief Default stub to run on wake from deep sleep. diff --git a/components/esp_hw_support/sleep_modes.c b/components/esp_hw_support/sleep_modes.c index f793a314a0..84df7619aa 100644 --- a/components/esp_hw_support/sleep_modes.c +++ b/components/esp_hw_support/sleep_modes.c @@ -2245,6 +2245,92 @@ esp_sleep_wakeup_cause_t esp_sleep_get_wakeup_cause(void) } } +uint32_t esp_sleep_get_wakeup_causes(void) +{ + uint32_t wakeup_cause = 0; + + if (esp_rom_get_reset_reason(0) != RESET_REASON_CORE_DEEP_SLEEP && !s_light_sleep_wakeup) { + wakeup_cause |= BIT(ESP_SLEEP_WAKEUP_UNDEFINED); + return wakeup_cause; + } + +#if SOC_PMU_SUPPORTED + uint32_t wakeup_cause_raw = pmu_ll_hp_get_wakeup_cause(&PMU); +#else + uint32_t wakeup_cause_raw = rtc_cntl_ll_get_wakeup_cause(); +#endif + + if (wakeup_cause_raw & RTC_TIMER_TRIG_EN) { + wakeup_cause |= BIT(ESP_SLEEP_WAKEUP_TIMER); + } + if (wakeup_cause_raw & RTC_GPIO_TRIG_EN) { + wakeup_cause |= BIT(ESP_SLEEP_WAKEUP_GPIO); + } + if (wakeup_cause_raw & RTC_UART0_TRIG_EN) { + wakeup_cause |= BIT(ESP_SLEEP_WAKEUP_UART); + } + if (wakeup_cause_raw & RTC_UART1_TRIG_EN) { + wakeup_cause |= BIT(ESP_SLEEP_WAKEUP_UART1); + } +#if SOC_PMU_SUPPORTED && (SOC_UART_HP_NUM > 2) + if (wakeup_cause_raw & RTC_UART2_TRIG_EN) { + wakeup_cause |= BIT(ESP_SLEEP_WAKEUP_UART2); + } +#endif +#if SOC_PM_SUPPORT_EXT0_WAKEUP + if (wakeup_cause_raw & RTC_EXT0_TRIG_EN) { + wakeup_cause |= BIT(ESP_SLEEP_WAKEUP_EXT0); + } +#endif +#if SOC_PM_SUPPORT_EXT1_WAKEUP + if (wakeup_cause_raw & RTC_EXT1_TRIG_EN) { + wakeup_cause |= BIT(ESP_SLEEP_WAKEUP_EXT1); + } +#endif +#if SOC_PM_SUPPORT_TOUCH_SENSOR_WAKEUP + if (wakeup_cause_raw & RTC_TOUCH_TRIG_EN) { + wakeup_cause |= BIT(ESP_SLEEP_WAKEUP_TOUCHPAD); + } +#endif +#if SOC_ULP_FSM_SUPPORTED + if (wakeup_cause_raw & RTC_ULP_TRIG_EN) { + wakeup_cause |= BIT(ESP_SLEEP_WAKEUP_ULP); + } +#endif +#if SOC_PM_SUPPORT_WIFI_WAKEUP + if (wakeup_cause_raw & RTC_WIFI_TRIG_EN) { + wakeup_cause |= BIT(ESP_SLEEP_WAKEUP_WIFI); + } +#endif +#if SOC_PM_SUPPORT_BT_WAKEUP + if (wakeup_cause_raw & RTC_BT_TRIG_EN) { + wakeup_cause |= BIT(ESP_SLEEP_WAKEUP_BT); + } +#endif +#if SOC_RISCV_COPROC_SUPPORTED + if (wakeup_cause_raw & RTC_COCPU_TRIG_EN) { + wakeup_cause |= BIT(ESP_SLEEP_WAKEUP_ULP); + } + if (wakeup_cause_raw & RTC_COCPU_TRAP_TRIG_EN) { + wakeup_cause |= BIT(ESP_SLEEP_WAKEUP_COCPU_TRAP_TRIG); + } +#endif +#if SOC_LP_CORE_SUPPORTED + if (wakeup_cause_raw & RTC_LP_CORE_TRIG_EN) { + wakeup_cause |= BIT(ESP_SLEEP_WAKEUP_ULP); + } +#endif +#if SOC_LP_VAD_SUPPORTED + if (wakeup_cause_raw & RTC_LP_VAD_TRIG_EN) { + wakeup_cause |= BIT(ESP_SLEEP_WAKEUP_VAD); + } +#endif + if (wakeup_cause == 0) { + wakeup_cause |= BIT(ESP_SLEEP_WAKEUP_UNDEFINED); + } + return wakeup_cause; +} + esp_err_t esp_sleep_pd_config(esp_sleep_pd_domain_t domain, esp_sleep_pd_option_t option) { if (domain >= ESP_PD_DOMAIN_MAX || option > ESP_PD_OPTION_AUTO) {