refactor(touch): separate touch sleep example

This commit is contained in:
laokaiyao
2025-04-23 18:24:28 +08:00
parent 692512c0b3
commit 4fed6450a3
29 changed files with 246 additions and 300 deletions

View File

@@ -476,6 +476,7 @@ Application Examples
------------------------
- :example:`peripherals/touch_sensor/touch_sens_basic` demonstrates how to register touch channels and read the data, including hardware requirements and project configuration instructions.
- :example:`peripherals/touch_sensor/touch_sens_sleep` demonstrates how to wake up the chip from the light or deep sleep by the touch sensor.
Application Notes
-----------------

View File

@@ -432,8 +432,6 @@ Only Touch Button can be configured as a wake-up source.
Light- or Deep-sleep modes are both supported to be wakened up by a touch sensor. For the Light-sleep mode, any installed touch button can wake it up. But only the sleep button can wake up from Deep-sleep mode, and the touch sensor will do a calibration immediately, the reference value will be calibrated to a wrong value if our finger does not remove timely. Though the wrong reference value recovers after the finger removes away and has no effect on the driver logic, if you do not want to see a wrong reference value while waking up from Deep-sleep mode, you can call :cpp:func:`touch_element_sleep_enable_wakeup_calibration` to disable the wakeup calibration.
The Touch Element Wakeup example is available in `system/light_sleep` directory.
.. code-block:: c
void app_main()

View File

@@ -475,8 +475,9 @@ Application Examples
: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: - :example:`system/deep_sleep` demonstrates the usage of Deep-sleep wakeup triggered by various sources, such as the RTC timer, GPIOs, EXT0, EXT1, the touch sensor, supported by {IDF_TARGET_NAME}.
- :example:`system/light_sleep` demonstrates the usage of Light-sleep wakeup triggered by various sources, such as the timer, GPIOs, the touch sensor, supported by {IDF_TARGET_NAME}.
:not SOC_ULP_SUPPORTED: - :example:`system/deep_sleep` demonstrates the usage of Deep-sleep wakeup triggered by various sources, such as the RTC timer, GPIOs, EXT0, EXT1, supported by {IDF_TARGET_NAME}.
- :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_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.
API Reference
-------------

View File

@@ -476,6 +476,7 @@
--------
- :example:`peripherals/touch_sensor/touch_sens_basic` 演示了如何注册触摸通道并读取数据,并说明了硬件要求及项目配置。
- :example:`peripherals/touch_sensor/touch_sens_sleep` 演示了如何通过触摸传感器将芯片从 Light Sleep 或 Deep Sleep 状态唤醒。
应用注意事项
------------

View File

@@ -432,8 +432,6 @@
使用触摸传感器,可以唤醒从 Light-sleep 或 Deep-sleep 模式中唤醒芯片。在 Light-sleep 模式下,任何已安装的触摸按键都可以唤醒芯片。但在 Deep-sleep 模式下,只有睡眠按键可以唤醒芯片,触摸传感器还会立即进行校准。如果手指没有及时离开,可能导致校准参考值出错。尽管在手指离开后,校准参考值会自行恢复,不会影响驱动逻辑,但如果你不想在从 Deep-sleep 模式唤醒时看到错误的校准参考值,可以调用 :cpp:func:`touch_element_sleep_enable_wakeup_calibration`,禁用唤醒校准功能。
查看使用触摸元件唤醒芯片的示例代码,请前往 ESP-IDF 示例的 :example:`system/light_sleep` 目录。
.. code-block:: c
void app_main()

View File

@@ -475,8 +475,9 @@ UART 输出处理
:SOC_WIFI_SUPPORTED: - :example:`wifi/power_save` 演示如何通过 Wi-Fi Modem-sleep 模式和自动 Light-sleep 模式保持 Wi-Fi 连接。
:SOC_BT_SUPPORTED: - :example:`bluetooth/nimble/power_save` 演示如何通过 Bluetooth Modem-sleep 模式和自动 Light-sleep 模式保持 Bluetooth 连接。
:SOC_ULP_SUPPORTED: - :example:`system/deep_sleep` 演示如何使用 Deep-sleep 唤醒触发器和 ULP 协处理器编程。
:not SOC_ULP_SUPPORTED: - :example:`system/deep_sleep` 演示如何通过 {IDF_TARGET_NAME} 的唤醒源,如 RTC 定时器, GPIO, EXT0, EXT1, 触摸传感器等,触发 Deep-sleep 唤醒。
- :example:`system/light_sleep` 演示如何使用 {IDF_TARGET_NAME} 的唤醒源如定时器GPIO,触摸传感器等,触发 Light-sleep 唤醒。
:not SOC_ULP_SUPPORTED: - :example:`system/deep_sleep` 演示如何通过 {IDF_TARGET_NAME} 的唤醒源,如 RTC 定时器, GPIO, EXT0, EXT1等触发 Deep-sleep 唤醒。
- :example:`system/light_sleep` 演示如何使用 {IDF_TARGET_NAME} 的唤醒源如定时器GPIO等触发 Light-sleep 唤醒。
:SOC_TOUCH_SENSOR_SUPPORTED and SOC_PM_SUPPORT_TOUCH_SENSOR_WAKEUP: - :example:`peripherals/touch_sensor/touch_sens_sleep` 演示如何使用触摸传感器唤醒 Light-sleep 或 Deep-sleep。
API 参考
-------------

View File

@@ -479,6 +479,12 @@ examples/peripherals/touch_sensor/touch_sens_basic:
depends_components:
- esp_driver_touch_sens
examples/peripherals/touch_sensor/touch_sens_sleep:
disable:
- if: SOC_TOUCH_SENSOR_SUPPORTED != 1 or SOC_PM_SUPPORT_TOUCH_SENSOR_WAKEUP != 1
depends_components:
- esp_driver_touch_sens
examples/peripherals/twai/twai_alert_and_recovery:
disable:
- if: SOC_TWAI_SUPPORTED != 1 or SOC_TWAI_SUPPORT_FD == 1

View File

@@ -0,0 +1,6 @@
# The following five lines of boilerplate have to be in your project's
# CMakeLists in this exact order for cmake to work correctly
cmake_minimum_required(VERSION 3.16)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(touch_sens_sleep)

View File

@@ -0,0 +1,95 @@
| Supported Targets | ESP32 | ESP32-P4 | ESP32-S2 | ESP32-S3 |
| ----------------- | ----- | -------- | -------- | -------- |
# Touch Sensor Sleep Wake up Example
(See the README.md file in the upper level 'examples' directory for more information about examples.)
This example is going to demonstrate how to wake up the chip from light/deep sleep by the touch sensor.
## How to Use Example
### Hardware Required
* A development board with any supported Espressif SOC chip (see `Supported Targets` table above)
* A USB cable for power supply and programming
* (Optional) Touch board with touch buttons on it.
- If you don't have a touch board, you can connect the touch pins with male jump wires and touch it directly for testing.
### Configure the Project
You can determine the touch channel number by ``EXAMPLE_TOUCH_CHANNEL_NUM`` in the example. And adjust the active threshold by ``s_thresh2bm_ratio``.
You can run `idf.py menuconfig` to configure the example
- `Example Configuration > Touch Sensor wakeup level`: Select `Light sleep wakeup` or `Deep sleep wakeup` mode
- `Example Configuration > Allow touch sensor power down during the deep sleep`: Choose whether to allow the touch sensor power down during the deep sleep. If enabled, the touch sensor will be powered down during the deep sleep, only one specified touch channel can wakeup the chip from deep sleep. If disabled, the touch sensor will keep working during the deep sleep. Any enabled touch channel can wakeup the chip from deep sleep.
### Build and Flash
Build the project and flash it to the board, then run monitor tool to view serial output:
```
idf.py -p PORT build flash monitor
```
(To exit the serial monitor, type ``Ctrl-]``.)
See the Getting Started Guide for full steps to configure and use ESP-IDF to build projects.
## Example Output
### Light Sleep Log
```
...
Touch [CH 7] enabled on GPIO9
Touch [CH 8] enabled on GPIO10
Touch [CH 9] enabled on GPIO11
Initial benchmark and new threshold are:
Touch [CH 7] 0: 4884, 97
Touch [CH 8] 0: 4993, 99
Touch [CH 9] 0: 4913, 98
I (399) touch_wakeup: touch wakeup source is ready
Entering light sleep in:
5 sec...
4 sec...
3 sec...
2 sec...
1 sec...
W (5399) touch callback: ch 8 active
I (5399) touch_wakeup: Wake up by touch
Entering light sleep in:
5 sec...
W (5479) touch callback: ch 8 inactive
4 sec...
3 sec...
2 sec...
1 sec...
```
### Deep Sleep Log
```
...
Touch [CH 7] enabled on GPIO9
Touch [CH 8] enabled on GPIO10
Touch [CH 9] enabled on GPIO11
Initial benchmark and new threshold are:
Touch [CH 7] 0: 4897, 97
Touch [CH 8] 0: 4879, 97
Touch [CH 9] 0: 4954, 99
I (405) touch_wakeup: touch wakeup source is ready
Entering deep sleep in:
5 sec...
4 sec...
3 sec...
2 sec...
1 sec...
```
## Troubleshooting
For any technical queries, please open an [issue](https://github.com/espressif/esp-idf/issues) on GitHub. We will get back to you soon.

View File

@@ -0,0 +1,3 @@
idf_component_register(SRCS "touch_sens_sleep.c"
PRIV_REQUIRES esp_driver_touch_sens esp_driver_uart
INCLUDE_DIRS ".")

View File

@@ -0,0 +1,27 @@
menu "Example Configuration"
choice EXAMPLE_TOUCH_SLP_WAKEUP
prompt "Touch Sensor wakeup level"
default EXAMPLE_TOUCH_LIGHT_SLEEP_WAKEUP
help
Select the touch sensor can wakeup from light sleep or deep sleep.
config EXAMPLE_TOUCH_LIGHT_SLEEP_WAKEUP
bool "Light sleep wakeup"
config EXAMPLE_TOUCH_DEEP_SLEEP_WAKEUP
bool "Deep sleep wakeup"
endchoice
config EXAMPLE_TOUCH_DEEP_SLEEP_PD
prompt "Allow touch sensor power down during the deep sleep"
bool
depends on EXAMPLE_TOUCH_DEEP_SLEEP_WAKEUP && !IDF_TARGET_ESP32
default "n"
help
Whether to allow the touch sensor power down during the deep sleep.
If enabled, the touch sensor will be powered down during the deep sleep,
only one specified touch channel can wakeup the chip from deep sleep.
If disabled, the touch sensor will keep working during the deep sleep,
any enabled touch channel can wakeup the chip from deep sleep.
endmenu

View File

@@ -1,13 +1,14 @@
/*
* SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
#include <string.h>
#include "freertos/FreeRTOS.h"
#include "esp_log.h"
#include "driver/touch_sens.h"
#include "driver/uart.h"
#include "touch_sens_example_config.h"
#include "esp_sleep.h"
static const char *TAG = "touch_wakeup";
@@ -15,7 +16,6 @@ static const char *TAG = "touch_wakeup";
#define EXAMPLE_TOUCH_CHANNEL_NUM 3
#define EXAMPLE_TOUCH_CHAN_INIT_SCAN_TIMES 3
// The touch channel IDs that used in this example
// If you want to change the wake-up channels, please make sure the channel GPIOs won't conflict to the EXT wakeup GPIOs
static int s_channel_id[EXAMPLE_TOUCH_CHANNEL_NUM] = {7, 8, 9};
@@ -80,10 +80,8 @@ static void example_touch_do_initial_scanning(touch_sensor_handle_t sens_handle,
}
}
esp_err_t example_deep_sleep_register_touch_wakeup(void)
esp_err_t example_touch_wakeup_init(void)
{
printf("Enabling touch wakeup\n");
/* Handles of touch sensor */
touch_sensor_handle_t sens_handle = NULL;
touch_channel_handle_t chan_handle[EXAMPLE_TOUCH_CHANNEL_NUM];
@@ -112,37 +110,82 @@ esp_err_t example_deep_sleep_register_touch_wakeup(void)
*/
example_touch_do_initial_scanning(sens_handle, chan_handle);
/* (Optional) Register the callbacks, optional for deep sleep wakeup */
/* (Optional) Register the callbacks, optional for light/deep sleep wakeup */
touch_event_callbacks_t callbacks = {
.on_active = example_touch_on_active_cb,
.on_inactive = example_touch_on_inactive_cb,
};
ESP_ERROR_CHECK(touch_sensor_register_callbacks(sens_handle, &callbacks, NULL));
/* Step 4: Enable the deep sleep wake-up with the basic configuration */
#if CONFIG_EXAMPLE_TOUCH_ALLOW_DSLP_PD
/* Step 4: Enable the light sleep wake-up with the basic configuration */
#if CONFIG_EXAMPLE_TOUCH_LIGHT_SLEEP_WAKEUP
touch_sleep_config_t slp_cfg = TOUCH_SENSOR_DEFAULT_LSLP_CONFIG();
#else
#if CONFIG_EXAMPLE_TOUCH_DEEP_SLEEP_PD
/* Get the channel information to use same active threshold for the sleep channel */
touch_chan_info_t chan_info = {};
ESP_ERROR_CHECK(touch_sensor_get_channel_info(chan_handle[0], &chan_info));
touch_sleep_config_t deep_slp_cfg = TOUCH_SENSOR_DEFAULT_DSLP_PD_CONFIG(chan_handle[0],
chan_info.active_thresh[0],
#if SOC_TOUCH_SENSOR_VERSION == 3
chan_info.active_thresh[1],
chan_info.active_thresh[2],
#endif
);
touch_sleep_config_t slp_cfg = TOUCH_SENSOR_DEFAULT_DSLP_PD_CONFIG(chan_handle[0], chan_info.active_thresh[0]);
printf("Touch channel %d (GPIO%d) is selected as deep sleep wakeup channel\n", chan_info.chan_id, chan_info.chan_gpio);
#else
touch_sleep_config_t deep_slp_cfg = TOUCH_SENSOR_DEFAULT_DSLP_CONFIG();
#endif
/* Enable deep sleep wake up for touch sensor */
ESP_ERROR_CHECK(touch_sensor_config_sleep_wakeup(sens_handle, &deep_slp_cfg));
touch_sleep_config_t slp_cfg = TOUCH_SENSOR_DEFAULT_DSLP_CONFIG();
#endif // CONFIG_EXAMPLE_TOUCH_DEEP_SLEEP_PD
#endif // CONFIG_EXAMPLE_TOUCH_LIGHT_SLEEP_WAKEUP
ESP_ERROR_CHECK(touch_sensor_config_sleep_wakeup(sens_handle, &slp_cfg));
/* Step 5: Enable touch sensor controller and start continuous scanning before entering deep sleep */
/* Step 5: Enable touch sensor controller and start continuous scanning before entering light sleep */
ESP_ERROR_CHECK(touch_sensor_enable(sens_handle));
ESP_ERROR_CHECK(touch_sensor_start_continuous_scanning(sens_handle));
ESP_LOGI(TAG, "touch wakeup source is ready");
return ESP_OK;
}
void example_prepare_sleep(void)
{
#if CONFIG_EXAMPLE_TOUCH_LIGHT_SLEEP_WAKEUP
while (1) {
printf("Entering light sleep in:\n");
for (int i = 0; i < 5; i++) {
printf("%d sec...\n", 5 - i);
vTaskDelay(pdMS_TO_TICKS(1000));
}
/* Wait the UART to finish printing the log */
uart_wait_tx_idle_polling(CONFIG_ESP_CONSOLE_UART_NUM);
/* Enter the light sleep */
esp_light_sleep_start();
/* Keep executing the code after waking up from the light sleep */
if (esp_sleep_get_wakeup_cause() == ESP_SLEEP_WAKEUP_TOUCHPAD) {
ESP_LOGI(TAG, "Wake up by touch\n");
} else {
ESP_LOGE(TAG, "Wake up by other source\n");
abort();
}
}
#else
printf("Entering deep sleep in:\n");
for (int i = 0; i < 5; i++) {
printf("%d sec...\n", 5 - i);
vTaskDelay(pdMS_TO_TICKS(1000));
}
/* Wait the UART to finish printing the log */
uart_wait_tx_idle_polling(CONFIG_ESP_CONSOLE_UART_NUM);
/* Enter the deep sleep */
esp_deep_sleep_start();
#endif
}
void app_main(void)
{
#if CONFIG_EXAMPLE_TOUCH_DEEP_SLEEP_WAKEUP
/* Printing the log if the chip is waken up from deepsleep by the touchpad */
if (esp_sleep_get_wakeup_cause() == ESP_SLEEP_WAKEUP_TOUCHPAD) {
ESP_LOGI(TAG, "Wake up by touch\n");
}
#endif // CONFIG_EXAMPLE_TOUCH_DEEP_SLEEP_WAKEUP
/* Initialize the touch pad and sleep wakeup feature */
example_touch_wakeup_init();
/* Prepare to sleep */
example_prepare_sleep();
}

View File

@@ -0,0 +1,29 @@
# SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
# SPDX-License-Identifier: Unlicense OR CC0-1.0
import pytest
from pytest_embedded import Dut
from pytest_embedded_idf.utils import idf_parametrize
from pytest_embedded_idf.utils import soc_filtered_targets
@pytest.mark.generic
@idf_parametrize(
'target',
soc_filtered_targets('SOC_TOUCH_SENSOR_SUPPORTED == 1 and SOC_PM_SUPPORT_TOUCH_SENSOR_WAKEUP == 1'),
indirect=['target'],
)
def test_touch_sens_sleep(dut: Dut) -> None:
dut.expect(r'Touch \[CH [0-9]+\] enabled on GPIO[0-9]+')
dut.expect(r'Initial benchmark and new threshold are:')
dut.expect(r'Touch \[CH [0-9]+\] 0: [0-9]+, [0-9]+')
dut.expect(r'touch_wakeup: touch wakeup source is ready')
if dut.app.sdkconfig.get('EXAMPLE_TOUCH_LIGHT_SLEEP_WAKEUP'):
sleep_mode_str = 'light'
else:
sleep_mode_str = 'deep'
dut.expect(f'Entering {sleep_mode_str} sleep in:')
dut.expect(r'5 sec...')
dut.expect(r'4 sec...')
dut.expect(r'3 sec...')
dut.expect(r'2 sec...')
dut.expect(r'1 sec...')

View File

@@ -0,0 +1 @@
CONFIG_EXAMPLE_TOUCH_DEEP_SLEEP_WAKEUP=y

View File

@@ -0,0 +1 @@
CONFIG_EXAMPLE_TOUCH_LIGHT_SLEEP_WAKEUP=y

View File

@@ -13,7 +13,6 @@ The following wake up sources are demonstrated in this example (refer to the [Wa
- **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 available on ESP32, ESP32-S2, ESP32-S3, ESP32-C6 and ESP32-H2.)
- **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, ESP32-S3 and ESP32-H2.)
- **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.
Note: Some wake up sources can be disabled via configuration (see section on [project configuration](#Configure-the-project))
@@ -33,15 +32,12 @@ This example should be able to run on any commonly available ESP32 series develo
- **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
```
idf.py menuconfig
```
* **Touch wake up** can be enabled/disabled via `Example configuration > Enable touch wake up`
* **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`
@@ -75,9 +71,6 @@ I (0) cpu_start: Starting scheduler on APP CPU.
Not a deep sleep reset
Enabling timer wakeup, 20s
Enabling EXT1 wakeup on pins GPIO2, GPIO4
Touch pad #8 average: 2148, wakeup threshold set to 2048.
Touch pad #9 average: 2148, wakeup threshold set to 2048.
Enabling touch pad wakeup
Entering deep sleep
```
@@ -91,8 +84,5 @@ Wake up from timer. Time spent in deep sleep: 20313ms
Initial T=87, latest T=87
Enabling timer wakeup, 20s
Enabling EXT1 wakeup on pins GPIO2, GPIO4
Touch pad #8 average: 2149, wakeup threshold set to 2049.
Touch pad #9 average: 2146, wakeup threshold set to 2046.
Enabling touch pad wakeup
Entering deep sleep
```

View File

@@ -3,10 +3,6 @@ set(srcs "deep_sleep_example_main.c"
"ext_wakeup.c")
set(includes ".")
if(CONFIG_SOC_TOUCH_SENSOR_SUPPORTED AND CONFIG_SOC_PM_SUPPORT_TOUCH_SENSOR_WAKEUP)
list(APPEND srcs "touch_sens_wakeup.c")
endif()
idf_component_register(SRCS ${srcs}
PRIV_REQUIRES nvs_flash ulp esp_driver_gpio esp_driver_touch_sens
PRIV_REQUIRES nvs_flash ulp esp_driver_gpio
INCLUDE_DIRS ${includes})

View File

@@ -1,17 +1,5 @@
menu "Example Configuration"
config EXAMPLE_TOUCH_WAKEUP
bool "Enable touch wake up"
default y
depends on SOC_PM_SUPPORT_TOUCH_SENSOR_WAKEUP && SOC_TOUCH_SENSOR_SUPPORTED
help
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.
ESP32P4 - TOUCH2, which corresponds to GPIO4.
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 if !IDF_TARGET_ESP32
@@ -285,18 +273,4 @@ menu "Example Configuration"
supported. If this option is enabled, it is a high level wake up, otherwise it is a low level wake up.
endmenu
menu "Touch wakeup configuration"
visible if EXAMPLE_TOUCH_WAKEUP
config EXAMPLE_TOUCH_ALLOW_DSLP_PD
bool "Allow RTC_PERIPH power domain to be powered down during deep sleep"
depends on !IDF_TARGET_ESP32
default y
help
Enable this option if allow the RTC_PERIPH power domain (contain touch sensor) to be powered down
during deep sleep. It can help to save more power, but only one specified touch channel can wakeup
from the deep sleep. If this option is disabled, the RTC_PERIPH power domain will be powered up
during deep sleep, and all enabled touch channels can wakeup from the deep sleep.
endmenu
endmenu

View File

@@ -24,10 +24,6 @@ void example_deep_sleep_register_ext0_wakeup(void);
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

View File

@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2017-2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2017-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
@@ -98,13 +98,6 @@ static void deep_sleep_task(void *args)
}
#endif // CONFIG_EXAMPLE_EXT1_WAKEUP
#ifdef CONFIG_EXAMPLE_TOUCH_WAKEUP
case ESP_SLEEP_WAKEUP_TOUCHPAD: {
printf("Wake up from touch\n");
break;
}
#endif // CONFIG_EXAMPLE_TOUCH_WAKEUP
case ESP_SLEEP_WAKEUP_UNDEFINED:
default:
printf("Not a deep sleep reset\n");
@@ -163,10 +156,5 @@ void app_main(void)
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);
}

View File

@@ -32,26 +32,7 @@ CONFIGS = [
'config,target', [('esp32_singlecore', 'esp32'), ('basic', 'supported_targets')], indirect=['config', 'target']
)
def test_deep_sleep(dut: Dut) -> None:
def expect_enable_deep_sleep_touch() -> None:
expect_items = ['Enabling timer wakeup, 20s']
expect_items += ['Enabling touch wakeup']
expect_items += [r'Touch \[CH [0-9]+\] enabled on GPIO[0-9]+']
if dut.target != 'esp32':
expect_items += [r'Touch channel [0-9]+ \(GPIO[0-9]+\) is selected as deep sleep wakeup channel']
expect_items += ['touch wakeup source is ready']
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)
if dut.app.sdkconfig.get('SOC_TOUCH_SUPPORT_SLEEP_WAKEUP'):
expect_enable_deep_sleep = expect_enable_deep_sleep_touch
else:
expect_enable_deep_sleep = expect_enable_deep_sleep_no_touch
expect_enable_deep_sleep()
dut.expect_exact('Enabling timer wakeup, 20s', timeout=10)
dut.expect_exact('Not a deep sleep reset')
dut.expect_exact('Entering deep sleep')
@@ -66,6 +47,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:
expect_enable_deep_sleep()
dut.expect_exact('Enabling timer wakeup, 20s', timeout=10)
dut.expect(r'Wake up from timer. Time spent in deep sleep: 2\d{4}ms', timeout=2)
dut.expect_exact('Entering deep sleep')

View File

@@ -6,4 +6,3 @@ CONFIG_LIBC_TIME_SYSCALL_USE_RTC_HRT=y
CONFIG_RTC_CLK_SRC_INT_RC=y
CONFIG_BOOTLOADER_SKIP_VALIDATE_IN_DEEP_SLEEP=y
CONFIG_PARTITION_TABLE_CUSTOM=y
CONFIG_TOUCH_SUPPRESS_DEPRECATE_WARN=y

View File

@@ -68,46 +68,6 @@ Note #3: due to limitation of the HW, the bytes that received during light sleep
Note #4: after waking-up from UART, you should send some extra data through the UART port, so that the internal wakeup indication signal can be cleared. Otherwises, the next UART wake-up would trigger with two less rising edges than the configured threshold value.
### Wake-up by Touch Pad
For this example, pressing any registered touch buttons can wake up the chip.
Note #1: For light sleep, all registered touch buttons can wake up the chip. But only the channel which is configured as wake up channel can wake up the chip from deep sleep.
Note #2: Waking-up by touch pad relies on 'touch_element' driver, which can only support ESP32-S2 and ESP32-S3 currently.
```
Entering light sleep
Returned from light sleep, reason: timer, t=2713 ms, slept for 1999 ms
Entering light sleep
Returned from light sleep, reason: timer, t=4722 ms, slept for 2000 ms
Entering light sleep
Returned from light sleep, reason: uart, t=5148 ms, slept for 418 ms
Entering light sleep
Returned from light sleep, reason: uart, t=6178 ms, slept for 1022 ms
Entering light sleep
Returned from light sleep, reason: timer, t=8187 ms, slept for 2000 ms
Entering light sleep
Returned from light sleep, reason: timer, t=10195 ms, slept for 2000 ms
Entering light sleep
Returned from light sleep, reason: timer, t=12203 ms, slept for 2000 ms
Entering light sleep
Returned from light sleep, reason: pin, t=12555 ms, slept for 342 ms
Waiting for GPIO9 to go high...
Entering light sleep
Returned from light sleep, reason: pin, t=12564 ms, slept for 1 ms
Waiting for GPIO9 to go high...
Entering light sleep
...
I (361) touch_wakeup: Button[1] Press
Returned from light sleep, reason: touch, t=14471 ms, slept for 467 ms
Entering light sleep
...
```
In the scenario above, the button attached to GPIO0 was pressed and held for about 3 seconds, after the 2nd wakeup from light sleep. The program has indicated the wakeup reason after each sleep iteration.
## Current Consumption
In this example, current consumption in light sleep mode is in the range of 0.8 — 1.1 mA. Current consumption in active mode is 28 — 32 mA. Average current consumption is 1.1 - 1.3 mA.

View File

@@ -6,10 +6,7 @@ set(srcs "light_sleep_example_main.c"
"uart_wakeup.c")
set(includes ".")
if(CONFIG_SOC_TOUCH_SENSOR_SUPPORTED AND CONFIG_SOC_PM_SUPPORT_TOUCH_SENSOR_WAKEUP)
list(APPEND srcs "touch_sens_wakeup.c")
endif()
idf_component_register(SRCS ${srcs}
PRIV_REQUIRES esp_driver_uart esp_driver_gpio esp_timer esp_driver_touch_sens
PRIV_REQUIRES esp_driver_uart esp_driver_gpio esp_timer
INCLUDE_DIRS ${includes})

View File

@@ -1,3 +0,0 @@
dependencies:
touch_sens_examples_common:
path: ${IDF_PATH}/examples/peripherals/touch_sensor/touch_sens_examples_common

View File

@@ -12,8 +12,6 @@
extern "C" {
#endif
#define TOUCH_LSLEEP_SUPPORTED (SOC_TOUCH_SENSOR_SUPPORTED && SOC_PM_SUPPORT_TOUCH_SENSOR_WAKEUP)
void example_wait_gpio_inactive(void);
esp_err_t example_register_gpio_wakeup(void);
@@ -22,10 +20,6 @@ esp_err_t example_register_timer_wakeup(void);
esp_err_t example_register_uart_wakeup(void);
#if TOUCH_LSLEEP_SUPPORTED
void example_register_touch_wakeup(void);
#endif
#ifdef __cplusplus
}
#endif

View File

@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
@@ -50,11 +50,6 @@ static void light_sleep_task(void *args)
* Otherwise the chip may fall sleep again before running uart task */
vTaskDelay(1);
break;
#if TOUCH_LSLEEP_SUPPORTED
case ESP_SLEEP_WAKEUP_TOUCHPAD:
wakeup_reason = "touch";
break;
#endif
default:
wakeup_reason = "other";
break;
@@ -83,10 +78,6 @@ void app_main(void)
example_register_timer_wakeup();
/* Enable wakeup from light sleep by uart */
example_register_uart_wakeup();
#if TOUCH_LSLEEP_SUPPORTED
/* Enable wakeup from light sleep by touch element */
example_register_touch_wakeup();
#endif
xTaskCreate(light_sleep_task, "light_sleep_task", 4096, NULL, 6, NULL);
}

View File

@@ -1,128 +0,0 @@
/*
* SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
#include "freertos/FreeRTOS.h"
#include "esp_log.h"
#include "driver/touch_sens.h"
#include "touch_sens_example_config.h"
static const char *TAG = "touch_wakeup";
#define EXAMPLE_TOUCH_SAMPLE_CFG_NUM 1
#define EXAMPLE_TOUCH_CHANNEL_NUM 3
#define EXAMPLE_TOUCH_CHAN_INIT_SCAN_TIMES 3
// If you want to change the wake-up channels, please make sure the channel GPIOs won't conflict to the EXT wakeup GPIOs
static int s_channel_id[EXAMPLE_TOUCH_CHANNEL_NUM] = {7, 8, 9};
// Active threshold to benchmark ratio. (i.e., touch will be activated when data >= benchmark * (1 + ratio))
static float s_thresh2bm_ratio[EXAMPLE_TOUCH_CHANNEL_NUM] = {
[0 ... EXAMPLE_TOUCH_CHANNEL_NUM - 1] = 0.02f, // 2%
};
static bool example_touch_on_active_cb(touch_sensor_handle_t sens_handle, const touch_active_event_data_t *event, void *user_ctx)
{
ESP_EARLY_LOGW("touch callback", "ch %d active", (int)event->chan_id);
return false;
}
static bool example_touch_on_inactive_cb(touch_sensor_handle_t sens_handle, const touch_inactive_event_data_t *event, void *user_ctx)
{
ESP_EARLY_LOGW("touch callback", "ch %d inactive", (int)event->chan_id);
return false;
}
static void example_touch_do_initial_scanning(touch_sensor_handle_t sens_handle, touch_channel_handle_t chan_handle[])
{
/* Enable the touch sensor to do the initial scanning, so that to initialize the channel data */
ESP_ERROR_CHECK(touch_sensor_enable(sens_handle));
/* Scan the enabled touch channels for several times, to make sure the initial channel data is stable */
for (int i = 0; i < EXAMPLE_TOUCH_CHAN_INIT_SCAN_TIMES; i++) {
ESP_ERROR_CHECK(touch_sensor_trigger_oneshot_scanning(sens_handle, 2000));
}
/* Disable the touch channel to rollback the state */
ESP_ERROR_CHECK(touch_sensor_disable(sens_handle));
/* (Optional) Read the initial channel benchmark and reconfig the channel active threshold accordingly */
printf("Initial benchmark and new threshold are:\n");
for (int i = 0; i < EXAMPLE_TOUCH_CHANNEL_NUM; i++) {
/* Read the initial benchmark of the touch channel */
uint32_t benchmark[EXAMPLE_TOUCH_SAMPLE_CFG_NUM] = {};
#if SOC_TOUCH_SUPPORT_BENCHMARK
ESP_ERROR_CHECK(touch_channel_read_data(chan_handle[i], TOUCH_CHAN_DATA_TYPE_BENCHMARK, benchmark));
#else
/* Read smooth data instead if the hardware does not support benchmark */
ESP_ERROR_CHECK(touch_channel_read_data(chan_handle[i], TOUCH_CHAN_DATA_TYPE_SMOOTH, benchmark));
#endif // SOC_TOUCH_SUPPORT_BENCHMARK
/* Calculate the proper active thresholds regarding the initial benchmark */
printf("Touch [CH %d]", s_channel_id[i]);
/* Generate the default channel configuration and then update the active threshold based on the real benchmark */
touch_channel_config_t chan_cfg = EXAMPLE_TOUCH_CHAN_CFG_DEFAULT();
for (int j = 0; j < EXAMPLE_TOUCH_SAMPLE_CFG_NUM; j++) {
#if SOC_TOUCH_SENSOR_VERSION == 1
// Touch V1 (ESP32) uses absolute threshold.
chan_cfg.abs_active_thresh[j] = (uint32_t)(benchmark[j] * (1 - s_thresh2bm_ratio[i]));
printf(" %d: %"PRIu32", %"PRIu32"\t", j, benchmark[j], chan_cfg.abs_active_thresh[j]);
#else
chan_cfg.active_thresh[j] = (uint32_t)(benchmark[j] * s_thresh2bm_ratio[i]);
printf(" %d: %"PRIu32", %"PRIu32"\t", j, benchmark[j], chan_cfg.active_thresh[j]);
#endif // SOC_TOUCH_SENSOR_VERSION == 1
}
printf("\n");
/* Update the channel configuration */
ESP_ERROR_CHECK(touch_sensor_reconfig_channel(chan_handle[i], &chan_cfg));
}
}
esp_err_t example_register_touch_wakeup(void)
{
/* Handles of touch sensor */
touch_sensor_handle_t sens_handle = NULL;
touch_channel_handle_t chan_handle[EXAMPLE_TOUCH_CHANNEL_NUM];
/* Step 1: Create a new touch sensor controller handle with default sample configuration */
touch_sensor_sample_config_t sample_cfg[TOUCH_SAMPLE_CFG_NUM] = EXAMPLE_TOUCH_SAMPLE_CFG_DEFAULT();
touch_sensor_config_t sens_cfg = TOUCH_SENSOR_DEFAULT_BASIC_CONFIG(EXAMPLE_TOUCH_SAMPLE_CFG_NUM, sample_cfg);
ESP_ERROR_CHECK(touch_sensor_new_controller(&sens_cfg, &sens_handle));
/* Step 2: Create and enable the new touch channel handles with default configurations */
touch_channel_config_t chan_cfg = EXAMPLE_TOUCH_CHAN_CFG_DEFAULT();
for (int i = 0; i < EXAMPLE_TOUCH_CHANNEL_NUM; i++) {
ESP_ERROR_CHECK(touch_sensor_new_channel(sens_handle, s_channel_id[i], &chan_cfg, &chan_handle[i]));
/* Display the touch channel corresponding GPIO number, you can also know from `touch_sensor_channel.h` */
touch_chan_info_t chan_info = {};
ESP_ERROR_CHECK(touch_sensor_get_channel_info(chan_handle[i], &chan_info));
printf("Touch [CH %d] enabled on GPIO%d\n", s_channel_id[i], chan_info.chan_gpio);
}
/* Step 3: Confiture the default filter for the touch sensor (Note: Touch V1 uses software filter) */
touch_sensor_filter_config_t filter_cfg = TOUCH_SENSOR_DEFAULT_FILTER_CONFIG();
ESP_ERROR_CHECK(touch_sensor_config_filter(sens_handle, &filter_cfg));
/* (Optional) Do the initial scanning to initialize the touch channel data
* Without this step, the channel data in the first read will be invalid
*/
example_touch_do_initial_scanning(sens_handle, chan_handle);
/* (Optional) Register the callbacks, optional for light sleep wakeup */
touch_event_callbacks_t callbacks = {
.on_active = example_touch_on_active_cb,
.on_inactive = example_touch_on_inactive_cb,
};
ESP_ERROR_CHECK(touch_sensor_register_callbacks(sens_handle, &callbacks, NULL));
/* Step 4: Enable the light sleep wake-up with the basic configuration */
touch_sleep_config_t light_slp_cfg = TOUCH_SENSOR_DEFAULT_LSLP_CONFIG();
ESP_ERROR_CHECK(touch_sensor_config_sleep_wakeup(sens_handle, &light_slp_cfg));
/* Step 5: Enable touch sensor controller and start continuous scanning before entering light sleep */
ESP_ERROR_CHECK(touch_sensor_enable(sens_handle));
ESP_ERROR_CHECK(touch_sensor_start_continuous_scanning(sens_handle));
ESP_LOGI(TAG, "touch wakeup source is ready");
return ESP_OK;
}