deep sleep: clarify compatibility issues between wakeup sources

ULP and touch FSMs in ESP32 revisions 0 and 1 do not operate correctly
if RTC_PERIPH power domain is force powered on (ESP_PD_OPTION_ON).

Both ULP and touch still work, but clock frequency of the ULP may be
incorrect and touch values may be off by considerable amount. As such,
when these wakeup modes are used, RTC_PERIPH power domain has to be set
to ESP_PD_OPTION_AUTO (or, in the current implementation,
ESP_PD_OPTION_OFF — though this will change in the future when _OFF will
actually *force* the power domain to be powered off).

Because EXT0 wakeup source requires RTC_PERIPH to be powered ON, mark
ULP and touch wakeup sources as incompatible with EXT0. Workaround for
this is to use EXT1 wakeup source instead, which offers similar or
better functions without having to keep RTC_PERIPH powered on.
This commit is contained in:
Ivan Grokhotkov 2017-01-27 23:36:52 +08:00
parent 611e510c49
commit 07ff47f103
3 changed files with 34 additions and 21 deletions

View file

@ -163,8 +163,8 @@ void system_deep_sleep(uint64_t) __attribute__((alias("esp_deep_sleep")));
esp_err_t esp_deep_sleep_enable_ulp_wakeup()
{
#ifdef CONFIG_ULP_COPROC_ENABLED
if(s_config.wakeup_triggers & RTC_TOUCH_TRIG_EN) {
ESP_LOGE(TAG, "Conflict wake-up triggers: touch");
if(s_config.wakeup_triggers & RTC_EXT_EVENT0_TRIG_EN) {
ESP_LOGE(TAG, "Conflicting wake-up trigger: ext0");
return ESP_ERR_INVALID_STATE;
}
s_config.wakeup_triggers |= RTC_SAR_TRIG_EN;
@ -183,8 +183,8 @@ esp_err_t esp_deep_sleep_enable_timer_wakeup(uint64_t time_in_us)
esp_err_t esp_deep_sleep_enable_touchpad_wakeup()
{
if (s_config.wakeup_triggers & (RTC_SAR_TRIG_EN | RTC_EXT_EVENT0_TRIG_EN)) {
ESP_LOGE(TAG, "Conflict wake-up triggers: ulp/ext0");
if (s_config.wakeup_triggers & (RTC_EXT_EVENT0_TRIG_EN)) {
ESP_LOGE(TAG, "Conflicting wake-up trigger: ext0");
return ESP_ERR_INVALID_STATE;
}
s_config.wakeup_triggers |= RTC_TOUCH_TRIG_EN;
@ -199,8 +199,8 @@ esp_err_t esp_deep_sleep_enable_ext0_wakeup(gpio_num_t gpio_num, int level)
if (!RTC_GPIO_IS_VALID_GPIO(gpio_num)) {
return ESP_ERR_INVALID_ARG;
}
if (s_config.wakeup_triggers & RTC_TOUCH_TRIG_EN) {
ESP_LOGE(TAG, "Conflict wake-up triggers: touch");
if (s_config.wakeup_triggers & (RTC_TOUCH_TRIG_EN | RTC_SAR_TRIG_EN)) {
ESP_LOGE(TAG, "Conflicting wake-up triggers: touch / ULP");
return ESP_ERR_INVALID_STATE;
}
s_config.ext0_rtc_gpio_num = rtc_gpio_desc[gpio_num].rtc_num;
@ -351,15 +351,14 @@ static uint32_t get_power_down_flags()
s_config.pd_options[ESP_PD_DOMAIN_RTC_FAST_MEM] = ESP_PD_OPTION_ON;
}
// RTC_PERIPH is needed for EXT0 wakeup and for ULP.
// If RTC_PERIPH is auto, and both EXT0 and ULP aren't enabled,
// power down RTC_PERIPH.
// RTC_PERIPH is needed for EXT0 wakeup.
// If RTC_PERIPH is auto, and EXT0 isn'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_SAR_TRIG_EN | RTC_EXT_EVENT0_TRIG_EN)) {
if (s_config.wakeup_triggers & RTC_EXT_EVENT0_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) {
// We have to set power down PERIPH so as to enable wake-up from touch sensor.
} else if (s_config.wakeup_triggers & (RTC_TOUCH_TRIG_EN | RTC_SAR_TRIG_EN)) {
// In both rev. 0 and rev. 1 of ESP32, forcing power up of RTC_PERIPH
// prevents ULP timer and touch FSMs from working correctly.
s_config.pd_options[ESP_PD_DOMAIN_RTC_PERIPH] = ESP_PD_OPTION_OFF;
}
}

View file

@ -53,7 +53,10 @@ typedef enum {
/**
* @brief Enable wakeup by ULP coprocessor
* @note ulp wakeup conflicts with touch wakeup.
* @note In revisions 0 and 1 of the ESP32, ULP wakeup source
* can not be used when RTC_PERIPH power domain is forced
* to be powered on (ESP_PD_OPTION_ON) or when ext0 wakeup
* source is used.
* @return
* - ESP_OK on success
* - ESP_ERR_INVALID_STATE if ULP co-processor is not enabled or if wakeup triggers conflict
@ -71,7 +74,12 @@ esp_err_t esp_deep_sleep_enable_timer_wakeup(uint64_t time_in_us);
/**
* @brief Enable wakeup by touch sensor
* @note Can not set touch wake-up if ulp or ext0 wake-up is enabled.
*
* @note In revisions 0 and 1 of the ESP32, touch wakeup source
* can not be used when RTC_PERIPH power domain is forced
* to be powered on (ESP_PD_OPTION_ON) or when ext0 wakeup
* source is used.
*
* @return
* - ESP_OK on success
* - ESP_ERR_INVALID_STATE if wakeup triggers conflict
@ -90,7 +98,9 @@ esp_err_t esp_deep_sleep_enable_touchpad_wakeup();
* @note This function does not modify pin configuration. The pin is
* configured in esp_deep_sleep_start, immediately before
* entering deep sleep.
* @note This ext0 wakeup conflicts with touch wakeup.
*
* @note In revisions 0 and 1 of the ESP32, ext0 wakeup source
* can not be used together with touch or ULP wakeup sources.
*
* @param gpio_num GPIO number used as wakeup source. Only GPIOs which are have RTC
* functionality can be used: 0,2,4,12-15,25-27,32-39.

View file

@ -31,7 +31,7 @@ Touch pad
RTC IO module contains logic to trigger wakeup when a touch sensor interrupt occurs. You need to configure the touch pad interrupt before the chip starts deep sleep.
Note that, for now, this wakeup requires RTC peripherals to be powered off during deep sleep.
Revisions 0 and 1 of the ESP32 only support this wakeup mode when RTC peripherals are not forced to be powered on (i.e. ESP_PD_DOMAIN_RTC_PERIPH should be set to ESP_PD_OPTION_AUTO).
.. doxygenfunction:: esp_deep_sleep_enable_touchpad_wakeup
@ -43,6 +43,8 @@ RTC IO module contains logic to trigger wakeup when one of RTC GPIOs is set to a
Because RTC IO module is enabled in this mode, internal pullup or pulldown resistors can also be used. They need to be configured by the application using ``rtc_gpio_pullup_en`` and ``rtc_gpio_pulldown_en`` functions, before calling ``esp_deep_sleep_start``.
In revisions 0 and 1 of the ESP32, this wakeup source is incompatible with ULP and touch wakeup sources.
.. doxygenfunction:: esp_deep_sleep_enable_ext0_wakeup
External wakeup (ext1)
@ -50,8 +52,8 @@ External wakeup (ext1)
RTC controller contains logic to trigger wakeup using multiple RTC GPIOs. One of the two logic functions can be used to trigger wakeup:
- wake up if any of the selected pins is low
- wake up if all the selected pins are high
- wake up if any of the selected pins is high (``ESP_EXT1_WAKEUP_ANY_HIGH``)
- wake up if all the selected pins are low (``ESP_EXT1_WAKEUP_ALL_LOW``)
This wakeup source is implemented by the RTC controller. As such, RTC peripherals and RTC memories can be powered off in this mode. However, if RTC peripherals are powered down, internal pullup and pulldown resistors will be disabled. To use internal pullup or pulldown resistors, request RTC peripherals power domain to be kept on during deep sleep, and configure pullup/pulldown resistors using ``rtc_gpio_`` functions, before entering deep sleep::
@ -69,7 +71,9 @@ The following function can be used to enable this wakeup mode:
ULP coprocessor wakeup
^^^^^^^^^^^^^^^^^^^^^^
ULP coprocessor can run while the chip is in deep sleep, and may be used to poll sensors, monitor ADC or touch sensor values, and wake up the chip when a specific event is detected. ULP coprocessor is part of RTC peripherals power domain, and it runs the program stored in RTC slow memeory. Therefore RTC peripherals and RTC slow memory will be powered on during deep sleep if this wakeup mode is requested.
ULP coprocessor can run while the chip is in deep sleep, and may be used to poll sensors, monitor ADC or touch sensor values, and wake up the chip when a specific event is detected. ULP coprocessor is part of RTC peripherals power domain, and it runs the program stored in RTC slow memeory. RTC slow memory will be powered on during deep sleep if this wakeup mode is requested. RTC peripherals will be automatically powered on before ULP coprocessor starts running the program; once the program stops running, RTC peripherals are automatically powered down again.
Revisions 0 and 1 of the ESP32 only support this wakeup mode when RTC peripherals are not forced to be powered on (i.e. ESP_PD_DOMAIN_RTC_PERIPH should be set to ESP_PD_OPTION_AUTO).
The following function can be used to enable this wakeup mode:
@ -80,7 +84,7 @@ Power-down of RTC peripherals and memories
By default, ``esp_deep_sleep_start`` function will power down all RTC power domains which are not needed by the enabled wakeup sources. To override this behaviour, the following function is provided:
Note: on the first revision of the ESP32, RTC fast memory will always be kept enabled in deep sleep, so that the deep sleep stub can run after reset. This can be overriden, if the application doesn't need clean reset behaviour after deep sleep.
Note: in revision 0 of the ESP32, RTC fast memory will always be kept enabled in deep sleep, so that the deep sleep stub can run after reset. This can be overriden, if the application doesn't need clean reset behaviour after deep sleep.
If some variables in the program are placed into RTC slow memory (for example, using ``RTC_DATA_ATTR`` attribute), RTC slow memory will be kept powered on by default. This can be overriden using ``esp_deep_sleep_pd_config`` function, if desired.