From b6580ea4ac6e59f650d67c74bd953d32b4dfbf2c Mon Sep 17 00:00:00 2001 From: jingli Date: Thu, 2 Mar 2023 20:49:14 +0800 Subject: [PATCH] example: refactor deep sleep example to make codes more structured --- .../system/deep_sleep/main/CMakeLists.txt | 3 + .../system/deep_sleep/main/Kconfig.projbuild | 2 +- .../deep_sleep/main/deep_sleep_example.h | 33 +++ .../deep_sleep/main/deep_sleep_example_main.c | 248 ++++-------------- examples/system/deep_sleep/main/ext_wakeup.c | 55 ++++ examples/system/deep_sleep/main/gpio_wakeup.c | 32 +++ .../system/deep_sleep/main/touch_wakeup.c | 109 ++++++++ .../system/deep_sleep/pytest_deep_sleep.py | 10 +- tools/ci/check_copyright_ignore.txt | 1 - 9 files changed, 296 insertions(+), 197 deletions(-) create mode 100644 examples/system/deep_sleep/main/deep_sleep_example.h create mode 100644 examples/system/deep_sleep/main/ext_wakeup.c create mode 100644 examples/system/deep_sleep/main/gpio_wakeup.c create mode 100644 examples/system/deep_sleep/main/touch_wakeup.c diff --git a/examples/system/deep_sleep/main/CMakeLists.txt b/examples/system/deep_sleep/main/CMakeLists.txt index 5474deaa87..f6c3a57090 100644 --- a/examples/system/deep_sleep/main/CMakeLists.txt +++ b/examples/system/deep_sleep/main/CMakeLists.txt @@ -1,2 +1,5 @@ idf_component_register(SRCS "deep_sleep_example_main.c" + "gpio_wakeup.c" + "ext_wakeup.c" + "touch_wakeup.c" INCLUDE_DIRS ".") diff --git a/examples/system/deep_sleep/main/Kconfig.projbuild b/examples/system/deep_sleep/main/Kconfig.projbuild index 6a680f6cfd..5e1cdbb36b 100644 --- a/examples/system/deep_sleep/main/Kconfig.projbuild +++ b/examples/system/deep_sleep/main/Kconfig.projbuild @@ -56,7 +56,7 @@ menu "Example Configuration" recommand you to connect external pull-up resistance. menu "GPIO wakeup configuration" - visible if SOC_GPIO_SUPPORT_DEEPSLEEP_WAKEUP + visible if EXAMPLE_GPIO_WAKEUP config EXAMPLE_GPIO_WAKEUP_PIN int "Enable wakeup from GPIO" diff --git a/examples/system/deep_sleep/main/deep_sleep_example.h b/examples/system/deep_sleep/main/deep_sleep_example.h new file mode 100644 index 0000000000..2e484a9bb4 --- /dev/null +++ b/examples/system/deep_sleep/main/deep_sleep_example.h @@ -0,0 +1,33 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ + +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +#include "sdkconfig.h" + +#if CONFIG_EXAMPLE_GPIO_WAKEUP +void example_deep_sleep_register_gpio_wakeup(void); +#endif + +#if CONFIG_EXAMPLE_EXT0_WAKEUP +void example_deep_sleep_register_ext0_wakeup(void); +#endif + +#if CONFIG_EXAMPLE_EXT1_WAKEUP +void example_deep_sleep_register_ext1_wakeup(void); +#endif + +#if CONFIG_EXAMPLE_TOUCH_WAKEUP +void example_deep_sleep_register_touch_wakeup(void); +#endif + +#ifdef __cplusplus +} +#endif 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 8ef6f77c35..d46a5c1ac2 100644 --- a/examples/system/deep_sleep/main/deep_sleep_example_main.c +++ b/examples/system/deep_sleep/main/deep_sleep_example_main.c @@ -1,18 +1,12 @@ -/* Deep sleep wake up example - - This example code is in the Public Domain (or CC0 licensed, at your option.) - - Unless required by applicable law or agreed to in writing, this - software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR - CONDITIONS OF ANY KIND, either express or implied. -*/ +/* + * SPDX-FileCopyrightText: 2017-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ #include -#include -#include #include #include -#include #include "sdkconfig.h" #include "soc/soc_caps.h" #include "freertos/FreeRTOS.h" @@ -20,9 +14,9 @@ #include "esp_sleep.h" #include "esp_log.h" #include "driver/rtc_io.h" -#include "soc/rtc.h" #include "nvs_flash.h" #include "nvs.h" +#include "deep_sleep_example.h" #if SOC_RTC_FAST_MEM_SUPPORTED static RTC_DATA_ATTR struct timeval sleep_enter_time; @@ -30,28 +24,7 @@ static RTC_DATA_ATTR struct timeval sleep_enter_time; static struct timeval sleep_enter_time; #endif -#if SOC_TOUCH_SENSOR_SUPPORTED -#include "soc/sens_periph.h" -#include "driver/touch_pad.h" -#endif - -#if SOC_GPIO_SUPPORT_DEEPSLEEP_WAKEUP -#define DEFAULT_WAKEUP_PIN CONFIG_EXAMPLE_GPIO_WAKEUP_PIN -#ifdef CONFIG_EXAMPLE_GPIO_WAKEUP_HIGH_LEVEL -#define DEFAULT_WAKEUP_LEVEL ESP_GPIO_WAKEUP_GPIO_HIGH -#else -#define DEFAULT_WAKEUP_LEVEL ESP_GPIO_WAKEUP_GPIO_LOW -#endif -#endif - -#ifdef CONFIG_EXAMPLE_TOUCH_WAKEUP -#if CONFIG_IDF_TARGET_ESP32 -#define TOUCH_THRESH_NO_USE 0 -static void calibrate_touch_pad(touch_pad_t pad); -#endif -#endif - -void app_main(void) +static void deep_sleep_task(void *args) { /** * Prefer to use RTC mem instead of NVS to save the deep sleep enter time, unless the chip @@ -87,12 +60,31 @@ void app_main(void) int sleep_time_ms = (now.tv_sec - sleep_enter_time.tv_sec) * 1000 + (now.tv_usec - sleep_enter_time.tv_usec) / 1000; switch (esp_sleep_get_wakeup_cause()) { + case ESP_SLEEP_WAKEUP_TIMER: { + printf("Wake up from timer. Time spent in deep sleep: %dms\n", sleep_time_ms); + break; + } + +#if CONFIG_EXAMPLE_GPIO_WAKEUP + case ESP_SLEEP_WAKEUP_GPIO: { + uint64_t wakeup_pin_mask = esp_sleep_get_gpio_wakeup_status(); + if (wakeup_pin_mask != 0) { + int pin = __builtin_ffsll(wakeup_pin_mask) - 1; + printf("Wake up from GPIO %d\n", pin); + } else { + printf("Wake up from GPIO\n"); + } + break; + } +#endif //CONFIG_EXAMPLE_GPIO_WAKEUP + #if CONFIG_EXAMPLE_EXT0_WAKEUP case ESP_SLEEP_WAKEUP_EXT0: { printf("Wake up from ext0\n"); break; } #endif // CONFIG_EXAMPLE_EXT0_WAKEUP + #ifdef CONFIG_EXAMPLE_EXT1_WAKEUP case ESP_SLEEP_WAKEUP_EXT1: { uint64_t wakeup_pin_mask = esp_sleep_get_ext1_wakeup_status(); @@ -105,22 +97,7 @@ void app_main(void) break; } #endif // CONFIG_EXAMPLE_EXT1_WAKEUP -#if SOC_GPIO_SUPPORT_DEEPSLEEP_WAKEUP - case ESP_SLEEP_WAKEUP_GPIO: { - uint64_t wakeup_pin_mask = esp_sleep_get_gpio_wakeup_status(); - if (wakeup_pin_mask != 0) { - int pin = __builtin_ffsll(wakeup_pin_mask) - 1; - printf("Wake up from GPIO %d\n", pin); - } else { - printf("Wake up from GPIO\n"); - } - break; - } -#endif //SOC_GPIO_SUPPORT_DEEPSLEEP_WAKEUP - case ESP_SLEEP_WAKEUP_TIMER: { - printf("Wake up from timer. Time spent in deep sleep: %dms\n", sleep_time_ms); - break; - } + #ifdef CONFIG_EXAMPLE_TOUCH_WAKEUP case ESP_SLEEP_WAKEUP_TOUCHPAD: { printf("Wake up from touch on pad %d\n", esp_sleep_get_touchpad_wakeup_status()); @@ -135,124 +112,6 @@ void app_main(void) vTaskDelay(1000 / portTICK_PERIOD_MS); - const int wakeup_time_sec = 20; - printf("Enabling timer wakeup, %ds\n", wakeup_time_sec); - 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_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. - 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; - const uint64_t ext_wakeup_pin_1_mask = 1ULL << ext_wakeup_pin_1; - const int ext_wakeup_pin_2 = 4; - 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_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 -#if SOC_PM_SUPPORT_RTC_PERIPH_PD - ESP_ERROR_CHECK(esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_ON)); -#endif - 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 - -#ifdef CONFIG_EXAMPLE_GPIO_WAKEUP - const gpio_config_t config = { - .pin_bit_mask = BIT(DEFAULT_WAKEUP_PIN), - .mode = GPIO_MODE_INPUT, - }; - ESP_ERROR_CHECK(gpio_config(&config)); - ESP_ERROR_CHECK(esp_deep_sleep_enable_gpio_wakeup(BIT(DEFAULT_WAKEUP_PIN), DEFAULT_WAKEUP_LEVEL)); - printf("Enabling GPIO wakeup on pins GPIO%d\n", DEFAULT_WAKEUP_PIN); -#endif - -#ifdef CONFIG_EXAMPLE_TOUCH_WAKEUP -#if CONFIG_IDF_TARGET_ESP32 - // Initialize touch pad peripheral. - // The default fsm mode is software trigger mode. - ESP_ERROR_CHECK(touch_pad_init()); - // If use touch pad wake up, should set touch sensor FSM mode at 'TOUCH_FSM_MODE_TIMER'. - touch_pad_set_fsm_mode(TOUCH_FSM_MODE_TIMER); - // Set reference voltage for charging/discharging - // In this case, the high reference valtage will be 2.4V - 1V = 1.4V - // The low reference voltage will be 0.5 - // The larger the range, the larger the pulse count value. - touch_pad_set_voltage(TOUCH_HVOLT_2V4, TOUCH_LVOLT_0V5, TOUCH_HVOLT_ATTEN_1V); - //init RTC IO and mode for touch pad. - touch_pad_config(TOUCH_PAD_NUM8, TOUCH_THRESH_NO_USE); - touch_pad_config(TOUCH_PAD_NUM9, TOUCH_THRESH_NO_USE); - calibrate_touch_pad(TOUCH_PAD_NUM8); - calibrate_touch_pad(TOUCH_PAD_NUM9); -#elif CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 - /* Initialize touch pad peripheral. */ - touch_pad_init(); - /* Only support one touch channel in sleep mode. */ - touch_pad_config(TOUCH_PAD_NUM9); - /* Denoise setting at TouchSensor 0. */ - touch_pad_denoise_t denoise = { - /* The bits to be cancelled are determined according to the noise level. */ - .grade = TOUCH_PAD_DENOISE_BIT4, - .cap_level = TOUCH_PAD_DENOISE_CAP_L4, - }; - touch_pad_denoise_set_config(&denoise); - touch_pad_denoise_enable(); - printf("Denoise function init\n"); - /* Filter setting */ - touch_filter_config_t filter_info = { - .mode = TOUCH_PAD_FILTER_IIR_16, - .debounce_cnt = 1, // 1 time count. - .noise_thr = 0, // 50% - .jitter_step = 4, // use for jitter mode. - .smh_lvl = TOUCH_PAD_SMOOTH_IIR_2, - }; - touch_pad_filter_set_config(&filter_info); - touch_pad_filter_enable(); - printf("touch pad filter init %d\n", TOUCH_PAD_FILTER_IIR_8); - /* Set sleep touch pad. */ - touch_pad_sleep_channel_enable(TOUCH_PAD_NUM9, true); - touch_pad_sleep_channel_enable_proximity(TOUCH_PAD_NUM9, false); - /* Reducing the operating frequency can effectively reduce power consumption. */ - touch_pad_sleep_channel_set_work_time(1000, TOUCH_PAD_MEASURE_CYCLE_DEFAULT); - /* Enable touch sensor clock. Work mode is "timer trigger". */ - touch_pad_set_fsm_mode(TOUCH_FSM_MODE_TIMER); - touch_pad_fsm_start(); - vTaskDelay(100 / portTICK_PERIOD_MS); - - /* set touchpad wakeup threshold */ - uint32_t touch_value, wake_threshold; - touch_pad_sleep_channel_read_smooth(TOUCH_PAD_NUM9, &touch_value); - wake_threshold = touch_value * 0.1; // wakeup when touch sensor crosses 10% of background level - touch_pad_sleep_set_threshold(TOUCH_PAD_NUM9, wake_threshold); - printf("Touch pad #%d average: %"PRIu32", wakeup threshold set to %"PRIu32"\n", - TOUCH_PAD_NUM9, touch_value, (uint32_t)(touch_value * 0.1)); -#endif - printf("Enabling touch pad wakeup\n"); - 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 // Isolate GPIO12 pin from external circuits. This is needed for modules // which have an external pull-up resistor on GPIO12 (such as ESP32-WROVER) @@ -277,28 +136,37 @@ void app_main(void) esp_deep_sleep_start(); } -#ifdef CONFIG_EXAMPLE_TOUCH_WAKEUP -#if CONFIG_IDF_TARGET_ESP32 -static void calibrate_touch_pad(touch_pad_t pad) +static void example_deep_sleep_register_rtc_timer_wakeup(void) { - int avg = 0; - const size_t calibration_count = 128; - for (int i = 0; i < calibration_count; ++i) { - uint16_t val; - touch_pad_read(pad, &val); - avg += val; - } - avg /= calibration_count; - const int min_reading = 300; - if (avg < min_reading) { - printf("Touch pad #%d average reading is too low: %d (expecting at least %d). " - "Not using for deep sleep wakeup.\n", pad, avg, min_reading); - touch_pad_config(pad, 0); - } else { - int threshold = avg - 100; - printf("Touch pad #%d average: %d, wakeup threshold set to %d.\n", pad, avg, threshold); - touch_pad_config(pad, threshold); - } + const int wakeup_time_sec = 20; + printf("Enabling timer wakeup, %ds\n", wakeup_time_sec); + ESP_ERROR_CHECK(esp_sleep_enable_timer_wakeup(wakeup_time_sec * 1000000)); } + +void app_main(void) +{ + /* Enable wakeup from deep sleep by rtc timer */ + example_deep_sleep_register_rtc_timer_wakeup(); + +#if CONFIG_EXAMPLE_GPIO_WAKEUP + /* Enable wakeup from deep sleep by gpio */ + example_deep_sleep_register_gpio_wakeup(); #endif -#endif // CONFIG_EXAMPLE_TOUCH_WAKEUP + +#if CONFIG_EXAMPLE_EXT0_WAKEUP + /* Enable wakeup from deep sleep by ext0 */ + example_deep_sleep_register_ext0_wakeup(); +#endif + +#if CONFIG_EXAMPLE_EXT1_WAKEUP + /* Enable wakeup from deep sleep by ext1 */ + example_deep_sleep_register_ext1_wakeup(); +#endif + +#if CONFIG_EXAMPLE_TOUCH_WAKEUP + /* Enable wakeup from deep sleep by touch */ + example_deep_sleep_register_touch_wakeup(); +#endif + + xTaskCreate(deep_sleep_task, "deep_sleep_task", 4096, NULL, 6, NULL); +} diff --git a/examples/system/deep_sleep/main/ext_wakeup.c b/examples/system/deep_sleep/main/ext_wakeup.c new file mode 100644 index 0000000000..72ce6b0a6c --- /dev/null +++ b/examples/system/deep_sleep/main/ext_wakeup.c @@ -0,0 +1,55 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ + +#include +#include "esp_sleep.h" +#include "sdkconfig.h" +#include "driver/rtc_io.h" + +#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 + +void example_deep_sleep_register_ext0_wakeup(void) +{ + printf("Enabling EXT0 wakeup on pin GPIO%d\n", ext_wakeup_pin_0); + 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. + 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 + +#if CONFIG_EXAMPLE_EXT1_WAKEUP +void example_deep_sleep_register_ext1_wakeup(void) +{ + const int ext_wakeup_pin_1 = 2; + const uint64_t ext_wakeup_pin_1_mask = 1ULL << ext_wakeup_pin_1; + const int ext_wakeup_pin_2 = 4; + 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_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_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 diff --git a/examples/system/deep_sleep/main/gpio_wakeup.c b/examples/system/deep_sleep/main/gpio_wakeup.c new file mode 100644 index 0000000000..6af2f0358c --- /dev/null +++ b/examples/system/deep_sleep/main/gpio_wakeup.c @@ -0,0 +1,32 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ + +#include +#include "driver/gpio.h" +#include "esp_sleep.h" +#include "sdkconfig.h" + +#if CONFIG_EXAMPLE_GPIO_WAKEUP +#define DEFAULT_WAKEUP_PIN CONFIG_EXAMPLE_GPIO_WAKEUP_PIN +#ifdef CONFIG_EXAMPLE_GPIO_WAKEUP_HIGH_LEVEL +#define DEFAULT_WAKEUP_LEVEL ESP_GPIO_WAKEUP_GPIO_HIGH +#else +#define DEFAULT_WAKEUP_LEVEL ESP_GPIO_WAKEUP_GPIO_LOW +#endif + +void example_deep_sleep_register_gpio_wakeup(void) +{ + const gpio_config_t config = { + .pin_bit_mask = BIT(DEFAULT_WAKEUP_PIN), + .mode = GPIO_MODE_INPUT, + }; + + ESP_ERROR_CHECK(gpio_config(&config)); + ESP_ERROR_CHECK(esp_deep_sleep_enable_gpio_wakeup(BIT(DEFAULT_WAKEUP_PIN), DEFAULT_WAKEUP_LEVEL)); + + printf("Enabling GPIO wakeup on pins GPIO%d\n", DEFAULT_WAKEUP_PIN); +} +#endif diff --git a/examples/system/deep_sleep/main/touch_wakeup.c b/examples/system/deep_sleep/main/touch_wakeup.c new file mode 100644 index 0000000000..c2dd41daf8 --- /dev/null +++ b/examples/system/deep_sleep/main/touch_wakeup.c @@ -0,0 +1,109 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ + +#include +#include +#include "esp_sleep.h" +#include "sdkconfig.h" +#include "driver/rtc_io.h" +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" + +#ifdef CONFIG_EXAMPLE_TOUCH_WAKEUP +#include "driver/touch_pad.h" + +#if CONFIG_IDF_TARGET_ESP32 +#define TOUCH_THRESH_NO_USE 0 + +static void calibrate_touch_pad(touch_pad_t pad) +{ + int avg = 0; + const size_t calibration_count = 128; + for (int i = 0; i < calibration_count; ++i) { + uint16_t val; + touch_pad_read(pad, &val); + avg += val; + } + avg /= calibration_count; + const int min_reading = 300; + if (avg < min_reading) { + printf("Touch pad #%d average reading is too low: %d (expecting at least %d). " + "Not using for deep sleep wakeup.\n", pad, avg, min_reading); + touch_pad_config(pad, 0); + } else { + int threshold = avg - 100; + printf("Touch pad #%d average: %d, wakeup threshold set to %d.\n", pad, avg, threshold); + touch_pad_config(pad, threshold); + } +} +#endif + +void example_deep_sleep_register_touch_wakeup(void) +{ +#if CONFIG_IDF_TARGET_ESP32 + // Initialize touch pad peripheral. + // The default fsm mode is software trigger mode. + ESP_ERROR_CHECK(touch_pad_init()); + // If use touch pad wake up, should set touch sensor FSM mode at 'TOUCH_FSM_MODE_TIMER'. + touch_pad_set_fsm_mode(TOUCH_FSM_MODE_TIMER); + // Set reference voltage for charging/discharging + // In this case, the high reference valtage will be 2.4V - 1V = 1.4V + // The low reference voltage will be 0.5 + // The larger the range, the larger the pulse count value. + touch_pad_set_voltage(TOUCH_HVOLT_2V4, TOUCH_LVOLT_0V5, TOUCH_HVOLT_ATTEN_1V); + //init RTC IO and mode for touch pad. + touch_pad_config(TOUCH_PAD_NUM8, TOUCH_THRESH_NO_USE); + touch_pad_config(TOUCH_PAD_NUM9, TOUCH_THRESH_NO_USE); + calibrate_touch_pad(TOUCH_PAD_NUM8); + calibrate_touch_pad(TOUCH_PAD_NUM9); +#elif CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 + /* Initialize touch pad peripheral. */ + touch_pad_init(); + /* Only support one touch channel in sleep mode. */ + touch_pad_config(TOUCH_PAD_NUM9); + /* Denoise setting at TouchSensor 0. */ + touch_pad_denoise_t denoise = { + /* The bits to be cancelled are determined according to the noise level. */ + .grade = TOUCH_PAD_DENOISE_BIT4, + .cap_level = TOUCH_PAD_DENOISE_CAP_L4, + }; + touch_pad_denoise_set_config(&denoise); + touch_pad_denoise_enable(); + printf("Denoise function init\n"); + /* Filter setting */ + touch_filter_config_t filter_info = { + .mode = TOUCH_PAD_FILTER_IIR_16, + .debounce_cnt = 1, // 1 time count. + .noise_thr = 0, // 50% + .jitter_step = 4, // use for jitter mode. + .smh_lvl = TOUCH_PAD_SMOOTH_IIR_2, + }; + touch_pad_filter_set_config(&filter_info); + touch_pad_filter_enable(); + printf("touch pad filter init %d\n", TOUCH_PAD_FILTER_IIR_8); + /* Set sleep touch pad. */ + touch_pad_sleep_channel_enable(TOUCH_PAD_NUM9, true); + touch_pad_sleep_channel_enable_proximity(TOUCH_PAD_NUM9, false); + /* Reducing the operating frequency can effectively reduce power consumption. */ + touch_pad_sleep_channel_set_work_time(1000, TOUCH_PAD_MEASURE_CYCLE_DEFAULT); + /* Enable touch sensor clock. Work mode is "timer trigger". */ + touch_pad_set_fsm_mode(TOUCH_FSM_MODE_TIMER); + touch_pad_fsm_start(); + vTaskDelay(100 / portTICK_PERIOD_MS); + + /* set touchpad wakeup threshold */ + uint32_t touch_value, wake_threshold; + touch_pad_sleep_channel_read_smooth(TOUCH_PAD_NUM9, &touch_value); + wake_threshold = touch_value * 0.1; // wakeup when touch sensor crosses 10% of background level + touch_pad_sleep_set_threshold(TOUCH_PAD_NUM9, wake_threshold); + printf("Touch pad #%d average: %"PRIu32", wakeup threshold set to %"PRIu32"\n", + TOUCH_PAD_NUM9, touch_value, (uint32_t)(touch_value * 0.1)); +#endif + printf("Enabling touch pad wakeup\n"); + 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 diff --git a/examples/system/deep_sleep/pytest_deep_sleep.py b/examples/system/deep_sleep/pytest_deep_sleep.py index 0ab6dc4068..2da08f2fc6 100644 --- a/examples/system/deep_sleep/pytest_deep_sleep.py +++ b/examples/system/deep_sleep/pytest_deep_sleep.py @@ -32,23 +32,22 @@ def test_deep_sleep(dut: Dut) -> None: expect_items = ['Enabling timer wakeup, 20s'] for pad in wake_pads: expect_items += [r'Touch pad #{} average: \d+, wakeup threshold set to \d+.'.format(pad)] - expect_items += ['Enabling touch pad wakeup', - 'Entering deep sleep'] + expect_items += ['Enabling touch pad wakeup'] for exp in expect_items: dut.expect(exp, timeout=10) def expect_enable_deep_sleep_no_touch() -> None: dut.expect_exact('Enabling timer wakeup, 20s', timeout=10) - dut.expect_exact('Entering deep sleep', timeout=10) if dut.target in touch_wake_up_support: expect_enable_deep_sleep = expect_enable_deep_sleep_touch else: expect_enable_deep_sleep = expect_enable_deep_sleep_no_touch - dut.expect_exact('Not a deep sleep reset') expect_enable_deep_sleep() + dut.expect_exact('Not a deep sleep reset') + dut.expect_exact('Entering deep sleep') start_sleep = time.time() logging.info('Waiting for wakeup...') @@ -65,5 +64,6 @@ def test_deep_sleep(dut: Dut) -> None: dut.expect_exact('boot: Fast booting app from partition', timeout=2) # Check that it measured 2xxxxms in deep sleep, i.e at least 20 seconds: - dut.expect(r'Wake up from timer. Time spent in deep sleep: 2\d{4}ms', timeout=2) expect_enable_deep_sleep() + dut.expect(r'Wake up from timer. Time spent in deep sleep: 2\d{4}ms', timeout=2) + dut.expect_exact('Entering deep sleep') diff --git a/tools/ci/check_copyright_ignore.txt b/tools/ci/check_copyright_ignore.txt index 39d178fc0d..fecc8763c2 100644 --- a/tools/ci/check_copyright_ignore.txt +++ b/tools/ci/check_copyright_ignore.txt @@ -1570,7 +1570,6 @@ examples/system/console/basic/main/cmd_wifi.h examples/system/console/basic/main/console_example_main.c examples/system/console_usb/main/console_usb_example_main.c examples/system/deep_sleep/example_test.py -examples/system/deep_sleep/main/deep_sleep_example_main.c examples/system/efuse/example_test.py examples/system/efuse/main/efuse_main.c examples/system/esp_event/default_event_loop/example_test.py