Deep Sleep¶
Overview¶
ESP32 is capable of deep sleep power saving mode. In this mode CPUs, most of the RAM, and all the digital peripherals which are clocked from APB_CLK are powered off. The only parts of the chip which can still be powered on are: RTC controller, RTC peripherals (including ULP coprocessor), and RTC memories (slow and fast).
Wakeup from deep sleep mode can be done using several sources. These sources can be combined, in this case the chip will wake up when any one of the sources is triggered. Wakeup sources can be enabled using esp_deep_sleep_enable_X_wakeup
APIs. Next section describes these APIs in detail. Wakeup sources can be configured at any moment before entering deep sleep mode.
Additionally, the application can force specific powerdown modes for the RTC peripherals and RTC memories using esp_deep_sleep_pd_config
API.
Once wakeup sources are configured, application can start deep sleep using esp_deep_sleep_start
API. At this point the hardware will be configured according to the requested wakeup sources, and RTC controller will power down the CPUs and digital peripherals.
Wakeup sources¶
Timer¶
RTC controller has a built in timer which can be used to wake up the chip after a predefined amount of time. Time is specified at microsecond precision, but the actual resolution depends on the clock source selected for RTC SLOW_CLK. See chapter “Reset and Clock” of the ESP32 Technical Reference Manual for details about RTC clock options.
This wakeup mode doesn’t require RTC peripherals or RTC memories to be powered on during deep sleep.
The following function can be used to enable deep sleep wakeup using a timer.
-
esp_err_t
esp_deep_sleep_enable_timer_wakeup
(uint64_t time_in_us)¶ Enable wakeup by timer.
- Return
- ESP_OK on success
- ESP_ERR_INVALID_ARG if value is out of range (TBD)
- Parameters
time_in_us
: time before wakeup, in microseconds
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.
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).
-
esp_err_t
esp_deep_sleep_enable_touchpad_wakeup
()¶ Enable wakeup by touch sensor.
- 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
External wakeup (ext0)¶
RTC IO module contains logic to trigger wakeup when one of RTC GPIOs is set to a predefined logic level. RTC IO is part of RTC peripherals power domain, so RTC peripherals will be kept powered on during deep sleep if this wakeup source is requested.
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.
Warning
After wake up from deep sleep, IO pad used for wakeup will be configured as RTC IO. Before using this pad as digital GPIO, reconfigure it using rtc_gpio_deinit(gpio_num)
function.
-
esp_err_t
esp_deep_sleep_enable_ext0_wakeup
(gpio_num_t gpio_num, int level)¶ Enable wakeup using a pin.
This function uses external wakeup feature of RTC_IO peripheral. It will work only if RTC peripherals are kept on during deep sleep.
This feature can monitor any pin which is an RTC IO. Once the pin transitions into the state given by level argument, the chip will be woken up.
- Note
- This function does not modify pin configuration. The pin is configured in esp_deep_sleep_start, immediately before entering deep sleep.
- Note
- In revisions 0 and 1 of the ESP32, ext0 wakeup source can not be used together with touch or ULP wakeup sources.
- Return
- ESP_OK on success
- ESP_ERR_INVALID_ARG if the selected GPIO is not an RTC GPIO, or the mode is invalid
- ESP_ERR_INVALID_STATE if wakeup triggers conflict
- Parameters
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.level
: input level which will trigger wakeup (0=low, 1=high)
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 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:
esp_deep_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_ON);
gpio_pullup_dis(gpio_num);
gpio_pulldown_en(gpio_num);
Warning
After wake up from deep sleep, IO pad(s) used for wakeup will be configured as RTC IO. Before using these pads as digital GPIOs, reconfigure them using rtc_gpio_deinit(gpio_num)
function.
The following function can be used to enable this wakeup mode:
-
esp_err_t
esp_deep_sleep_enable_ext1_wakeup
(uint64_t mask, esp_ext1_wakeup_mode_t mode)¶ Enable wakeup using multiple pins.
This function uses external wakeup feature of RTC controller. It will work even if RTC peripherals are shut down during deep sleep.
This feature can monitor any number of pins which are in RTC IOs. Once any of the selected pins goes into the state given by mode argument, the chip will be woken up.
- Note
- This function does not modify pin configuration. The pins are configured in esp_deep_sleep_start, immediately before entering deep sleep.
- Note
- internal pullups and pulldowns don’t work when RTC peripherals are shut down. In this case, external resistors need to be added. Alternatively, RTC peripherals (and pullups/pulldowns) may be kept enabled using esp_deep_sleep_pd_config function.
- Return
- ESP_OK on success
- ESP_ERR_INVALID_ARG if any of the selected GPIOs is not an RTC GPIO, or mode is invalid
- Parameters
mask
: bit mask of GPIO numbers which will cause wakeup. Only GPIOs which are have RTC functionality can be used in this bit map: 0,2,4,12-15,25-27,32-39.mode
: select logic function used to determine wakeup condition:- ESP_EXT1_WAKEUP_ALL_LOW: wake up when all selected GPIOs are low
- ESP_EXT1_WAKEUP_ANY_HIGH: wake up when any of the selected GPIOs is high
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. 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:
-
esp_err_t
esp_deep_sleep_enable_ulp_wakeup
()¶ Enable wakeup by ULP coprocessor.
- 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
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: 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.
-
esp_err_t
esp_deep_sleep_pd_config
(esp_deep_sleep_pd_domain_t domain, esp_deep_sleep_pd_option_t option)¶ Set power down mode for an RTC power domain in deep sleep.
If not set set using this API, all power domains default to ESP_PD_OPTION_AUTO.
- Return
- ESP_OK on success
- ESP_ERR_INVALID_ARG if either of the arguments is out of range
- Parameters
domain
: power domain to configureoption
: power down option (ESP_PD_OPTION_OFF, ESP_PD_OPTION_ON, or ESP_PD_OPTION_AUTO)
-
enum
esp_deep_sleep_pd_domain_t
¶ Power domains which can be powered down in deep sleep.
Values:
-
ESP_PD_DOMAIN_RTC_PERIPH
¶ RTC IO, sensors and ULP co-processor.
-
ESP_PD_DOMAIN_RTC_SLOW_MEM
¶ RTC slow memory.
-
ESP_PD_DOMAIN_RTC_FAST_MEM
¶ RTC fast memory.
-
ESP_PD_DOMAIN_MAX
¶ Number of domains.
-
-
enum
esp_deep_sleep_pd_option_t
¶ Power down options.
Values:
-
ESP_PD_OPTION_OFF
¶ Power down the power domain in deep sleep.
-
ESP_PD_OPTION_ON
¶ Keep power domain enabled during deep sleep.
-
ESP_PD_OPTION_AUTO
¶ Keep power domain enabled in deep sleep, if it is needed by one of the wakeup options. Otherwise power it down.
-
Entering deep sleep¶
The following function can be used to enter deep sleep once wakeup sources are configured. It is also possible to go into deep sleep with no wakeup sources configured, in this case the chip will be in deep sleep mode indefinetly, until external reset is applied.
-
void
esp_deep_sleep_start
()¶ Enter deep sleep with the configured wakeup options.
This function does not return.
Checking deep sleep wakeup cause¶
The following function can be used to check which wakeup source has triggered wakeup from deep sleep mode. For touch pad and ext1 wakeup sources, it is possible to identify pin or touch pad which has caused wakeup.
-
esp_deep_sleep_wakeup_cause_t
esp_deep_sleep_get_wakeup_cause
()¶ Get the source which caused deep sleep wakeup.
- Return
- wakeup cause, or ESP_DEEP_SLEEP_WAKEUP_UNDEFINED if reset reason is other than deep sleep reset.
-
enum
esp_deep_sleep_wakeup_cause_t
¶ Deep sleep wakeup cause.
Values:
-
ESP_DEEP_SLEEP_WAKEUP_UNDEFINED
¶
-
ESP_DEEP_SLEEP_WAKEUP_EXT0
¶ Wakeup was not caused by deep sleep.
-
ESP_DEEP_SLEEP_WAKEUP_EXT1
¶ Wakeup caused by external signal using RTC_IO.
-
ESP_DEEP_SLEEP_WAKEUP_TIMER
¶ Wakeup caused by external signal using RTC_CNTL.
-
ESP_DEEP_SLEEP_WAKEUP_TOUCHPAD
¶ Wakeup caused by timer.
-
ESP_DEEP_SLEEP_WAKEUP_ULP
¶ Wakeup caused by touchpad.
-
-
touch_pad_t
esp_deep_sleep_get_touchpad_wakeup_status
()¶ Get the touch pad which caused wakeup.
If wakeup was caused by another source, this function will return TOUCH_PAD_MAX;
- Return
- touch pad which caused wakeup
-
uint64_t
esp_deep_sleep_get_ext1_wakeup_status
()¶ Get the bit mask of GPIOs which caused wakeup (ext1)
If wakeup was caused by another source, this function will return 0.
- Return
- bit mask, if GPIOn caused wakeup, BIT(n) will be set
Application Example¶
Implementation of basic functionality of deep sleep is shown in protocols/sntp example, where ESP module is periodically waken up to retrive time from NTP server.
More extensive example in system/deep_sleep illustrates usage of various deep sleep wakeup triggers and ULP coprocessor programming.