Sleep Modes
===========

:link_to_translation:`zh_CN:[中文]`

{IDF_TARGET_SPI_POWER_DOMAIN:default="VDD_SPI", esp32="VDD_SDIO"}
{IDF_TARGET_RTC_POWER_DOMAIN:default="VDD3P3_RTC", esp32c5="VDDPST1", esp32c6="VDDPST1", esp32c61="VDDPST1", esp32p4="VDD_LP"}

Overview
--------

{IDF_TARGET_NAME} supports two major power saving modes: Light-sleep and Deep-sleep. According to the features used by an application, there are some sub sleep modes. See :ref:`sleep_modes` for these sleep modes and sub sleep modes. Additionally, there are some power-down options that can be configured to further reduce the power consumption. See :ref:`power_down_options` for more details.

There are several wakeup sources in the sleep modes. These sources can also be combined so that the chip will wake up when any of the sources are triggered. :ref:`api-reference-wakeup-source` describes these wakeup sources and configuration APIs in detail.

The configuration of power-down options and wakeup sources are optional. They can be configured at any moment before entering the sleep modes.

Then the application can call sleep start APIs to enter one of the sleep modes. See :ref:`enter_sleep` for more details. When the wakeup condition is met, the application is awoken from sleep. See :ref:`wakeup_cause` on how to get the wakeup cause, and :ref:`disable_sleep_wakeup_source` on how to handle the wakeup sources after wakeup.

.. _sleep_modes:

Sleep Modes
-----------

In Light-sleep mode, the digital peripherals, most of the RAM, and CPUs are clock-gated and their supply voltage is reduced. Upon exit from Light-sleep, the digital peripherals, RAM, and CPUs resume operation and their internal states are preserved.

In Deep-sleep mode, the CPUs, most of the RAM, and all digital peripherals that are clocked from APB_CLK are powered off. The only parts of the chip that remain powered on are:

    .. list::

        - RTC controller
        :SOC_ULP_SUPPORTED: - ULP coprocessor
        :SOC_RTC_FAST_MEM_SUPPORTED: - RTC FAST memory
        :SOC_RTC_SLOW_MEM_SUPPORTED: - RTC SLOW memory

.. only:: SOC_WIFI_SUPPORTED and SOC_BT_SUPPORTED

    Wi-Fi/Bluetooth and Sleep Modes
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

    In Deep-sleep and Light-sleep modes, the wireless peripherals are powered down. Before entering Deep-sleep or Light-sleep modes, the application must disable Wi-Fi and Bluetooth using the appropriate calls (i.e., :cpp:func:`nimble_port_stop`, :cpp:func:`nimble_port_deinit`, :cpp:func:`esp_bluedroid_disable`, :cpp:func:`esp_bluedroid_deinit`, :cpp:func:`esp_bt_controller_disable`, :cpp:func:`esp_bt_controller_deinit`, :cpp:func:`esp_wifi_stop`). Wi-Fi and Bluetooth connections are not maintained in Deep-sleep or Light-sleep mode, even if these functions are not called.

    If Wi-Fi/Bluetooth connections need to be maintained, enable Wi-Fi/Bluetooth Modem-sleep mode and automatic Light-sleep feature (see :doc:`Power Management APIs <power_management>`). This allows the system to wake up from sleep automatically when required by the Wi-Fi/Bluetooth driver, thereby maintaining the connection.

.. only:: SOC_WIFI_SUPPORTED and not SOC_BT_SUPPORTED

    Wi-Fi and Sleep Modes
    ^^^^^^^^^^^^^^^^^^^^^^^

    In Deep-sleep and Light-sleep modes, the wireless peripherals are powered down. Before entering Deep-sleep or Light-sleep modes, applications must disable Wi-Fi using the appropriate calls (:cpp:func:`esp_wifi_stop`). Wi-Fi connections are not maintained in Deep-sleep or Light-sleep mode, even if these functions are not called.

    If Wi-Fi connections need to be maintained, enable Wi-Fi Modem-sleep mode and automatic Light-sleep feature (see :doc:`Power Management APIs <power_management>`). This will allow the system to wake up from sleep automatically when required by the Wi-Fi driver, thereby maintaining a connection to the AP.

.. only:: esp32s2 or esp32s3 or esp32c2 or esp32c3

    Sub Sleep Modes
    ^^^^^^^^^^^^^^^

    Tables below list the sub sleep modes in the first row and the features they support in the first column. Modes that support more features may consume more power during sleep mode. The sleep system automatically selects the mode that satisfies all the features required by the user while consuming least power.

    Deep-sleep:

    .. list-table::
       :widths: auto
       :header-rows: 2

       * -
         - DSLP_ULTRA_LOW
         - DSLP_DEFAULT
         - DSLP_8MD256/
       * -
         -
         -
         - DSLP_ADC_TSENS
       * - ULP/Touch sensor (ESP32-S2 and ESP32-S3 only)
         - Y
         - Y
         - Y
       * - RTC IO input/RTC memory at high temperature
         -
         - Y
         - Y
       * - ADC_TSEN_MONITOR
         -
         -
         - Y
       * - 8MD256 as the clock source for RTC_SLOW_CLK
         -
         -
         - Y

    Features:

    1. RTC IO input/RTC memory at high temperature (experimental): Use RTC IO as input pins, or use RTC memory at high temperature. The chip can go into ultra low power mode when these features are disabled. Controlled by API :cpp:func:`esp_sleep_sub_mode_config` with `ESP_SLEEP_ULTRA_LOW_MODE` argument.

    2. ADC_TSEN_MONITOR: Use ADC/Temperature Sensor in monitor mode (controlled by ULP). Enabled by API :cpp:func:`ulp_adc_init` or its higher level APIs. Only available for ESP32-S2 and ESP32-S3 chips with monitor mode.

    3. 8MD256 as the clock source for RTC_SLOW_CLK: When 8MD256 is selected as the clock source for RTC_SLOW_CLK using the Kconfig option ``CONFIG_RTC_CLK_SRC_INT_8MD256``, the chip will automatically enter this sub sleep mode during Deep-sleep mode.

    Light-sleep:

    .. list-table::
       :widths: auto
       :header-rows: 2

       * -
         - LSLP_DEFAULT
         - LSLP_ADC_TSENS
         - LSLP_8MD256
         - LSLP_LEDC8M/
       * -
         -
         -
         -
         - LSLP_XTAL_FPU
       * - ULP/Touch sensor (ESP32-S2 and ESP32-S3 only)
         - Y
         - Y
         - Y
         - Y
       * - RTC IO input/RTC memory at high temperature
         - Y
         - Y
         - Y
         - Y
       * - ADC_TSEN_MONITOR
         -
         - Y
         - Y
         - Y
       * - 8MD256 as the clock source for RTC_SLOW_CLK
         -
         -
         - Y
         - Y
       * - 8 MHz RC clock source used by digital peripherals
         -
         -
         -
         - Y
       * - Keep the XTAL clock on
         -
         -
         -
         - Y

    Features: (Also see 8MD256 and ADC_TSEN_MONITOR features for Deep-sleep mode above)

    1. 8 MHz RC clock source used by digital peripherals: Currently, only LEDC uses this clock source during Light-sleep mode. When LEDC selects this clock source, this feature is automatically enabled.

    2. Keep the XTAL clock on: Keep the XTAL clock on during Light-sleep mode. Controlled by ``ESP_PD_DOMAIN_XTAL`` power domain.

    .. only:: esp32s2

        {IDF_TARGET_NAME} uses the same power mode for LSLP_8MD256, LSLP_LEDC8M, and LSLP_XTAL_FPU features.

    .. only:: esp32s3

        Default mode of {IDF_TARGET_NAME} already supports ADC_TSEN_MONITOR feature.

    .. only:: esp32c2 or esp32c3

        {IDF_TARGET_NAME} does not have ADC_TSEN_MONITOR or LSLP_ADC_TSENS feature.

.. _api-reference-wakeup-source:

Wakeup Sources
--------------

Wakeup sources can be enabled using ``esp_sleep_enable_X_wakeup`` APIs. Wakeup sources are not disabled after wakeup, you can disable them using :cpp:func:`esp_sleep_disable_wakeup_source` API if you do not need them any more. See :ref:`disable_sleep_wakeup_source`.

Following are the wakeup sources supported on {IDF_TARGET_NAME}.

Timer
^^^^^

The 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.

.. only:: SOC_ULP_SUPPORTED

    For details on RTC clock options, see **{IDF_TARGET_NAME} Technical Reference Manual** > **ULP Coprocessor** [`PDF <{IDF_TARGET_TRM_EN_URL}#ulp>`__].

RTC peripherals or RTC memories do not need to be powered on during sleep in this wakeup mode.

:cpp:func:`esp_sleep_enable_timer_wakeup` function can be used to enable sleep wakeup using a timer.

.. only:: SOC_PM_SUPPORT_TOUCH_SENSOR_WAKEUP

    Touchpad
    ^^^^^^^^^

    The RTC IO module contains the logic to trigger wakeup when a touch sensor interrupt occurs. To wakeup from a touch sensor interrupt, users need to configure the touch pad interrupt before the chip enters Deep-sleep or Light-sleep modes.

    .. only:: esp32

        Revisions 0 and 1 of 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).

    :cpp:func:`esp_sleep_enable_touchpad_wakeup` function can be used to enable this wakeup source.

.. only:: SOC_PM_SUPPORT_EXT0_WAKEUP

    External Wakeup (``ext0``)
    ^^^^^^^^^^^^^^^^^^^^^^^^^^

    The RTC IO module contains the logic to trigger wakeup when one of RTC GPIOs is set to a predefined logic level. RTC IO is part of the RTC peripherals power domain, so RTC peripherals will be kept powered on during Deep-sleep if this wakeup source is requested.

    The RTC IO module is enabled in this mode, so internal pullup or pulldown resistors can also be used. They need to be configured by the application using :cpp:func:`rtc_gpio_pullup_en` and :cpp:func:`rtc_gpio_pulldown_en` functions before calling :cpp:func:`esp_deep_sleep_start`.

    .. only:: esp32

        In revisions 0 and 1 of ESP32, this wakeup source is incompatible with ULP and touch wakeup sources.

    :cpp:func:`esp_sleep_enable_ext0_wakeup` function can be used to enable this wakeup source.

    .. warning::

        After waking up from sleep, the IO pad used for wakeup will be configured as RTC IO. Therefore, before using this pad as digital GPIO, users need to reconfigure it using :cpp:func:`rtc_gpio_deinit` function.

.. only:: SOC_PM_SUPPORT_EXT1_WAKEUP

    .. _sleep-ext1-wakeup:

    External Wakeup (``ext1``)
    ^^^^^^^^^^^^^^^^^^^^^^^^^^

    The RTC controller contains the logic to trigger wakeup using multiple RTC GPIOs. One of the following two logic functions can be used to trigger ext1 wakeup:

    .. only:: esp32

        - 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``)

    .. only:: not esp32

        - wake up if any of the selected pins is high (``ESP_EXT1_WAKEUP_ANY_HIGH``)
        - wake up if any of the selected pins is low (``ESP_EXT1_WAKEUP_ANY_LOW``)

    This wakeup source is controlled by the RTC controller. It supports wakeup even when the RTC peripheral is powered down. Although the power domain of the RTC peripheral, where RTC IOs are located, is powered down during sleep modes, ESP-IDF will automatically lock the state of the wakeup pin before the system enters sleep modes and unlock upon exiting sleep modes. Therefore, the internal pull-up or pull-down resistors can still be configured for the wakeup pin::

        esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_ON);
        rtc_gpio_pullup_dis(gpio_num);
        rtc_gpio_pulldown_en(gpio_num);

    If we turn off the ``RTC_PERIPH`` domain, we will use the HOLD feature to maintain the pull-up and pull-down on the pins during sleep. HOLD feature will be acted on the pin internally before the system enters sleep modes, and this can further reduce power consumption::

        rtc_gpio_pullup_dis(gpio_num);
        rtc_gpio_pulldown_en(gpio_num);

    If certain chips lack the ``RTC_PERIPH`` domain, we can only use the HOLD feature to maintain the pull-up and pull-down on the pins during sleep modes::

        gpio_pullup_dis(gpio_num);
        gpio_pulldown_en(gpio_num);

    :cpp:func:`esp_sleep_enable_ext1_wakeup_io` function can be used to append ext1 wakeup IO and set corresponding wakeup level.

    :cpp:func:`esp_sleep_disable_ext1_wakeup_io` function can be used to remove ext1 wakeup IO.

    .. only:: SOC_PM_SUPPORT_EXT1_WAKEUP_MODE_PER_PIN

        The RTC controller also supports triggering wakeup, allowing configurable IO to use different wakeup levels simultaneously. This can be configured with :cpp:func:`esp_sleep_enable_ext1_wakeup_io`.

    .. only:: not SOC_PM_SUPPORT_EXT1_WAKEUP_MODE_PER_PIN

        .. note::

           Due to hardware limitation, when we use more than one IO for EXT1 wakeup, it is not allowed to configure different wakeup levels for the IOs, and there is corresponding inspection mechanism in :cpp:func:`esp_sleep_enable_ext1_wakeup_io`.

    .. warning::

        - To use the EXT1 wakeup, the IO pad(s) are configured as RTC IO. Therefore, before using these pads as digital GPIOs, users need to reconfigure them by calling the :cpp:func:`rtc_gpio_deinit` function.

        - If the RTC peripherals are configured to be powered down (which is by default), the wakeup IOs will be set to the holding state before entering sleep. Therefore, after the chip wakes up from Light-sleep, please call ``rtc_gpio_hold_dis`` to disable the hold function to perform any pin re-configuration. For Deep-sleep wakeup, this is already being handled at the application startup stage.

.. only:: SOC_ULP_SUPPORTED

    ULP Coprocessor Wakeup
    ^^^^^^^^^^^^^^^^^^^^^^

    ULP coprocessor can run while the chip is in sleep mode, and may be used to poll sensors, monitor ADC or GPIO states, and wake up the chip when a specific event is detected. ULP coprocessor is part of the 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.

    .. only:: esp32

        Revisions 0 and 1 of 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).

    :cpp:func:`esp_sleep_enable_ulp_wakeup` function can be used to enable this wakeup source.

.. only:: SOC_RTCIO_WAKE_SUPPORTED

    GPIO Wakeup from Light-sleep
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

    .. only:: SOC_PM_SUPPORT_EXT0_WAKEUP and SOC_PM_SUPPORT_EXT1_WAKEUP

        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 :cpp:func:`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).

    .. only:: SOC_PM_SUPPORT_EXT1_WAKEUP and not SOC_PM_SUPPORT_EXT0_WAKEUP

        In addition to the EXT1 wakeup source 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 :cpp:func:`gpio_wakeup_enable` function. Unlike the EXT1 wakeup source, which can only be used with RTC IOs, this wakeup source can be used with any IO (RTC or digital).

    .. only:: not (SOC_PM_SUPPORT_EXT0_WAKEUP or SOC_PM_SUPPORT_EXT1_WAKEUP)

        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 :cpp:func:`gpio_wakeup_enable` function. This wakeup source can be used with any IO (RTC or digital).

    :cpp:func:`esp_sleep_enable_gpio_wakeup` function can be used to enable this wakeup source.

    .. warning::

        Before entering Light-sleep mode, check if any GPIO pin to be driven is part of the {IDF_TARGET_SPI_POWER_DOMAIN} power domain. If so, this power domain must be configured to remain ON during sleep.

        For example, on ESP32-WROOM-32 board, GPIO16 and GPIO17 are linked to {IDF_TARGET_SPI_POWER_DOMAIN} power domain. If they are configured to remain high during Light-sleep, the power domain should be configured to remain powered ON. This can be done with :cpp:func:`esp_sleep_pd_config()`::

            esp_sleep_pd_config(ESP_PD_DOMAIN_VDDSDIO, ESP_PD_OPTION_ON);

    .. only:: SOC_PM_SUPPORT_TOP_PD

       .. note::

            .. only::  SOC_GPIO_SUPPORT_HP_PERIPH_PD_SLEEP_WAKEUP

                In Light-sleep mode, if you set Kconfig option :ref:`CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP`， to continue using :cpp:func:`gpio_wakeup_enable` for GPIO wakeup, you need to first call :cpp:func:`rtc_gpio_init` and :cpp:func:`rtc_gpio_set_direction`, setting the RTCIO to input mode.

                Alternatively，you can use :cpp:func:`esp_sleep_enable_gpio_wakeup_on_hp_periph_powerdown` directly in that condition for GPIO wakeup, because the digital IO power domain is being powered off.

            .. only::  not SOC_GPIO_SUPPORT_HP_PERIPH_PD_SLEEP_WAKEUP

                In Light-sleep mode, if you set Kconfig option :ref:`CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP`， to continue using :cpp:func:`gpio_wakeup_enable` for GPIO wakeup, you need to first call :cpp:func:`rtc_gpio_init` and :cpp:func:`rtc_gpio_set_direction`, setting the RTCIO to input mode.

    .. only:: SOC_GPIO_SUPPORT_HP_PERIPH_PD_SLEEP_WAKEUP

        .. _deep_sleep_gpio_wakeup:

        GPIO Wakeup from Deep-sleep
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^

        In addition to the GPIO wakeup mechanism available in Light-sleep mode, {IDF_TARGET_NAME} also supports waking up from Deep-sleep using GPIOs.

        This wakeup source is implemented by :cpp:func:`esp_sleep_enable_gpio_wakeup_on_hp_periph_powerdown`, which allows selecting one or more GPIOs and the wakeup level (high or low). Only GPIOs powered by the {IDF_TARGET_RTC_POWER_DOMAIN} power domain can be used as Deep-sleep GPIO wakeup sources. The exact set of supported pins can be checked in the `datasheet <{IDF_TARGET_DATASHEET_EN_URL}>`__ > Section IO Pins.

        .. note::
            This API also works for Light-sleep mode when the peripheral power domain is powered down (see :ref:`CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP`). In this case, it should be used instead of :cpp:func:`esp_sleep_enable_gpio_wakeup` because the GPIO module is powered down during sleep.

        For a complete example of using GPIO to wake up from Deep-sleep, see :example:`system/deep_sleep`.

.. only:: not SOC_RTCIO_WAKE_SUPPORTED and not esp32h2

    GPIO Wakeup
    ^^^^^^^^^^^

    .. only:: SOC_GPIO_SUPPORT_HP_PERIPH_PD_SLEEP_WAKEUP

        There are two GPIO wakeup APIs available, each designed for different sleep scenarios:

    .. only:: not SOC_GPIO_SUPPORT_HP_PERIPH_PD_SLEEP_WAKEUP

        On {IDF_TARGET_NAME}, :cpp:func:`esp_sleep_enable_gpio_wakeup` together with :cpp:func:`gpio_wakeup_enable` can wake the chip from Light-sleep.

        .. only:: SOC_PM_SUPPORT_EXT1_WAKEUP

            To wake from Deep-sleep using RTC GPIOs, use EXT1 wakeup (:cpp:func:`esp_sleep_enable_ext1_wakeup_io`); see :ref:`sleep-ext1-wakeup`.

    **1. :cpp:func:`esp_sleep_enable_gpio_wakeup` - For Light-sleep (GPIO module powered on)**

        Any IO can be used as the external input to wake up the chip from Light-sleep when the GPIO module remains powered on. Each pin can be individually configured to trigger wakeup on high or low level using the :cpp:func:`gpio_wakeup_enable` function. Then the :cpp:func:`esp_sleep_enable_gpio_wakeup` function should be called to enable this wakeup source.

        .. only:: SOC_GPIO_SUPPORT_HP_PERIPH_PD_SLEEP_WAKEUP

            .. note::
                This API is **not available** when :ref:`CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP` is enabled, because the GPIO module is powered down during sleep in this case. Use :cpp:func:`esp_sleep_enable_gpio_wakeup_on_hp_periph_powerdown` instead.

        .. only:: not SOC_GPIO_SUPPORT_HP_PERIPH_PD_SLEEP_WAKEUP

            .. note::
                When :ref:`CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP` is enabled, to keep using :cpp:func:`gpio_wakeup_enable`, call :cpp:func:`rtc_gpio_init` and :cpp:func:`rtc_gpio_set_direction` so the pin is used as an RTC GPIO input.

    .. only:: SOC_GPIO_SUPPORT_HP_PERIPH_PD_SLEEP_WAKEUP

        **2. :cpp:func:`esp_sleep_enable_gpio_wakeup_on_hp_periph_powerdown` - For Deep-sleep and Light-sleep (peripheral powerdown)**

            IOs that are powered by the VDD3P3_RTC power domain can be used to wake up the chip from Deep-sleep or Light-sleep when the peripheral power domain is powered down. The wakeup pin and wakeup trigger level can be configured by calling :cpp:func:`esp_sleep_enable_gpio_wakeup_on_hp_periph_powerdown`. This function works for:

            - Deep-sleep mode (always)
            - Light-sleep mode when :ref:`CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP` is enabled

            .. only:: SOC_RTC_GPIO_EDGE_WAKEUP_SUPPORTED

                On {IDF_TARGET_NAME} the API also accepts edge-triggered wakeup modes: ``ESP_GPIO_WAKEUP_GPIO_POSEDGE`` (rising edge), ``ESP_GPIO_WAKEUP_GPIO_NEGEDGE`` (falling edge), and ``ESP_GPIO_WAKEUP_GPIO_ANYEDGE`` (both edges). For ``ESP_GPIO_WAKEUP_GPIO_ANYEDGE``, the internal pull-up/pull-down is disabled (when :ref:`CONFIG_ESP_SLEEP_GPIO_ENABLE_INTERNAL_RESISTORS` is enabled) because the idle level is ambiguous; an external pull or an already-stable line is recommended.

            .. note::
                Only GPIOs powered by the VDD3P3_RTC power domain (RTC IOs) can be used with this API. The exact set of supported pins can be checked in the `datasheet <{IDF_TARGET_DATASHEET_EN_URL}>`__ > Section IO Pins.

    .. note::
        Any GPIO/IO wakeup signal -- whether level or edge -- must be held (or have a pulse width) of at least 3 RTC slow-clock cycles to be reliably sampled by the wakeup logic. The duration of one slow-clock cycle depends on :ref:`CONFIG_RTC_CLK_SRC` (e.g. RC_SLOW @ ~136 kHz ~= 7.4 us/cycle, XTAL32K @ 32.768 kHz ~= 30.5 us/cycle). This applies to both :cpp:func:`esp_sleep_enable_gpio_wakeup` and :cpp:func:`esp_sleep_enable_gpio_wakeup_on_hp_periph_powerdown`.

.. only:: esp32h2

    GPIO Wakeup
    ^^^^^^^^^^^

    Any IO can be used as the external input to wake up the chip from Light-sleep. Each pin can be individually configured using :cpp:func:`gpio_wakeup_enable` (low/high level only). Then the :cpp:func:`esp_sleep_enable_gpio_wakeup` function should be called to enable this wakeup source.


.. _uart_wakeup_light_sleep:

UART Wakeup (Light-sleep Only)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

When {IDF_TARGET_NAME} receives UART input from external devices, it is often necessary to wake up the chip when input data is available. The UART peripheral supports multiple wakeup modes that can wake up the chip from Light-sleep. The wakeup mode and its parameters can be configured using :cpp:func:`uart_wakeup_setup` function.

The UART wakeup supports the following modes:

.. only:: SOC_UART_WAKEUP_SUPPORT_ACTIVE_THRESH_MODE

    **Mode 0 (UART_WK_MODE_ACTIVE_THRESH) - Active Edge Threshold Wakeup**

        When all clocks are powered down, the chip can be woken up by toggling the RXD pin for a certain number of cycles. The chip wakes up when the number of rising edges is greater than or equal to threshold value. The threshold value can be configured using the ``rx_edge_threshold`` field in :cpp:type:`uart_wakeup_cfg_t` structure.

.. only:: SOC_UART_WAKEUP_SUPPORT_FIFO_THRESH_MODE

    **Mode 1 (UART_WK_MODE_FIFO_THRESH) - RX FIFO Threshold Wakeup**

        Since the UART Core clock remains active, the UART RX can still receive data and store it in the RX FIFO. The chip can be woken up from Light-sleep when the number of bytes in the RX FIFO exceeds the configured threshold. The threshold value can be configured using the ``rx_fifo_threshold`` field in :cpp:type:`uart_wakeup_cfg_t` structure.

.. only:: SOC_UART_WAKEUP_SUPPORT_START_BIT_MODE

    **Mode 2 (UART_WK_MODE_START_BIT) - Start Bit Detection Wakeup**

        The chip wakes up when the UART RX detects a start bit.

.. only:: SOC_UART_WAKEUP_SUPPORT_CHAR_SEQ_MODE

    **Mode 3 (UART_WK_MODE_CHAR_SEQ) - Character Sequence Detection Wakeup**

        The chip wakes up when the UART RX receives a specific character sequence. The character sequence can be configured using the ``wake_chars_seq`` field in :cpp:type:`uart_wakeup_cfg_t` structure. The character sequence supports wildcard matching using '*' to represent any symbol.

:cpp:func:`esp_sleep_enable_uart_wakeup` function can be used to enable this wakeup source.

.. only:: SOC_UART_WAKEUP_SUPPORT_ACTIVE_THRESH_MODE

    After waking-up from UART wakeup mode 0, you should send some extra data through the UART port or reset the UART module in Active mode, otherwise, the next UART wake-up would trigger with two less rising edges than the configured threshold value.

    .. only:: SOC_PM_SUPPORT_TOP_PD

       .. note::

           In Light-sleep mode, setting Kconfig option :ref:`CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP` will invalidate UART wakeup.

.. only:: SOC_ULP_LP_UART_SUPPORTED

    LP_UART can wake up the ULP LP core coprocessor. LP_UART supports the same wakeup modes as the HP UART described above, including active edge threshold wakeup, RX FIFO threshold wakeup, start bit detection wakeup, and character sequence detection wakeup.

    To use LP_UART to wake up the ULP LP core, follow these steps:

    #. Set the :c:macro:`ULP_LP_CORE_WAKEUP_SOURCE_LP_UART` flag in the ``wakeup_source`` field of the :cpp:type:`ulp_lp_core_cfg_t` structure.
    #. Initialize the LP UART (call :cpp:func:`lp_core_uart_init`).
    #. Configure the LP_UART wakeup mode using the :cpp:func:`lp_core_uart_wakeup_setup` function with a :cpp:type:`uart_wakeup_cfg_t` structure, using the same configuration method as HP UART.

    .. only:: SOC_LP_CORE_LP_UART_WAKEUP_KEEP_TRIGGERED

       .. note::

           On chips with ``SOC_LP_CORE_LP_UART_WAKEUP_KEEP_TRIGGERED``, the LP UART wakeup signal remains triggered after a wakeup event. The LP core startup flow (:cpp:func:`ulp_lp_core_update_wakeup_cause`) automatically calls :cpp:func:`ulp_lp_core_lp_uart_reset_wakeup_en` and :cpp:func:`lp_core_uart_clear_buf` to clear this state. If the standard startup flow is not used, you must handle this manually; otherwise, repeated wakeups will occur.

    For example code on LP_UART wakeup, refer to :example:`system/ulp/lp_core/lp_uart/lp_uart_char_seq_wakeup`.

.. _disable_sleep_wakeup_source:

Disable Sleep Wakeup Source
^^^^^^^^^^^^^^^^^^^^^^^^^^^

Previously configured wakeup sources can be disabled later using :cpp:func:`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``.

.. _power_down_options:

Power-down Options
------------------

The application can force specific powerdown modes for RTC peripherals and RTC memories. In Deep-sleep mode, we can also isolate some IOs to further reduce current consumption.

Power-down of RTC Peripherals and Memories
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

By default, :cpp:func:`esp_deep_sleep_start` and :cpp:func:`esp_light_sleep_start` functions power down all RTC power domains which are not needed by the enabled wakeup sources. To override this behaviour, :cpp:func:`esp_sleep_pd_config` function is provided.

.. only:: esp32

    Note: in revision 0 of ESP32, RTC FAST memory is always kept enabled in Deep-sleep, so that the Deep-sleep stub can run after reset. This can be overridden, if the application does not need clean reset behaviour after Deep-sleep.

.. only:: SOC_RTC_SLOW_MEM_SUPPORTED

    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 :cpp:func:`esp_sleep_pd_config` function, if desired.

.. only:: not SOC_RTC_SLOW_MEM_SUPPORTED and SOC_RTC_FAST_MEM_SUPPORTED

    In {IDF_TARGET_NAME}, there is only RTC FAST memory, so if some variables in the program are marked by ``RTC_DATA_ATTR``, ``RTC_SLOW_ATTR`` or ``RTC_FAST_ATTR`` attributes, all of them go to RTC FAST memory. It will be kept powered on by default. This can be overridden using :cpp:func:`esp_sleep_pd_config` function, if desired.

.. _spi_flash_power_down_dpd:

Flash Entering Deep Power-Down Mode
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

For Light-sleep, ESP-IDF recommends lowering SPI Flash sleep current using **Deep Power-Down (DPD)** first: enable :ref:`CONFIG_ESP_SLEEP_SET_FLASH_DPD` so the SPI Flash enters its deep power-down command mode while the supply rail remains on. Current draw is typically very low (often below 1 µA for many SPI Flash devices), without the wake-up delay of fully cycling the SPI Flash supply.

In almost all use cases, DPD offers better overall trade-offs than cutting SPI Flash supply power—both safer for execution and still very low power.

.. note::
    **Mutually exclusive strategies:** Power-down SPI Flash during Light-sleep (:ref:`CONFIG_ESP_SLEEP_POWER_DOWN_FLASH` or ``esp_sleep_pd_config(ESP_PD_DOMAIN_VDDSDIO, ESP_PD_OPTION_OFF)``) **cannot be combined** with DPD. Kconfig exposes :ref:`CONFIG_ESP_SLEEP_SET_FLASH_DPD` only when :ref:`CONFIG_ESP_SLEEP_POWER_DOWN_FLASH` is disabled.

.. warning::

    Before using this feature, check the datasheet of the SPI Flash device used on your chip to ensure it supports the Deep Power-Down mode.

.. _spi_flash_power_down:

Power-down of Flash
^^^^^^^^^^^^^^^^^^^^^^^^

By default, to avoid potential issues, :cpp:func:`esp_light_sleep_start` function does **not** power down SPI Flash. To be more specific, it takes time to power down the SPI Flash and during this period the system may be woken up, which then actually powers up the SPI Flash before this SPI Flash could be powered down completely. As a result, there is a chance that the SPI Flash may not work properly.

So, in theory, it is ok if you only wake up the system after the SPI Flash is completely powered down. However, in reality, the SPI Flash power-down period can be hard to predict (for example, this period can be much longer when you add filter capacitors to the SPI Flash's power supply circuit) and uncontrollable (for example, the asynchronous wake-up signals make the actual sleep time uncontrollable).

.. warning::

    If a filter capacitor is added to your SPI Flash power supply circuit, please do everything possible to avoid powering down SPI Flash.

Therefore, it is recommended not to power down SPI Flash when using ESP-IDF. For power-sensitive applications, it is recommended to use Kconfig option :ref:`CONFIG_ESP_SLEEP_FLASH_LEAKAGE_WORKAROUND` to reduce the power consumption of the SPI Flash during Light-sleep, instead of powering down the SPI Flash.

.. only:: SOC_SPIRAM_SUPPORTED

    It is worth mentioning that PSRAM has a similar Kconfig option :ref:`CONFIG_ESP_SLEEP_PSRAM_LEAKAGE_WORKAROUND`.

However, for those who have fully understood the risk and are still willing to power down the SPI Flash to further reduce the power consumption, please check the following mechanisms:

    .. list::

        - Setting Kconfig option :ref:`CONFIG_ESP_SLEEP_POWER_DOWN_FLASH` only powers down the SPI Flash when the RTC timer is the only wake-up source **and** the sleep time is longer than the SPI Flash power-down period.
        - Calling ``esp_sleep_pd_config(ESP_PD_DOMAIN_VDDSDIO, ESP_PD_OPTION_OFF)`` powers down SPI Flash when the RTC timer is not enabled as a wakeup source **or** the sleep time is longer than the SPI Flash power-down period.

.. note::

    .. list::

        - ESP-IDF does not provide any mechanism that can power down the SPI Flash in all conditions when Light-sleep.
        - :cpp:func:`esp_deep_sleep_start` function forces power down SPI Flash regardless of user configuration.

.. _spi_flash_sleep_strategy_recommendations:

Flash Sleep Strategy Recommendations
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

In sleep scenarios, the SPI Flash handling method directly affects system safety, and power consumption. Different application scenarios prioritize these factors differently, so it is important to choose an appropriate SPI Flash sleep strategy.

Keep Flash Powered On
"""""""""""""""""""""""""""""

The standby power consumption of different SPI Flash varies. In ESP series chips, the standby power consumption of SPI Flash is typically below 30 µA. In the following scenarios, it is recommended to keep the SPI Flash powered on:

1. The system has extremely high stability requirements and cannot accept any potential risks from SPI Flash power-off.

2. Sleep duration is short or unpredictable, for example, when asynchronous wake-up sources exist (GPIO, UART, etc.).

3. Large filter capacitors exist in the SPI Flash power supply circuit, making it difficult to estimate the actual SPI Flash power-down time.

In the above cases, keeping the SPI Flash powered on is the most conservative and safest choice, but note that its standby power consumption is relatively high (about 10-30 µA).

Flash Entering Deep Power-Down (DPD) Mode
"""""""""""""""""""""""""""""""""""""""""

When standby power is still too high, prefer **Deep Power-Down** via :ref:`CONFIG_ESP_SLEEP_SET_FLASH_DPD`; see :ref:`spi_flash_power_down_dpd` for figures, timings, and how to enable it.

DPD mode is suitable for the following scenarios:

1. Significant reduction in SPI Flash power consumption during sleep is needed, but the risk of SPI Flash re-powering should be avoided.

2. Sleep duration is short or unpredictable, for example, when asynchronous wake-up sources exist (GPIO, UART, etc.).

3. SPI Flash chip used explicitly supports Deep Power-Down mode.

.. only:: not SOC_PM_FLASH_KEEP_POWER_IN_LSLP

    Power Down Flash
    """"""""""""""""""""

    You can refer to :ref:`spi_flash_power_down` to power down the SPI Flash during sleep. After the following conditions are met or after thorough evaluation, you may consider this strategy:

    1. The application has strict requirements for extremely low power consumption.

    2. Wake-up sources are controllable, typically only RTC timer wake-up sources are enabled.

    3. It can be ensured that the actual sleep time is greater than the time required for the SPI Flash to completely power down. For ESP series chips, the time required for the SPI Flash to completely power down may be greater than 300ms. If parallel capacitors exist in the SPI Flash power supply circuit, longer sleep time may be required.

    4. If the sleep time is too short, the power consumption during the SPI Flash power-on and power-down processes may exceed the power consumption when keeping it powered on.

    5. There is sufficient control over SPI Flash power supply and IO states to avoid SPI Flash leakage due to pin pull-up during sleep.

    Since the SPI Flash power-down process is greatly affected by hardware design, IO impedance characteristics, power supply, and environmental factors, ESP-IDF cannot guarantee that the SPI Flash will be safely powered down in Light-sleep mode. Therefore, this method is only suitable for scenarios with controllable risks and thorough verification.

Configuring IOs (Deep-sleep Only)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Some {IDF_TARGET_NAME} 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.

.. only:: SOC_RTCIO_HOLD_SUPPORTED and SOC_RTCIO_INPUT_OUTPUT_SUPPORTED

    To isolate a pin to prevent extra current draw, call :cpp:func:`rtc_gpio_isolate` function.

    For example, on ESP32-WROVER module, GPIO12 is pulled up externally, and it also has an internal pulldown in the ESP32 chip. This means that in Deep-sleep, some current flows through these external and internal resistors, increasing Deep-sleep current above the minimal possible value.

    Add the following code before :cpp:func:`esp_deep_sleep_start` to remove such extra current::

        rtc_gpio_isolate(GPIO_NUM_12);

.. only:: esp32c2 or esp32c3

    In Deep-sleep mode:
        - digital GPIOs (GPIO6 ~ 21) are in a high impedance state.
        - RTC GPIOs (GPIO0 ~ 5) can be in the following states, depending on their hold function enabled or not:
            - if the hold function is not enabled, RTC GPIOs will be in a high impedance state.
            - if the hold function is enabled, RTC GPIOs will retain the pin state latched at that hold moment.

.. _enter_sleep:

Entering Sleep
--------------

:cpp:func:`esp_light_sleep_start` or :cpp:func:`esp_deep_sleep_start` functions can be used to enter Light-sleep or Deep-sleep modes correspondingly. After that, the system configures the parameters of RTC controller according to the requested wakeup sources and power-down options.

It is also possible to enter sleep modes with no wakeup sources configured. In this case, the chip will be in sleep modes indefinitely until external reset is applied.

.. note::

    The sleep process will disable the cache, so the task stack of the task requesting sleep must be located in internal memory (DRAM or RTC fast memory). If a task with its stack in PSRAM requests Light-sleep or Deep-sleep, it will be rejected and an error will be returned.

UART Output Handling
^^^^^^^^^^^^^^^^^^^^

Before entering sleep, the sleep flow prepares the **console UART** (the UART used for debug output, selected by :ref:`CONFIG_ESP_CONSOLE_UART_NUM`) so that APB clock changes or power-down do not cause garbled output or undefined behavior. The strategy applied is configurable and affects data integrity, sleep entry time, and power consumption.

**Default behavior (auto mode)**

If you do not call :cpp:func:`esp_sleep_set_console_uart_handling_mode`, the following default strategy is used:

- **Deep-sleep**: Always wait until all data in the console UART FIFO has been transmitted before entering sleep, so that all debug output is sent and no data is lost.
- **Light-sleep**: Behavior depends on whether the UART power domain is powered down:
    - If the UART remains powered (e.g. HP peripheral domain not powered down): UART output is **suspended** after the current frame completes; after wakeup it is resumed and any remaining data in the UART TX FIFO before sleep continues to be sent.
    - If the UART power domain is powered down: The sleep flow waits until all data in the console UART TX FIFO has been transmitted before entering sleep; data in other UARTs is discarded to enter sleep faster.

**Configuring console UART handling**

You can override the default by calling :cpp:func:`esp_sleep_set_console_uart_handling_mode` and choosing one of the following modes (see :cpp:enum:`esp_sleep_uart_handling_mode_t`):

- :cpp:enumerator:`ESP_SLEEP_AUTO_FLUSH_SUSPEND_UART` (default): Automatically choose flush or suspend based on sleep type and power domain, as described above.
- :cpp:enumerator:`ESP_SLEEP_ALWAYS_FLUSH_UART` : Always wait until all data in the console UART TX FIFO has been transmitted before entering sleep. Use when you must guarantee that all debug output is visible; sleep entry will take longer and the chip will stay in Active state longer, increasing power consumption.
- :cpp:enumerator:`ESP_SLEEP_ALWAYS_SUSPEND_UART` : Wait for the current UART frame to complete, then suspend the UART. If the UART stays powered during Light-sleep, transmission continues after wake. If the UART power domain is powered down, unsent data will be lost.
- :cpp:enumerator:`ESP_SLEEP_ALWAYS_DISCARD_UART` : Discard all unsent data in the console UART FIFO and enter sleep immediately. Use for the fastest sleep entry and lowest power when debug output can be discarded.
- :cpp:enumerator:`ESP_SLEEP_NO_HANDLING` : Do not perform any handling on the console UART before sleep. Use only when the UART state is known to be safe (e.g. no pending output or the console UART is disabled).

.. note::

   The sleep flow runs in a critical section. When using a mode that flushes the console UART (e.g. :cpp:enumerator:`ESP_SLEEP_ALWAYS_FLUSH_UART` , or the default behavior for Light-sleep/Deep-sleep when the HP peripheral domain is powered down), set :ref:`CONFIG_ESP_INT_WDT_TIMEOUT_MS` to be **greater than** ``SOC_UART_FIFO_LEN`` × (time to send one character at the current baud rate). Otherwise, if too much data is queued in the TX FIFO, the flush may take longer than the interrupt watchdog timeout and trigger a watchdog reset during sleep entry.

Example: ensure all debug output is sent before every sleep::

.. code-block:: C

    fflush(stdout);
    esp_sleep_set_console_uart_handling_mode(ESP_SLEEP_ALWAYS_FLUSH_UART);
    esp_light_sleep_start();

Example: minimize sleep entry time and allow discarding console output::

.. code-block:: C

    esp_sleep_set_console_uart_handling_mode(ESP_SLEEP_ALWAYS_DISCARD_UART);
    esp_deep_sleep_start();

.. _wakeup_cause:

Checking Sleep Wakeup Cause
---------------------------

:cpp:func:`esp_sleep_get_wakeup_cause` function can be used to check which wakeup source has triggered wakeup from sleep mode.

.. only:: SOC_TOUCH_SENSOR_SUPPORTED

    For touchpad, it is possible to identify which touch pin has caused wakeup using :cpp:func:`esp_sleep_get_touchpad_wakeup_status` functions.

.. only:: SOC_PM_SUPPORT_EXT1_WAKEUP

    For ext1 wakeup sources, it is possible to identify which GPIO has caused wakeup using :cpp:func:`esp_sleep_get_ext1_wakeup_status` functions.

Application Examples
--------------------

.. list::

    - :example:`protocols/sntp` demonstrates the implementation of basic functionality of Deep-sleep, where ESP module is periodically waken up to retrieve time from NTP server.
    :SOC_WIFI_SUPPORTED: - :example:`wifi/power_save` demonstrates the usage of Wi-Fi Modem-sleep mode and automatic Light-sleep feature to maintain Wi-Fi connections.
    :SOC_BT_SUPPORTED: - :example:`bluetooth/nimble/power_save` demonstrates the usage of Bluetooth Modem-sleep mode and automatic Light-sleep feature to maintain Bluetooth connections.
    :SOC_ULP_SUPPORTED: - :example:`system/deep_sleep` demonstrates the usage of various Deep-sleep wakeup triggers and ULP coprocessor programming.
    :not SOC_ULP_SUPPORTED and not esp32c3 and not esp32h2 and SOC_PM_SUPPORT_EXT1_WAKEUP and SOC_GPIO_SUPPORT_HP_PERIPH_PD_SLEEP_WAKEUP: - :example:`system/deep_sleep` demonstrates the usage of Deep-sleep wakeup triggered by various sources, such as the RTC timer, GPIOs, EXT1, supported by {IDF_TARGET_NAME}.
    :not SOC_ULP_SUPPORTED and not esp32c3 and not esp32h2 and SOC_PM_SUPPORT_EXT1_WAKEUP and not SOC_GPIO_SUPPORT_HP_PERIPH_PD_SLEEP_WAKEUP: - :example:`system/deep_sleep` demonstrates the usage of Deep-sleep wakeup triggered by various sources, such as the RTC timer and EXT1, supported by {IDF_TARGET_NAME}.
    :not SOC_ULP_SUPPORTED and not esp32c3 and not esp32h2 and not SOC_PM_SUPPORT_EXT1_WAKEUP: - :example:`system/deep_sleep` demonstrates the usage of Deep-sleep wakeup triggered by various sources, such as the RTC timer, GPIOs, supported by {IDF_TARGET_NAME}.
    :esp32c3: - :example:`system/deep_sleep` demonstrates the usage of Deep-sleep wakeup triggered by various sources, such as the RTC timer, GPIOs, supported by ESP32-C3.
    :esp32h2: - :example:`system/deep_sleep` demonstrates the usage of Deep-sleep wakeup triggered by various sources, such as the RTC timer and EXT1, supported by ESP32-H2.
    - :example:`system/light_sleep` demonstrates the usage of Light-sleep wakeup triggered by various sources, such as the timer, GPIOs, supported by {IDF_TARGET_NAME}.
    :SOC_PM_SUPPORT_USB_WAKEUP: - :example:`peripherals/usb/device/tusb_cdc_acm_wakeup` demonstrates the usage of USB 2.0 wakeup from Light-sleep.
    :SOC_TOUCH_SENSOR_SUPPORTED and SOC_PM_SUPPORT_TOUCH_SENSOR_WAKEUP: - :example:`peripherals/touch_sensor/touch_sens_sleep` demonstrates the usage of Light-sleep and Deep-sleep wakeup triggered by the touch sensor.
    :SOC_VBAT_SUPPORTED: - :example:`lowpower/vbat` demonstrates the use of backup battery power (VBAT) during Deep-sleep, allowing the RTC timer to keep running after the main power is removed.

API Reference
-------------

.. include-build-file:: inc/esp_sleep.inc
