Sleep Modes¶
Overview¶
ESP32 is capable of light sleep and deep sleep power saving modes.
In light sleep mode, digital peripherals, most of the RAM, and CPUs are clock-gated, and supply voltage is reduced. Upon exit from light sleep, peripherals and CPUs resume operation, their internal state is preserved.
In deep sleep 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 and light sleep modes 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_sleep_enable_X_wakeup
APIs and can be disabled using esp_sleep_disable_wakeup_source()
API. Next section describes these APIs in detail. Wakeup sources can be configured at any moment before entering light or deep sleep mode.
Additionally, the application can force specific powerdown modes for the RTC peripherals and RTC memories using esp_sleep_pd_config()
API.
Once wakeup sources are configured, application can enter sleep mode using esp_light_sleep_start()
or esp_deep_sleep_start()
APIs. At this point the hardware will be configured according to the requested wakeup sources, and RTC controller will either power down or power off the CPUs and digital peripherals.
WiFi/BT and sleep modes¶
In deep sleep and light sleep modes, wireless peripherals are powered down. Before entering deep sleep or light sleep modes, applications must disable WiFi and BT using appropriate calls (esp_bluedroid_disable()
, esp_bt_controller_disable()
, esp_wifi_stop()
). WiFi and BT connections will not be maintained in deep sleep or light sleep, even if these functions are not called.
If WiFi connection needs to be maintained, enable WiFi modem sleep, and enable automatic light sleep feature (see Power Management APIs). This will allow the system to wake up from sleep automatically when required by WiFi driver, thereby maintaining connection to the AP.
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. For details on RTC clock options, see ESP32 Technical Reference Manual > ULP Coprocessor [PDF].
This wakeup mode doesn’t require RTC peripherals or RTC memories to be powered on during sleep.
esp_sleep_enable_timer_wakeup()
function can be used to enable deep sleep wakeup using a timer.
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_sleep_enable_touchpad_wakeup()
function can be used to enable this wakeup source.
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_sleep_start()
.
In revisions 0 and 1 of the ESP32, this wakeup source is incompatible with ULP and touch wakeup sources.
esp_sleep_enable_ext0_wakeup()
function can be used to enable this wakeup source.
Warning
After wake up from 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.
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 down 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 sleep, and configure pullup/pulldown resistors using rtc_gpio_
functions, before entering sleep:
esp_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 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.
esp_sleep_enable_ext1_wakeup()
function can be used to enable this wakeup source.
ULP coprocessor wakeup¶
ULP coprocessor can run while the chip is in sleep mode, 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 memory. RTC slow memory will be powered on during 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).
esp_sleep_enable_ulp_wakeup()
function can be used to enable this wakeup source.
GPIO wakeup (light sleep only)¶
In addition to EXT0 and EXT1 wakeup sources described above, one more method of wakeup from external inputs is available in light sleep mode. With this wakeup source, each pin can be individually configured to trigger wakeup on high or low level using gpio_wakeup_enable()
function. Unlike EXT0 and EXT1 wakeup sources, which can only be used with RTC IOs, this wakeup source can be used with any IO (RTC or digital).
esp_sleep_enable_gpio_wakeup()
function can be used to enable this wakeup source.
UART wakeup (light sleep only)¶
When ESP32 receives UART input from external devices, it is often required to wake up the chip when input data is available. UART peripheral contains a feature which allows waking up the chip from light sleep when a certain number of positive edges on RX pin are seen. This number of positive edges can be set using uart_set_wakeup_threshold()
function. Note that the character which triggers wakeup (and any characters before it) will not be received by the UART after wakeup. This means that the external device typically needs to send an extra character to the ESP32 to trigger wakeup, before sending the data.
esp_sleep_enable_uart_wakeup()
function can be used to enable this wakeup source.
Power-down of RTC peripherals and memories¶
By default, esp_deep_sleep_start()
and esp_light_sleep_start()
functions will power down all RTC power domains which are not needed by the enabled wakeup sources. To override this behaviour, esp_sleep_pd_config()
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 overridden, 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 overridden using esp_sleep_pd_config()
function, if desired.
Entering light sleep¶
esp_light_sleep_start()
function can be used to enter light sleep once wakeup sources are configured. It is also possible to go into light sleep with no wakeup sources configured, in this case the chip will be in light sleep mode indefinitely, until external reset is applied.
Entering deep sleep¶
esp_deep_sleep_start()
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 indefinitely, until external reset is applied.
Configuring IOs¶
Some ESP32 IOs have internal pullups or pulldowns, which are enabled by default. If an external circuit drives this pin in deep sleep mode, current consumption may increase due to current flowing through these pullups and pulldowns.
To isolate a pin, preventing extra current draw, call rtc_gpio_isolate()
function.
For example, on ESP32-WROVER module, GPIO12 is pulled up externally. GPIO12 also has an internal pulldown in the ESP32 chip. This means that in deep sleep, some current will flow through these external and internal resistors, increasing deep sleep current above the minimal possible value.
Add the following code before esp_deep_sleep_start()
to remove this extra current:
rtc_gpio_isolate(GPIO_NUM_12);
UART output handling¶
Before entering sleep mode, esp_deep_sleep_start()
will flush the contents of UART FIFOs.
When entering light sleep mode using esp_light_sleep_start()
, UART FIFOs will not be flushed. Instead, UART output will be suspended, and remaining characters in the FIFO will be sent out after wakeup from light sleep.
Checking sleep wakeup cause¶
esp_sleep_get_wakeup_cause()
function can be used to check which wakeup source has triggered wakeup from sleep mode.
For touch pad and ext1 wakeup sources, it is possible to identify pin or touch pad which has caused wakeup using esp_sleep_get_touchpad_wakeup_status()
and esp_sleep_get_ext1_wakeup_status()
functions.
Disable sleep wakeup source¶
Previously configured wakeup source can be disabled later using esp_sleep_disable_wakeup_source()
API. This function deactivates trigger for the given wakeup source. Additionally it can disable all triggers if the argument is ESP_SLEEP_WAKEUP_ALL
.
Application Example¶
Implementation of basic functionality of deep sleep is shown in protocols/sntp example, where ESP module is periodically waken up to retrieve time from NTP server.
More extensive example in system/deep_sleep illustrates usage of various deep sleep wakeup triggers and ULP coprocessor programming.
API Reference¶
Header File¶
Functions¶
-
esp_err_t
esp_sleep_disable_wakeup_source
(esp_sleep_source_t source)¶ Disable wakeup source.
This function is used to deactivate wake up trigger for source defined as parameter of the function.
See docs/sleep-modes.rst for details.
- Note
This function does not modify wake up configuration in RTC. It will be performed in esp_sleep_start function.
- Return
ESP_OK on success
ESP_ERR_INVALID_STATE if trigger was not active
- Parameters
source
: - number of source to disable of type esp_sleep_source_t
-
esp_err_t
esp_sleep_enable_ulp_wakeup
(void)¶ Enable wakeup by ULP coprocessor.
- Note
In revisions 0 and 1 of the ESP32, ULP wakeup source cannot 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_NOT_SUPPORTED if additional current by touch (CONFIG_ESP32_RTC_EXT_CRYST_ADDIT_CURRENT) is enabled.
ESP_ERR_INVALID_STATE if ULP co-processor is not enabled or if wakeup triggers conflict
-
esp_err_t
esp_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
-
esp_err_t
esp_sleep_enable_touchpad_wakeup
(void)¶ 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.
- Note
The FSM mode of the touch button should be configured as the timer trigger mode.
- Return
ESP_OK on success
ESP_ERR_NOT_SUPPORTED if additional current by touch (CONFIG_ESP32_RTC_EXT_CRYST_ADDIT_CURRENT) is enabled.
ESP_ERR_INVALID_STATE if wakeup triggers conflict
-
touch_pad_t
esp_sleep_get_touchpad_wakeup_status
(void)¶ 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
-
bool
esp_sleep_is_valid_wakeup_gpio
(gpio_num_t gpio_num)¶ Returns true if a GPIO number is valid for use as wakeup source.
- Note
For SoCs with RTC IO capability, this can be any valid RTC IO input pin.
- Return
True if this GPIO number will be accepted as a sleep wakeup source.
- Parameters
gpio_num
: Number of the GPIO to test for wakeup source capability
-
esp_err_t
esp_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 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_sleep_start, immediately before entering sleep mode.
- 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)
-
esp_err_t
esp_sleep_enable_ext1_wakeup
(uint64_t mask, esp_sleep_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 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_sleep_start, immediately before entering sleep mode.
- 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_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
-
esp_err_t
esp_sleep_enable_gpio_wakeup
(void)¶ 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_uart_wakeup
(int uart_num)¶ 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.
- Return
ESP_OK on success
ESP_ERR_INVALID_ARG if wakeup from given UART is not supported
- Parameters
uart_num
: UART port to wake up from
-
uint64_t
esp_sleep_get_ext1_wakeup_status
(void)¶ 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
-
esp_err_t
esp_sleep_pd_config
(esp_sleep_pd_domain_t domain, esp_sleep_pd_option_t option)¶ Set power down mode for an RTC power domain in sleep mode.
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)
-
void
esp_deep_sleep_start
(void)¶ Enter deep sleep with the configured wakeup options.
This function does not return.
-
esp_err_t
esp_light_sleep_start
(void)¶ Enter light sleep with the configured wakeup options.
- Return
ESP_OK on success (returned after wakeup)
ESP_ERR_INVALID_STATE if WiFi or BT is not stopped
-
void
esp_deep_sleep
(uint64_t time_in_us)¶ Enter deep-sleep mode.
The device will automatically wake up after the deep-sleep time Upon waking up, the device calls deep sleep wake stub, and then proceeds to load application.
Call to this function is equivalent to a call to esp_deep_sleep_enable_timer_wakeup followed by a call to esp_deep_sleep_start.
esp_deep_sleep does not shut down WiFi, BT, and higher level protocol connections gracefully. Make sure relevant WiFi and BT stack functions are called to close any connections and deinitialize the peripherals. These include:
esp_bluedroid_disable
esp_bt_controller_disable
esp_wifi_stop
This function does not return.
- Parameters
time_in_us
: deep-sleep time, unit: microsecond
-
esp_sleep_wakeup_cause_t
esp_sleep_get_wakeup_cause
(void)¶ Get the wakeup source which caused wakeup from sleep.
- Return
cause of wake up from last sleep (deep sleep or light sleep)
-
void
esp_wake_deep_sleep
(void)¶ Default stub to run on wake from deep sleep.
Allows for executing code immediately on wake from sleep, before the software bootloader or ESP-IDF app has started up.
This function is weak-linked, so you can implement your own version to run code immediately when the chip wakes from sleep.
See docs/deep-sleep-stub.rst for details.
-
void
esp_set_deep_sleep_wake_stub
(esp_deep_sleep_wake_stub_fn_t new_stub)¶ Install a new stub at runtime to run on wake from deep sleep.
If implementing esp_wake_deep_sleep() then it is not necessary to call this function.
However, it is possible to call this function to substitute a different deep sleep stub. Any function used as a deep sleep stub must be marked RTC_IRAM_ATTR, and must obey the same rules given for esp_wake_deep_sleep().
-
esp_deep_sleep_wake_stub_fn_t
esp_get_deep_sleep_wake_stub
(void)¶ Get current wake from deep sleep stub.
- Return
Return current wake from deep sleep stub, or NULL if no stub is installed.
-
void
esp_default_wake_deep_sleep
(void)¶ The default esp-idf-provided esp_wake_deep_sleep() stub.
See docs/deep-sleep-stub.rst for details.
-
void
esp_deep_sleep_disable_rom_logging
(void)¶ Disable logging from the ROM code after deep sleep.
Using LSB of RTC_STORE4.
-
void
esp_sleep_gpio_status_init
(void)¶ Disable all GPIO pins at slept status.
-
void
esp_sleep_gpio_status_switch_configure
(bool enable)¶ Configure GPIO pins status switching between slept status and waked status.
- Parameters
enable
: decide whether to switch status or not
Type Definitions¶
-
typedef esp_sleep_source_t
esp_sleep_wakeup_cause_t
¶
-
typedef void (*
esp_deep_sleep_wake_stub_fn_t
)(void)¶ Function type for stub to run on wake from sleep.
Enumerations¶
-
enum
esp_sleep_ext1_wakeup_mode_t
¶ Logic function used for EXT1 wakeup mode.
Values:
-
ESP_EXT1_WAKEUP_ALL_LOW
= 0¶ Wake the chip when all selected GPIOs go low.
-
ESP_EXT1_WAKEUP_ANY_HIGH
= 1¶ Wake the chip when any of the selected GPIOs go high.
-
-
enum
esp_sleep_pd_domain_t
¶ Power domains which can be powered down in sleep mode.
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_XTAL
¶ XTAL oscillator.
-
ESP_PD_DOMAIN_CPU
¶ CPU core.
-
ESP_PD_DOMAIN_MAX
¶ Number of domains.
-
-
enum
esp_sleep_pd_option_t
¶ Power down options.
Values:
-
ESP_PD_OPTION_OFF
¶ Power down the power domain in sleep mode.
-
ESP_PD_OPTION_ON
¶ Keep power domain enabled during sleep mode.
-
ESP_PD_OPTION_AUTO
¶ Keep power domain enabled in sleep mode, if it is needed by one of the wakeup options. Otherwise power it down.
-
-
enum
esp_sleep_source_t
¶ Sleep wakeup cause.
Values:
-
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)
-
ESP_SLEEP_WAKEUP_UART
¶ Wakeup caused by UART (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)
-