From a0cec6a7ef1e0b6540fe76add4549c98c1b46548 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 | 8 +- components/esp_hw_support/include/esp_sleep.h | 13 ++- components/esp_hw_support/sleep_modes.c | 81 +++++++++++++++++++ 3 files changed, 100 insertions(+), 2 deletions(-) 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 29ff7568f1..13ed455e65 100644 --- a/components/esp_hw_support/include/esp_private/esp_pmu.h +++ b/components/esp_hw_support/include/esp_private/esp_pmu.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2019-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2019-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -66,9 +66,15 @@ extern "C" { #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 4f12a12c7c..73704f8c61 100644 --- a/components/esp_hw_support/include/esp_sleep.h +++ b/components/esp_hw_support/include/esp_sleep.h @@ -110,7 +110,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 @@ -661,10 +663,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 e1561b9a92..8ee198ebee 100644 --- a/components/esp_hw_support/sleep_modes.c +++ b/components/esp_hw_support/sleep_modes.c @@ -2037,6 +2037,87 @@ 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 (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) {