forked from espressif/esp-idf
feat(touch): support s2 & s3 in touch driver-ng
This commit is contained in:
committed by
Kevin (Lao Kaiyao)
parent
6856aec19e
commit
1ccb534dc7
@@ -8,10 +8,11 @@ set(srcs)
|
||||
set(public_inc)
|
||||
|
||||
if(CONFIG_SOC_TOUCH_SENSOR_SUPPORTED)
|
||||
if(CONFIG_SOC_TOUCH_SENSOR_VERSION EQUAL 3)
|
||||
list(APPEND srcs "hw_ver3/touch_version_specific.c"
|
||||
"common/touch_sens_common.c")
|
||||
list(APPEND public_inc "include" "hw_ver3/include")
|
||||
set(version_folder "hw_ver${CONFIG_SOC_TOUCH_SENSOR_VERSION}")
|
||||
if(CONFIG_SOC_TOUCH_SENSOR_VERSION GREATER 1)
|
||||
list(APPEND srcs "common/touch_sens_common.c"
|
||||
"${version_folder}/touch_version_specific.c")
|
||||
list(APPEND public_inc "include" "${version_folder}/include")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
|
@@ -21,6 +21,7 @@
|
||||
#include "soc/interrupts.h"
|
||||
#include "esp_intr_alloc.h"
|
||||
#endif
|
||||
#include "esp_private/touch_sens_helper.h"
|
||||
|
||||
#if CONFIG_TOUCH_ENABLE_DEBUG_LOG
|
||||
// The local log level must be defined before including esp_log.h
|
||||
@@ -112,7 +113,7 @@ esp_err_t touch_sensor_del_controller(touch_sensor_handle_t sens_handle)
|
||||
ESP_GOTO_ON_ERROR(esp_intr_free(sens_handle->intr_handle), err, TAG, "Failed to deregister the interrupt handler");
|
||||
#endif
|
||||
TOUCH_ENTER_CRITICAL(TOUCH_PERIPH_LOCK);
|
||||
touch_ll_intr_disable(TOUCH_LL_INTR_MASK_ALL);
|
||||
touch_ll_interrupt_disable(TOUCH_LL_INTR_MASK_ALL);
|
||||
touch_ll_clear_active_channel_status();
|
||||
TOUCH_EXIT_CRITICAL(TOUCH_PERIPH_LOCK);
|
||||
|
||||
@@ -133,6 +134,7 @@ esp_err_t touch_sensor_new_channel(touch_sensor_handle_t sens_handle, int chan_i
|
||||
TOUCH_NULL_POINTER_CHECK(chan_cfg);
|
||||
TOUCH_NULL_POINTER_CHECK(ret_chan_handle);
|
||||
TOUCH_CHANNEL_CHECK(chan_id);
|
||||
|
||||
ESP_RETURN_ON_FALSE(g_touch == sens_handle, ESP_ERR_INVALID_ARG, TAG, "The input touch sensor handle is unmatched");
|
||||
|
||||
esp_err_t ret = ESP_OK;
|
||||
@@ -145,18 +147,18 @@ esp_err_t touch_sensor_new_channel(touch_sensor_handle_t sens_handle, int chan_i
|
||||
ESP_GOTO_ON_FALSE(sens_handle->ch[chan_id], ESP_ERR_NO_MEM, err2, TAG, "No memory for touch channel");
|
||||
sens_handle->ch[chan_id]->id = chan_id;
|
||||
sens_handle->ch[chan_id]->base = sens_handle;
|
||||
sens_handle->ch[chan_id]->is_prox_chan = false;
|
||||
sens_handle->ch[chan_id]->prox_id = 0;
|
||||
|
||||
/* Init the channel */
|
||||
ESP_GOTO_ON_ERROR(touch_priv_config_channel(sens_handle->ch[chan_id], chan_cfg),
|
||||
err1, TAG, "Failed to configure the touch channel %d", chan_id);
|
||||
touch_channel_pin_init(chan_id);
|
||||
|
||||
touch_chan_benchmark_config_t bm_cfg = {.do_reset = true};
|
||||
TOUCH_ENTER_CRITICAL(TOUCH_PERIPH_LOCK);
|
||||
#if SOC_TOUCH_SENSOR_VERSION == 2
|
||||
touch_ll_reset_chan_benchmark(1 << chan_id);
|
||||
#endif
|
||||
sens_handle->chan_mask |= 1 << chan_id;
|
||||
touch_ll_set_channel_mask(sens_handle->chan_mask);
|
||||
/* Reset the benchmark to overwrite the legacy benchmark during the deep sleep */
|
||||
touch_priv_config_benchmark(sens_handle->ch[chan_id], &bm_cfg);
|
||||
TOUCH_EXIT_CRITICAL(TOUCH_PERIPH_LOCK);
|
||||
|
||||
*ret_chan_handle = sens_handle->ch[chan_id];
|
||||
@@ -180,18 +182,32 @@ esp_err_t touch_sensor_del_channel(touch_channel_handle_t chan_handle)
|
||||
xSemaphoreTake(sens_handle->mutex, portMAX_DELAY);
|
||||
|
||||
ESP_GOTO_ON_FALSE(!sens_handle->is_enabled, ESP_ERR_INVALID_STATE, err, TAG, "Please disable the touch sensor first");
|
||||
#if SOC_TOUCH_SENSOR_VERSION == 2
|
||||
if (sens_handle->guard_chan == chan_handle || (BIT(chan_handle->id) & sens_handle->shield_chan_mask)) {
|
||||
#if SOC_TOUCH_SUPPORT_WATERPROOF
|
||||
if (sens_handle->shield_chan == chan_handle) {
|
||||
ESP_GOTO_ON_ERROR(touch_sensor_config_waterproof(sens_handle, NULL), err, TAG, "Failed to disable waterproof on this channel");
|
||||
} else if (sens_handle->guard_chan == chan_handle) {
|
||||
TOUCH_ENTER_CRITICAL(TOUCH_PERIPH_LOCK);
|
||||
touch_ll_waterproof_set_guard_chan(TOUCH_LL_NULL_CHANNEL);
|
||||
sens_handle->guard_chan = NULL;
|
||||
TOUCH_EXIT_CRITICAL(TOUCH_PERIPH_LOCK);
|
||||
}
|
||||
if (sens_handle->sleep_chan == chan_handle) {
|
||||
ESP_GOTO_ON_ERROR(touch_sensor_config_sleep_channel(sens_handle, NULL), err, TAG, "Failed to disable sleep function on this channel");
|
||||
#endif // SOC_TOUCH_SUPPORT_WATERPROOF
|
||||
#if SOC_TOUCH_SUPPORT_SLEEP_WAKEUP
|
||||
if (sens_handle->deep_slp_chan == chan_handle) {
|
||||
ESP_GOTO_ON_ERROR(touch_sensor_config_sleep_wakeup(sens_handle, NULL), err, TAG, "Failed to disable sleep function on this channel");
|
||||
}
|
||||
#endif
|
||||
#if SOC_TOUCH_SUPPORT_PROX_SENSING
|
||||
if (chan_handle->prox_id > 0) {
|
||||
TOUCH_ENTER_CRITICAL(TOUCH_PERIPH_LOCK);
|
||||
chan_handle->prox_id = 0;
|
||||
touch_ll_set_proximity_sensing_channel(chan_handle->prox_id - 1, TOUCH_LL_NULL_CHANNEL);
|
||||
TOUCH_EXIT_CRITICAL(TOUCH_PERIPH_LOCK);
|
||||
}
|
||||
#endif
|
||||
int id = chan_handle->id;
|
||||
TOUCH_ENTER_CRITICAL(TOUCH_PERIPH_LOCK);
|
||||
sens_handle->chan_mask &= ~(1UL << id);
|
||||
touch_ll_set_channel_mask(sens_handle->chan_mask);
|
||||
TOUCH_EXIT_CRITICAL(TOUCH_PERIPH_LOCK);
|
||||
|
||||
free(g_touch->ch[id]);
|
||||
@@ -230,13 +246,14 @@ esp_err_t touch_sensor_enable(touch_sensor_handle_t sens_handle)
|
||||
|
||||
sens_handle->is_enabled = true;
|
||||
TOUCH_ENTER_CRITICAL(TOUCH_PERIPH_LOCK);
|
||||
touch_ll_intr_clear(TOUCH_LL_INTR_MASK_ALL);
|
||||
touch_ll_intr_enable(TOUCH_LL_INTR_MASK_ALL);
|
||||
touch_ll_enable_channel_mask(sens_handle->chan_mask);
|
||||
touch_ll_interrupt_clear(TOUCH_LL_INTR_MASK_ALL);
|
||||
touch_ll_interrupt_enable(TOUCH_LL_INTR_MASK_ALL);
|
||||
TOUCH_EXIT_CRITICAL(TOUCH_PERIPH_LOCK);
|
||||
#if SOC_TOUCH_SUPPORT_PROX_SENSING
|
||||
/* Reset the cached data of proximity channel */
|
||||
FOR_EACH_TOUCH_CHANNEL(i) {
|
||||
if (sens_handle->ch[i] && sens_handle->ch[i]->is_prox_chan) {
|
||||
if (sens_handle->ch[i] && sens_handle->ch[i]->prox_id > 0) {
|
||||
sens_handle->ch[i]->prox_cnt = 0;
|
||||
memset(sens_handle->ch[i]->prox_val, 0, sizeof(sens_handle->ch[i]->prox_val[0]) * TOUCH_SAMPLE_CFG_NUM);
|
||||
}
|
||||
@@ -257,7 +274,8 @@ esp_err_t touch_sensor_disable(touch_sensor_handle_t sens_handle)
|
||||
ESP_GOTO_ON_FALSE(sens_handle->is_enabled, ESP_ERR_INVALID_STATE, err, TAG, "Touch sensor has not enabled");
|
||||
|
||||
TOUCH_ENTER_CRITICAL(TOUCH_PERIPH_LOCK);
|
||||
touch_ll_intr_disable(TOUCH_LL_INTR_MASK_ALL);
|
||||
touch_ll_interrupt_disable(TOUCH_LL_INTR_MASK_ALL);
|
||||
touch_ll_enable_channel_mask(0);
|
||||
TOUCH_EXIT_CRITICAL(TOUCH_PERIPH_LOCK);
|
||||
sens_handle->is_enabled = false;
|
||||
|
||||
@@ -294,13 +312,8 @@ esp_err_t touch_sensor_start_continuous_scanning(touch_sensor_handle_t sens_hand
|
||||
|
||||
TOUCH_ENTER_CRITICAL_SAFE(TOUCH_PERIPH_LOCK);
|
||||
sens_handle->is_started = true;
|
||||
#if SOC_TOUCH_SENSOR_VERSION <= 2
|
||||
touch_ll_set_fsm_mode(TOUCH_FSM_MODE_TIMER);
|
||||
touch_ll_start_fsm();
|
||||
#else
|
||||
touch_ll_enable_fsm_timer(true);
|
||||
touch_ll_start_fsm_repeated_timer(false);
|
||||
#endif
|
||||
touch_ll_start_fsm_repeated_timer();
|
||||
TOUCH_EXIT_CRITICAL_SAFE(TOUCH_PERIPH_LOCK);
|
||||
|
||||
err:
|
||||
@@ -316,13 +329,8 @@ esp_err_t touch_sensor_stop_continuous_scanning(touch_sensor_handle_t sens_handl
|
||||
ESP_GOTO_ON_FALSE_ISR(sens_handle->is_started, ESP_ERR_INVALID_STATE, err, TAG, "Continuous scanning not started yet");
|
||||
|
||||
TOUCH_ENTER_CRITICAL_SAFE(TOUCH_PERIPH_LOCK);
|
||||
#if SOC_TOUCH_SENSOR_VERSION <= 2
|
||||
touch_ll_stop_fsm();
|
||||
touch_ll_set_fsm_mode(TOUCH_FSM_MODE_SW);
|
||||
#else
|
||||
touch_ll_stop_fsm_repeated_timer(false);
|
||||
touch_ll_stop_fsm_repeated_timer();
|
||||
touch_ll_enable_fsm_timer(false);
|
||||
#endif
|
||||
sens_handle->is_started = false;
|
||||
TOUCH_EXIT_CRITICAL_SAFE(TOUCH_PERIPH_LOCK);
|
||||
|
||||
@@ -351,7 +359,6 @@ esp_err_t touch_sensor_trigger_oneshot_scanning(touch_sensor_handle_t sens_handl
|
||||
}
|
||||
xSemaphoreTake(sens_handle->mutex, ticks);
|
||||
TickType_t end_tick = xTaskGetTickCount() + ticks;
|
||||
// TODO: extract the following implementation into version specific source file when supporting other targets
|
||||
TOUCH_ENTER_CRITICAL(TOUCH_PERIPH_LOCK);
|
||||
touch_ll_enable_fsm_timer(false);
|
||||
TOUCH_EXIT_CRITICAL(TOUCH_PERIPH_LOCK);
|
||||
@@ -426,3 +433,21 @@ esp_err_t touch_channel_config_benchmark(touch_channel_handle_t chan_handle, con
|
||||
touch_priv_config_benchmark(chan_handle, benchmark_cfg);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
/* Scope: Private APIs */
|
||||
/******************************************************************************/
|
||||
esp_err_t touch_sensor_get_channel_info(touch_channel_handle_t chan_handle, touch_chan_info_t *chan_info)
|
||||
{
|
||||
TOUCH_NULL_POINTER_CHECK(chan_handle);
|
||||
TOUCH_NULL_POINTER_CHECK(chan_info);
|
||||
xSemaphoreTake(chan_handle->base->mutex, portMAX_DELAY);
|
||||
chan_info->chan_id = chan_handle->id;
|
||||
chan_info->chan_gpio = touch_sensor_channel_io_map[chan_handle->id];
|
||||
chan_info->flags.is_dp_slp = chan_handle == chan_handle->base->deep_slp_chan;
|
||||
chan_info->flags.is_proxi = chan_handle->prox_id > 0;
|
||||
chan_info->flags.is_guard = chan_handle == chan_handle->base->guard_chan;
|
||||
chan_info->flags.is_shield = chan_handle == chan_handle->base->shield_chan;
|
||||
xSemaphoreGive(chan_handle->base->mutex);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
@@ -14,7 +14,7 @@
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/semphr.h"
|
||||
#include "soc/soc_caps.h"
|
||||
#include "hal/touch_sensor_hal.h"
|
||||
#include "hal/touch_sens_hal.h"
|
||||
#include "driver/touch_sens_types.h"
|
||||
#include "esp_memory_utils.h"
|
||||
#include "esp_check.h"
|
||||
@@ -85,6 +85,7 @@ struct touch_sensor_s {
|
||||
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 */
|
||||
bool denoise_en; /*!< Flag to indicate whether the denoise channel feature is enabled */
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -94,7 +95,7 @@ struct touch_sensor_s {
|
||||
struct touch_channel_s {
|
||||
touch_sensor_handle_t base; /*!< The touch sensor controller handle */
|
||||
int id; /*!< Touch channel id, the range is target-specific */
|
||||
bool is_prox_chan; /*!< Flag to indicate whether this is a proximity channel */
|
||||
int prox_id; /*!< The proximity channel id + 1. It is 0 if not a proximity channel */
|
||||
uint32_t prox_cnt; /*!< Cache the proximity measurement count, only takes effect when the channel is a proximity channel.
|
||||
* When this count reaches `touch_proximity_config_t::scan_times`,
|
||||
* this field will be cleared and call the `on_proximity_meas_done` callback.
|
||||
|
@@ -9,4 +9,375 @@
|
||||
* Version 2 includes ESP32-S2 and ESP32-S3
|
||||
*/
|
||||
|
||||
#error "'esp_driver_touch_sens' does not support for ESP32-S2 and ESP32-S3 yet"
|
||||
#pragma once
|
||||
|
||||
#include "soc/soc_caps.h"
|
||||
#include "driver/touch_sens_types.h"
|
||||
#include "esp_err.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define TOUCH_MIN_CHAN_ID 1 /*!< The minimum available channel id of the touch pad */
|
||||
#define TOUCH_MAX_CHAN_ID 14 /*!< The maximum available channel id of the touch pad */
|
||||
|
||||
#define TOUCH_SHIELD_CHAN_ID 14 /*!< The touch channel that can be used as the shield channel */
|
||||
|
||||
/**
|
||||
* @brief Helper macro to the default configurations of the touch sensor controller
|
||||
*
|
||||
* @param[in] sample_cfg_number The number of the sample configurations, which can only be 1 here because there is only one sample configuration
|
||||
* @param[in] sample_cfg_ptr The pointer to the sample configurations
|
||||
*/
|
||||
#define TOUCH_SENSOR_DEFAULT_BASIC_CONFIG(sample_cfg_number, sample_cfg_ptr) { \
|
||||
.power_on_wait_us = 256, \
|
||||
.meas_interval_us = 32.0, \
|
||||
.max_meas_time_us = 0, \
|
||||
.sample_cfg_num = sample_cfg_number, \
|
||||
.sample_cfg = sample_cfg_ptr, \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Helper macro to the default sample configurations
|
||||
* @note This default configuration uses `sample frequency = clock frequency / 1`
|
||||
*
|
||||
* @param[in] chg_times The charge times of the touch channel
|
||||
* @param[in] volt_low The low voltage limit of the touch channel
|
||||
* @param[in] volt_high The high voltage limit of the touch channel
|
||||
*/
|
||||
#define TOUCH_SENSOR_V2_DEFAULT_SAMPLE_CONFIG(chg_times, volt_low, volt_high) { \
|
||||
.charge_times = chg_times, \
|
||||
.charge_volt_lim_h = volt_high, \
|
||||
.charge_volt_lim_l = volt_low, \
|
||||
.idle_conn = TOUCH_IDLE_CONN_GND, \
|
||||
.bias_type = TOUCH_BIAS_TYPE_SELF, \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Helper macro to the default filter configurations
|
||||
*
|
||||
*/
|
||||
#define TOUCH_SENSOR_DEFAULT_FILTER_CONFIG() { \
|
||||
.benchmark = { \
|
||||
.filter_mode = TOUCH_BM_IIR_FILTER_4, \
|
||||
.jitter_step = 4, \
|
||||
.denoise_lvl = 1, \
|
||||
}, \
|
||||
.data = { \
|
||||
.smooth_filter = TOUCH_SMOOTH_IIR_FILTER_2, \
|
||||
.active_hysteresis = 2, \
|
||||
.debounce_cnt = 2, \
|
||||
}, \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief The data type of the touch channel
|
||||
*
|
||||
*/
|
||||
typedef enum {
|
||||
TOUCH_CHAN_DATA_TYPE_RAW, /*!< The raw data of the touch channel */
|
||||
TOUCH_CHAN_DATA_TYPE_SMOOTH, /*!< The smooth data of the touch channel */
|
||||
TOUCH_CHAN_DATA_TYPE_BENCHMARK, /*!< The benchmark of the touch channel */
|
||||
TOUCH_CHAN_DATA_TYPE_PROXIMITY, /*!< The proximity data of the proximity channel */
|
||||
} touch_chan_data_type_t;
|
||||
|
||||
/**
|
||||
* @brief Sample configurations of the touch sensor
|
||||
*
|
||||
*/
|
||||
typedef struct {
|
||||
uint32_t charge_times; /*!< The charge and discharge times of this sample configuration, the read data are positive correlation to the charge_times */
|
||||
touch_volt_lim_h_t charge_volt_lim_h; /*!< The upper voltage limit while charging a touch pad */
|
||||
touch_volt_lim_l_t charge_volt_lim_l; /*!< The lower voltage limit while charging a touch pad */
|
||||
touch_idle_conn_t idle_conn; /*!< The connection of the idle touch channels.
|
||||
* The idle touch channel is a channel which is enabled but not under measuring.
|
||||
*/
|
||||
touch_bias_type_t bias_type; /*!< The type of the touch sensor bias */
|
||||
} touch_sensor_sample_config_t;
|
||||
|
||||
/**
|
||||
* @brief Configurations of the touch sensor controller
|
||||
*
|
||||
*/
|
||||
typedef struct {
|
||||
uint32_t power_on_wait_us; /*!< The waiting time between the channels power on and able to measure, to ensure the data stability */
|
||||
float meas_interval_us; /*!< Measurement interval of each channels */
|
||||
uint32_t max_meas_time_us; /*!< The maximum time of measuring one channel, if the time exceeds this value, the timeout interrupt will be triggered.
|
||||
* Set to '0' to ignore the measurement time limitation, otherwise please set a proper time considering the configurations
|
||||
* of this sample configurations below.
|
||||
*/
|
||||
/* Touch sensor sample configuration */
|
||||
uint32_t sample_cfg_num; /*!< The sample configuration number that used for sampling, CANNOT exceed TOUCH_SAMPLE_CFG_NUM */
|
||||
touch_sensor_sample_config_t *sample_cfg; /*!< The array of this sample configuration configurations, the length should be specified in `touch_sensor_config_t::sample_cfg_num` */
|
||||
} touch_sensor_config_t;
|
||||
|
||||
/**
|
||||
* @brief Configurations of the touch sensor channel
|
||||
*
|
||||
*/
|
||||
typedef struct {
|
||||
uint32_t active_thresh[TOUCH_SAMPLE_CFG_NUM]; /*!< The active threshold of each sample configuration,
|
||||
* while the touch channel smooth value minus benchmark value exceed this threshold,
|
||||
* will be regarded as activated
|
||||
*/
|
||||
touch_charge_speed_t charge_speed; /*!< The speed of charging and discharging the touch pad, the higher the speed, the faster charging and discharging */
|
||||
touch_init_charge_volt_t init_charge_volt; /*!< The initial voltage before charging/discharging a touch pad */
|
||||
} touch_channel_config_t;
|
||||
|
||||
/**
|
||||
* @brief Configurations of the touch sensor filter
|
||||
*
|
||||
*/
|
||||
typedef struct {
|
||||
/**
|
||||
* @brief Benchmark configuration
|
||||
*/
|
||||
struct {
|
||||
touch_benchmark_filter_mode_t filter_mode; /*!< Benchmark filter mode. IIR filter and Jitter filter can be selected,
|
||||
* TOUCH_BM_IIR_FILTER_16 is recommended
|
||||
*/
|
||||
uint32_t jitter_step; /*!< Jitter filter step size, only takes effect when the `filter_mode` is TOUCH_BM_JITTER_FILTER. Range: [0 ~ 15] */
|
||||
int denoise_lvl; /*!< The denoise level, which determines the noise bouncing range that won't trigger benchmark update.
|
||||
* Range: [0 ~ 4]. The greater the denoise_lvl is, more noise resistance will be. Specially, `0` stands for no denoise
|
||||
* Typically, recommend to set this field to 1.
|
||||
*/
|
||||
} benchmark; /*!< Benchmark filter */
|
||||
/**
|
||||
* @brief Data configuration
|
||||
*/
|
||||
struct {
|
||||
touch_smooth_filter_mode_t smooth_filter; /*!< Smooth data IIR filter mode */
|
||||
uint32_t active_hysteresis; /*!< The hysteresis threshold to judge whether the touch channel is active
|
||||
* If the channel data exceed the 'touch_channel_config_t::active_thresh + active_hysteresis'
|
||||
* The channel will be activated. If the channel data is below to
|
||||
* 'touch_channel_config_t::active_thresh - active_hysteresis' the channel will be inactivated.
|
||||
*/
|
||||
uint32_t debounce_cnt; /*!< The debounce count of the touch channel.
|
||||
* Only when the channel data exceed the `touch_channel_config_t::active_thresh + active_hysteresis` for `debounce_cnt` times
|
||||
* The channel will be activated. And only if the channel data is below to the `touch_channel_config_t::active_thresh - active_hysteresis`
|
||||
* for `debounce_cnt` times, the channel will be inactivated.
|
||||
* (The unit of `debounce_cnt` is the tick of the slow clock source)
|
||||
*/
|
||||
} data; /*!< Channel data filter */
|
||||
} touch_sensor_filter_config_t;
|
||||
|
||||
/**
|
||||
* @brief Touch sensor configuration during the deep sleep
|
||||
* @note Currently it is the same as the normal controller configuration.
|
||||
* The deep sleep configuration only takes effect when the chip entered sleep,
|
||||
* so that to update a more power efficient configuration.
|
||||
*
|
||||
*/
|
||||
typedef touch_sensor_config_t touch_sensor_config_dslp_t;
|
||||
|
||||
/**
|
||||
* @brief Configuration of the touch sensor sleep function
|
||||
*
|
||||
*/
|
||||
typedef struct {
|
||||
touch_sleep_wakeup_level_t slp_wakeup_lvl; /*!< The sleep level that can be woke up by touch sensor. */
|
||||
touch_channel_handle_t deep_slp_chan; /*!< The touch channel handle that supposed to work in the deep sleep. It can wake up the chip
|
||||
* from deep sleep when this channel is activated.
|
||||
* Only effective when the `touch_sleep_config_t::slp_wakeup_lvl` is `TOUCH_DEEP_SLEEP_WAKEUP`
|
||||
*/
|
||||
uint32_t deep_slp_thresh[TOUCH_SAMPLE_CFG_NUM]; /*!< The active threshold of the deep sleep channel during deep sleep,
|
||||
* while the sleep channel exceed this threshold, it will be regarded as activated
|
||||
* Only effective when the `touch_sleep_config_t::slp_wakeup_lvl` is `TOUCH_DEEP_SLEEP_WAKEUP`
|
||||
*/
|
||||
touch_sensor_config_dslp_t *deep_slp_sens_cfg; /*!< Specify the touch sensor configuration during the deep sleep.
|
||||
* Note that these configurations will no take effect immediately,
|
||||
* they will be set automatically while the chip prepare to enter sleep.
|
||||
* Set NULL to not change the configurations before entering sleep.
|
||||
* The sleep configuration mainly aims at lower down the charging and measuring times,
|
||||
* so that to save power consumption during the sleep.
|
||||
* Only effective when the `touch_sleep_config_t::slp_wakeup_lvl` is `TOUCH_DEEP_SLEEP_WAKEUP`
|
||||
*/
|
||||
} touch_sleep_config_t;
|
||||
|
||||
/**
|
||||
* @brief Configuration of the touch sensor waterproof function
|
||||
*
|
||||
*/
|
||||
typedef struct {
|
||||
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 guard channel will be activated.
|
||||
*/
|
||||
touch_channel_handle_t shield_chan; /*!< The shield channel that used for water droplets shield, can't be NULL.
|
||||
* The shield channel can only be the No.14 channel on touch version 2.
|
||||
* 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.
|
||||
*/
|
||||
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;
|
||||
|
||||
/**
|
||||
* @brief Configuration of the touch sensor proximity function
|
||||
*
|
||||
*/
|
||||
typedef struct {
|
||||
touch_channel_handle_t proximity_chan[TOUCH_PROXIMITY_CHAN_NUM]; /*!< The touch channel handles that will be configured as proximity sensing channels */
|
||||
uint32_t scan_times; /*!< The total scan times of EACH sample configuration, all sample configurations share a same `scan_times`.
|
||||
* The measurement result of each scanning will be accumulated together to get the final result.
|
||||
*/
|
||||
} touch_proximity_config_t;
|
||||
|
||||
/**
|
||||
* @brief Configuration of denoise channel
|
||||
*
|
||||
*/
|
||||
typedef struct {
|
||||
touch_charge_speed_t charge_speed; /*!< The speed of charging and discharging the denoise touch channel, the higher the speed, the faster charging and discharging */
|
||||
touch_init_charge_volt_t init_charge_volt; /*!< The initial voltage before starting charging/discharging the denoise channel */
|
||||
touch_denoise_chan_cap_t ref_cap; /*!< The reference capacitance of the denoise channel. */
|
||||
touch_denoise_chan_res_t resolution; /*!< The noise suppression resolution of the denoise channel.
|
||||
* The higher the resolution, the better the suppression effect,
|
||||
* but at the same time, the attenuation of other touch channel sampling values also increases.
|
||||
*/
|
||||
} touch_denoise_chan_config_t;
|
||||
|
||||
/**
|
||||
* @brief Base event structure used in touch event queue
|
||||
*/
|
||||
typedef struct {
|
||||
touch_channel_handle_t chan; /*!< the current triggered touch channel handle */
|
||||
int chan_id; /*!< the current triggered touch channel number */
|
||||
uint32_t status_mask; /*!< the current channel triggered status.
|
||||
* For the bits in the status mask,
|
||||
* if the bit is set, the corresponding channel is active
|
||||
* if the bit is cleared, the corresponding channel is inactive
|
||||
*/
|
||||
} touch_base_event_data_t;
|
||||
|
||||
/**
|
||||
* @brief Measure done event data
|
||||
* @note Currently same as base event data
|
||||
*
|
||||
*/
|
||||
typedef touch_base_event_data_t touch_meas_done_event_data_t;
|
||||
|
||||
/**
|
||||
* @brief Scan done event data
|
||||
* @note Currently same as base event data
|
||||
*
|
||||
*/
|
||||
typedef touch_base_event_data_t touch_scan_done_event_data_t;
|
||||
|
||||
/**
|
||||
* @brief Active event data
|
||||
* @note Currently same as base event data
|
||||
*
|
||||
*/
|
||||
typedef touch_base_event_data_t touch_active_event_data_t;
|
||||
|
||||
/**
|
||||
* @brief Inactive event data
|
||||
* @note Currently same as base event data
|
||||
*
|
||||
*/
|
||||
typedef touch_base_event_data_t touch_inactive_event_data_t;
|
||||
|
||||
/**
|
||||
* @brief Proximity sensing measure done event data
|
||||
* @note Currently same as base event data
|
||||
*
|
||||
*/
|
||||
typedef touch_base_event_data_t touch_prox_done_event_data_t;
|
||||
|
||||
/**
|
||||
* @brief Timeout event data
|
||||
* @note Currently same as base event data
|
||||
*
|
||||
*/
|
||||
typedef touch_base_event_data_t touch_timeout_event_data_t;
|
||||
|
||||
/**
|
||||
* @brief Touch sensor callbacks
|
||||
* @note Set NULL for the used callbacks.
|
||||
*
|
||||
*/
|
||||
typedef struct {
|
||||
/**
|
||||
* @brief Touch sensor on active event callback.
|
||||
* Callback when any touch channel is activated.
|
||||
* @param[in] sens_handle Touch sensor controller handle, created from `touch_sensor_new_controller()`
|
||||
* @param[in] event Touch sensor active event data
|
||||
* @param[in] user_ctx User registered context, passed from `touch_sensor_register_callbacks()`
|
||||
*
|
||||
* @return Whether a high priority task has been waken up by this callback function
|
||||
*/
|
||||
bool (*on_active)(touch_sensor_handle_t sens_handle, const touch_active_event_data_t *event, void *user_ctx);
|
||||
/**
|
||||
* @brief Touch sensor on inactive event callback.
|
||||
* Callback when any touch channel is inactivated.
|
||||
* @param[in] sens_handle Touch sensor controller handle, created from `touch_sensor_new_controller()`
|
||||
* @param[in] event Touch sensor inactive event data
|
||||
* @param[in] user_ctx User registered context, passed from `touch_sensor_register_callbacks()`
|
||||
*
|
||||
* @return Whether a high priority task has been waken up by this callback function
|
||||
*/
|
||||
bool (*on_inactive)(touch_sensor_handle_t sens_handle, const touch_inactive_event_data_t *event, void *user_ctx);
|
||||
/**
|
||||
* @brief Touch sensor on measure done event callback.
|
||||
* Callback when the measurement of all the sample configurations on the current touch channel is done.
|
||||
* @param[in] sens_handle Touch sensor controller handle, created from `touch_sensor_new_controller()`
|
||||
* @param[in] event Touch sensor measure done event data
|
||||
* @param[in] user_ctx User registered context, passed from `touch_sensor_register_callbacks()`
|
||||
*
|
||||
* @return Whether a high priority task has been waken up by this callback function
|
||||
*/
|
||||
bool (*on_measure_done)(touch_sensor_handle_t sens_handle, const touch_meas_done_event_data_t *event, void *user_ctx);
|
||||
/**
|
||||
* @brief Touch sensor on scan done event callback.
|
||||
* Callback when finished scanning all the registered touch channels.
|
||||
* @param[in] sens_handle Touch sensor controller handle, created from `touch_sensor_new_controller()`
|
||||
* @param[in] event Touch sensor scan done event data
|
||||
* @param[in] user_ctx User registered context, passed from `touch_sensor_register_callbacks()`
|
||||
*
|
||||
* @return Whether a high priority task has been waken up by this callback function
|
||||
*/
|
||||
bool (*on_scan_done)(touch_sensor_handle_t sens_handle, const touch_scan_done_event_data_t *event, void *user_ctx);
|
||||
/**
|
||||
* @brief Touch sensor on measurement timeout event callback.
|
||||
* Callback when measure the current touch channel timeout.
|
||||
* @param[in] sens_handle Touch sensor controller handle, created from `touch_sensor_new_controller()`
|
||||
* @param[in] event Touch sensor timeout event data
|
||||
* @param[in] user_ctx User registered context, passed from `touch_sensor_register_callbacks()`
|
||||
*
|
||||
* @return Whether a high priority task has been waken up by this callback function
|
||||
*/
|
||||
bool (*on_timeout)(touch_sensor_handle_t sens_handle, const touch_timeout_event_data_t *event, void *user_ctx);
|
||||
/**
|
||||
* @brief Touch sensor on proximity sensing measurement done event callback.
|
||||
* Callback when proximity sensing measurement of the current channel is done.
|
||||
* @param[in] sens_handle Touch sensor controller handle, created from `touch_sensor_new_controller()`
|
||||
* @param[in] event Touch sensor proximity sensing measure done event data
|
||||
* @param[in] user_ctx User registered context, passed from `touch_sensor_register_callbacks()`
|
||||
*
|
||||
* @return Whether a high priority task has been waken up by this callback function
|
||||
*/
|
||||
bool (*on_proximity_meas_done)(touch_sensor_handle_t sens_handle, const touch_prox_done_event_data_t *event, void *user_ctx);
|
||||
} touch_event_callbacks_t;
|
||||
|
||||
/**
|
||||
* @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_config_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@@ -0,0 +1,470 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief This file is only applicable to the touch hardware version2
|
||||
* Version 2 includes ESP32-S2 and ESP32-S3
|
||||
*/
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <string.h>
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/semphr.h"
|
||||
#include "soc/soc_caps.h"
|
||||
#include "soc/clk_tree_defs.h"
|
||||
#include "soc/touch_sensor_periph.h"
|
||||
#include "soc/rtc.h"
|
||||
#include "hal/hal_utils.h"
|
||||
#include "driver/touch_sens.h"
|
||||
#include "esp_private/rtc_ctrl.h"
|
||||
#include "esp_private/periph_ctrl.h"
|
||||
#include "esp_clk_tree.h"
|
||||
#include "esp_sleep.h"
|
||||
#include "../../common/touch_sens_private.h"
|
||||
#if CONFIG_TOUCH_ENABLE_DEBUG_LOG
|
||||
// The local log level must be defined before including esp_log.h
|
||||
// Set the maximum log level for this source file
|
||||
#define LOG_LOCAL_LEVEL ESP_LOG_DEBUG
|
||||
#endif
|
||||
#include "esp_check.h"
|
||||
|
||||
#define TOUCH_DENOISE_CHAN_ID 0 /*!< The touch channel that can be used as the denoise channel */
|
||||
|
||||
static const char *TAG = "touch";
|
||||
|
||||
portMUX_TYPE g_touch_spinlock = portMUX_INITIALIZER_UNLOCKED;
|
||||
|
||||
/******************************************************************************
|
||||
* Scope: touch driver private *
|
||||
******************************************************************************/
|
||||
|
||||
void touch_priv_enable_module(bool enable)
|
||||
{
|
||||
TOUCH_ENTER_CRITICAL(TOUCH_RTC_LOCK);
|
||||
touch_ll_enable_clock_gate(enable);
|
||||
// Reset the benchmark after finished the scanning
|
||||
touch_ll_reset_chan_benchmark(TOUCH_LL_FULL_CHANNEL_MASK);
|
||||
TOUCH_EXIT_CRITICAL(TOUCH_RTC_LOCK);
|
||||
}
|
||||
|
||||
void IRAM_ATTR touch_priv_default_intr_handler(void *arg)
|
||||
{
|
||||
/* If the touch controller object has not been allocated, return directly */
|
||||
if (!g_touch) {
|
||||
return;
|
||||
}
|
||||
bool need_yield = false;
|
||||
uint32_t status = touch_ll_get_intr_status_mask();
|
||||
g_touch->is_meas_timeout = false;
|
||||
touch_ll_interrupt_clear(status);
|
||||
touch_base_event_data_t data;
|
||||
touch_ll_get_active_channel_mask(&data.status_mask);
|
||||
data.chan = g_touch->ch[touch_ll_get_current_meas_channel()];
|
||||
/* If the channel is not registered, return directly */
|
||||
if (!data.chan) {
|
||||
return;
|
||||
}
|
||||
data.chan_id = data.chan->id;
|
||||
|
||||
if (status & TOUCH_LL_INTR_MASK_DONE) {
|
||||
#if !SOC_TOUCH_PROXIMITY_MEAS_DONE_SUPPORTED
|
||||
/* For the target like ESP32-S2 that don't support proximity done interrupt,
|
||||
Simulate the interrupt by software by judge the scan times. */
|
||||
if (data.chan->prox_id > 0 &&
|
||||
touch_ll_proximity_get_total_scan_times() == touch_ll_proximity_get_curr_scan_cnt(data.chan_id)) {
|
||||
/* Set the proximity scan done flag to simulate a proximity done interrupt */
|
||||
status |= TOUCH_LL_INTR_MASK_PROX_DONE;
|
||||
}
|
||||
#endif
|
||||
if (g_touch->cbs.on_measure_done) {
|
||||
need_yield |= g_touch->cbs.on_measure_done(g_touch, &data, g_touch->user_ctx);
|
||||
}
|
||||
}
|
||||
if (status & TOUCH_LL_INTR_MASK_SCAN_DONE) {
|
||||
#if CONFIG_IDF_TARGET_ESP32S2
|
||||
/* Workaround for the fake scan done interrupt.
|
||||
(Only happens when both channel 13 and 14 are enabled)
|
||||
The scan done interrupt will be triggered twice for channel 13 and 14,
|
||||
but we only hope it be triggered after channel 14 measurement done. */
|
||||
bool fake_scan_done = data.chan_id == 13 && (g_touch->chan_mask >> 13 == 0x03);
|
||||
if (g_touch->cbs.on_scan_done && !fake_scan_done)
|
||||
#else
|
||||
if (g_touch->cbs.on_scan_done)
|
||||
#endif
|
||||
{
|
||||
need_yield |= g_touch->cbs.on_scan_done(g_touch, &data, g_touch->user_ctx);
|
||||
}
|
||||
}
|
||||
if (status & TOUCH_LL_INTR_MASK_PROX_DONE) {
|
||||
/* Accumulated proximity sensing data is stored in the benchmark data register.
|
||||
Read it out to latch the last proximity sensing data. */
|
||||
touch_ll_read_chan_data(data.chan_id, TOUCH_LL_READ_BENCHMARK, &data.chan->prox_val[0]);
|
||||
// TODO: support to judge by software if the proximity channel triggered
|
||||
if (g_touch->cbs.on_proximity_meas_done) {
|
||||
need_yield |= g_touch->cbs.on_proximity_meas_done(g_touch, &data, g_touch->user_ctx);
|
||||
}
|
||||
}
|
||||
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) {
|
||||
touch_ll_enable_scan_mask(~BIT(data.chan->id), false);
|
||||
}
|
||||
TOUCH_EXIT_CRITICAL_SAFE(TOUCH_PERIPH_LOCK);
|
||||
if (g_touch->cbs.on_active) {
|
||||
need_yield |= g_touch->cbs.on_active(g_touch, &data, g_touch->user_ctx);
|
||||
}
|
||||
}
|
||||
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) {
|
||||
touch_ll_enable_scan_mask(g_touch->chan_mask & (~BIT(g_touch->shield_chan->id)), true);
|
||||
}
|
||||
TOUCH_EXIT_CRITICAL_SAFE(TOUCH_PERIPH_LOCK);
|
||||
if (g_touch->cbs.on_inactive) {
|
||||
need_yield |= g_touch->cbs.on_inactive(g_touch, &data, g_touch->user_ctx);
|
||||
}
|
||||
}
|
||||
if (status & TOUCH_LL_INTR_MASK_TIMEOUT) {
|
||||
g_touch->is_meas_timeout = true;
|
||||
touch_ll_force_done_curr_measurement();
|
||||
if ((g_touch->cbs.on_timeout)) {
|
||||
need_yield |= g_touch->cbs.on_timeout(g_touch, &data, g_touch->user_ctx);
|
||||
}
|
||||
}
|
||||
|
||||
if (need_yield) {
|
||||
portYIELD_FROM_ISR();
|
||||
}
|
||||
}
|
||||
|
||||
static esp_err_t s_touch_convert_to_hal_config(touch_sensor_handle_t sens_handle, const touch_sensor_config_t *sens_cfg, touch_hal_config_t *hal_cfg)
|
||||
{
|
||||
TOUCH_NULL_POINTER_CHECK(sens_cfg);
|
||||
TOUCH_NULL_POINTER_CHECK(hal_cfg);
|
||||
|
||||
ESP_RETURN_ON_FALSE(sens_cfg->sample_cfg_num && sens_cfg->sample_cfg, ESP_ERR_INVALID_ARG, TAG,
|
||||
"at least one sample configuration required");
|
||||
ESP_RETURN_ON_FALSE(sens_cfg->sample_cfg_num <= TOUCH_SAMPLE_CFG_NUM, ESP_ERR_INVALID_ARG, TAG,
|
||||
"at most %d sample configurations supported", (int)(TOUCH_SAMPLE_CFG_NUM));
|
||||
|
||||
/* Get the source clock frequency for the first time */
|
||||
if (!sens_handle->src_freq_hz) {
|
||||
/* Touch sensor actually uses dynamic fast clock LP_DYN_FAST_CLK, but it will only switch to the slow clock during sleep,
|
||||
* This driver only designed for wakeup case (sleep case should use ULP driver), so we only need to consider RTC_FAST here */
|
||||
esp_clk_tree_src_get_freq_hz(SOC_MOD_CLK_RTC_FAST, ESP_CLK_TREE_SRC_FREQ_PRECISION_CACHED, &sens_handle->src_freq_hz);
|
||||
ESP_LOGD(TAG, "touch rtc clock source: RTC_FAST, frequency: %"PRIu32" Hz", sens_handle->src_freq_hz);
|
||||
}
|
||||
|
||||
uint32_t src_freq_mhz = sens_handle->src_freq_hz / 1000000;
|
||||
hal_cfg->power_on_wait_ticks = (uint32_t)sens_cfg->power_on_wait_us * src_freq_mhz;
|
||||
hal_cfg->power_on_wait_ticks = hal_cfg->power_on_wait_ticks > TOUCH_LL_PAD_MEASURE_WAIT_MAX ?
|
||||
TOUCH_LL_PAD_MEASURE_WAIT_MAX : hal_cfg->power_on_wait_ticks;
|
||||
hal_cfg->meas_interval_ticks = (uint32_t)(sens_cfg->meas_interval_us * src_freq_mhz);
|
||||
hal_cfg->timeout_ticks = (uint32_t)sens_cfg->max_meas_time_us * src_freq_mhz;
|
||||
ESP_RETURN_ON_FALSE(hal_cfg->timeout_ticks <= TOUCH_LL_TIMEOUT_MAX, ESP_ERR_INVALID_ARG, TAG,
|
||||
"max_meas_time_ms should within %"PRIu32, TOUCH_LL_TIMEOUT_MAX / src_freq_mhz);
|
||||
hal_cfg->sample_cfg_num = sens_cfg->sample_cfg_num; // Only one sample cfg
|
||||
hal_cfg->sample_cfg = (touch_hal_sample_config_t *)sens_cfg->sample_cfg;
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t touch_priv_config_controller(touch_sensor_handle_t sens_handle, const touch_sensor_config_t *sens_cfg)
|
||||
{
|
||||
#if CONFIG_TOUCH_ENABLE_DEBUG_LOG
|
||||
esp_log_level_set(TAG, ESP_LOG_DEBUG);
|
||||
#endif
|
||||
/* Check and convert the configuration to hal configurations */
|
||||
touch_hal_config_t hal_cfg = {};
|
||||
ESP_RETURN_ON_ERROR(s_touch_convert_to_hal_config(sens_handle, sens_cfg, &hal_cfg),
|
||||
TAG, "parse the configuration failed due to the invalid configuration");
|
||||
sens_handle->sample_cfg_num = 1; // Only have one set of sampling configuration
|
||||
|
||||
/* Configure the hardware */
|
||||
TOUCH_ENTER_CRITICAL(TOUCH_PERIPH_LOCK);
|
||||
touch_hal_config_controller(&hal_cfg);
|
||||
TOUCH_EXIT_CRITICAL(TOUCH_PERIPH_LOCK);
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t touch_priv_config_channel(touch_channel_handle_t chan_handle, const touch_channel_config_t *chan_cfg)
|
||||
{
|
||||
// Check the validation of the channel active threshold
|
||||
ESP_RETURN_ON_FALSE(chan_cfg->active_thresh[0] <= TOUCH_LL_ACTIVE_THRESH_MAX, ESP_ERR_INVALID_ARG,
|
||||
TAG, "the active threshold out of range 0~%d", TOUCH_LL_ACTIVE_THRESH_MAX);
|
||||
TOUCH_ENTER_CRITICAL(TOUCH_PERIPH_LOCK);
|
||||
touch_ll_set_chan_active_threshold(chan_handle->id, chan_cfg->active_thresh[0]);
|
||||
touch_ll_set_charge_speed(chan_handle->id, chan_cfg->charge_speed);
|
||||
touch_ll_set_init_charge_voltage(chan_handle->id, chan_cfg->init_charge_volt);
|
||||
TOUCH_EXIT_CRITICAL(TOUCH_PERIPH_LOCK);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t touch_priv_deinit_controller(touch_sensor_handle_t sens_handle)
|
||||
{
|
||||
/* Disable the additional functions */
|
||||
if (sens_handle->proximity_en) {
|
||||
touch_sensor_config_proximity_sensing(sens_handle, NULL);
|
||||
}
|
||||
if (sens_handle->sleep_en) {
|
||||
touch_sensor_config_sleep_wakeup(sens_handle, NULL);
|
||||
}
|
||||
if (sens_handle->waterproof_en) {
|
||||
touch_sensor_config_waterproof(sens_handle, NULL);
|
||||
}
|
||||
if (sens_handle->denoise_en) {
|
||||
touch_sensor_config_denoise_channel(sens_handle, NULL);
|
||||
}
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t IRAM_ATTR touch_priv_channel_read_data(touch_channel_handle_t chan_handle, touch_chan_data_type_t type, uint32_t *data)
|
||||
{
|
||||
ESP_RETURN_ON_FALSE_ISR(type >= TOUCH_CHAN_DATA_TYPE_RAW && type <= TOUCH_CHAN_DATA_TYPE_PROXIMITY,
|
||||
ESP_ERR_INVALID_ARG, TAG, "The channel data type is invalid");
|
||||
ESP_RETURN_ON_FALSE_ISR(type != TOUCH_CHAN_DATA_TYPE_PROXIMITY || chan_handle->prox_id > 0, ESP_ERR_INVALID_ARG, TAG, "This is not a proximity sensing channel");
|
||||
TOUCH_ENTER_CRITICAL_SAFE(TOUCH_PERIPH_LOCK);
|
||||
switch (type) {
|
||||
default: // fall through
|
||||
case TOUCH_CHAN_DATA_TYPE_RAW:
|
||||
touch_ll_read_chan_data(chan_handle->id, TOUCH_LL_READ_RAW, data);
|
||||
break;
|
||||
case TOUCH_CHAN_DATA_TYPE_SMOOTH:
|
||||
touch_ll_read_chan_data(chan_handle->id, TOUCH_LL_READ_SMOOTH, data);
|
||||
break;
|
||||
case TOUCH_CHAN_DATA_TYPE_BENCHMARK:
|
||||
touch_ll_read_chan_data(chan_handle->id, TOUCH_LL_READ_BENCHMARK, data);
|
||||
break;
|
||||
case TOUCH_CHAN_DATA_TYPE_PROXIMITY:
|
||||
/* Get the proximity value from the stored data.
|
||||
* The proximity value are updated in the isr when proximity scanning is done */
|
||||
*data = chan_handle->prox_val[0];
|
||||
break;
|
||||
}
|
||||
TOUCH_EXIT_CRITICAL_SAFE(TOUCH_PERIPH_LOCK);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
void touch_priv_config_benchmark(touch_channel_handle_t chan_handle, const touch_chan_benchmark_config_t *benchmark_cfg)
|
||||
{
|
||||
if (benchmark_cfg->do_reset) {
|
||||
touch_ll_reset_chan_benchmark(BIT(chan_handle->id));
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* Scope: public APIs *
|
||||
******************************************************************************/
|
||||
|
||||
esp_err_t touch_sensor_config_filter(touch_sensor_handle_t sens_handle, const touch_sensor_filter_config_t *filter_cfg)
|
||||
{
|
||||
TOUCH_NULL_POINTER_CHECK(sens_handle);
|
||||
if (filter_cfg) {
|
||||
ESP_RETURN_ON_FALSE(filter_cfg->benchmark.denoise_lvl >= 0 && filter_cfg->benchmark.denoise_lvl <= 4,
|
||||
ESP_ERR_INVALID_ARG, TAG, "denoise_lvl is out of range");
|
||||
}
|
||||
|
||||
esp_err_t ret = ESP_OK;
|
||||
xSemaphoreTake(sens_handle->mutex, portMAX_DELAY);
|
||||
TOUCH_ENTER_CRITICAL(TOUCH_PERIPH_LOCK);
|
||||
|
||||
if (filter_cfg) {
|
||||
touch_ll_filter_enable(true);
|
||||
/* Configure the benchmark filter and update strategy */
|
||||
touch_ll_filter_set_filter_mode(filter_cfg->benchmark.filter_mode);
|
||||
if (filter_cfg->benchmark.filter_mode == TOUCH_BM_JITTER_FILTER) {
|
||||
touch_ll_filter_set_jitter_step(filter_cfg->benchmark.jitter_step);
|
||||
}
|
||||
touch_ll_filter_set_denoise_level(filter_cfg->benchmark.denoise_lvl);
|
||||
/* Configure the touch data filter */
|
||||
touch_ll_filter_set_smooth_mode(filter_cfg->data.smooth_filter);
|
||||
touch_ll_filter_set_active_hysteresis(filter_cfg->data.active_hysteresis);
|
||||
touch_ll_filter_set_debounce(filter_cfg->data.debounce_cnt);
|
||||
} else {
|
||||
touch_ll_filter_enable(false);
|
||||
}
|
||||
|
||||
TOUCH_EXIT_CRITICAL(TOUCH_PERIPH_LOCK);
|
||||
xSemaphoreGive(sens_handle->mutex);
|
||||
return ret;
|
||||
}
|
||||
|
||||
esp_err_t touch_sensor_config_sleep_wakeup(touch_sensor_handle_t sens_handle, const touch_sleep_config_t *sleep_cfg)
|
||||
{
|
||||
TOUCH_NULL_POINTER_CHECK(sens_handle);
|
||||
|
||||
esp_err_t ret = ESP_OK;
|
||||
int dp_slp_chan_id = -1;
|
||||
touch_hal_config_t hal_cfg = {};
|
||||
touch_hal_config_t *hal_cfg_ptr = NULL;
|
||||
|
||||
xSemaphoreTake(sens_handle->mutex, portMAX_DELAY);
|
||||
ESP_GOTO_ON_FALSE(!sens_handle->is_enabled, ESP_ERR_INVALID_STATE, err, TAG, "Please disable the touch sensor first");
|
||||
|
||||
if (sleep_cfg) {
|
||||
ESP_GOTO_ON_FALSE(sleep_cfg->slp_wakeup_lvl == TOUCH_LIGHT_SLEEP_WAKEUP || sleep_cfg->slp_wakeup_lvl == TOUCH_DEEP_SLEEP_WAKEUP,
|
||||
ESP_ERR_INVALID_ARG, err, TAG, "Invalid sleep level");
|
||||
/* Enabled touch sensor as wake-up source */
|
||||
esp_sleep_enable_touchpad_wakeup();
|
||||
#if SOC_PM_SUPPORT_RTC_PERIPH_PD
|
||||
// Keep ESP_PD_DOMAIN_RTC_PERIPH power domain on during the light/deep sleep, so that to keep the touch sensor working
|
||||
esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_ON);
|
||||
#endif // SOC_PM_SUPPORT_RC_FAST_PD
|
||||
|
||||
/* If set the deep sleep channel (i.e., enable deep sleep wake-up),
|
||||
configure the deep sleep related settings. */
|
||||
if (sleep_cfg->slp_wakeup_lvl == TOUCH_DEEP_SLEEP_WAKEUP) {
|
||||
ESP_GOTO_ON_FALSE(sleep_cfg->deep_slp_chan, ESP_ERR_INVALID_ARG, err, TAG, "deep sleep waken channel can't be NULL");
|
||||
dp_slp_chan_id = sleep_cfg->deep_slp_chan->id;
|
||||
|
||||
/* Check and convert the configuration to hal configurations */
|
||||
if (sleep_cfg->deep_slp_sens_cfg) {
|
||||
hal_cfg_ptr = &hal_cfg;
|
||||
ESP_GOTO_ON_ERROR(s_touch_convert_to_hal_config(sens_handle, sleep_cfg->deep_slp_sens_cfg, hal_cfg_ptr),
|
||||
err, TAG, "parse the configuration failed due to the invalid configuration");
|
||||
}
|
||||
sens_handle->sleep_en = true;
|
||||
sens_handle->deep_slp_chan = sleep_cfg->deep_slp_chan;
|
||||
TOUCH_ENTER_CRITICAL(TOUCH_PERIPH_LOCK);
|
||||
touch_ll_sleep_set_threshold(sleep_cfg->deep_slp_thresh[0]);
|
||||
TOUCH_EXIT_CRITICAL(TOUCH_PERIPH_LOCK);
|
||||
}
|
||||
|
||||
} else {
|
||||
/* Disable the touch sensor as wake-up source */
|
||||
esp_sleep_disable_wakeup_source(ESP_SLEEP_WAKEUP_TOUCHPAD);
|
||||
#if SOC_PM_SUPPORT_RTC_PERIPH_PD
|
||||
esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_AUTO);
|
||||
#endif // SOC_PM_SUPPORT_RC_FAST_PD
|
||||
sens_handle->deep_slp_chan = NULL;
|
||||
sens_handle->sleep_en = false;
|
||||
}
|
||||
|
||||
/* Save or update the sleep config */
|
||||
TOUCH_ENTER_CRITICAL(TOUCH_PERIPH_LOCK);
|
||||
touch_hal_save_sleep_config(dp_slp_chan_id, hal_cfg_ptr);
|
||||
TOUCH_EXIT_CRITICAL(TOUCH_PERIPH_LOCK);
|
||||
|
||||
err:
|
||||
xSemaphoreGive(sens_handle->mutex);
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Water proof can be enabled separately
|
||||
esp_err_t touch_sensor_config_waterproof(touch_sensor_handle_t sens_handle, const touch_waterproof_config_t *wp_cfg)
|
||||
{
|
||||
TOUCH_NULL_POINTER_CHECK(sens_handle);
|
||||
|
||||
esp_err_t ret = ESP_OK;
|
||||
xSemaphoreTake(sens_handle->mutex, portMAX_DELAY);
|
||||
|
||||
ESP_GOTO_ON_FALSE(!sens_handle->is_enabled, ESP_ERR_INVALID_STATE, err, TAG, "Please disable the touch sensor first");
|
||||
|
||||
if (wp_cfg) {
|
||||
ESP_GOTO_ON_FALSE(wp_cfg->shield_chan && wp_cfg->shield_chan->id == 14, ESP_ERR_INVALID_ARG, err, TAG, "Shield channel must be channel 14");
|
||||
// Check the validation of the waterproof configuration
|
||||
TOUCH_NULL_POINTER_CHECK(wp_cfg->shield_chan);
|
||||
TOUCH_ENTER_CRITICAL(TOUCH_PERIPH_LOCK);
|
||||
sens_handle->waterproof_en = true;
|
||||
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);
|
||||
// need to disable the scanning of the shield channel
|
||||
touch_ll_enable_scan_mask(BIT(wp_cfg->shield_chan->id), false);
|
||||
touch_ll_waterproof_set_shield_driver(wp_cfg->shield_drv);
|
||||
touch_ll_waterproof_enable(true);
|
||||
TOUCH_EXIT_CRITICAL(TOUCH_PERIPH_LOCK);
|
||||
} else {
|
||||
TOUCH_ENTER_CRITICAL(TOUCH_PERIPH_LOCK);
|
||||
touch_ll_waterproof_enable(false);
|
||||
touch_ll_waterproof_set_guard_chan(TOUCH_LL_NULL_CHANNEL);
|
||||
touch_ll_enable_scan_mask(BIT(sens_handle->shield_chan->id), true);
|
||||
touch_ll_waterproof_set_shield_driver(0);
|
||||
sens_handle->guard_chan = NULL;
|
||||
sens_handle->shield_chan = NULL;
|
||||
sens_handle->waterproof_en = false;
|
||||
TOUCH_EXIT_CRITICAL(TOUCH_PERIPH_LOCK);
|
||||
}
|
||||
err:
|
||||
xSemaphoreGive(sens_handle->mutex);
|
||||
return ret;
|
||||
}
|
||||
|
||||
esp_err_t touch_sensor_config_proximity_sensing(touch_sensor_handle_t sens_handle, const touch_proximity_config_t *prox_cfg)
|
||||
{
|
||||
TOUCH_NULL_POINTER_CHECK(sens_handle);
|
||||
|
||||
esp_err_t ret = ESP_OK;
|
||||
xSemaphoreTake(sens_handle->mutex, portMAX_DELAY);
|
||||
|
||||
ESP_GOTO_ON_FALSE(!sens_handle->is_enabled, ESP_ERR_INVALID_STATE, err, TAG, "Please disable the touch sensor first");
|
||||
|
||||
TOUCH_ENTER_CRITICAL(TOUCH_PERIPH_LOCK);
|
||||
|
||||
/* Reset proximity sensing part of all channels */
|
||||
FOR_EACH_TOUCH_CHANNEL(i) {
|
||||
if (sens_handle->ch[i]) {
|
||||
sens_handle->ch[i]->prox_id = 0;
|
||||
sens_handle->ch[i]->prox_cnt = 0;
|
||||
memset(sens_handle->ch[i]->prox_val, 0, sizeof(sens_handle->ch[i]->prox_val[0]) * TOUCH_SAMPLE_CFG_NUM);
|
||||
}
|
||||
}
|
||||
|
||||
if (prox_cfg) {
|
||||
sens_handle->proximity_en = true;
|
||||
for (int i = 0; i < TOUCH_PROXIMITY_CHAN_NUM; i++) {
|
||||
if (prox_cfg->proximity_chan[i]) {
|
||||
prox_cfg->proximity_chan[i]->prox_id = i + 1;
|
||||
touch_ll_set_proximity_sensing_channel(i, prox_cfg->proximity_chan[i]->id);
|
||||
} else {
|
||||
touch_ll_set_proximity_sensing_channel(i, TOUCH_LL_NULL_CHANNEL);
|
||||
}
|
||||
}
|
||||
touch_ll_proximity_set_total_scan_times(prox_cfg->scan_times);
|
||||
} else {
|
||||
for (int i = 0; i < TOUCH_PROXIMITY_CHAN_NUM; i++) {
|
||||
touch_ll_set_proximity_sensing_channel(i, TOUCH_LL_NULL_CHANNEL);
|
||||
}
|
||||
sens_handle->proximity_en = false;
|
||||
}
|
||||
TOUCH_EXIT_CRITICAL(TOUCH_PERIPH_LOCK);
|
||||
|
||||
err:
|
||||
xSemaphoreGive(sens_handle->mutex);
|
||||
return ret;
|
||||
}
|
||||
|
||||
esp_err_t touch_sensor_config_denoise_channel(touch_sensor_handle_t sens_handle, const touch_denoise_chan_config_t *denoise_cfg)
|
||||
{
|
||||
TOUCH_NULL_POINTER_CHECK(sens_handle);
|
||||
esp_err_t ret = ESP_OK;
|
||||
xSemaphoreTake(sens_handle->mutex, portMAX_DELAY);
|
||||
|
||||
ESP_GOTO_ON_FALSE(!sens_handle->is_enabled, ESP_ERR_INVALID_STATE, err, TAG, "Please disable the touch sensor first");
|
||||
|
||||
if (denoise_cfg) {
|
||||
TOUCH_ENTER_CRITICAL(TOUCH_PERIPH_LOCK);
|
||||
sens_handle->denoise_en = true;
|
||||
sens_handle->chan_mask |= BIT(TOUCH_DENOISE_CHAN_ID);
|
||||
touch_ll_set_charge_speed(TOUCH_DENOISE_CHAN_ID, denoise_cfg->charge_speed);
|
||||
touch_ll_set_init_charge_voltage(TOUCH_DENOISE_CHAN_ID, denoise_cfg->init_charge_volt);
|
||||
touch_ll_denoise_set_reference_cap(denoise_cfg->ref_cap);
|
||||
touch_ll_denoise_set_resolution(denoise_cfg->resolution);
|
||||
touch_ll_denoise_enable(true);
|
||||
TOUCH_EXIT_CRITICAL(TOUCH_PERIPH_LOCK);
|
||||
} else {
|
||||
TOUCH_ENTER_CRITICAL(TOUCH_PERIPH_LOCK);
|
||||
sens_handle->denoise_en = false;
|
||||
sens_handle->chan_mask &= ~BIT(TOUCH_DENOISE_CHAN_ID);
|
||||
touch_ll_denoise_enable(false);
|
||||
TOUCH_EXIT_CRITICAL(TOUCH_PERIPH_LOCK);
|
||||
}
|
||||
err:
|
||||
xSemaphoreGive(sens_handle->mutex);
|
||||
return ret;
|
||||
}
|
@@ -25,6 +25,9 @@ extern "C" {
|
||||
/**
|
||||
* @brief Helper macro to the default configurations of the touch sensor controller
|
||||
*
|
||||
* @param[in] sample_cfg_number The number of sample configurations, which should be less than or equal to `SOC_TOUCH_SAMPLE_CFG_NUM`
|
||||
* Given multiple sample configurations to enable the frequency hopping
|
||||
* @param[in] sample_cfg_array The pointer to the sample configurations array
|
||||
*/
|
||||
#define TOUCH_SENSOR_DEFAULT_BASIC_CONFIG(sample_cfg_number, sample_cfg_array) { \
|
||||
.power_on_wait_us = 256, \
|
||||
@@ -39,6 +42,9 @@ extern "C" {
|
||||
* @brief Helper macro to the default sample configurations
|
||||
* @note This default configuration uses `sample frequency = clock frequency / 1`
|
||||
*
|
||||
* @param[in] _div_num The division of the final data, used to scaling the final data
|
||||
* @param[in] coarse_freq_tune The coarse frequency tuning value
|
||||
* @param[in] fine_freq_tune The fine frequency tuning value
|
||||
*/
|
||||
#define TOUCH_SENSOR_V3_DEFAULT_SAMPLE_CONFIG(_div_num, coarse_freq_tune, fine_freq_tune) { \
|
||||
.div_num = _div_num, \
|
||||
@@ -51,6 +57,10 @@ extern "C" {
|
||||
.bypass_shield_output = false, \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Helper macro to the default filter configurations
|
||||
*
|
||||
*/
|
||||
#define TOUCH_SENSOR_DEFAULT_FILTER_CONFIG() { \
|
||||
.benchmark = { \
|
||||
.filter_mode = TOUCH_BM_IIR_FILTER_4, \
|
||||
@@ -60,6 +70,7 @@ extern "C" {
|
||||
.data = { \
|
||||
.smooth_filter = TOUCH_SMOOTH_IIR_FILTER_2, \
|
||||
.active_hysteresis = 2, \
|
||||
.debounce_cnt = 2, \
|
||||
}, \
|
||||
}
|
||||
|
||||
@@ -73,68 +84,6 @@ typedef enum {
|
||||
TOUCH_CHAN_DATA_TYPE_PROXIMITY, /*!< The proximity data of the proximity channel */
|
||||
} touch_chan_data_type_t;
|
||||
|
||||
/**
|
||||
* @brief The chip sleep level that allows the touch sensor to wake-up
|
||||
*
|
||||
*/
|
||||
typedef enum {
|
||||
TOUCH_LIGHT_SLEEP_WAKEUP, /*!< Only enable the touch sensor to wake up the chip from light sleep */
|
||||
TOUCH_DEEP_SLEEP_WAKEUP, /*!< Enable the touch sensor to wake up the chip from deep sleep or light sleep */
|
||||
} touch_sleep_wakeup_level_t;
|
||||
|
||||
/**
|
||||
* @brief Touch sensor shield channel drive capability level
|
||||
*
|
||||
*/
|
||||
typedef enum {
|
||||
TOUCH_SHIELD_CAP_40PF, /*!< The max equivalent capacitance in shield channel is 40pf */
|
||||
TOUCH_SHIELD_CAP_80PF, /*!< The max equivalent capacitance in shield channel is 80pf */
|
||||
TOUCH_SHIELD_CAP_120PF, /*!< The max equivalent capacitance in shield channel is 120pf */
|
||||
TOUCH_SHIELD_CAP_160PF, /*!< The max equivalent capacitance in shield channel is 160pf */
|
||||
TOUCH_SHIELD_CAP_200PF, /*!< The max equivalent capacitance in shield channel is 200pf */
|
||||
TOUCH_SHIELD_CAP_240PF, /*!< The max equivalent capacitance in shield channel is 240pf */
|
||||
TOUCH_SHIELD_CAP_280PF, /*!< The max equivalent capacitance in shield channel is 280pf */
|
||||
TOUCH_SHIELD_CAP_320PF, /*!< The max equivalent capacitance in shield channel is 320pf */
|
||||
} touch_chan_shield_cap_t;
|
||||
|
||||
/**
|
||||
* @brief Touch channel Infinite Impulse Response (IIR) filter or Jitter filter for benchmark
|
||||
* @note Recommended filter coefficient selection is `IIR_16`.
|
||||
*/
|
||||
typedef enum {
|
||||
TOUCH_BM_IIR_FILTER_4, /*!< IIR Filter for benchmark, 1/4 raw_value + 3/4 benchmark */
|
||||
TOUCH_BM_IIR_FILTER_8, /*!< IIR Filter for benchmark, 1/8 raw_value + 7/8 benchmark */
|
||||
TOUCH_BM_IIR_FILTER_16, /*!< IIR Filter for benchmark, 1/16 raw_value + 15/16 benchmark (typical) */
|
||||
TOUCH_BM_IIR_FILTER_32, /*!< IIR Filter for benchmark, 1/32 raw_value + 31/32 benchmark */
|
||||
TOUCH_BM_IIR_FILTER_64, /*!< IIR Filter for benchmark, 1/64 raw_value + 63/64 benchmark */
|
||||
TOUCH_BM_IIR_FILTER_128, /*!< IIR Filter for benchmark, 1/128 raw_value + 127/128 benchmark */
|
||||
TOUCH_BM_JITTER_FILTER, /*!< Jitter Filter for benchmark, raw value +/- jitter_step */
|
||||
} touch_benchmark_filter_mode_t;
|
||||
|
||||
/**
|
||||
* @brief Touch channel Infinite Impulse Response (IIR) filter for smooth data
|
||||
*
|
||||
*/
|
||||
typedef enum {
|
||||
TOUCH_SMOOTH_NO_FILTER, /*!< No filter adopted for smooth data, smooth data equals raw data */
|
||||
TOUCH_SMOOTH_IIR_FILTER_2, /*!< IIR filter adopted for smooth data, smooth data equals 1/2 raw data + 1/2 last smooth data (typical) */
|
||||
TOUCH_SMOOTH_IIR_FILTER_4, /*!< IIR filter adopted for smooth data, smooth data equals 1/4 raw data + 3/4 last smooth data */
|
||||
TOUCH_SMOOTH_IIR_FILTER_8, /*!< IIR filter adopted for smooth data, smooth data equals 1/8 raw data + 7/8 last smooth data */
|
||||
} touch_smooth_filter_mode_t;
|
||||
|
||||
/**
|
||||
* @brief Interrupt events
|
||||
*
|
||||
*/
|
||||
typedef enum {
|
||||
TOUCH_INTR_EVENT_ACTIVE, /*!< Touch channel active event */
|
||||
TOUCH_INTR_EVENT_INACTIVE, /*!< Touch channel inactive event */
|
||||
TOUCH_INTR_EVENT_MEASURE_DONE, /*!< Touch channel measure done event */
|
||||
TOUCH_INTR_EVENT_SCAN_DONE, /*!< All touch channels scan done event */
|
||||
TOUCH_INTR_EVENT_TIMEOUT, /*!< Touch channel measurement timeout event */
|
||||
TOUCH_INTR_EVENT_PROXIMITY_DONE, /*!< Proximity channel measurement done event */
|
||||
} touch_intr_event_t;
|
||||
|
||||
/**
|
||||
* @brief Sample configurations of the touch sensor
|
||||
*
|
||||
@@ -162,7 +111,7 @@ typedef struct {
|
||||
* of this sample configurations below.
|
||||
*/
|
||||
touch_out_mode_t output_mode; /*!< Touch channel counting mode of the binarized touch output */
|
||||
uint32_t sample_cfg_num; /*!< The sample configuration number that used for sampling */
|
||||
uint32_t sample_cfg_num; /*!< The sample configuration number that used for sampling, CANNOT exceed TOUCH_SAMPLE_CFG_NUM */
|
||||
touch_sensor_sample_config_t *sample_cfg; /*!< The array of this sample configuration configurations, the length should be specified in `touch_sensor_config_t::sample_cfg_num` */
|
||||
} touch_sensor_config_t;
|
||||
|
||||
@@ -224,7 +173,7 @@ typedef struct {
|
||||
typedef touch_sensor_config_t touch_sensor_config_dslp_t;
|
||||
|
||||
/**
|
||||
* @brief Configure the touch sensor sleep function
|
||||
* @brief Configuration of the touch sensor sleep function
|
||||
*
|
||||
*/
|
||||
typedef struct {
|
||||
@@ -248,7 +197,7 @@ typedef struct {
|
||||
} touch_sleep_config_t;
|
||||
|
||||
/**
|
||||
* @brief Configure the touch sensor waterproof function
|
||||
* @brief Configuration of the touch sensor waterproof function
|
||||
*
|
||||
*/
|
||||
typedef struct {
|
||||
@@ -274,7 +223,7 @@ typedef struct {
|
||||
} touch_waterproof_config_t;
|
||||
|
||||
/**
|
||||
* @brief Configure the touch sensor proximity function
|
||||
* @brief Configuration of the touch sensor proximity function
|
||||
*
|
||||
*/
|
||||
typedef struct {
|
||||
@@ -292,13 +241,13 @@ typedef struct {
|
||||
* @brief Base event structure used in touch event queue
|
||||
*/
|
||||
typedef struct {
|
||||
touch_channel_handle_t chan; /*!< the current triggered touch channel handle */
|
||||
int chan_id; /*!< the current triggered touch channel number */
|
||||
uint32_t status_mask; /*!< the current channel triggered status.
|
||||
* For the bits in the status mask,
|
||||
* if the bit is set, the corresponding channel is active
|
||||
* if the bit is cleared, the corresponding channel is inactive
|
||||
*/
|
||||
touch_channel_handle_t chan; /*!< the current triggered touch channel handle */
|
||||
int chan_id; /*!< the current triggered touch channel number */
|
||||
uint32_t status_mask; /*!< the current channel triggered status.
|
||||
* For the bits in the status mask,
|
||||
* if the bit is set, the corresponding channel is active
|
||||
* if the bit is cleared, the corresponding channel is inactive
|
||||
*/
|
||||
} touch_base_event_data_t;
|
||||
|
||||
/**
|
||||
|
@@ -44,10 +44,6 @@ void touch_priv_enable_module(bool enable)
|
||||
TOUCH_ENTER_CRITICAL(TOUCH_RTC_LOCK);
|
||||
touch_ll_enable_module_clock(enable);
|
||||
touch_ll_enable_out_gate(enable);
|
||||
#if SOC_TOUCH_SENSOR_VERSION >= 2
|
||||
// Reset the benchmark after finished the scanning
|
||||
touch_ll_reset_chan_benchmark(TOUCH_LL_FULL_CHANNEL_MASK);
|
||||
#endif
|
||||
TOUCH_EXIT_CRITICAL(TOUCH_RTC_LOCK);
|
||||
}
|
||||
|
||||
@@ -60,7 +56,7 @@ void IRAM_ATTR touch_priv_default_intr_handler(void *arg)
|
||||
bool need_yield = false;
|
||||
uint32_t status = touch_ll_get_intr_status_mask();
|
||||
g_touch->is_meas_timeout = false;
|
||||
touch_ll_intr_clear(status);
|
||||
touch_ll_interrupt_clear(status);
|
||||
touch_base_event_data_t data;
|
||||
touch_ll_get_active_channel_mask(&data.status_mask);
|
||||
data.chan = g_touch->ch[touch_ll_get_current_meas_channel()];
|
||||
@@ -253,7 +249,7 @@ esp_err_t touch_priv_channel_read_data(touch_channel_handle_t chan_handle, touch
|
||||
TOUCH_EXIT_CRITICAL_SAFE(TOUCH_PERIPH_LOCK);
|
||||
}
|
||||
} else {
|
||||
if (!chan_handle->is_prox_chan) {
|
||||
if (!chan_handle->prox_id) {
|
||||
ESP_EARLY_LOGW(TAG, "This is not a proximity sensing channel");
|
||||
}
|
||||
TOUCH_ENTER_CRITICAL_SAFE(TOUCH_PERIPH_LOCK);
|
||||
@@ -436,8 +432,8 @@ esp_err_t touch_sensor_config_proximity_sensing(touch_sensor_handle_t sens_handl
|
||||
|
||||
/* Reset proximity sensing part of all channels */
|
||||
FOR_EACH_TOUCH_CHANNEL(i) {
|
||||
if (sens_handle->ch[i] && sens_handle->ch[i]->is_prox_chan) {
|
||||
sens_handle->ch[i]->is_prox_chan = false;
|
||||
if (sens_handle->ch[i] && sens_handle->ch[i]->prox_id > 0) {
|
||||
sens_handle->ch[i]->prox_id = 0;
|
||||
sens_handle->ch[i]->prox_cnt = 0;
|
||||
for (int i = 0; i < TOUCH_SAMPLE_CFG_NUM; i++) {
|
||||
sens_handle->ch[i]->prox_val[i] = 0;
|
||||
@@ -450,7 +446,7 @@ esp_err_t touch_sensor_config_proximity_sensing(touch_sensor_handle_t sens_handl
|
||||
uint8_t sample_cfg_num = sens_handle->sample_cfg_num;
|
||||
for (int i = 0; i < TOUCH_PROXIMITY_CHAN_NUM; i++) {
|
||||
if (prox_cfg->proximity_chan[i]) {
|
||||
prox_cfg->proximity_chan[i]->is_prox_chan = true;
|
||||
prox_cfg->proximity_chan[i]->prox_id = i + 1;
|
||||
touch_ll_set_proximity_sensing_channel(i, prox_cfg->proximity_chan[i]->id);
|
||||
} else {
|
||||
touch_ll_set_proximity_sensing_channel(i, TOUCH_LL_NULL_CHANNEL);
|
||||
|
@@ -61,6 +61,8 @@ esp_err_t touch_sensor_new_channel(touch_sensor_handle_t sens_handle, int chan_i
|
||||
/**
|
||||
* @brief Delete the touch channel
|
||||
* @note This function can be called when the touch sensor controller is NOT enabled (i.e. INIT state).
|
||||
* @note If the channel has been enabled other sub-features like proximity sensing, sleep wakeup, waterproof, denoise.
|
||||
* The attached sub-features will be disabled while deleting the channel.
|
||||
*
|
||||
* @param[in] chan_handle Touch channel handle
|
||||
* @return
|
||||
@@ -289,6 +291,24 @@ esp_err_t touch_sensor_config_proximity_sensing(touch_sensor_handle_t sens_handl
|
||||
esp_err_t touch_sensor_config_sleep_wakeup(touch_sensor_handle_t sens_handle, const touch_sleep_config_t *sleep_cfg);
|
||||
#endif
|
||||
|
||||
#if SOC_TOUCH_SUPPORT_DENOISE_CHAN
|
||||
/**
|
||||
* @brief Configure the touch denoise channel
|
||||
* @note The denoise channel is used to suppress the internal background noise.
|
||||
* Once the denoise channel enabled, the measured data of the other touch channels
|
||||
* will minus the data of the denoise channel automatically.
|
||||
* So the channel data will be attenuated after enabling the denoise channel.
|
||||
*
|
||||
* @param[in] sens_handle Touch sensor controller handle
|
||||
* @param[in] denoise_cfg Denoise channel configurations, set NULL to disable the touch channel
|
||||
* @return
|
||||
* - ESP_OK: Configure the denoise channel success
|
||||
* - ESP_ERR_INVALID_ARG: The sensor handle is NULL or invalid denoise configuration
|
||||
* - ESP_ERR_INVALID_STATE: The touch sensor is enabled
|
||||
*/
|
||||
esp_err_t touch_sensor_config_denoise_channel(touch_sensor_handle_t sens_handle, const touch_denoise_chan_config_t *denoise_cfg);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@@ -10,7 +10,7 @@
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include "soc/soc_caps.h"
|
||||
#include "hal/touch_sensor_types.h"
|
||||
#include "hal/touch_sens_types.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@@ -22,6 +22,71 @@ extern "C" {
|
||||
#define TOUCH_PROXIMITY_CHAN_NUM SOC_TOUCH_PROXIMITY_CHANNEL_NUM /*!< The supported proximity channel number in proximity sensing mode */
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief The chip sleep level that allows the touch sensor to wake-up
|
||||
*
|
||||
*/
|
||||
typedef enum {
|
||||
TOUCH_LIGHT_SLEEP_WAKEUP, /*!< Only enable the touch sensor to wake up the chip from light sleep */
|
||||
TOUCH_DEEP_SLEEP_WAKEUP, /*!< Enable the touch sensor to wake up the chip from deep sleep or light sleep */
|
||||
} touch_sleep_wakeup_level_t;
|
||||
|
||||
/**
|
||||
* @brief Touch sensor shield channel drive capability level
|
||||
*
|
||||
*/
|
||||
typedef enum {
|
||||
TOUCH_SHIELD_CAP_40PF, /*!< The max equivalent capacitance in shield channel is 40pf */
|
||||
TOUCH_SHIELD_CAP_80PF, /*!< The max equivalent capacitance in shield channel is 80pf */
|
||||
TOUCH_SHIELD_CAP_120PF, /*!< The max equivalent capacitance in shield channel is 120pf */
|
||||
TOUCH_SHIELD_CAP_160PF, /*!< The max equivalent capacitance in shield channel is 160pf */
|
||||
TOUCH_SHIELD_CAP_200PF, /*!< The max equivalent capacitance in shield channel is 200pf */
|
||||
TOUCH_SHIELD_CAP_240PF, /*!< The max equivalent capacitance in shield channel is 240pf */
|
||||
TOUCH_SHIELD_CAP_280PF, /*!< The max equivalent capacitance in shield channel is 280pf */
|
||||
TOUCH_SHIELD_CAP_320PF, /*!< The max equivalent capacitance in shield channel is 320pf */
|
||||
} touch_chan_shield_cap_t;
|
||||
|
||||
/**
|
||||
* @brief Touch channel Infinite Impulse Response (IIR) filter or Jitter filter for benchmark
|
||||
* @note Recommended filter coefficient selection is `IIR_16`.
|
||||
*/
|
||||
typedef enum {
|
||||
TOUCH_BM_IIR_FILTER_4, /*!< IIR Filter for benchmark, 1/4 raw_value + 3/4 benchmark */
|
||||
TOUCH_BM_IIR_FILTER_8, /*!< IIR Filter for benchmark, 1/8 raw_value + 7/8 benchmark */
|
||||
TOUCH_BM_IIR_FILTER_16, /*!< IIR Filter for benchmark, 1/16 raw_value + 15/16 benchmark (typical) */
|
||||
TOUCH_BM_IIR_FILTER_32, /*!< IIR Filter for benchmark, 1/32 raw_value + 31/32 benchmark */
|
||||
TOUCH_BM_IIR_FILTER_64, /*!< IIR Filter for benchmark, 1/64 raw_value + 63/64 benchmark */
|
||||
TOUCH_BM_IIR_FILTER_128, /*!< IIR Filter for benchmark, 1/128 raw_value + 127/128 benchmark */
|
||||
#if SOC_TOUCH_SENSOR_VERSION == 2
|
||||
TOUCH_BM_IIR_FILTER_256, /*!< IIR Filter for benchmark, 1/256 raw_value + 255/256 benchmark */
|
||||
#endif
|
||||
TOUCH_BM_JITTER_FILTER, /*!< Jitter Filter for benchmark, raw value +/- jitter_step */
|
||||
} touch_benchmark_filter_mode_t;
|
||||
|
||||
/**
|
||||
* @brief Touch channel Infinite Impulse Response (IIR) filter for smooth data
|
||||
*
|
||||
*/
|
||||
typedef enum {
|
||||
TOUCH_SMOOTH_NO_FILTER, /*!< No filter adopted for smooth data, smooth data equals raw data */
|
||||
TOUCH_SMOOTH_IIR_FILTER_2, /*!< IIR filter adopted for smooth data, smooth data equals 1/2 raw data + 1/2 last smooth data (typical) */
|
||||
TOUCH_SMOOTH_IIR_FILTER_4, /*!< IIR filter adopted for smooth data, smooth data equals 1/4 raw data + 3/4 last smooth data */
|
||||
TOUCH_SMOOTH_IIR_FILTER_8, /*!< IIR filter adopted for smooth data, smooth data equals 1/8 raw data + 7/8 last smooth data */
|
||||
} touch_smooth_filter_mode_t;
|
||||
|
||||
/**
|
||||
* @brief Interrupt events
|
||||
*
|
||||
*/
|
||||
typedef enum {
|
||||
TOUCH_INTR_EVENT_ACTIVE, /*!< Touch channel active event */
|
||||
TOUCH_INTR_EVENT_INACTIVE, /*!< Touch channel inactive event */
|
||||
TOUCH_INTR_EVENT_MEASURE_DONE, /*!< Touch channel measure done event */
|
||||
TOUCH_INTR_EVENT_SCAN_DONE, /*!< All touch channels scan done event */
|
||||
TOUCH_INTR_EVENT_TIMEOUT, /*!< Touch channel measurement timeout event */
|
||||
TOUCH_INTR_EVENT_PROXIMITY_DONE, /*!< Proximity channel measurement done event */
|
||||
} touch_intr_event_t;
|
||||
|
||||
typedef struct touch_sensor_s *touch_sensor_handle_t; /*!< The handle of touch sensor controller */
|
||||
typedef struct touch_channel_s *touch_channel_handle_t; /*!< The handle of touch channel */
|
||||
|
||||
|
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include "esp_err.h"
|
||||
#include "driver/touch_sens_types.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Touch channel information
|
||||
*
|
||||
*/
|
||||
typedef struct {
|
||||
int chan_id; /*!< Touch channel number */
|
||||
int chan_gpio; /*!< Corresponding GPIO of this channel */
|
||||
struct {
|
||||
uint32_t is_dp_slp: 1; /*!< Whether this channel can wakeup from deep sleep */
|
||||
uint32_t is_proxi: 1; /*!< Whether this channel is used for proximity sensing */
|
||||
uint32_t is_guard: 1; /*!< Whether this channel is used for waterproof guard channel */
|
||||
uint32_t is_shield: 1; /*!< Whether this channel is used for waterproof shield channel */
|
||||
} flags; /*!< Channel sub-feature flags */
|
||||
} touch_chan_info_t;
|
||||
|
||||
/**
|
||||
* @brief Get the touch channel information by the channel handle
|
||||
*
|
||||
* @param[in] chan_handle Touch channel handle
|
||||
* @param[out] chan_info Touch channel information
|
||||
* @return
|
||||
* - ESP_OK: Success to get the channel information
|
||||
* - ESP_ERR_INVALID_ARG: NULL pointer
|
||||
*/
|
||||
esp_err_t touch_sensor_get_channel_info(touch_channel_handle_t chan_handle, touch_chan_info_t *chan_info);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@@ -1,6 +1,8 @@
|
||||
components/esp_driver_touch_sens/test_apps/touch_sens:
|
||||
disable:
|
||||
- if: SOC_TOUCH_SENSOR_VERSION != 3
|
||||
temporary: currently driver ng only support version 3
|
||||
- if: SOC_TOUCH_SENSOR_SUPPORTED != 1
|
||||
- if: SOC_TOUCH_SENSOR_VERSION == 1
|
||||
temporary: true
|
||||
reason: currently driver ng does not support version 1
|
||||
depends_components:
|
||||
- esp_driver_touch_sens
|
||||
|
@@ -1,3 +1,3 @@
|
||||
| Supported Targets | ESP32-P4 |
|
||||
| ----------------- | -------- |
|
||||
| Supported Targets | ESP32-P4 | ESP32-S2 | ESP32-S3 |
|
||||
| ----------------- | -------- | -------- | -------- |
|
||||
|
||||
|
@@ -10,29 +10,36 @@
|
||||
#include "unity.h"
|
||||
#include "driver/touch_sens.h"
|
||||
#include "hal/touch_sensor_ll.h"
|
||||
#include "esp_private/touch_sens_helper.h"
|
||||
#include "esp_log.h"
|
||||
#include "esp_attr.h"
|
||||
|
||||
static touch_sensor_sample_config_t s_sample_cfg[TOUCH_SAMPLE_CFG_NUM] = {
|
||||
#if SOC_TOUCH_SENSOR_VERSION == 2
|
||||
TOUCH_SENSOR_V2_DEFAULT_SAMPLE_CONFIG(500, TOUCH_VOLT_LIM_L_0V5, TOUCH_VOLT_LIM_H_2V2),
|
||||
#elif SOC_TOUCH_SENSOR_VERSION == 3
|
||||
TOUCH_SENSOR_V3_DEFAULT_SAMPLE_CONFIG(1, 1, 1),
|
||||
#if TOUCH_SAMPLE_CFG_NUM > 1
|
||||
TOUCH_SENSOR_V3_DEFAULT_SAMPLE_CONFIG(2, 1, 1),
|
||||
#endif
|
||||
#if TOUCH_SAMPLE_CFG_NUM > 2
|
||||
TOUCH_SENSOR_V3_DEFAULT_SAMPLE_CONFIG(4, 1, 1),
|
||||
#else
|
||||
#error "Target not support"
|
||||
#endif
|
||||
};
|
||||
|
||||
static touch_channel_config_t s_chan_cfg = {
|
||||
#if SOC_TOUCH_SENSOR_VERSION == 2
|
||||
.active_thresh = {
|
||||
2000,
|
||||
},
|
||||
.charge_speed = TOUCH_CHARGE_SPEED_7,
|
||||
.init_charge_volt = TOUCH_INIT_CHARGE_VOLT_LOW,
|
||||
#elif SOC_TOUCH_SENSOR_VERSION == 3
|
||||
.active_thresh = {
|
||||
5000,
|
||||
#if TOUCH_SAMPLE_CFG_NUM > 1
|
||||
2500,
|
||||
#endif
|
||||
#if TOUCH_SAMPLE_CFG_NUM > 2
|
||||
1000,
|
||||
#endif
|
||||
},
|
||||
#endif
|
||||
};
|
||||
|
||||
TEST_CASE("touch_sens_install_uninstall_test", "[touch]")
|
||||
@@ -119,7 +126,13 @@ static bool TEST_TCH_IRAM_ATTR s_test_touch_on_inactive_callback(touch_sensor_ha
|
||||
|
||||
static void s_test_touch_simulate_touch(touch_sensor_handle_t touch, touch_channel_handle_t touch_chan, bool active)
|
||||
{
|
||||
#if SOC_TOUCH_SENSOR_VERSION == 2
|
||||
touch_chan_info_t chan_info = {};
|
||||
touch_sensor_get_channel_info(touch_chan, &chan_info);
|
||||
touch_ll_set_charge_speed(chan_info.chan_id, active ? TOUCH_CHARGE_SPEED_4 : TOUCH_CHARGE_SPEED_7);
|
||||
#elif SOC_TOUCH_SENSOR_VERSION == 3
|
||||
touch_ll_set_internal_capacitor(active ? 0x7f : 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void s_test_touch_log_data(touch_channel_handle_t touch_chan, uint32_t sample_cfg_num, const char *tag)
|
||||
@@ -146,15 +159,21 @@ TEST_CASE("touch_sens_active_inactive_test", "[touch]")
|
||||
/* Configuring the filter */
|
||||
touch_sensor_filter_config_t filter_cfg = TOUCH_SENSOR_DEFAULT_FILTER_CONFIG();
|
||||
TEST_ESP_OK(touch_sensor_config_filter(touch, &filter_cfg));
|
||||
TEST_ESP_OK(touch_sensor_new_channel(touch, 0, &s_chan_cfg, &touch_chan));
|
||||
TEST_ESP_OK(touch_sensor_new_channel(touch, 1, &s_chan_cfg, &touch_chan));
|
||||
#if SOC_TOUCH_SENSOR_VERSION == 3
|
||||
/* Connect the touch channels to the internal capacitor */
|
||||
touch_ll_enable_internal_capacitor(true);
|
||||
#endif // SOC_TOUCH_SENSOR_VERSION == 3
|
||||
|
||||
s_test_touch_do_initial_scanning(touch, 3);
|
||||
|
||||
/* Read benchmark */
|
||||
uint32_t benchmark[TOUCH_SAMPLE_CFG_NUM] = {0};
|
||||
TEST_ESP_OK(touch_channel_read_data(touch_chan, TOUCH_CHAN_DATA_TYPE_BENCHMARK, benchmark));
|
||||
/* Test whether success to finish the initial scanning */
|
||||
for (int i = 0; i < TOUCH_SAMPLE_CFG_NUM; i++) {
|
||||
TEST_ASSERT_GREATER_THAN(0, benchmark[i]);
|
||||
}
|
||||
/* Re-configure the threshold according to the benchmark */
|
||||
touch_channel_config_t chan_cfg = s_test_get_chan_cfg_by_benchmark(benchmark, TOUCH_SAMPLE_CFG_NUM, TEST_ACTIVE_THRESH_RATIO);
|
||||
TEST_ESP_OK(touch_sensor_reconfig_channel(touch_chan, &chan_cfg));
|
||||
|
@@ -4,8 +4,9 @@ import pytest
|
||||
from pytest_embedded import Dut
|
||||
|
||||
|
||||
@pytest.mark.esp32s2
|
||||
@pytest.mark.esp32s3
|
||||
@pytest.mark.esp32p4
|
||||
@pytest.mark.temp_skip_ci(targets=['esp32p4'], reason='esp32p4 runners do not support touch pins')
|
||||
@pytest.mark.generic
|
||||
@pytest.mark.parametrize(
|
||||
'config',
|
||||
|
@@ -62,6 +62,7 @@
|
||||
#include "hal/uart_hal.h"
|
||||
#if SOC_TOUCH_SENSOR_SUPPORTED
|
||||
#include "hal/touch_sensor_hal.h"
|
||||
#include "hal/touch_sens_hal.h"
|
||||
#endif
|
||||
|
||||
#if CONFIG_SPIRAM && CONFIG_ESP_LDO_RESERVE_PSRAM
|
||||
@@ -301,7 +302,7 @@ static void ext0_wakeup_prepare(void);
|
||||
static void ext1_wakeup_prepare(void);
|
||||
#endif
|
||||
static esp_err_t timer_wakeup_prepare(int64_t sleep_duration);
|
||||
#if SOC_TOUCH_SENSOR_SUPPORTED && SOC_TOUCH_SENSOR_VERSION != 1
|
||||
#if SOC_TOUCH_SENSOR_VERSION >= 2
|
||||
static void touch_wakeup_prepare(void);
|
||||
#endif
|
||||
#if SOC_GPIO_SUPPORT_DEEPSLEEP_WAKEUP && SOC_DEEP_SLEEP_SUPPORTED
|
||||
@@ -881,11 +882,7 @@ static esp_err_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags, esp_sleep_mode_t m
|
||||
/* In light sleep, the RTC_PERIPH power domain should be in the power-on state (Power on the touch circuit in light sleep),
|
||||
* otherwise the touch sensor FSM will be cleared, causing touch sensor false triggering.
|
||||
*/
|
||||
#if SOC_TOUCH_SENSOR_VERSION == 3
|
||||
bool keep_rtc_power_on = touch_ll_is_fsm_repeated_timer_enabled();
|
||||
#else
|
||||
bool keep_rtc_power_on = touch_ll_get_fsm_state();
|
||||
#endif
|
||||
if (keep_rtc_power_on) { // Check if the touch sensor is working properly.
|
||||
pd_flags &= ~RTC_SLEEP_PD_RTC_PERIPH;
|
||||
}
|
||||
@@ -1711,26 +1708,7 @@ static esp_err_t timer_wakeup_prepare(int64_t sleep_duration)
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
#if SOC_TOUCH_SENSOR_VERSION == 2
|
||||
/* In deep sleep mode, only the sleep channel is supported, and other touch channels should be turned off. */
|
||||
static void touch_wakeup_prepare(void)
|
||||
{
|
||||
uint16_t sleep_cycle = 0;
|
||||
uint16_t meas_times = 0;
|
||||
touch_pad_t touch_num = TOUCH_PAD_NUM0;
|
||||
touch_ll_sleep_get_channel_num(&touch_num); // Check if the sleep pad is enabled.
|
||||
if ((touch_num > TOUCH_PAD_NUM0) && (touch_num < TOUCH_PAD_MAX) && touch_ll_get_fsm_state()) {
|
||||
touch_ll_stop_fsm();
|
||||
touch_ll_clear_channel_mask(TOUCH_PAD_BIT_MASK_ALL);
|
||||
touch_ll_intr_clear(TOUCH_PAD_INTR_MASK_ALL); // Clear state from previous wakeup
|
||||
touch_hal_sleep_channel_get_work_time(&sleep_cycle, &meas_times);
|
||||
touch_ll_set_meas_times(meas_times);
|
||||
touch_ll_set_sleep_time(sleep_cycle);
|
||||
touch_ll_set_channel_mask(BIT(touch_num));
|
||||
touch_ll_start_fsm();
|
||||
}
|
||||
}
|
||||
#elif SOC_TOUCH_SENSOR_VERSION == 3
|
||||
#if SOC_TOUCH_SENSOR_VERSION >= 2
|
||||
static void touch_wakeup_prepare(void)
|
||||
{
|
||||
touch_hal_prepare_deep_sleep();
|
||||
|
Reference in New Issue
Block a user