From 5ba8b5e3dc62ba7dc01f211f488caffe25b31cd6 Mon Sep 17 00:00:00 2001 From: wuzhenghui Date: Wed, 25 Jun 2025 17:08:18 +0800 Subject: [PATCH] feat(esp_hw_support): add new API to get all wakeup sources --- components/esp_hw_support/include/esp_sleep.h | 38 +++++--- components/esp_hw_support/sleep_modes.c | 91 +++++++++++++++++++ 2 files changed, 116 insertions(+), 13 deletions(-) diff --git a/components/esp_hw_support/include/esp_sleep.h b/components/esp_hw_support/include/esp_sleep.h index 02e7b22ac5..30c34f15f5 100644 --- a/components/esp_hw_support/include/esp_sleep.h +++ b/components/esp_hw_support/include/esp_sleep.h @@ -105,21 +105,23 @@ typedef enum { * @brief Sleep wakeup cause */ typedef enum { - ESP_SLEEP_WAKEUP_UNDEFINED, //!< In case of deep sleep, reset was not caused by exit from deep sleep - ESP_SLEEP_WAKEUP_ALL, //!< Not a wakeup cause, used to disable all wakeup sources with esp_sleep_disable_wakeup_source - ESP_SLEEP_WAKEUP_EXT0, //!< Wakeup caused by external signal using RTC_IO - ESP_SLEEP_WAKEUP_EXT1, //!< Wakeup caused by external signal using RTC_CNTL - ESP_SLEEP_WAKEUP_TIMER, //!< Wakeup caused by timer - 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_UNDEFINED, //!< In case of deep sleep, reset was not caused by exit from deep sleep + ESP_SLEEP_WAKEUP_ALL, //!< Not a wakeup cause, used to disable all wakeup sources with esp_sleep_disable_wakeup_source + ESP_SLEEP_WAKEUP_EXT0, //!< Wakeup caused by external signal using RTC_IO + ESP_SLEEP_WAKEUP_EXT1, //!< Wakeup caused by external signal using RTC_CNTL + ESP_SLEEP_WAKEUP_TIMER, //!< Wakeup caused by timer + 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 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 - ESP_SLEEP_WAKEUP_BT, //!< Wakeup caused by BT (light sleep only) - ESP_SLEEP_WAKEUP_VAD, //!< Wakeup caused by VAD - ESP_SLEEP_WAKEUP_VBAT_UNDER_VOLT, //!< Wakeup caused by VDD_BAT under voltage. + ESP_SLEEP_WAKEUP_BT, //!< Wakeup caused by BT (light sleep only) + ESP_SLEEP_WAKEUP_VAD, //!< Wakeup caused by VAD + ESP_SLEEP_WAKEUP_VBAT_UNDER_VOLT, //!< Wakeup caused by VDD_BAT under voltage. } esp_sleep_source_t; /** @@ -691,10 +693,20 @@ 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); +esp_sleep_wakeup_cause_t esp_sleep_get_wakeup_cause(void) +__attribute__((deprecated("use esp_sleep_get_wakeup_causes instead"))); +/** + * @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 6672e26f42..abbb21890c 100644 --- a/components/esp_hw_support/sleep_modes.c +++ b/components/esp_hw_support/sleep_modes.c @@ -2339,6 +2339,97 @@ 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 SOC_VBAT_SUPPORTED + if (wakeup_cause_raw & RTC_VBAT_UNDER_VOLT_TRIG_EN) { + wakeup_cause |= BIT(ESP_SLEEP_WAKEUP_VBAT_UNDER_VOLT); + } +#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) {