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)
+ ESP_SLEEP_WAKEUP_UART, //!< Wakeup caused by UART (light sleep only)
} esp_sleep_source_t;
/* Leave this type define for compatibility */
*/
esp_err_t esp_sleep_enable_ext1_wakeup(uint64_t mask, esp_sleep_ext1_wakeup_mode_t mode);
+/**
+ * @brief Enable wakeup from light sleep using GPIOs
+ *
+ * Each GPIO supports wakeup function, which can be triggered on either low level
+ * or high level. Unlike EXT0 and EXT1 wakeup sources, this method can be used
+ * both for all IOs: RTC IOs and digital IOs. It can only be used to wakeup from
+ * light sleep though.
+ *
+ * To enable wakeup, first call gpio_wakeup_enable, specifying gpio number and
+ * wakeup level, for each GPIO which is used for wakeup.
+ * Then call this function to enable wakeup feature.
+ *
+ * @note In revisions 0 and 1 of the ESP32, GPIO wakeup source
+ * can not be used together with touch or ULP wakeup sources.
+ *
+ * @return
+ * - ESP_OK on success
+ * - ESP_ERR_INVALID_STATE if wakeup triggers conflict
+ */
+esp_err_t esp_sleep_enable_gpio_wakeup();
+
+/**
+ * @brief Enable wakeup from light sleep using UART
+ *
+ * Use uart_set_wakeup_threshold function to configure UART wakeup threshold.
+ *
+ * Wakeup from light sleep takes some time, so not every character sent
+ * to the UART can be received by the application.
+ *
+ * @note ESP32 does not support wakeup from UART2.
+ *
+ * @param uart_num UART port to wake up from
+ * @return
+ * - ESP_OK on success
+ * - ESP_ERR_INVALID_ARG if wakeup from given UART is not supported
+ */
+esp_err_t esp_sleep_enable_uart_wakeup(int uart_num);
/**
* @brief Get the bit mask of GPIOs which caused wakeup (ext1)
#include "soc/dport_reg.h"
#include "soc/rtc_wdt.h"
#include "driver/rtc_io.h"
+#include "driver/uart.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "sdkconfig.h"
if (CHECK_SOURCE(source, ESP_SLEEP_WAKEUP_TIMER, RTC_TIMER_TRIG_EN)) {
s_config.wakeup_triggers &= ~RTC_TIMER_TRIG_EN;
s_config.sleep_duration = 0;
- }
- else if (CHECK_SOURCE(source, ESP_SLEEP_WAKEUP_EXT0, RTC_EXT0_TRIG_EN)) {
+ } else if (CHECK_SOURCE(source, ESP_SLEEP_WAKEUP_EXT0, RTC_EXT0_TRIG_EN)) {
s_config.ext0_rtc_gpio_num = 0;
s_config.ext0_trigger_level = 0;
s_config.wakeup_triggers &= ~RTC_EXT0_TRIG_EN;
- }
- else if (CHECK_SOURCE(source, ESP_SLEEP_WAKEUP_EXT1, RTC_EXT1_TRIG_EN)) {
+ } else if (CHECK_SOURCE(source, ESP_SLEEP_WAKEUP_EXT1, RTC_EXT1_TRIG_EN)) {
s_config.ext1_rtc_gpio_mask = 0;
s_config.ext1_trigger_mode = 0;
s_config.wakeup_triggers &= ~RTC_EXT1_TRIG_EN;
- }
- else if (CHECK_SOURCE(source, ESP_SLEEP_WAKEUP_TOUCHPAD, RTC_TOUCH_TRIG_EN)) {
+ } else if (CHECK_SOURCE(source, ESP_SLEEP_WAKEUP_TOUCHPAD, RTC_TOUCH_TRIG_EN)) {
s_config.wakeup_triggers &= ~RTC_TOUCH_TRIG_EN;
+ } else if (CHECK_SOURCE(source, ESP_SLEEP_WAKEUP_GPIO, RTC_GPIO_TRIG_EN)) {
+ s_config.wakeup_triggers &= ~RTC_GPIO_TRIG_EN;
+ } else if (CHECK_SOURCE(source, ESP_SLEEP_WAKEUP_UART, (RTC_UART0_TRIG_EN | RTC_UART1_TRIG_EN))) {
+ s_config.wakeup_triggers &= ~(RTC_UART0_TRIG_EN | RTC_UART1_TRIG_EN);
}
#ifdef CONFIG_ULP_COPROC_ENABLED
else if (CHECK_SOURCE(source, ESP_SLEEP_WAKEUP_ULP, RTC_ULP_TRIG_EN)) {
return gpio_mask;
}
+esp_err_t esp_sleep_enable_gpio_wakeup()
+{
+ if (s_config.wakeup_triggers & (RTC_TOUCH_TRIG_EN | RTC_ULP_TRIG_EN)) {
+ ESP_LOGE(TAG, "Conflicting wake-up triggers: touch / ULP");
+ return ESP_ERR_INVALID_STATE;
+ }
+ s_config.wakeup_triggers |= RTC_GPIO_TRIG_EN;
+ return ESP_OK;
+}
+
+esp_err_t esp_sleep_enable_uart_wakeup(int uart_num)
+{
+ if (uart_num == UART_NUM_0) {
+ s_config.wakeup_triggers |= RTC_UART0_TRIG_EN;
+ } else if (uart_num == UART_NUM_1) {
+ s_config.wakeup_triggers |= RTC_UART1_TRIG_EN;
+ } else {
+ return ESP_ERR_INVALID_ARG;
+ }
+
+ return ESP_OK;
+}
+
esp_sleep_wakeup_cause_t esp_sleep_get_wakeup_cause()
{
if (rtc_get_reset_reason(0) != DEEPSLEEP_RESET) {
return ESP_SLEEP_WAKEUP_TOUCHPAD;
} else if (wakeup_cause & RTC_ULP_TRIG_EN) {
return ESP_SLEEP_WAKEUP_ULP;
+ } else if (wakeup_cause & RTC_GPIO_TRIG_EN) {
+ return ESP_SLEEP_WAKEUP_GPIO;
+ } else if (wakeup_cause & (RTC_UART0_TRIG_EN | RTC_UART1_TRIG_EN)) {
+ return ESP_SLEEP_WAKEUP_UART;
} else {
return ESP_SLEEP_WAKEUP_UNDEFINED;
}
s_config.pd_options[ESP_PD_DOMAIN_RTC_FAST_MEM] = ESP_PD_OPTION_ON;
}
- // RTC_PERIPH is needed for EXT0 wakeup.
- // If RTC_PERIPH is auto, and EXT0 isn't enabled, power down RTC_PERIPH.
+ // RTC_PERIPH is needed for EXT0 wakeup and GPIO wakeup.
+ // If RTC_PERIPH is auto, and EXT0/GPIO aren't enabled, power down RTC_PERIPH.
if (s_config.pd_options[ESP_PD_DOMAIN_RTC_PERIPH] == ESP_PD_OPTION_AUTO) {
- if (s_config.wakeup_triggers & RTC_EXT0_TRIG_EN) {
+ if (s_config.wakeup_triggers & (RTC_EXT0_TRIG_EN | RTC_GPIO_TRIG_EN)) {
s_config.pd_options[ESP_PD_DOMAIN_RTC_PERIPH] = ESP_PD_OPTION_ON;
} else if (s_config.wakeup_triggers & (RTC_TOUCH_TRIG_EN | RTC_ULP_TRIG_EN)) {
// In both rev. 0 and rev. 1 of ESP32, forcing power up of RTC_PERIPH