From 8c40017d2d04d7edd33517ef196d62adb1fb9b39 Mon Sep 17 00:00:00 2001 From: Song Ruo Jing Date: Thu, 27 Oct 2022 15:00:02 +0800 Subject: [PATCH] examples: system/deep_sleep 1. Fix EXT0 wakeup pin error on ESP32: GPIO3 is not a RTC IO, change to use GPIO25. 2. Add ESP_ERROR_CHECK to explicitly show the runtime error 3. Improve example README --- examples/system/deep_sleep/README.md | 29 ++++++++++++++----- .../system/deep_sleep/main/Kconfig.projbuild | 22 +++++++++----- .../deep_sleep/main/deep_sleep_example_main.c | 28 ++++++++++-------- 3 files changed, 51 insertions(+), 28 deletions(-) diff --git a/examples/system/deep_sleep/README.md b/examples/system/deep_sleep/README.md index 5b82a00d7872..a22ecabd6ffa 100644 --- a/examples/system/deep_sleep/README.md +++ b/examples/system/deep_sleep/README.md @@ -5,28 +5,36 @@ (See the README.md file in the upper level 'examples' directory for more information about examples.) -The [deep sleep mode](https://docs.espressif.com/projects/esp-idf/en/latest/api-reference/system/sleep_modes.html#sleep-modes) of the ESP32 is a power saving mode that causes the CPU, majority of RAM, and digital peripherals that are clocked from APB_CLK to be powered off. Deep sleep mode can be exited using one of multiple [wake up sources](https://docs.espressif.com/projects/esp-idf/en/latest/api-reference/system/sleep_modes.html#wakeup-sources). This example demonstrates how to use the [`esp_sleep.h`](https://docs.espressif.com/projects/esp-idf/en/latest/api-reference/system/sleep_modes.html#api-reference) API to enter deep sleep mode, then wake up form different sources. +The [deep sleep mode](https://docs.espressif.com/projects/esp-idf/en/latest/api-reference/system/sleep_modes.html#sleep-modes) is a power saving mode that causes the CPU, majority of RAM, and digital peripherals that are clocked from APB_CLK to be powered off. Deep sleep mode can be exited using one of multiple [wake up sources](https://docs.espressif.com/projects/esp-idf/en/latest/api-reference/system/sleep_modes.html#wakeup-sources). This example demonstrates how to use the [`esp_sleep.h`](https://docs.espressif.com/projects/esp-idf/en/latest/api-reference/system/sleep_modes.html#api-reference) API to enter deep sleep mode, then wake up form different sources. The following wake up sources are demonstrated in this example (refer to the [Wakeup Sources documentation](https://docs.espressif.com/projects/esp-idf/en/latest/api-reference/system/sleep_modes.html#wakeup-sources) for more details regarding wake up sources): -1. **Timer:** An RTC timer that can be programmed to trigger a wake up after a preset time. This example will trigger a wake up every 20 seconds. -2. **EXT1:** External wake up 1 which is tied to multiple RTC GPIOs. This example use GPIO2 and GPIO4 to trigger a wake up with any one of the two pins are HIGH. -3. **Touch:** Touch pad sensor interrupt. This example uses touch pads connected to GPIO32, GPIO33 in ESP32 or GPIO9 in ESP32-S2 to trigger a wake up when any of the pads are pressed. -4. **ULP:** Ultra Low Power Coprocessor which can continue to run during deep sleep. This example utilizes the ULP and constantly sample the chip's temperature and trigger a wake up if the chips temperature exceeds ~5 degrees Celsius. +- **Timer:** An RTC timer that can be programmed to trigger a wake up after a preset time. This example will trigger a wake up every 20 seconds. +- **EXT0:** External wake up 0 can trigger wakeup when one predefined RTC GPIO is at a predefined logic level. This example uses GPIO25 in ESP32 or GPIO3 in ESP32-S2/S3 to trigger a wake up when the pin is HIGH. (This wake up source is only available on ESP32, ESP32-S2, and ESP32-S3.) +- **EXT1:** External wake up 1 which is tied to multiple RTC GPIOs. This example uses GPIO2 and GPIO4 to trigger a wake up with any one of the two pins are HIGH. (This wake up source is only available on ESP32, ESP32-S2, and ESP32-S3.) +- **GPIO:** Pads powered by VDD3P3_RTC can be used to trigger a wake up from deep sleep. You may choose the pin and trigger level in menuconfig. (This wake up source is unavailable on ESP32, ESP32-S2, and ESP32-S3.) +- **Touch:** Touch pad sensor interrupt. This example uses touch pads connected to GPIO32, GPIO33 in ESP32 or GPIO9 in ESP32-S2/S3 to trigger a wake up when any of the pads are pressed. +- **ULP:** Ultra Low Power Coprocessor which can continue to run during deep sleep. This example utilizes the ULP and constantly sample the chip's temperature and trigger a wake up if the chips temperature exceeds ~5 degrees Celsius. Note: Some wake up sources can be disabled via configuration (see section on [project configuration](#Configure-the-project)) +Warning: On ESP32, touch wake up source cannot be used together with EXT0 or ULP wake up source. If they co-exist, IDF will give a runtime error and the program will crash. By default in this example, touch wake up is enabled, and the other two are disabled. You can switch to enable the other wake up sources via menuconfig. + In this example, the `CONFIG_BOOTLOADER_SKIP_VALIDATE_IN_DEEP_SLEEP` Kconfig option is used, which allows you to reduce the boot time of the bootloader during waking up from deep sleep. The bootloader stores in rtc memory the address of a running partition and uses it when it wakes up. This example allows you to skip all image checks and speed up the boot. ## How to use example ### Hardware Required -This example should be able to run on any commonly available ESP32 development board without any extra hardware if only **Timer** and **ULP** wake up sources are used. However, the following extra connections will be required for the remaining wake up sources. +This example should be able to run on any commonly available ESP32 series development board without any extra hardware if only **Timer** and **ULP** wake up sources are used. However, the following extra connections will be required for the remaining wake up sources. + +- **EXT0:** Connect GPIO25 in ESP32 or GPIO3 in ESP32-S2/S3 to HIGH to trigger a wake up. - **EXT1:** GPIO2 and GPIO4 should be connected to LOW to avoid floating pins. When triggering a wake up, connect one or both of the pins to HIGH. Note that floating pins may trigger a wake up. -- **Touch:** GPIO32, GPIO33 in ESP32 or GPIO9 in ESP32-S2 should be connected to touch sensors (see [Touch Sensor Application Note](https://github.com/espressif/esp-iot-solution/blob/release/v1.0/documents/touch_pad_solution/touch_sensor_design_en.md)). +- **GPIO:** If `EXAMPLE_GPIO_WAKEUP_HIGH_LEVEL` is selected in menuconfig, then connect `EXAMPLE_GPIO_WAKEUP_PIN` to HIGH to trigger a wake up; Otherwise, connect `EXAMPLE_GPIO_WAKEUP_PIN` to LOW to trigger a wake up. + +- **Touch:** GPIO32, GPIO33 in ESP32 or GPIO9 in ESP32-S2/S3 should be connected to touch sensors (see [Touch Sensor Application Note](https://github.com/espressif/esp-iot-solution/blob/release/v1.0/documents/touch_pad_solution/touch_sensor_design_en.md)). ### Configure the project @@ -35,7 +43,12 @@ idf.py menuconfig ``` * **Touch wake up** can be enabled/disabled via `Example configuration > Enable touch wake up` -* **ULT wake up** can be enabled/disabled via `Example configuration > Enable temperature monitoring by ULP` +* **EXT0 wake up** can be enabled/disabled via `Example configuration > Enable wakeup from GPIO (ext0)` +* **EXT1 wake up** can be enabled/disabled via `Example configuration > Enable wakeup from GPIO (ext1)` +* **GPIO wake up** can be enabled/disabled via `Example configuration > Enable wakeup from GPIO` + Trigger pin can be chosen via `Example configuration > GPIO wakeup configuration > Enable wakeup from GPIO` + Trigger level can be selected via `Example configuration > GPIO wakeup configuration > Enable GPIO high-level wakeup` +* **ULP wake up** can be enabled/disabled via `Example configuration > Enable temperature monitoring by ULP` Wake up sources that are unused or unconnected should be disabled in configuration to prevent inadvertent triggering of wake up as a result of floating pins. diff --git a/examples/system/deep_sleep/main/Kconfig.projbuild b/examples/system/deep_sleep/main/Kconfig.projbuild index 1c5000dff242..d3e89751b341 100644 --- a/examples/system/deep_sleep/main/Kconfig.projbuild +++ b/examples/system/deep_sleep/main/Kconfig.projbuild @@ -5,22 +5,28 @@ menu "Example Configuration" default y depends on SOC_PM_SUPPORT_TOUCH_SENSOR_WAKEUP help - This option enables wake up from deep sleep using touch pads - TOUCH8 and TOUCH9, which correspond to GPIO33 and GPIO32. + This option enables wake up from deep sleep using touch pads. + ESP32 - TOUCH8 and TOUCH9, which correspond to GPIO33 and GPIO32. + ESP32S2/S3 - TOUCH9, which corresponds to GPIO9. + + Note: On ESP32, touch wakeup source can not be used together with ext0 wakeup source. config EXAMPLE_EXT0_WAKEUP bool "Enable wakeup from GPIO (ext0)" - default y - depends on !SOC_GPIO_SUPPORT_DEEPSLEEP_WAKEUP + default y if !IDF_TARGET_ESP32 + default n if IDF_TARGET_ESP32 + depends on SOC_PM_SUPPORT_EXT_WAKEUP help - This option enables wake up from deep sleep from GPIO3. They should be connected to LOW to avoid - floating pins. When triggering a wake up, connect one or both of the pins to HIGH. Note that floating - pins may trigger a wake up. + This option enables wake up from deep sleep from GPIO25(ESP32)/GPIO3(ESP32S2,S3). The pin should be + connected to LOW to avoid being in a floating state. When triggering a wake up, connect the pin to HIGH. + Note that floating pins may trigger a wake up. + + Note: On ESP32, ext0 wakeup source can not be used together with touch wakeup source. config EXAMPLE_EXT1_WAKEUP bool "Enable wakeup from GPIO (ext1)" default y - depends on !SOC_GPIO_SUPPORT_DEEPSLEEP_WAKEUP + depends on SOC_PM_SUPPORT_EXT_WAKEUP help This option enables wake up from deep sleep from GPIO2 and GPIO4. They should be connected to LOW to avoid floating pins. When triggering a wake up, connect one or both of the pins to HIGH. Note that floating diff --git a/examples/system/deep_sleep/main/deep_sleep_example_main.c b/examples/system/deep_sleep/main/deep_sleep_example_main.c index c4470bef0552..243e60cd5f2b 100644 --- a/examples/system/deep_sleep/main/deep_sleep_example_main.c +++ b/examples/system/deep_sleep/main/deep_sleep_example_main.c @@ -101,19 +101,23 @@ void app_main(void) const int wakeup_time_sec = 20; printf("Enabling timer wakeup, %ds\n", wakeup_time_sec); - esp_sleep_enable_timer_wakeup(wakeup_time_sec * 1000000); + ESP_ERROR_CHECK(esp_sleep_enable_timer_wakeup(wakeup_time_sec * 1000000)); #if CONFIG_EXAMPLE_EXT0_WAKEUP +#if CONFIG_IDF_TARGET_ESP32 + const int ext_wakeup_pin_0 = 25; +#else const int ext_wakeup_pin_0 = 3; +#endif printf("Enabling EXT0 wakeup on pin GPIO%d\n", ext_wakeup_pin_0); - esp_sleep_enable_ext0_wakeup(ext_wakeup_pin_0, 1); + ESP_ERROR_CHECK(esp_sleep_enable_ext0_wakeup(ext_wakeup_pin_0, 1)); // Configure pullup/downs via RTCIO to tie wakeup pins to inactive level during deepsleep. // EXT0 resides in the same power domain (RTC_PERIPH) as the RTC IO pullup/downs. // No need to keep that power domain explicitly, unlike EXT1. - rtc_gpio_pullup_dis(ext_wakeup_pin_0); - rtc_gpio_pulldown_en(ext_wakeup_pin_0); + ESP_ERROR_CHECK(rtc_gpio_pullup_dis(ext_wakeup_pin_0)); + ESP_ERROR_CHECK(rtc_gpio_pulldown_en(ext_wakeup_pin_0)); #endif // CONFIG_EXAMPLE_EXT0_WAKEUP #ifdef CONFIG_EXAMPLE_EXT1_WAKEUP const int ext_wakeup_pin_1 = 2; @@ -122,17 +126,17 @@ void app_main(void) const uint64_t ext_wakeup_pin_2_mask = 1ULL << ext_wakeup_pin_2; printf("Enabling EXT1 wakeup on pins GPIO%d, GPIO%d\n", ext_wakeup_pin_1, ext_wakeup_pin_2); - esp_sleep_enable_ext1_wakeup(ext_wakeup_pin_1_mask | ext_wakeup_pin_2_mask, ESP_EXT1_WAKEUP_ANY_HIGH); + ESP_ERROR_CHECK(esp_sleep_enable_ext1_wakeup(ext_wakeup_pin_1_mask | ext_wakeup_pin_2_mask, ESP_EXT1_WAKEUP_ANY_HIGH)); /* If there are no external pull-up/downs, tie wakeup pins to inactive level with internal pull-up/downs via RTC IO * during deepsleep. However, RTC IO relies on the RTC_PERIPH power domain. Keeping this power domain on will * increase some power comsumption. */ # if CONFIG_EXAMPLE_EXT1_USE_INTERNAL_PULLUPS - esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_ON); - rtc_gpio_pullup_dis(ext_wakeup_pin_1); - rtc_gpio_pulldown_en(ext_wakeup_pin_1); - rtc_gpio_pullup_dis(ext_wakeup_pin_2); - rtc_gpio_pulldown_en(ext_wakeup_pin_2); + ESP_ERROR_CHECK(esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_ON)); + ESP_ERROR_CHECK(rtc_gpio_pullup_dis(ext_wakeup_pin_1)); + ESP_ERROR_CHECK(rtc_gpio_pulldown_en(ext_wakeup_pin_1)); + ESP_ERROR_CHECK(rtc_gpio_pullup_dis(ext_wakeup_pin_2)); + ESP_ERROR_CHECK(rtc_gpio_pulldown_en(ext_wakeup_pin_2)); # endif //CONFIG_EXAMPLE_EXT1_USE_INTERNAL_PULLUPS #endif // CONFIG_EXAMPLE_EXT1_WAKEUP @@ -207,8 +211,8 @@ void app_main(void) TOUCH_PAD_NUM9, touch_value, (uint32_t)(touch_value * 0.1)); #endif printf("Enabling touch pad wakeup\n"); - esp_sleep_enable_touchpad_wakeup(); - esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_ON); + ESP_ERROR_CHECK(esp_sleep_enable_touchpad_wakeup()); + ESP_ERROR_CHECK(esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_ON)); #endif // CONFIG_EXAMPLE_TOUCH_WAKEUP #if CONFIG_IDF_TARGET_ESP32