sleep: add support for GPIO and UART wakeup from light sleep
This commit is contained in:
parent
002d913ab6
commit
75629b7fc3
2 changed files with 77 additions and 9 deletions
|
@ -61,6 +61,8 @@ typedef enum {
|
||||||
ESP_SLEEP_WAKEUP_TIMER, //!< Wakeup caused by timer
|
ESP_SLEEP_WAKEUP_TIMER, //!< Wakeup caused by timer
|
||||||
ESP_SLEEP_WAKEUP_TOUCHPAD, //!< Wakeup caused by touchpad
|
ESP_SLEEP_WAKEUP_TOUCHPAD, //!< Wakeup caused by touchpad
|
||||||
ESP_SLEEP_WAKEUP_ULP, //!< Wakeup caused by ULP program
|
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;
|
} esp_sleep_source_t;
|
||||||
|
|
||||||
/* Leave this type define for compatibility */
|
/* Leave this type define for compatibility */
|
||||||
|
@ -189,6 +191,43 @@ esp_err_t esp_sleep_enable_ext0_wakeup(gpio_num_t gpio_num, int level);
|
||||||
*/
|
*/
|
||||||
esp_err_t esp_sleep_enable_ext1_wakeup(uint64_t mask, esp_sleep_ext1_wakeup_mode_t mode);
|
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)
|
* @brief Get the bit mask of GPIOs which caused wakeup (ext1)
|
||||||
|
|
|
@ -34,6 +34,7 @@
|
||||||
#include "soc/dport_reg.h"
|
#include "soc/dport_reg.h"
|
||||||
#include "soc/rtc_wdt.h"
|
#include "soc/rtc_wdt.h"
|
||||||
#include "driver/rtc_io.h"
|
#include "driver/rtc_io.h"
|
||||||
|
#include "driver/uart.h"
|
||||||
#include "freertos/FreeRTOS.h"
|
#include "freertos/FreeRTOS.h"
|
||||||
#include "freertos/task.h"
|
#include "freertos/task.h"
|
||||||
#include "sdkconfig.h"
|
#include "sdkconfig.h"
|
||||||
|
@ -363,19 +364,20 @@ esp_err_t esp_sleep_disable_wakeup_source(esp_sleep_source_t source)
|
||||||
if (CHECK_SOURCE(source, ESP_SLEEP_WAKEUP_TIMER, RTC_TIMER_TRIG_EN)) {
|
if (CHECK_SOURCE(source, ESP_SLEEP_WAKEUP_TIMER, RTC_TIMER_TRIG_EN)) {
|
||||||
s_config.wakeup_triggers &= ~RTC_TIMER_TRIG_EN;
|
s_config.wakeup_triggers &= ~RTC_TIMER_TRIG_EN;
|
||||||
s_config.sleep_duration = 0;
|
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_rtc_gpio_num = 0;
|
||||||
s_config.ext0_trigger_level = 0;
|
s_config.ext0_trigger_level = 0;
|
||||||
s_config.wakeup_triggers &= ~RTC_EXT0_TRIG_EN;
|
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_rtc_gpio_mask = 0;
|
||||||
s_config.ext1_trigger_mode = 0;
|
s_config.ext1_trigger_mode = 0;
|
||||||
s_config.wakeup_triggers &= ~RTC_EXT1_TRIG_EN;
|
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;
|
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
|
#ifdef CONFIG_ULP_COPROC_ENABLED
|
||||||
else if (CHECK_SOURCE(source, ESP_SLEEP_WAKEUP_ULP, RTC_ULP_TRIG_EN)) {
|
else if (CHECK_SOURCE(source, ESP_SLEEP_WAKEUP_ULP, RTC_ULP_TRIG_EN)) {
|
||||||
|
@ -561,6 +563,29 @@ uint64_t esp_sleep_get_ext1_wakeup_status()
|
||||||
return gpio_mask;
|
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()
|
esp_sleep_wakeup_cause_t esp_sleep_get_wakeup_cause()
|
||||||
{
|
{
|
||||||
if (rtc_get_reset_reason(0) != DEEPSLEEP_RESET) {
|
if (rtc_get_reset_reason(0) != DEEPSLEEP_RESET) {
|
||||||
|
@ -578,6 +603,10 @@ esp_sleep_wakeup_cause_t esp_sleep_get_wakeup_cause()
|
||||||
return ESP_SLEEP_WAKEUP_TOUCHPAD;
|
return ESP_SLEEP_WAKEUP_TOUCHPAD;
|
||||||
} else if (wakeup_cause & RTC_ULP_TRIG_EN) {
|
} else if (wakeup_cause & RTC_ULP_TRIG_EN) {
|
||||||
return ESP_SLEEP_WAKEUP_ULP;
|
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 {
|
} else {
|
||||||
return ESP_SLEEP_WAKEUP_UNDEFINED;
|
return ESP_SLEEP_WAKEUP_UNDEFINED;
|
||||||
}
|
}
|
||||||
|
@ -620,10 +649,10 @@ static uint32_t get_power_down_flags()
|
||||||
s_config.pd_options[ESP_PD_DOMAIN_RTC_FAST_MEM] = ESP_PD_OPTION_ON;
|
s_config.pd_options[ESP_PD_DOMAIN_RTC_FAST_MEM] = ESP_PD_OPTION_ON;
|
||||||
}
|
}
|
||||||
|
|
||||||
// RTC_PERIPH is needed for EXT0 wakeup.
|
// RTC_PERIPH is needed for EXT0 wakeup and GPIO wakeup.
|
||||||
// If RTC_PERIPH is auto, and EXT0 isn't enabled, power down RTC_PERIPH.
|
// 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.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;
|
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)) {
|
} 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
|
// In both rev. 0 and rev. 1 of ESP32, forcing power up of RTC_PERIPH
|
||||||
|
|
Loading…
Reference in a new issue