docs(touch): add doc for cap touch sens driver

This commit is contained in:
laokaiyao 2024-06-07 17:26:31 +08:00
parent e8b29653c0
commit d263ab3145
22 changed files with 914 additions and 122 deletions

View File

@ -419,10 +419,10 @@ esp_err_t touch_channel_read_data(touch_channel_handle_t chan_handle, touch_chan
return touch_priv_channel_read_data(chan_handle, type, data);
}
esp_err_t touch_sensor_set_benchmark(touch_channel_handle_t chan_handle, const touch_chan_benchmark_op_t *benchmark_op)
esp_err_t touch_channel_config_benchmark(touch_channel_handle_t chan_handle, const touch_chan_benchmark_config_t *benchmark_cfg)
{
TOUCH_NULL_POINTER_CHECK_ISR(chan_handle);
TOUCH_NULL_POINTER_CHECK_ISR(benchmark_op);
touch_priv_set_benchmark(chan_handle, benchmark_op);
TOUCH_NULL_POINTER_CHECK_ISR(benchmark_cfg);
touch_priv_config_benchmark(chan_handle, benchmark_cfg);
return ESP_OK;
}

View File

@ -15,7 +15,7 @@
#include "freertos/semphr.h"
#include "soc/soc_caps.h"
#include "hal/touch_sensor_hal.h"
#include "driver/touch_common_types.h"
#include "driver/touch_sens_types.h"
#include "esp_memory_utils.h"
#include "esp_check.h"
#include "sdkconfig.h"
@ -31,7 +31,7 @@ extern "C" {
#define TOUCH_IRAM_CHECK(cb) (!(cb) || esp_ptr_in_iram(cb))
/* IRAM safe caps */
#if CONFIG_TOUCH_ISR_IRAM_SAFE
#if CONFIG_TOUCH_ISR_IRAM_SAFE || CONFIG_TOUCH_CTRL_FUNC_IN_IRAM
#define TOUCH_INTR_ALLOC_FLAGS (ESP_INTR_FLAG_IRAM | ESP_INTR_FLAG_SHARED | ESP_INTR_FLAG_LOWMED)
#define TOUCH_MEM_ALLOC_CAPS (MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT)
#else
@ -82,6 +82,7 @@ struct touch_sensor_s {
bool is_meas_timeout; /*!< Flag to indicate whether the measurement timeout, will force to stop the current measurement if the timeout is triggered */
bool sleep_en; /*!< Flag to indicate whether the sleep wake-up feature is enabled */
bool waterproof_en; /*!< Flag to indicate whether the water proof feature is enabled */
bool immersion_proof; /*!< Flag to indicate whether to disable scanning when the guard ring is triggered */
bool proximity_en; /*!< Flag to indicate whether the proximity sensing feature is enabled */
bool timeout_en; /*!< Flag to indicate whether the measurement timeout feature (hardware timeout) is enabled */
};
@ -182,9 +183,9 @@ esp_err_t touch_priv_channel_read_data(touch_channel_handle_t chan_handle, touch
* It should be implemented by each hardware version
*
* @param[in] chan_handle The channel handle
* @param[in] benchmark_op The benchmark operation
* @param[in] benchmark_cfg The benchmark operation
*/
void touch_priv_set_benchmark(touch_channel_handle_t chan_handle, const touch_chan_benchmark_op_t *benchmark_op);
void touch_priv_config_benchmark(touch_channel_handle_t chan_handle, const touch_chan_benchmark_config_t *benchmark_cfg);
#ifdef __cplusplus
}

View File

@ -12,15 +12,15 @@
#pragma once
#include "soc/soc_caps.h"
#include "driver/touch_common_types.h"
#include "driver/touch_sens_types.h"
#include "esp_err.h"
#ifdef __cplusplus
extern "C" {
#endif
#define TOUCH_MIN_CHAN_ID 0 /*!< The minimum available channel id of the touch pad */
#define TOUCH_MAX_CHAN_ID 13 /*!< The maximum available channel id of the touch pad */
#define TOUCH_MIN_CHAN_ID 0 /*!< The minimum available channel id of the touch pad */
#define TOUCH_MAX_CHAN_ID 13 /*!< The maximum available channel id of the touch pad */
/**
* @brief Helper macro to the default configurations of the touch sensor controller
@ -37,52 +37,20 @@ extern "C" {
/**
* @brief Helper macro to the default sample configurations
* @note This default configuration is based on clock frequency 16MHz
* @note This default configuration uses `sample frequency = clock frequency / 1`
*
*/
#define TOUCH_SENSOR_DEFAULT_SAMPLE_CONFIG0() { \
.freq_hz = 16000000, \
#define TOUCH_SENSOR_V3_DEFAULT_SAMPLE_CONFIG(_div_num, coarse_freq_tune, fine_freq_tune) { \
.div_num = _div_num, \
.charge_times = 500, \
.rc_filter_res = 2, \
.rc_filter_cap = 88, \
.low_drv = 3, \
.high_drv = 0, \
.rc_filter_res = 1, \
.rc_filter_cap = 1, \
.low_drv = fine_freq_tune, \
.high_drv = coarse_freq_tune, \
.bias_volt = 5, \
.bypass_shield_output = false, \
}
/**
* @brief Helper macro to the default sample configurations
* @note This default configuration is based on clock frequency 8MHz
*
*/
#define TOUCH_SENSOR_DEFAULT_SAMPLE_CONFIG1() { \
.freq_hz = 8000000, \
.charge_times = 500, \
.rc_filter_res = 3, \
.rc_filter_cap = 29, \
.low_drv = 3, \
.high_drv = 8, \
.bias_volt = 5, \
.bypass_shield_output = false, \
}
/**
* @brief Helper macro to the default sample configurations
* @note This default configuration is based on clock frequency 4MHz
*
*/
#define TOUCH_SENSOR_DEFAULT_SAMPLE_CONFIG2() { \
.freq_hz = 4000000, \
.charge_times = 500, \
.rc_filter_res = 3, \
.rc_filter_cap = 10, \
.low_drv = 7, \
.high_drv = 31, \
.bias_volt = 15, \
.bypass_shield_output = false, \
}
#define TOUCH_SENSOR_DEFAULT_FILTER_CONFIG() { \
.benchmark = { \
.filter_mode = TOUCH_BM_IIR_FILTER_4, \
@ -205,7 +173,7 @@ typedef enum {
*
*/
typedef struct {
uint32_t freq_hz; /*!< The sampling frequency for this configuration in Hz */
uint32_t div_num; /*!< Division of the touch output pulse, `touch_out_pulse / div_num = charge_times` */
uint32_t charge_times; /*!< The charge and discharge times of this sample configuration, the read data are positive correlation to the charge_times */
uint8_t rc_filter_res; /*!< The resistance of the RC filter of this sample configuration, range [0, 3], while 0 = 0K, 1 = 1.5K, 2 = 3K, 3 = 4.5K */
uint8_t rc_filter_cap; /*!< The capacitance of the RC filter of this sample configuration, range [0, 127], while 0 = 0pF, 1 = 20fF, ..., 127 = 2.54pF */
@ -337,12 +305,12 @@ typedef struct {
*
*/
typedef struct {
touch_channel_handle_t guard_chan; /*!< The guard channel of waterproof. Set NULL if you don't need the guard channel.
touch_channel_handle_t guard_chan; /*!< The guard channel of that used for immersion detect. Set NULL if you don't need the guard channel.
* Typically, the guard channel is a ring that surrounds the touch panels,
* it is used to detect the large area that covered by water.
* While large area of water covers the touch panel, the touch sensor will be temporary disable to avoid the fake touch.
* While large area of water covers the touch panel, the guard channel will be activated.
*/
touch_channel_handle_t shield_chan; /*!< The touch channel that used as the shield channel, can't be NULL.
touch_channel_handle_t shield_chan; /*!< The shield channel that used for water droplets shield, can't be NULL.
* Typically, the shield channel uses grid layout which covers the touch area,
* it is used to shield the influence of water droplets covering both the touch panel and the shield channel.
* The shield channel will be paralleled to the current measuring channel (except the guard channel) to reduce the influence of water droplets.
@ -350,6 +318,12 @@ typedef struct {
uint32_t shield_drv; /*!< The shield channel driver, which controls the drive capability of shield channel, range: 0 ~ 7
* The larger the parasitic capacitance on the shielding channel, the higher the drive capability needs to be set.
*/
struct {
uint32_t immersion_proof: 1; /*!< Enable to protect the touch sensor pad when immersion detected.
* It will temporary disable the touch scanning if the guard channel triggered, and enable again if guard channel released.
* So that to avoid the fake touch when the touch panel is immersed in water.
*/
} flags; /*!< Flags of the water proof function */
} touch_waterproof_config_t;
/**
@ -491,12 +465,12 @@ typedef struct {
} touch_event_callbacks_t;
/**
* @brief Touch sensor benchmark operation, to set or reset the benchmark of the channel
* @brief Touch sensor benchmark configurations, to set or reset the benchmark of the channel
*
*/
typedef struct {
bool do_reset; /*!< Whether to reset the benchmark to the channel's latest smooth data */
} touch_chan_benchmark_op_t;
} touch_chan_benchmark_config_t;
#ifdef __cplusplus
}

View File

@ -96,7 +96,7 @@ void IRAM_ATTR touch_priv_default_intr_handler(void *arg)
if (status & TOUCH_LL_INTR_MASK_ACTIVE) {
/* When the guard ring activated, disable the scanning of other channels to avoid fake touch */
TOUCH_ENTER_CRITICAL_SAFE(TOUCH_PERIPH_LOCK);
if (g_touch->waterproof_en && data.chan == g_touch->guard_chan) {
if (g_touch->immersion_proof && data.chan == g_touch->guard_chan) {
touch_ll_enable_scan_mask(~BIT(data.chan->id), false);
}
TOUCH_EXIT_CRITICAL_SAFE(TOUCH_PERIPH_LOCK);
@ -107,7 +107,7 @@ void IRAM_ATTR touch_priv_default_intr_handler(void *arg)
if (status & TOUCH_LL_INTR_MASK_INACTIVE) {
/* When the guard ring inactivated, enable the scanning of other channels again */
TOUCH_ENTER_CRITICAL_SAFE(TOUCH_PERIPH_LOCK);
if (g_touch->waterproof_en && data.chan == g_touch->guard_chan) {
if (g_touch->immersion_proof && data.chan == g_touch->guard_chan) {
touch_ll_enable_scan_mask(g_touch->chan_mask & (~BIT(g_touch->shield_chan->id)), true);
}
TOUCH_EXIT_CRITICAL_SAFE(TOUCH_PERIPH_LOCK);
@ -157,36 +157,12 @@ static esp_err_t s_touch_convert_to_hal_config(touch_sensor_handle_t sens_handle
hal_cfg->sample_cfg_num = sens_cfg->sample_cfg_num;
hal_cfg->output_mode = sens_cfg->output_mode;
hal_utils_clk_info_t clk_info = {
.src_freq_hz = sens_handle->src_freq_hz,
.min_integ = 1,
.max_integ = TOUCH_LL_CLK_DIV_MAX,
.round_opt = HAL_DIV_ROUND,
};
for (uint32_t div_num, smp_cfg_id = 0; smp_cfg_id < sens_cfg->sample_cfg_num; smp_cfg_id++) {
for (uint32_t smp_cfg_id = 0; smp_cfg_id < sens_cfg->sample_cfg_num; smp_cfg_id++) {
const touch_sensor_sample_config_t *sample_cfg = &(sens_cfg->sample_cfg[smp_cfg_id]);
uint32_t actual_freq_hz = 0;
/* Allow 10% overflow to increase the robustness when the sample frequency is close to the source clock,
because the source clock is from RTC FAST whose frequency is floating up and down among startups */
if (sample_cfg->freq_hz > sens_handle->src_freq_hz && sample_cfg->freq_hz < sens_handle->src_freq_hz * 1.1) {
ESP_LOGW(TAG, "[sample_cfg_id %"PRIu32"] sample frequency exceed the src clock but still within 10%%", smp_cfg_id);
div_num = 1;
actual_freq_hz = sens_handle->src_freq_hz;
} else {
clk_info.exp_freq_hz = sample_cfg->freq_hz;
actual_freq_hz = hal_utils_calc_clk_div_integer(&clk_info, &div_num);
}
/* Check the actual frequency and its precision */
ESP_RETURN_ON_FALSE(actual_freq_hz, ESP_ERR_INVALID_ARG, TAG,
"[sample_cfg_id %"PRIu32"] sample frequency should within range %"PRIu32" ~ %"PRIu32" hz",
smp_cfg_id, sens_handle->src_freq_hz / TOUCH_LL_CLK_DIV_MAX, sens_handle->src_freq_hz);
ESP_LOGD(TAG, "[sample_cfg_id %"PRIu32"] clock divider %"PRIu32, smp_cfg_id, div_num);
if (actual_freq_hz != clk_info.exp_freq_hz) {
ESP_LOGW(TAG, "[sample_cfg_id %"PRIu32"] clock precision loss, expect %"PRIu32" hz, got %"PRIu32" hz",
smp_cfg_id, clk_info.exp_freq_hz, actual_freq_hz);
}
ESP_RETURN_ON_FALSE(sample_cfg->div_num > 0, ESP_ERR_INVALID_ARG, TAG,
"div_num can't be 0");
/* Assign the hal configurations */
hal_cfg->sample_cfg[smp_cfg_id].div_num = div_num;
hal_cfg->sample_cfg[smp_cfg_id].div_num = sample_cfg->div_num;
hal_cfg->sample_cfg[smp_cfg_id].charge_times = sample_cfg->charge_times;
hal_cfg->sample_cfg[smp_cfg_id].rc_filter_res = sample_cfg->rc_filter_res;
hal_cfg->sample_cfg[smp_cfg_id].rc_filter_cap = sample_cfg->rc_filter_cap;
@ -271,14 +247,8 @@ esp_err_t touch_priv_channel_read_data(touch_channel_handle_t chan_handle, touch
}
if (type <= TOUCH_CHAN_DATA_TYPE_BENCHMARK) {
TOUCH_ENTER_CRITICAL_SAFE(TOUCH_PERIPH_LOCK);
if (chan_handle != chan_handle->base->deep_slp_chan) {
for (int i = 0; i < sample_cfg_num; i++) {
touch_ll_read_chan_data(chan_handle->id, i, internal_type, &data[i]);
}
} else {
for (int i = 0; i < sample_cfg_num; i++) {
touch_ll_sleep_read_chan_data(internal_type, i, &data[i]);
}
for (int i = 0; i < sample_cfg_num; i++) {
touch_ll_read_chan_data(chan_handle->id, i, internal_type, &data[i]);
}
TOUCH_EXIT_CRITICAL_SAFE(TOUCH_PERIPH_LOCK);
}
@ -297,9 +267,9 @@ esp_err_t touch_priv_channel_read_data(touch_channel_handle_t chan_handle, touch
return ESP_OK;
}
void touch_priv_set_benchmark(touch_channel_handle_t chan_handle, const touch_chan_benchmark_op_t *benchmark_op)
void touch_priv_config_benchmark(touch_channel_handle_t chan_handle, const touch_chan_benchmark_config_t *benchmark_cfg)
{
if (benchmark_op->do_reset) {
if (benchmark_cfg->do_reset) {
touch_ll_reset_chan_benchmark(BIT(chan_handle->id));
}
}
@ -423,6 +393,7 @@ esp_err_t touch_sensor_config_waterproof(touch_sensor_handle_t sens_handle, cons
TOUCH_NULL_POINTER_CHECK(wp_cfg->shield_chan);
TOUCH_ENTER_CRITICAL(TOUCH_PERIPH_LOCK);
sens_handle->waterproof_en = true;
sens_handle->immersion_proof = wp_cfg->flags.immersion_proof;
sens_handle->guard_chan = wp_cfg->guard_chan;
sens_handle->shield_chan = wp_cfg->shield_chan;
touch_ll_waterproof_set_guard_chan(wp_cfg->guard_chan ? wp_cfg->guard_chan->id : TOUCH_LL_NULL_CHANNEL);
@ -441,6 +412,7 @@ esp_err_t touch_sensor_config_waterproof(touch_sensor_handle_t sens_handle, cons
touch_ll_waterproof_set_shield_driver(0);
sens_handle->guard_chan = NULL;
sens_handle->shield_chan = NULL;
sens_handle->immersion_proof = false;
sens_handle->waterproof_en = false;
TOUCH_EXIT_CRITICAL(TOUCH_PERIPH_LOCK);
}

View File

@ -7,7 +7,7 @@
#pragma once
#include "esp_err.h"
#include "driver/touch_common_types.h"
#include "driver/touch_sens_types.h"
#include "driver/touch_version_types.h"
#ifdef __cplusplus
@ -179,7 +179,7 @@ esp_err_t touch_sensor_stop_continuous_scanning(touch_sensor_handle_t sens_handl
* And the touch sensor driver will be in SCANNING state after this function is called successfully,
* and then switch back to ENABLED state after the scanning is done or timeout.
* @note The block time of this function depends on various factors,
* In common practice, recommend to set the timeout to a second-level timeout or wait forever,
* In common practice, recommend to set the timeout to several seconds or wait forever,
* because oneshot scanning can't last for so long.
*
* @param[in] sens_handle Touch sensor controller handle
@ -208,17 +208,17 @@ esp_err_t touch_sensor_trigger_oneshot_scanning(touch_sensor_handle_t sens_handl
esp_err_t touch_sensor_register_callbacks(touch_sensor_handle_t sens_handle, const touch_event_callbacks_t *callbacks, void *user_ctx);
/**
* @brief Set the touch sensor benchmark for all the registered channels
* @brief Confiture the touch sensor benchmark for all the registered channels
* @note This function can be called no matter the touch sensor controller is enabled or not (i.e. ENABLED or SCANNING state).
* And it can also be called in ISR/callback context.
*
* @param[in] chan_handle Touch channel handle
* @param[in] benchmark_op The benchmark operations
* @param[in] benchmark_cfg The benchmark configurations
* @return
* - ESP_OK On success
* - ESP_ERR_INVALID_ARG NULL pointer
*/
esp_err_t touch_sensor_set_benchmark(touch_channel_handle_t chan_handle, const touch_chan_benchmark_op_t *benchmark_op);
esp_err_t touch_channel_config_benchmark(touch_channel_handle_t chan_handle, const touch_chan_benchmark_config_t *benchmark_cfg);
/**
* @brief Read the touch channel data according to the types

View File

@ -5,6 +5,6 @@ entries:
touch_sens_common: touch_sensor_start_continuous_scanning (noflash)
touch_sens_common: touch_sensor_stop_continuous_scanning (noflash)
touch_sens_common: touch_channel_read_data (noflash)
touch_sens_common: touch_sensor_set_benchmark (noflash)
touch_sens_common: touch_channel_config_benchmark (noflash)
touch_sens_version_specific: touch_priv_channel_read_data (noflash)
touch_sens_version_specific: touch_priv_set_benchmark (noflash)
touch_sens_version_specific: touch_priv_config_benchmark (noflash)

View File

@ -14,12 +14,12 @@
#include "esp_attr.h"
static touch_sensor_sample_config_t s_sample_cfg[TOUCH_SAMPLE_CFG_NUM] = {
TOUCH_SENSOR_DEFAULT_SAMPLE_CONFIG0(),
TOUCH_SENSOR_V3_DEFAULT_SAMPLE_CONFIG(1, 1, 1),
#if TOUCH_SAMPLE_CFG_NUM > 1
TOUCH_SENSOR_DEFAULT_SAMPLE_CONFIG1(),
TOUCH_SENSOR_V3_DEFAULT_SAMPLE_CONFIG(2, 1, 1),
#endif
#if TOUCH_SAMPLE_CFG_NUM > 2
TOUCH_SENSOR_DEFAULT_SAMPLE_CONFIG2(),
TOUCH_SENSOR_V3_DEFAULT_SAMPLE_CONFIG(4, 1, 1),
#endif
};

View File

@ -119,6 +119,7 @@ typedef enum {
RTC_UART1_TRIG_EN | \
RTC_BT_TRIG_EN | \
RTC_LP_CORE_TRIG_EN | \
RTC_TOUCH_TRIG_EN | \
RTC_XTAL32K_DEAD_TRIG_EN | \
RTC_USB_TRIG_EN | \
RTC_BROWNOUT_DET_TRIG_EN)

View File

@ -25,6 +25,7 @@ static touch_hal_deep_sleep_obj_t s_touch_slp_obj = {
void touch_hal_config_controller(const touch_hal_config_t *cfg)
{
HAL_ASSERT(cfg);
touch_ll_sleep_set_channel_num(TOUCH_LL_NULL_CHANNEL);
touch_ll_set_out_mode(cfg->output_mode);
touch_ll_set_power_on_wait_cycle(cfg->power_on_wait_ticks);
touch_ll_set_measure_interval_ticks(cfg->meas_interval_ticks);
@ -76,7 +77,6 @@ static void s_touch_hal_apply_sleep_config(void)
void touch_hal_prepare_deep_sleep(void)
{
s_touch_hal_apply_sleep_config();
// TODO: check if it is necessary to reset the sleep benchmark
touch_ll_sleep_reset_benchmark();
touch_ll_intr_clear(TOUCH_LL_INTR_MASK_ALL);
}

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 31 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 27 KiB

View File

@ -108,8 +108,6 @@ LDO_DOCS = ['api-reference/peripherals/ldo_regulator.rst']
TEMP_SENSOR_DOCS = ['api-reference/peripherals/temp_sensor.rst']
TOUCH_SENSOR_DOCS = ['api-reference/peripherals/touch_pad.rst']
SPIRAM_DOCS = ['api-guides/external-ram.rst']
USB_DOCS = ['api-reference/peripherals/usb_device.rst',
@ -187,6 +185,7 @@ ESP32_DOCS = ['api-reference/system/himem.rst',
'security/secure-boot-v1.rst',
'api-reference/peripherals/dac.rst',
'api-reference/peripherals/sd_pullup_requirements.rst',
'api-reference/peripherals/touch_pad.rst',
'hw-reference/esp32/**',
'api-guides/RF_calibration.rst',
'api-guides/phy.rst'] + FTDI_JTAG_DOCS + QEMU_DOCS
@ -196,6 +195,7 @@ ESP32S2_DOCS = ['hw-reference/esp32s2/**',
'api-reference/peripherals/ds.rst',
'api-reference/peripherals/temp_sensor.rst',
'api-reference/system/async_memcpy.rst',
'api-reference/peripherals/touch_pad.rst',
'api-reference/peripherals/touch_element.rst',
'api-guides/RF_calibration.rst',
'api-guides/phy.rst'] + FTDI_JTAG_DOCS + USB_OTG_DFU_DOCS + USB_OTG_CONSOLE_DOCS
@ -203,6 +203,7 @@ ESP32S2_DOCS = ['hw-reference/esp32s2/**',
ESP32S3_DOCS = ['hw-reference/esp32s3/**',
'api-reference/system/ipc.rst',
'api-guides/flash_psram_config.rst',
'api-reference/peripherals/touch_pad.rst',
'api-reference/peripherals/sd_pullup_requirements.rst',
'api-guides/RF_calibration.rst',
'api-guides/phy.rst'] + USB_OTG_DFU_DOCS + USB_OTG_CONSOLE_DOCS
@ -227,6 +228,7 @@ ESP32H2_DOCS = ['api-guides/RF_calibration.rst',
'api-guides/phy.rst']
ESP32P4_DOCS = ['api-reference/system/ipc.rst',
'api-reference/peripherals/cap_touch_sens.rst',
'api-reference/peripherals/sd_pullup_requirements.rst']
# format: {tag needed to include: documents to included}, tags are parsed from sdkconfig and peripheral_caps.h headers
@ -257,7 +259,6 @@ conditional_include_dict = {'SOC_BT_SUPPORTED':BT_DOCS,
'SOC_RMT_SUPPORTED':RMT_DOCS,
'SOC_DAC_SUPPORTED':DAC_DOCS,
'SOC_ETM_SUPPORTED':ETM_DOCS,
'SOC_TOUCH_SENSOR_SUPPORTED':TOUCH_SENSOR_DOCS,
'SOC_ULP_FSM_SUPPORTED':ULP_FSM_DOCS,
'SOC_RISCV_COPROC_SUPPORTED':RISCV_COPROC_DOCS,
'SOC_LP_CORE_SUPPORTED':LP_CORE_DOCS,

View File

@ -18,6 +18,9 @@ INPUT += \
$(PROJECT_PATH)/components/esp_driver_cam/csi/include/esp_cam_ctlr_csi.h \
$(PROJECT_PATH)/components/hal/include/hal/jpeg_types.h \
$(PROJECT_PATH)/components/hal/include/hal/ppa_types.h \
$(PROJECT_PATH)/components/esp_driver_touch_sens/include/driver/touch_sens.h \
$(PROJECT_PATH)/components/esp_driver_touch_sens/include/driver/touch_sens_types.h \
$(PROJECT_PATH)/components/esp_driver_touch_sens/hw_ver3/include/driver/touch_version_types.h \
$(PROJECT_PATH)/components/esp_driver_jpeg/include/driver/jpeg_types.h \
$(PROJECT_PATH)/components/esp_driver_isp/include/driver/isp.h \
$(PROJECT_PATH)/components/esp_driver_isp/include/driver/isp_types.h \

View File

@ -0,0 +1,416 @@
Capacitive Touch Sensor
=========================
:link_to_translation:`zh_CN:[中文]`
{IDF_TARGET_TOUCH_SENSOR_VERSION:default="NOT_UPDATED", esp32p4="v3"}
Introduction
---------------
A touch sensor system is built on a substrate which carries electrodes and relevant connections under a protective flat surface. When the surface is touched, the capacitance variation is used to evaluate if the touch was valid.
The sensing pads can be arranged in different combinations (e.g., matrix, slider), so that a larger area or more points can be detected. The touch pad sensing process is under the control of a hardware-implemented finite-state machine (FSM) which is initiated by software or a dedicated hardware timer.
For design, operation, and control registers of a touch sensor, see **{IDF_TARGET_NAME} Technical Reference Manual** > **On-Chip Sensors and Analog Signal Processing** [`PDF <{IDF_TARGET_TRM_EN_URL}#sensor>`__].
In-depth design details of touch sensors and firmware development guidelines for {IDF_TARGET_NAME} are available in `Touch Sensor Application Note <https://github.com/espressif/esp-iot-solution/blob/release/v1.0/documents/touch_pad_solution/touch_sensor_design_en.md>`_.
Overview of Capacitive Touch Sensor Versions
-----------------------------------------------
+------------------+--------------+------------------------------------------------------------------------+
| Hardware Version | Chip | Main Features |
+==================+==============+========================================================================+
| V1 | ESP32 | Version 1, the channel value decreases when it is touched |
+------------------+--------------+------------------------------------------------------------------------+
| V2 | ESP32-S2 | Version 2, the channel value increases when it is touched |
| | | Supports waterproof, proximity sensing and sleep wake-up |
| +--------------+------------------------------------------------------------------------+
| | ESP32-S3 | Version 2, support proximity measurement done interrupt |
+------------------+--------------+------------------------------------------------------------------------+
| V3 | ESP32-P4 | Version 3, support frequency hopping |
+------------------+--------------+------------------------------------------------------------------------+
Overview of Touch Sensor Channels
------------------------------------
.. only:: esp32p4
========= ===== ===== ===== ===== ===== ===== ===== ===== ====== ====== ====== ====== ====== ====== ==========
Channel CH0 CH1 CH2 CH3 CH4 CH5 CH6 CH7 CH8 CH9 CH10 CH11 CH12 CH13 CH14
--------- ----- ----- ----- ----- ----- ----- ----- ----- ------ ------ ------ ------ ------ ------ ----------
GPIO IO2 IO3 IO4 IO5 IO6 IO7 IO8 IO9 IO10 IO11 IO12 IO13 IO14 IO15 Internal
========= ===== ===== ===== ===== ===== ===== ===== ===== ====== ====== ====== ====== ====== ====== ==========
Terminology in the Driver
----------------------------
- **Touch Sensor Controller**: The controller of the touch sensor, responsible for configuring and managing the touch sensor.
- **Touch Sensor Channel**: A specific touch sensor sampling channel. A touch sensor module has multiple touch channels, which are usually connected to the touch pad for measuring the capacitance change. In the driver, sampling of **one** channel is called one ``measurement`` and the scanning of **all** registered channels is called one ``scan``.
.. only:: SOC_TOUCH_SUPPORT_FREQ_HOP
- **Touch Sensor Sampling Configuration**: Touch sensor sampling configuration refers to all the hardware configurations that related to the sampling. It can determine how the touch channels sample by setting the number of charging times, charging frequency, measurement interval, etc. {IDF_TARGET_NAME} supports multiple sets of sample configuration, which means it can support frequency hopping.
.. only:: not SOC_TOUCH_SUPPORT_FREQ_HOP
- **Touch Sensor Sampling Configuration**: Touch sensor sampling configuration refers to all the hardware configurations that related to the sampling. It can determine how the touch channels sample by setting the number of charging times, charging frequency, measurement interval, etc. {IDF_TARGET_NAME} only support one set of sample configuration, so it doesn't support frequency hopping.
File Structure
-----------------
.. figure:: ../../../_static/diagrams/cap_touch_sens/touch_file_structure.svg
:align: center
:alt: File Structure of Touch Sensor Driver
File Structure of Touch Sensor Driver
Finite-state Machine
---------------------
The following diagram shows the state machine of the touch sensor driver, which describes the driver state after calling a function, and the constraint of the state transition.
.. figure:: ../../../_static/diagrams/cap_touch_sens/touch_state_machine.svg
:align: center
:alt: Finite-state Machine of Touch Sensor Driver
Finite-state Machine of Touch Sensor Driver
The diagram above is the finite-state machine of the touch sensor driver, which describes how the state transferred by invoking different APIs. ``<other_configurations>`` in the diagram stands for the other optional configurations, like reconfigurations to the touch sensor controller or channels, callback registration, filter, and so on.
.. note::
:cpp:func:`touch_channel_read_data` can be called at any time after the channel is registered (i.e., since ``INIT`` state), but please take care of the validation of the data.
Functionality Introduction
------------------------------
Categorized by functionality, the APIs of Capacitive Touch Sensor mainly include:
.. list::
- `Touch Sensor Controller Management <#touch-ctrl>`__
- `Touch Sensor Channel Management <#touch-chan>`__
- `Filter Configuration <#touch-filter>`__
- `Callback <#touch-callback>`__
- `Enable and Disable <#touch-enable>`__
- `Continuous Scan <#touch-conti-scan>`__
- `Oneshot Scan <#touch-oneshot-scan>`__
- `Benchmark Configuration <#touch-benchmark>`__
- `Read Measurement Data <#touch-read>`__
:SOC_TOUCH_SUPPORT_WATERPROOF: - `Waterproof Configuration <#touch-waterproof>`__
:SOC_TOUCH_SUPPORT_PROX_SENSING: - `Proximity Sensing Configuration <#touch-prox-sensing>`__
:SOC_TOUCH_SUPPORT_SLEEP_WAKEUP: - `Sleep Wake-up Configuration <#touch-sleep-wakeup>`__
.. _touch-ctrl:
Touch Sensor Controller Management
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Touch Sensor is controlled by controller handle :cpp:type:`touch_sensor_handle_t`, it can be initialized and allocated by :cpp:func:`touch_sensor_new_controller`.
.. code-block:: c
// Some target has multiple sets of sample configuration can be set, here take one for example
#define SAMPLE_NUM 1
touch_sensor_handle_t sens_handle = NULL;
// sample configuration
touch_sensor_sample_config_t sample_cfg[SAMPLE_NUM] = {
// Specify sample configuration or apply the default sample configuration via `TOUCH_SENSOR_Vn_DEFAULT_SAMPLE_CONFIG`
// ...
};
// Use the default touch controller configuration
touch_sensor_config_t touch_cfg = TOUCH_SENSOR_DEFAULT_BASIC_CONFIG(SAMPLE_NUM, sample_cfg);
// Allocate a new touch sensor controller handle
ESP_ERROR_CHECK(touch_sensor_new_controller(&touch_cfg, &sens_handle));
To delete the controller handle and free the software and hardware resources, please call :cpp:func:`touch_sensor_del_controller`. But note that you need to delete the other resources that based on the controller first, like the registered touch channels, otherwise it can't be deleted directly.
.. code-block:: c
ESP_ERROR_CHECK(touch_sensor_del_controller(sens_handle));
You can also update the configurations via :cpp:func:`touch_sensor_reconfig_controller` before the controller is enabled.
.. code-block:: c
touch_sensor_config_t touch_cfg = {
// New controller configurations
// ...
};
ESP_ERROR_CHECK(touch_sensor_reconfig_controller(sens_handle, &touch_cfg));
.. _touch-chan:
Touch Sensor Channel Management
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
There are multiple touch channels in the touch sensor module, the touch sensor channel is controlled by the channel handle :cpp:type:`touch_channel_handle_t`. It can be initialized and allocated by :cpp:func:`touch_sensor_new_channel`.
.. code-block:: c
// ...
touch_channel_config_t chan_cfg = {
// Touch channel configurations
// ...
};
touch_channel_handle_t chan_handle = NULL;
int chan_id = 0;
// Allocate a new touch sensor controller handle
ESP_ERROR_CHECK(touch_sensor_new_channel(sens_handle, chan_id, &chan_cfg, &chan_handle));
To delete the touch channel handle and free the software and hardware resources, please call :cpp:func:`touch_sensor_del_channel`.
.. code-block:: c
ESP_ERROR_CHECK(touch_sensor_del_channel(chan_handle));
You can also update the configurations via :cpp:func:`touch_sensor_reconfig_channel` before the controller is enabled.
.. code-block:: c
touch_channel_config_t chan_cfg = {
// New touch channel configurations
// ...
};
ESP_ERROR_CHECK(touch_sensor_reconfig_channel(chan_handle, &chan_cfg));
.. _touch-filter:
Filter Configuration
^^^^^^^^^^^^^^^^^^^^^^
The filter can help to increase the stability in different use cases. The filter can be registered by calling :cpp:func:`touch_sensor_config_filter` and specify the configurations :cpp:type:`touch_sensor_filter_config_t`. These configurations mainly determine how to filter and update the benchmark and read data. Please note that all touch channels will share this filter.
To deregister the filter, you can call :cpp:func:`touch_sensor_config_filter` again, and set the second parameter (i.e. :cpp:type:`touch_sensor_filter_config_t` pointer) to ``NULL``.
.. code-block:: c
// ...
touch_sensor_filter_config_t filter_config = {
// Filter configurations
// ...
};
// Register the filter
ESP_ERROR_CHECK(touch_sensor_config_filter(sens_handle, &filter_config));
// ...
// Deregister the filter
ESP_ERROR_CHECK(touch_sensor_config_filter(sens_handle, NULL));
.. _touch-callback:
Callback
^^^^^^^^^^^^^
Calling :cpp:func:`touch_sensor_register_callbacks` to register the touch sensor event callbacks. Once the touch sensor events (like ``on_active``, ``on_inactive``) trigger, the corresponding callbacks will be invoked, so that to deal with the event in the upper application.
For the general example, when the measured data of the current touch channel exceed the ``benchmark`` + ``active_threshold``, this channel is activated, and the driver will call ``on_active`` callback to inform the application layer. Similar, when the active channel measured a lower data than ``benchmark`` + ``active_threshold``, then this channel will be inactivated, and ``on_inactive`` will be called to inform this channel is released.
.. note::
To ensure the stability of the triggering and releasing, ``active_hysteresis`` and ``debounce_cnt`` can be configured to avoid the frequent triggering that caused by jitter and noise.
Please refer to :cpp:type:`touch_event_callbacks_t` for the details about the supported callbacks.
.. code-block:: c
touch_event_callbacks_t callbacks = {
.on_active = example_touch_on_active_cb,
// Other callbacks
// ...
};
// Register callbacks
ESP_ERROR_CHECK(touch_sensor_register_callbacks(sens_handle, &callbacks, NULL));
// To deregister callbacks, set the corresponding callback to NULL
callbacks.on_active = NULL;
// Other callbacks to deregister
// ...
ESP_ERROR_CHECK(touch_sensor_register_callbacks(sens_handle, &callbacks, NULL));
.. _touch-enable:
Enable and Disable
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
After finished the configuration of the touch controller and touch channels, :cpp:func:`touch_sensor_enable` can be called to enable the touch sensor controller. It will enter ``READY`` status and power on the registered channels, then you can start scanning and sampling the touch data. Note that you can only do scanning and reading operation once the controller is enabled. If you want to update the controller or channel configurations, you need to call :cpp:func:`touch_sensor_disable` first.
.. code-block:: c
// Enable touch sensor
ESP_ERROR_CHECK(touch_sensor_enable(sens_handle));
// ...
// Disable touch sensor
ESP_ERROR_CHECK(touch_sensor_disable(sens_handle));
.. _touch-conti-scan:
Continuous Scan
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
With the touch controller enabled, :cpp:func:`touch_sensor_start_continuous_scanning` can be called to start the continuous scanning to all the registered touch channels. The read data of these touch channels will be updated automatically in each scan. Calling :cpp:func:`touch_sensor_stop_continuous_scanning` can stop the continuous scan.
.. code-block:: c
// Start continuous scan
ESP_ERROR_CHECK(touch_sensor_start_continuous_scanning(sens_handle));
// ...
// Stop continuous scan
ESP_ERROR_CHECK(touch_sensor_stop_continuous_scanning(sens_handle));
.. _touch-oneshot-scan:
Oneshot Scan
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
With the touch controller enabled, :cpp:func:`touch_sensor_trigger_oneshot_scanning` can be called to trigger an one-time scan to all the registered touch channels. Note that oneshot scan is a blocking function, it will keep blocking and only return when the scan is finished. Moreover, you can't trigger an oneshot scan after the continuous scan has started.
.. code-block:: c
// Trigger an oneshot scan with timeout 1000ms
ESP_ERROR_CHECK(touch_sensor_trigger_oneshot_scanning(sens_handle, 1000));
.. _touch-benchmark:
Benchmark Configuration
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Normally, you don't have to set the benchmark manually, but you can force reset the benchmark to the current smooth value by calling :cpp:func:`touch_channel_config_benchmark` when necessary
.. code-block:: c
touch_chan_benchmark_config_t benchmark_cfg = {
// Benchmark operations
// ...
};
ESP_ERROR_CHECK(touch_channel_config_benchmark(chan_handle, &benchmark_cfg));
.. _touch-read:
Read Measurement Data
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Call :cpp:func:`touch_channel_read_data` to read the data with different types. Like, benchmark, smooth data, etc. You can refer to :cpp:type:`touch_chan_data_type_t` for the supported data types.
.. only:: SOC_TOUCH_SUPPORT_FREQ_HOP
{IDF_TARGET_NAME} supports frequency hopping by configuring multiple set of sample configurations, :cpp:func:`touch_channel_read_data` can read out the data of each sample configuration in a single call, you can determine the sample configuration number by :cpp:member:`touch_sensor_config_t::sample_cfg_num`, and pass an array (which length is not smaller than the configuration number) to the third parameter ``*data``, so that all the measured data of this channel will be stored in the array.
.. code-block:: c
#define SAMPLE_NUM 1 // Take one sample configuration set for example
uint32_t smooth_data[SAMPLE_NUM] = {};
// Read the smooth data
ESP_ERROR_CHECK(touch_channel_read_data(chan_handle, TOUCH_CHAN_DATA_TYPE_SMOOTH, smooth_data));
.. _touch-waterproof:
.. only:: SOC_TOUCH_SUPPORT_WATERPROOF
Waterproof Configuration
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
{IDF_TARGET_NAME} supports waterproof. Waterproof can be registered by calling :cpp:func:`touch_sensor_config_waterproof` and specify the configurations :cpp:type:`touch_waterproof_config_t`. There are two parts of the waterproof function:
- Immersion (in-water) proof: :cpp:member:`touch_waterproof_config_t::guard_chan` can be specified for detecting immersion. It is usually designed as a ring on the PCB, which surrounds all the other touch pads. When this guard ring channel is triggered, that means the touch panel is immersed by water, all the touch channels will stop measuring to avoid falsely triggering.
- Moisture (water-drop) proof: :cpp:member:`touch_waterproof_config_t::shield_chan` can be specified for detecting moisture. It usually uses the grid layout on the PCB, which covers the whole touch panel. The shield channel will charge and discharge synchronously with the current touch channel, when there is a water droplet covers both shield channel and normal touch channel, :cpp:member:`touch_waterproof_config_t::shield_drv` can strengthen the electrical coupling caused by the water droplets, and then reconfigure the active threshold based on the disturbance to eliminate the influence that introduced by the water droplet.
To deregister the waterproof function, you can call :cpp:func:`touch_sensor_config_waterproof` again, and set the second parameter (i.e. :cpp:type:`touch_waterproof_config_t` pointer) to ``NULL``.
.. code-block:: c
touch_waterproof_config_t waterproof_cfg = {
// Waterproof configurations
// ...
};
// Register waterproof function
ESP_ERROR_CHECK(touch_sensor_config_waterproof(sens_handle, &waterproof_cfg));
// ...
// Deregister waterproof function
ESP_ERROR_CHECK(touch_sensor_config_waterproof(sens_handle, NULL));
.. _touch-prox-sensing:
.. only:: SOC_TOUCH_SUPPORT_PROX_SENSING
Proximity Sensing Configuration
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
{IDF_TARGET_NAME} supports proximity sensing. Proximity sensing can be registered by calling :cpp:func:`touch_sensor_config_proximity_sensing` and specify the configurations :cpp:type:`touch_proximity_config_t`.
Since the capacitance change caused by proximity sensing is far less than that caused by physical touch, large area of copper foil is often used on PCB to increase the sensing area. In addition, multiple rounds of scans are needed and the result of each scan will be accumulated in the driver to improve the measurement sensitivity. The scan times (rounds) can be determined by :cpp:member:`touch_proximity_config_t::scan_times` and the charging times of the proximity channel in one scan can be determined by :cpp:member:`touch_proximity_config_t::charge_times`. Generally, the larger the scan times and charging times is, the higher the sensitivity will be, however, the read data will be unstable if the sensitivity is too high. Proper parameters should be determined regarding the application.
The accumulated proximity data can be read by :cpp:func:`touch_channel_read_data` with the data type :cpp:enumerator:`TOUCH_CHAN_DATA_TYPE_PROXIMITY`
To deregister the proximity sensing, you can call :cpp:func:`touch_sensor_config_proximity_sensing` again, and set the second parameter (i.e. :cpp:type:`touch_proximity_config_t` pointer) to ``NULL``.
.. code-block:: c
touch_proximity_config_t prox_cfg = {
// Proximity sensing configuration
// ...
};
// Register the proximity sensing
ESP_ERROR_CHECK(touch_sensor_config_proximity_sensing(sens_handle, &prox_cfg));
// ...
// Deregister the proximity sensing
ESP_ERROR_CHECK(touch_sensor_config_proximity_sensing(sens_handle, NULL));
.. _touch-sleep-wakeup:
.. only:: SOC_TOUCH_SUPPORT_SLEEP_WAKEUP
Sleep Wake-up Configuration
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
{IDF_TARGET_NAME} supports waking-up the chip from light sleep or deep sleep with the touch sensor as a wake-up source. The wake-up functionality can be registered by calling :cpp:func:`touch_sensor_config_sleep_wakeup` and specifying the configurations :cpp:type:`touch_sleep_config_t`.
After registering the touch sensor sleep wake-up, the chip will continue to sample the touch channels after sleep, which will increase the power consumption during the sleep. To reduce the sleep power consumption, you can reduce the number of charging and discharging times, increase the sampling interval, etc.
Moreover, please note that the operations like sampling, wake-up are all done by hardware when the main core is sleeping. Since this driver runs on the main core, it cannot provide functions such as reading or configuring during the sleep.
.. only:: SOC_RISCV_COPROC_SUPPORTED
If you want to read or configure the touch sensor during the sleep, you can turn to the driver ``components/ulp/ulp_riscv/ulp_core/include/ulp_riscv_touch_ulp_core.h`` which based on the :doc:`Ultra Low Power (ULP) Coprocessor <../system/ulp>`.
- Light sleep wake-up: you need to set :cpp:member:`slp_wakeup_lvl` to :cpp:enumerator:`TOUCH_LIGHT_SLEEP_WAKEUP` to enable the light sleep wake-up by touch sensor. Note that any registered touch channel can wake-up the chip from light sleep.
- Deep sleep wake-up: beside setting :cpp:member:`slp_wakeup_lvl` to :cpp:enumerator:`TOUCH_DEEP_SLEEP_WAKEUP`, you need to specify :cpp:member:`deep_slp_chan` additionally. Only the specified channel can wake-up the chip from the deep sleep, in order to reduce the power consumption. And also, the driver supports to store another set of configurations for the deep sleep via :cpp:member:`deep_slp_sens_cfg`, this set of configurations only takes effect during the deep sleep, you can customize the configurations to save more power. The configurations will be reset to the previous set after waking-up from the deep sleep. Please be aware that, not only deep sleep wake-up, but also light sleep wake-up will be enabled when the :cpp:member:`slp_wakeup_lvl` is :cpp:enumerator:`TOUCH_DEEP_SLEEP_WAKEUP`.
To deregister the sleep wake-up function, you can call :cpp:func:`touch_sensor_config_sleep_wakeup` again, and set the second parameter (i.e. :cpp:type:`touch_sleep_config_t` pointer) to ``NULL``.
.. code-block:: c
touch_sleep_config_t light_slp_cfg = {
.slp_wakeup_lvl = TOUCH_LIGHT_SLEEP_WAKEUP,
};
// Register the light sleep wake-up
ESP_ERROR_CHECK(touch_sensor_config_sleep_wakeup(sens_handle, &light_slp_cfg));
// ...
// Deregister the light sleep wake-up
ESP_ERROR_CHECK(touch_sensor_config_sleep_wakeup(sens_handle, NULL));
touch_sleep_config_t deep_slp_cfg = {
.slp_wakeup_lvl = TOUCH_DEEP_SLEEP_WAKEUP,
.deep_slp_chan = dslp_chan_handle,
// Other deep sleep configurations
// ...
};
// Register the deep sleep wake-up
ESP_ERROR_CHECK(touch_sensor_config_sleep_wakeup(sens_handle, &deep_slp_cfg));
Application Examples
------------------------
.. only:: esp32p4
- Touch sensor basic example: :example:`peripherals/touch_sensor/touch_sensor_{IDF_TARGET_TOUCH_SENSOR_VERSION}`.
API 参考
-------------
.. only:: esp32p4
.. include-build-file:: inc/touch_sens.inc
.. include-build-file:: inc/touch_sens_types.inc
.. include-build-file:: inc/touch_version_types.inc

View File

@ -42,7 +42,8 @@ Peripherals API
:SOC_GPSPI_SUPPORTED: spi_slave
:SOC_SPI_SUPPORT_SLAVE_HD_VER2: spi_slave_hd
:SOC_TEMP_SENSOR_SUPPORTED: temp_sensor
:SOC_TOUCH_SENSOR_SUPPORTED: touch_pad
:SOC_TOUCH_SENSOR_SUPPORTED and not esp32p4: touch_pad
:esp32p4: cap_touch_sens
:esp32s2: touch_element
:SOC_TWAI_SUPPORTED: twai
uart

View File

@ -0,0 +1,415 @@
电容式触摸传感器
===================
:link_to_translation:`en:[English]`
{IDF_TARGET_TOUCH_SENSOR_VERSION:default="NOT_UPDATED", esp32p4="v3"}
概述
------------
触摸传感器系统由保护覆盖层、触摸电极、绝缘基板和走线组成,保护覆盖层位于最上层,绝缘基板上设有电极及走线。触摸覆盖层将引起电容变化,根据电容变化,可以判断此次触摸是否为有效触摸行为。
触摸传感器可以以矩阵或滑条等方式组合使用,从而覆盖更大触感区域及更多触感点。触摸传感由软件或专用硬件计时器发起,由有限状态机 (FSM) 硬件控制。
如需了解触摸传感器设计、操作及其控制寄存器等相关信息,请参考《`{IDF_TARGET_NAME} 技术参考手册 <{IDF_TARGET_TRM_CN_URL}>`_》(PDF) 中“片上传感器与模拟信号处理”章节。
请参考 `触摸传感器应用方案简介 <https://github.com/espressif/esp-iot-solution/blob/release/v1.0/documents/touch_pad_solution/touch_sensor_design_en.md>`_,查看触摸传感器设计详情和固件开发指南。
电容式触摸传感器版本概览
-------------------------
+-----------+--------------+------------------------------------------------------------------------+
| 硬件版本 | 芯片 | 主要特征 |
+===========+==============+========================================================================+
| V1 | ESP32 | 第一代触摸传感器,触摸时读数变小 |
+-----------+--------------+------------------------------------------------------------------------+
| V2 | ESP32-S2 | 第二代触摸传感器,触摸时读数变大 |
| | | 新增防水防潮、接近感应、睡眠唤醒功能 |
| +--------------+------------------------------------------------------------------------+
| | ESP32-S3 | 第二代触摸传感器,新增接近感应测量完成中断 |
+-----------+--------------+------------------------------------------------------------------------+
| V3 | ESP32-P4 | 第三代触摸传感器,新增跳频扫描 |
+-----------+--------------+------------------------------------------------------------------------+
触摸通道概览
----------------------
.. only:: esp32p4
====== ===== ===== ===== ===== ===== ===== ===== ===== ====== ====== ====== ====== ====== ====== ==========
通道 CH0 CH1 CH2 CH3 CH4 CH5 CH6 CH7 CH8 CH9 CH10 CH11 CH12 CH13 CH14
------ ----- ----- ----- ----- ----- ----- ----- ----- ------ ------ ------ ------ ------ ------ ----------
GPIO IO2 IO3 IO4 IO5 IO6 IO7 IO8 IO9 IO10 IO11 IO12 IO13 IO14 IO15 未引出
====== ===== ===== ===== ===== ===== ===== ===== ===== ====== ====== ====== ====== ====== ====== ==========
驱动中的术语介绍
-------------------------
- **触摸传感器控制器**:触摸传感器驱动的控制器,负责触摸传感器的配置和管理。
- **触摸传感器通道**:具体的一路触摸传感器采样通道。一个触摸传感器模块具有多个通道,一般连接到触摸板上,用于测量该触摸板电容的变化。驱动中把对 **一个** 通道的采样称为 ``测量``,而对 **所有** 注册通道的 ``测量`` 称为一次 ``扫描``
.. only:: IDF_TARGET_TOUCH_SAMPLE_CFG_DESC
- **触摸传感器采样配置**:触摸传感器采样配置是驱动中对采样有关的硬件配置的统称。采样配置负责触摸传感器通道的采样,其配置决定了触摸通道的充放电次数、充放电频率、测量间隔等。{IDF_TARGET_NAME} 支持多套采样配置,支持跳频采样。
.. only:: not IDF_TARGET_TOUCH_SAMPLE_CFG_DESC
- **触摸传感器采样配置**:触摸传感器采样配置是驱动中对采样有关的硬件配置的统称。采样配置负责触摸传感器通道的采样,其配置决定了触摸通道的充放电次数、充放电频率、测量间隔等。{IDF_TARGET_NAME} 仅支持一套采样配置,不支持跳频采样。
文件结构
--------------------
.. figure:: ../../../_static/diagrams/cap_touch_sens/touch_file_structure.svg
:align: center
:alt: 触摸传感器驱动文件结构图
触摸传感器驱动文件结构图
驱动状态机
---------------------
下图为触摸传感器驱动的状态机,描述了调用不同函数后驱动的运行状态,以及状态变迁的约束。
.. figure:: ../../../_static/diagrams/cap_touch_sens/touch_state_machine.svg
:align: center
:alt: 触摸传感器驱动状态机示意图
触摸传感器驱动状态机示意图
上图为触摸传感器驱动的状态机,描述了调用不同函数后状态的变换关系。其中 ``<other_configurations>`` 部分为可选的配置项,包括对触摸驱动控制器和触摸通道的重新配置、回调函数注册等。
.. note::
:cpp:func:`touch_channel_read_data` 可在获取触摸通道句柄后(即 ``INIT`` 后)任意状态调用,但请注意读数值的有效性。
功能介绍
------------------
{IDF_TARGET_NAME} 的电容式触摸传感器驱动提供的 API 按功能主要可分为:
.. list::
- `触摸传感器控制器管理 <#touch-ctrl>`__
- `触摸传感器通道管理 <#touch-chan>`__
- `滤波器配置 <#touch-filter>`__
- `回调函数 <#touch-callback>`__
- `启用和禁用 <#touch-enable>`__
- `连续扫描 <#touch-conti-scan>`__
- `单次扫描 <#touch-oneshot-scan>`__
- `基线值配置 <#touch-benchmark>`__
- `测量值读数 <#touch-read>`__
:SOC_TOUCH_SUPPORT_WATERPROOF: - `防水防潮配置 <#touch-waterproof>`__
:SOC_TOUCH_SUPPORT_PROX_SENSING: - `接近感应配置 <#touch-prox-sensing>`__
:SOC_TOUCH_SUPPORT_SLEEP_WAKEUP: - `睡眠唤醒配置 <#touch-sleep-wakeup>`__
.. _touch-ctrl:
触摸传感器控制器管理
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
触摸传感器驱动通过触摸传感器控制器句柄 :cpp:type:`touch_sensor_handle_t` 控制。调用 :cpp:func:`touch_sensor_new_controller` 函数即可初始化触摸传感器控制器并得到控制器句柄。
.. code-block:: c
// 有些芯片支持多套采样配置,这里以一套为例
#define SAMPLE_NUM 1
touch_sensor_handle_t sens_handle = NULL;
// 采样配置
touch_sensor_sample_config_t sample_cfg[SAMPLE_NUM] = {
// 指定采样配置或通过 `TOUCH_SENSOR_Vn_DEFAULT_SAMPLE_CONFIG` 使用默认采样配置
// ...
};
// 默认控制器配置
touch_sensor_config_t touch_cfg = TOUCH_SENSOR_DEFAULT_BASIC_CONFIG(SAMPLE_NUM, sample_cfg);
// 申请一个新的触摸传感器控制器句柄
ESP_ERROR_CHECK(touch_sensor_new_controller(&touch_cfg, &sens_handle));
删除触摸传感器驱动控制器时需调用 :cpp:func:`touch_sensor_del_controller` 函数,从而释放该控制器所占用的软硬件资源。注意,需要将基于该控制器申请的其他资源销毁或释放后才能删除该控制器。如该控制器下仍有触摸通道未被删除,则无法直接删除。
.. code-block:: c
ESP_ERROR_CHECK(touch_sensor_del_controller(sens_handle));
在触摸传感器驱动控制器初始化后,且未启用触摸传感器时,可调用 :cpp:func:`touch_sensor_reconfig_controller` 函数对该控制器进行重新配置。
.. code-block:: c
touch_sensor_config_t touch_cfg = {
// 控制器的新配置
// ...
};
ESP_ERROR_CHECK(touch_sensor_reconfig_controller(sens_handle, &touch_cfg));
.. _touch-chan:
触摸传感器通道管理
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
一个触摸传感器具有多个测量通道,每个触摸传感器通道由句柄 :cpp:type:`touch_channel_handle_t` 控制。调用 :cpp:func:`touch_sensor_new_channel` 函数即可初始化触摸传感器通道并得到通道句柄。
.. code-block:: c
// ...
touch_channel_config_t chan_cfg = {
// 触摸通道配置
// ...
};
touch_channel_handle_t chan_handle = NULL;
int chan_id = 0;
// 申请一个新的触摸通道句柄
ESP_ERROR_CHECK(touch_sensor_new_channel(sens_handle, chan_id, &chan_cfg, &chan_handle));
删除触摸传感器通道时需调用 :cpp:func:`touch_sensor_del_channel` 函数,从而释放该通道所占用的软硬件资源。
.. code-block:: c
ESP_ERROR_CHECK(touch_sensor_del_channel(chan_handle));
在触摸传感器驱动通道初始化后,且未启用触摸传感器时,可调用 :cpp:func:`touch_sensor_reconfig_channel` 函数对该通道进行重新配置。
.. code-block:: c
touch_channel_config_t chan_cfg = {
// 触摸通道新配置
// ...
};
ESP_ERROR_CHECK(touch_sensor_reconfig_channel(chan_handle, &chan_cfg));
.. _touch-filter:
滤波器配置
^^^^^^^^^^^^^^
触摸传感器可以通过配置滤波器来提升不同场景下的数据稳定性。调用 :cpp:func:`touch_sensor_config_filter` 并指定 :cpp:type:`touch_sensor_filter_config_t` 来配置基线值和读数值的滤波策略和更新方式,配置后对所有启用的触摸通道都生效。
若需要注销滤波器,可再次调用 :cpp:func:`touch_sensor_config_filter` 并将第二个参数(即 :cpp:type:`touch_sensor_filter_config_t` 的配置结构体指针)设为 ``NULL`` 来注销滤波器功能。
.. code-block:: c
// ...
touch_sensor_filter_config_t filter_config = {
// 滤波器配置
// ...
};
// 注册滤波器
ESP_ERROR_CHECK(touch_sensor_config_filter(sens_handle, &filter_config));
// ...
// 注销滤波器
ESP_ERROR_CHECK(touch_sensor_config_filter(sens_handle, NULL));
.. _touch-callback:
回调函数
^^^^^^^^^^^^^
通过调用 :cpp:func:`touch_sensor_register_callbacks` 注册各类触摸传感器事件回调函数,当触摸传感器通道触发如触摸 ``on_active``、释放 ``on_inactive`` 等事件时,就会调用对应的回调函数通知上层应用,以便对触摸事件进行处理。
例如,测量值超出当前的测量通道的 ``基线值`` + ``触发阈值``,则该通道将被触发,并调用 ``on_active`` 事件的回调函数,通知应用层该触摸通道被 ``触发``。同理,若处于 ``触发`` 状态的通道测量值小于 ``基线值`` + ``触发阈值``,则该通道将回到未触发状态,并调用 ``on_inactive`` 事件的回调函数,通知应用层该触摸通道被 ``释放``
.. note::
为保证触发和释放事件的稳定性,触摸传感器可配置 ``触发阈值`` 的迟滞比较裕量和 ``去抖动计数`` 来避免短时间内由噪声和读数抖动引起的反复触发和释放
具体可注册的回调时间请参考 :cpp:type:`touch_event_callbacks_t`
.. code-block:: c
touch_event_callbacks_t callbacks = {
.on_active = example_touch_on_active_cb,
// 其他回调函数
// ...
};
// 注册回调函数
ESP_ERROR_CHECK(touch_sensor_register_callbacks(sens_handle, &callbacks, NULL));
// 通过把相应回调设为 NULL 以注销回调函数
callbacks.on_active = NULL;
// 其他需要注销的回调函数
// ...
ESP_ERROR_CHECK(touch_sensor_register_callbacks(sens_handle, &callbacks, NULL));
.. _touch-enable:
启用和禁用
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
配置完成触摸传感器控制器以及通道后,可调用 :cpp:func:`touch_sensor_enable` 函数启用该控制器,启用后控制器处于 ``就绪`` 状态,会对注册的通道上电,可以开始扫描并采集触摸数据。注意,控制器启用后无法更新配置,只能进行扫描采样和读数操作。若要更新配置,需先调用 :cpp:func:`touch_sensor_disable` 函数禁用控制器,方可重新配置控制器、通道等。
.. code-block:: c
// 启用触摸传感器
ESP_ERROR_CHECK(touch_sensor_enable(sens_handle));
// ...
// 禁用触摸传感器
ESP_ERROR_CHECK(touch_sensor_disable(sens_handle));
.. _touch-conti-scan:
连续扫描
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
在控制器启用后,调用 :cpp:func:`touch_sensor_start_continuous_scanning` 函数可开始对所有已注册的触摸通道进行连续扫描,每次扫描都会更新对应通道的测量值。调用 :cpp:func:`touch_sensor_stop_continuous_scanning` 函数后则停止扫描。
.. code-block:: c
// 开始连续扫描
ESP_ERROR_CHECK(touch_sensor_start_continuous_scanning(sens_handle));
// ...
// 停止连续扫描
ESP_ERROR_CHECK(touch_sensor_stop_continuous_scanning(sens_handle));
.. _touch-oneshot-scan:
单次扫描
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
在控制器启用后,调用 :cpp:func:`touch_sensor_trigger_oneshot_scanning` 函数可触发一次对所有已注册的触摸通道的扫描。注意,单次扫描为阻塞函数,调用后会保持阻塞直到扫描结束后返回。此外在开始连续扫描后,无法再触发单次扫描。
.. code-block:: c
// 触发单次扫描,并设置超时时间为 1000ms
ESP_ERROR_CHECK(touch_sensor_trigger_oneshot_scanning(sens_handle, 1000));
.. _touch-benchmark:
基线值配置
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
一般情况下,不需要额外设置触摸传感器的基线值,若有必要强制复位基线值到当前平滑值,可调用 :cpp:func:`touch_channel_config_benchmark`
.. code-block:: c
touch_chan_benchmark_config_t benchmark_cfg = {
// 基线操作
// ...
};
ESP_ERROR_CHECK(touch_channel_config_benchmark(chan_handle, &benchmark_cfg));
.. _touch-read:
测量值读数
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
调用 :cpp:func:`touch_channel_read_data` 可读取每个通道不同种类的数据,例如基线值、经过滤波后的平滑值等。支持的数据类型请参考 :cpp:type:`touch_chan_data_type_t`
.. only:: SOC_TOUCH_SUPPORT_FREQ_HOP
{IDF_TARGET_NAME} 支持通过配置多套采样配置来实现跳频采样,:cpp:func:`touch_channel_read_data` 可一次性读出一个通道所有采样配置的测量值。根据配置的 :cpp:member:`touch_sensor_config_t::sample_cfg_num` 采样配置数量,第三个参数 (``*data``) 数据指针传入数组长度大于等于采样配置数量的数组指针即可,该函数会将所指定通道的所有采样配置的测量值存入该数组中。
.. code-block:: c
#define SAMPLE_NUM 1 // 以一套采样配置为例
uint32_t smooth_data[SAMPLE_NUM] = {};
// 读取滤波后的平滑数据
ESP_ERROR_CHECK(touch_channel_read_data(chan_handle, TOUCH_CHAN_DATA_TYPE_SMOOTH, smooth_data));
.. _touch-waterproof:
.. only:: SOC_TOUCH_SUPPORT_WATERPROOF
防水防潮配置
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
{IDF_TARGET_NAME} 支持防水防潮功能。可通过调用 :cpp:func:`touch_sensor_config_waterproof` 并配置 :cpp:type:`touch_waterproof_config_t` 来注册防水防潮功能。防水防潮功能主要包含两部分:
- 遇水(浸没)保护功能: :cpp:member:`touch_waterproof_config_t::guard_chan` 用于指定用于遇水保护功能的触摸通道,该通道在 PCB 上一般设计成环形,其他普通触摸通道布局在该环形保护圈内,当电路板大面积浸水时,该环形保护通道会被触发,并停止其他触摸通道的扫描,由此防止其他普通通道的误触发;
- 防潮(水滴)屏蔽功能: :cpp:member:`touch_waterproof_config_t::shield_chan` 用于指定防潮屏蔽功能的触摸通道,该通道在 PCB 上一般设计成网格状铺铜。防潮屏蔽通道将与当前测量通道进行同步充放电,当有小水珠覆盖时,通过配置适当的 :cpp:member:`touch_waterproof_config_t::shield_drv` 来提高因水滴造成的电耦合强度,从而识别水滴造成的误触。在实际应用中识别到水滴造成的误触后可适当增加触摸通道触发的阈值来实现通道在水滴覆盖下的正常触发,从而实现防潮功能。
若需要注销防水防潮功能,可再次调用 :cpp:func:`touch_sensor_config_waterproof` 并将第二个参数(即 :cpp:type:`touch_waterproof_config_t` 的配置结构体指针)设为 ``NULL`` 来注销防水防潮功能。
.. code-block:: c
touch_waterproof_config_t waterproof_cfg = {
// 防水防潮配置
// ...
};
// 注册防水防潮功能
ESP_ERROR_CHECK(touch_sensor_config_waterproof(sens_handle, &waterproof_cfg));
// ...
// 注销防水防潮功能
ESP_ERROR_CHECK(touch_sensor_config_waterproof(sens_handle, NULL));
.. _touch-prox-sensing:
.. only:: SOC_TOUCH_SUPPORT_PROX_SENSING
接近感应配置
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
{IDF_TARGET_NAME} 支持接近感应功能。可通过调用 :cpp:func:`touch_sensor_config_proximity_sensing` 并配置 :cpp:type:`touch_proximity_config_t` 来注册接近感应功能。
由于接近感应引起的电容变化远小于物理触摸PCB 上常用较大面积的铺铜来增大触摸通道的感应面积,另外需要在硬件上对接近感应通道进行多轮扫描并在驱动中进行累加来提高测量灵敏度。接近感应的灵敏度由测量轮数 :cpp:member:`touch_proximity_config_t::scan_times` 以及单次测量的充放电次数 :cpp:member:`touch_proximity_config_t::charge_times` 决定。测量轮数以及充放电次数越高,灵敏度越高,但是过高的灵敏度容易导致误触发,请选择适当的灵敏度来保证触发的稳定性。
接近感应通道多次测量的累加值也可通过 :cpp:func:`touch_channel_read_data` 获取,数据类型 :cpp:type:`touch_chan_data_type_t`:cpp:enumerator:`TOUCH_CHAN_DATA_TYPE_PROXIMITY`
若需要注销接近感应功能,可再次调用 :cpp:func:`touch_sensor_config_proximity_sensing` 并将第二个参数(即 :cpp:type:`touch_proximity_config_t` 的配置结构体指针)设为 ``NULL`` 来注销接近感应功能。
.. code-block:: c
touch_proximity_config_t prox_cfg = {
// 接近感应配置
// ...
};
// 注册接近感应功能
ESP_ERROR_CHECK(touch_sensor_config_proximity_sensing(sens_handle, &prox_cfg));
// ...
// 注销接近感应功能
ESP_ERROR_CHECK(touch_sensor_config_proximity_sensing(sens_handle, NULL));
.. _touch-sleep-wakeup:
.. only:: SOC_TOUCH_SUPPORT_SLEEP_WAKEUP
睡眠唤醒配置
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
{IDF_TARGET_NAME} 支持触摸传感器将芯片从浅睡眠或深睡眠状态中唤醒。可通过调用 :cpp:func:`touch_sensor_config_sleep_wakeup` 并配置 :cpp:type:`touch_sleep_config_t` 来注册接近感应功能。
注册触摸传感器的睡眠唤醒功能后,处于睡眠状态下的芯片仍将继续保持对触摸传感器的采样,这将会导致芯片睡眠后的功耗增加,可通过减少充放电次数、增加采样间隔等方式来降低功耗。
另外,请注意在主核睡眠期间的采样、唤醒等操作均由硬件完成,本驱动由于运行在主核上,无法提供读数、配置等功能。
.. only:: SOC_RISCV_COPROC_SUPPORTED
若需要在睡眠过程中进行读数、配置等操作,可通过运行在 :doc:`超低功耗协处理器 ULP <../system/ulp>` 上的触摸传感器驱动 ``components/ulp/ulp_riscv/ulp_core/include/ulp_riscv_touch_ulp_core.h`` 实现。
- 浅睡眠状态唤醒:通过指定 :cpp:member:`slp_wakeup_lvl`:cpp:enumerator:`TOUCH_LIGHT_SLEEP_WAKEUP` 即可启用触摸传感器浅睡眠唤醒功能。注意任何已注册的触摸传感器通道都会在浅睡眠状态下保持采样并支持唤醒浅睡眠。
- 深睡眠状态唤醒:启用触摸传感器深睡眠唤醒功能除了指定 :cpp:member:`slp_wakeup_lvl`:cpp:enumerator:`TOUCH_DEEP_SLEEP_WAKEUP` 外,还需要指定深睡眠唤醒通道 :cpp:member:`deep_slp_chan`,注意只有该指定的通道才会在深睡眠状态下保持采样以及唤醒,以此降低在深睡眠状态下的功耗。此外,若需要在深度睡眠下使用另一套低功耗的配置来进一步降低功耗,可以通过 :cpp:member:`deep_slp_sens_cfg` 额外指定一套低功耗配置,在进入深睡眠前,驱动会应用这套配置,从深睡眠状态唤醒后,则会重新配置到之前的配置。请注意当 :cpp:member:`slp_wakeup_lvl` 配置为 :cpp:enumerator:`TOUCH_DEEP_SLEEP_WAKEUP` 后,触摸传感器不仅能唤醒深睡眠状态,还能唤醒浅睡眠状态。
若需要注销睡眠唤醒功能,可再次调用 :cpp:func:`touch_sensor_config_sleep_wakeup` 并将第二个参数(即 :cpp:type:`touch_sleep_config_t` 的配置结构体指针)设为 ``NULL`` 来注销睡眠唤醒功能。
.. code-block:: c
touch_sleep_config_t light_slp_cfg = {
.slp_wakeup_lvl = TOUCH_LIGHT_SLEEP_WAKEUP,
};
// 注册浅睡眠唤醒功能
ESP_ERROR_CHECK(touch_sensor_config_sleep_wakeup(sens_handle, &light_slp_cfg));
// ...
// 注销睡眠唤醒功能
ESP_ERROR_CHECK(touch_sensor_config_sleep_wakeup(sens_handle, NULL));
touch_sleep_config_t deep_slp_cfg = {
.slp_wakeup_lvl = TOUCH_DEEP_SLEEP_WAKEUP,
.deep_slp_chan = dslp_chan_handle,
// 其他深睡眠唤醒配置
// ...
};
// 注册深睡眠唤醒功能
ESP_ERROR_CHECK(touch_sensor_config_sleep_wakeup(sens_handle, &deep_slp_cfg));
应用示例
--------------------
.. only:: esp32p4
- 触摸传感器基础例程: :example:`peripherals/touch_sensor/touch_sensor_{IDF_TARGET_TOUCH_SENSOR_VERSION}`.
API 参考
-------------
.. only:: esp32p4
.. include-build-file:: inc/touch_sens.inc
.. include-build-file:: inc/touch_sens_types.inc
.. include-build-file:: inc/touch_version_types.inc

View File

@ -42,7 +42,8 @@
:SOC_SPI_SUPPORT_SLAVE_HD_VER2: spi_slave_hd
:SOC_JPEG_CODEC_SUPPORTED: jpeg
:SOC_TEMP_SENSOR_SUPPORTED: temp_sensor
:SOC_TOUCH_SENSOR_SUPPORTED: touch_pad
:SOC_TOUCH_SENSOR_SUPPORTED and not esp32p4: touch_pad
:esp32p4: cap_touch_sens
:esp32s2: touch_element
:SOC_TWAI_SUPPORTED: twai
uart

View File

@ -1,3 +1,3 @@
idf_component_register(SRCS "touch_sens_v3_example_main.c"
PRIV_REQUIRES esp_driver_touch_sens
REQUIRES esp_driver_touch_sens
INCLUDE_DIRS ".")

View File

@ -9,11 +9,10 @@
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/touch_sens.h"
#include "soc/lp_analog_peri_struct.h"
#include "esp_check.h"
// Touch version 3 supports multiple sample configurations
#define EXAMPLE_TOUCH_SAMPLE_CFG_NUM TOUCH_SAMPLE_CFG_NUM
#define EXAMPLE_TOUCH_SAMPLE_CFG_NUM 1 // Up to 'TOUCH_SAMPLE_CFG_NUM'
#define EXAMPLE_TOUCH_CHANNEL_NUM 4
#define EXAMPLE_TOUCH_CHAN_INIT_SCAN_TIMES 3
@ -21,7 +20,7 @@ static touch_sensor_handle_t s_sens_handle = NULL;
static touch_channel_handle_t s_chan_handle[EXAMPLE_TOUCH_CHANNEL_NUM] = {};
// 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%
[0 ... EXAMPLE_TOUCH_CHANNEL_NUM - 1] = 0.015f, // 1.5%
};
bool example_touch_on_active_callback(touch_sensor_handle_t sens_handle, const touch_active_event_data_t *event, void *user_ctx)
@ -59,7 +58,7 @@ static void example_touch_do_initial_scanning(void)
printf("[CH %d]", i);
touch_channel_config_t chan_cfg = {};
for (int j = 0; j < EXAMPLE_TOUCH_SAMPLE_CFG_NUM; j++) {
chan_cfg.active_thresh[j] = (uint32_t)(benchmark[j] * s_thresh2bm_ratio[j]);
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]);
}
printf("\n");
@ -72,12 +71,12 @@ void app_main(void)
{
/* Use the default sample configurations */
touch_sensor_sample_config_t sample_cfg[EXAMPLE_TOUCH_SAMPLE_CFG_NUM] = {
TOUCH_SENSOR_DEFAULT_SAMPLE_CONFIG0(),
TOUCH_SENSOR_V3_DEFAULT_SAMPLE_CONFIG(1, 1, 1),
#if EXAMPLE_TOUCH_SAMPLE_CFG_NUM > 1
TOUCH_SENSOR_DEFAULT_SAMPLE_CONFIG1(),
TOUCH_SENSOR_V3_DEFAULT_SAMPLE_CONFIG(2, 1, 1),
#endif
#if EXAMPLE_TOUCH_SAMPLE_CFG_NUM > 2
TOUCH_SENSOR_DEFAULT_SAMPLE_CONFIG2(),
TOUCH_SENSOR_V3_DEFAULT_SAMPLE_CONFIG(4, 1, 1),
#endif
};
/* Allocate new touch controller handle */
@ -108,12 +107,12 @@ void app_main(void)
* Step3: adjust the `s_thresh2bm_ratio` to a proper value to trigger the active callback
*/
.active_thresh = {
5000, // estimated active threshold of sample configuration 0
1000, // estimated active threshold of sample configuration 0
#if EXAMPLE_TOUCH_SAMPLE_CFG_NUM > 1
2500, // estimated active threshold of sample configuration 1
#endif
#if EXAMPLE_TOUCH_SAMPLE_CFG_NUM > 2
1000, // estimated active threshold of sample configuration 2
5000, // estimated active threshold of sample configuration 2
#endif
},
};

View File

@ -66,7 +66,7 @@ esp_err_t example_register_touch_wakeup(void)
{
touch_sensor_handle_t sens_handle = NULL;
touch_sensor_sample_config_t sample_cfg[EXAMPLE_TOUCH_SAMPLE_CFG_NUM] = {
TOUCH_SENSOR_DEFAULT_SAMPLE_CONFIG0(),
TOUCH_SENSOR_V3_DEFAULT_SAMPLE_CONFIG(1, 1, 1),
};
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));