mirror of
https://github.com/espressif/esp-idf
synced 2025-03-09 09:09:10 -04:00
feat(touch): support touch v1 in new touch driver
This commit is contained in:
parent
057bae82e1
commit
fd7b80833c
@ -1,2 +1,3 @@
|
||||
CONFIG_FREERTOS_HZ=1000
|
||||
CONFIG_ESP_TASK_WDT_EN=n
|
||||
CONFIG_TOUCH_SUPPRESS_DEPRECATE_WARN=y
|
||||
|
@ -1,385 +1,17 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2019-2024 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "driver/touch_sensor_common.h"
|
||||
|
||||
/**
|
||||
* @brief Configure touch pad interrupt threshold.
|
||||
*
|
||||
* @note If FSM mode is set to TOUCH_FSM_MODE_TIMER, this function will be blocked for one measurement cycle and wait for data to be valid.
|
||||
*
|
||||
* @param touch_num touch pad index
|
||||
* @param threshold interrupt threshold,
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK Success
|
||||
* - ESP_ERR_INVALID_ARG if argument wrong
|
||||
* - ESP_FAIL if touch pad not initialized
|
||||
*/
|
||||
esp_err_t touch_pad_config(touch_pad_t touch_num, uint16_t threshold);
|
||||
|
||||
/**
|
||||
* @brief get touch sensor counter value.
|
||||
* Each touch sensor has a counter to count the number of charge/discharge cycles.
|
||||
* When the pad is not 'touched', we can get a number of the counter.
|
||||
* When the pad is 'touched', the value in counter will get smaller because of the larger equivalent capacitance.
|
||||
*
|
||||
* @note This API requests hardware measurement once. If IIR filter mode is enabled,
|
||||
* please use 'touch_pad_read_raw_data' interface instead.
|
||||
*
|
||||
* @param touch_num touch pad index
|
||||
* @param touch_value pointer to accept touch sensor value
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK Success
|
||||
* - ESP_ERR_INVALID_ARG Touch pad parameter error
|
||||
* - ESP_ERR_INVALID_STATE This touch pad hardware connection is error, the value of "touch_value" is 0.
|
||||
* - ESP_FAIL Touch pad not initialized
|
||||
*/
|
||||
esp_err_t touch_pad_read(touch_pad_t touch_num, uint16_t *touch_value);
|
||||
|
||||
/**
|
||||
* @brief get filtered touch sensor counter value by IIR filter.
|
||||
*
|
||||
* @note touch_pad_filter_start has to be called before calling touch_pad_read_filtered.
|
||||
* This function can be called from ISR
|
||||
*
|
||||
* @param touch_num touch pad index
|
||||
* @param touch_value pointer to accept touch sensor value
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK Success
|
||||
* - ESP_ERR_INVALID_ARG Touch pad parameter error
|
||||
* - ESP_ERR_INVALID_STATE This touch pad hardware connection is error, the value of "touch_value" is 0.
|
||||
* - ESP_FAIL Touch pad not initialized
|
||||
*/
|
||||
esp_err_t touch_pad_read_filtered(touch_pad_t touch_num, uint16_t *touch_value);
|
||||
|
||||
/**
|
||||
* @brief get raw data (touch sensor counter value) from IIR filter process.
|
||||
* Need not request hardware measurements.
|
||||
*
|
||||
* @note touch_pad_filter_start has to be called before calling touch_pad_read_raw_data.
|
||||
* This function can be called from ISR
|
||||
*
|
||||
* @param touch_num touch pad index
|
||||
* @param touch_value pointer to accept touch sensor value
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK Success
|
||||
* - ESP_ERR_INVALID_ARG Touch pad parameter error
|
||||
* - ESP_ERR_INVALID_STATE This touch pad hardware connection is error, the value of "touch_value" is 0.
|
||||
* - ESP_FAIL Touch pad not initialized
|
||||
*/
|
||||
esp_err_t touch_pad_read_raw_data(touch_pad_t touch_num, uint16_t *touch_value);
|
||||
|
||||
/**
|
||||
* @brief Callback function that is called after each IIR filter calculation.
|
||||
* @note This callback is called in timer task in each filtering cycle.
|
||||
* @note This callback should not be blocked.
|
||||
* @param raw_value The latest raw data(touch sensor counter value) that
|
||||
* points to all channels(raw_value[0..TOUCH_PAD_MAX-1]).
|
||||
* @param filtered_value The latest IIR filtered data(calculated from raw data) that
|
||||
* points to all channels(filtered_value[0..TOUCH_PAD_MAX-1]).
|
||||
*
|
||||
*/
|
||||
typedef void (* filter_cb_t)(uint16_t *raw_value, uint16_t *filtered_value);
|
||||
|
||||
/**
|
||||
* @brief Register the callback function that is called after each IIR filter calculation.
|
||||
* @note The 'read_cb' callback is called in timer task in each filtering cycle.
|
||||
* @param read_cb Pointer to filtered callback function.
|
||||
* If the argument passed in is NULL, the callback will stop.
|
||||
* @return
|
||||
* - ESP_OK Success
|
||||
* - ESP_ERR_INVALID_ARG set error
|
||||
*/
|
||||
esp_err_t touch_pad_set_filter_read_cb(filter_cb_t read_cb);
|
||||
|
||||
/**
|
||||
* @brief Register touch-pad ISR.
|
||||
* The handler will be attached to the same CPU core that this function is running on.
|
||||
* @param fn Pointer to ISR handler
|
||||
* @param arg Parameter for ISR
|
||||
* @return
|
||||
* - ESP_OK Success ;
|
||||
* - ESP_ERR_INVALID_ARG GPIO error
|
||||
* - ESP_ERR_NO_MEM No memory
|
||||
*/
|
||||
esp_err_t touch_pad_isr_register(intr_handler_t fn, void *arg);
|
||||
|
||||
/**
|
||||
* @brief Set the clock cycles of each measurement
|
||||
* @note This function will specify the clock cycles of each measurement
|
||||
* and the clock is sourced from SOC_MOD_CLK_RTC_FAST, its default frequency is SOC_CLK_RC_FAST_FREQ_APPROX
|
||||
* The touch sensor will record the charge and discharge times during these clock cycles as the final result (raw value)
|
||||
* @note If clock cycles is too small, it may lead to inaccurate results.
|
||||
*
|
||||
* @param clock_cycle The clock cycles of each measurement
|
||||
* measure_time = clock_cycle / SOC_CLK_RC_FAST_FREQ_APPROX, the maximum measure time is 0xffff / SOC_CLK_RC_FAST_FREQ_APPROX
|
||||
* @return
|
||||
* - ESP_OK Set the clock cycle success
|
||||
*/
|
||||
esp_err_t touch_pad_set_measurement_clock_cycles(uint16_t clock_cycle);
|
||||
|
||||
/**
|
||||
* @brief Get the clock cycles of each measurement
|
||||
*
|
||||
* @param clock_cycle The clock cycles of each measurement
|
||||
* @return
|
||||
* - ESP_OK Get the clock cycle success
|
||||
* - ESP_ERR_INVALID_ARG The input parameter is NULL
|
||||
*/
|
||||
esp_err_t touch_pad_get_measurement_clock_cycles(uint16_t *clock_cycle);
|
||||
|
||||
/**
|
||||
* @brief Set the interval between two measurements
|
||||
* @note The touch sensor will sleep between two measurements
|
||||
* This function is to set the interval cycle
|
||||
* And the interval is clocked from SOC_MOD_CLK_RTC_SLOW, its default frequency is SOC_CLK_RC_SLOW_FREQ_APPROX
|
||||
*
|
||||
* @param interval_cycle The interval between two measurements
|
||||
* sleep_time = interval_cycle / SOC_CLK_RC_SLOW_FREQ_APPROX.
|
||||
* The approximate frequency value of RTC_SLOW_CLK can be obtained using rtc_clk_slow_freq_get_hz function.
|
||||
* @return
|
||||
* - ESP_OK Set interval cycle success
|
||||
*/
|
||||
esp_err_t touch_pad_set_measurement_interval(uint16_t interval_cycle);
|
||||
|
||||
/**
|
||||
* @brief Get the interval between two measurements
|
||||
*
|
||||
* @param interval_cycle The interval between two measurements
|
||||
* @return
|
||||
* - ESP_OK Get interval cycle success
|
||||
* - ESP_ERR_INVALID_ARG The input parameter is NULL
|
||||
*/
|
||||
esp_err_t touch_pad_get_measurement_interval(uint16_t *interval_cycle);
|
||||
|
||||
/**
|
||||
* @brief Set touch sensor measurement and sleep time.
|
||||
* Excessive total time will slow down the touch response.
|
||||
* Too small measurement time will not be sampled enough, resulting in inaccurate measurements.
|
||||
* @note The touch sensor will count the number of charge/discharge cycles over a fixed period of time (specified as the second parameter).
|
||||
* That means the number of cycles (raw value) will decrease as the capacity of the touch pad is increasing.
|
||||
* @note The greater the duty cycle of the measurement time, the more system power is consumed.
|
||||
*
|
||||
* @param sleep_cycle The touch sensor will sleep after each measurement.
|
||||
* sleep_cycle decide the interval between each measurement.
|
||||
* t_sleep = sleep_cycle / SOC_CLK_RC_SLOW_FREQ_APPROX.
|
||||
* The approximate frequency value of RTC_SLOW_CLK can be obtained using rtc_clk_slow_freq_get_hz function.
|
||||
* @param meas_cycle The duration of the touch sensor measurement.
|
||||
* t_meas = meas_cycle / SOC_CLK_RC_FAST_FREQ_APPROX, the maximum measure time is 0xffff / SOC_CLK_RC_FAST_FREQ_APPROX
|
||||
* @return
|
||||
* - ESP_OK on success
|
||||
*/
|
||||
esp_err_t touch_pad_set_meas_time(uint16_t sleep_cycle, uint16_t meas_cycle)
|
||||
__attribute__((deprecated("please use 'touch_pad_set_measurement_clock_cycles' and 'touch_pad_set_measurement_interval' instead")));
|
||||
|
||||
/**
|
||||
* @brief Get touch sensor measurement and sleep time
|
||||
* @param sleep_cycle Pointer to accept sleep cycle number
|
||||
* @param meas_cycle Pointer to accept measurement cycle count.
|
||||
* @return
|
||||
* - ESP_OK on success
|
||||
* - ESP_ERR_INVALID_ARG The input parameter is NULL
|
||||
*/
|
||||
esp_err_t touch_pad_get_meas_time(uint16_t *sleep_cycle, uint16_t *meas_cycle)
|
||||
__attribute__((deprecated("please use 'touch_pad_get_measurement_clock_cycles' and 'touch_pad_get_measurement_interval' instead")));
|
||||
|
||||
/**
|
||||
* @brief Trigger a touch sensor measurement, only support in SW mode of FSM
|
||||
* @return
|
||||
* - ESP_OK on success
|
||||
*/
|
||||
esp_err_t touch_pad_sw_start(void);
|
||||
|
||||
/**
|
||||
* @brief Set touch sensor interrupt threshold
|
||||
* @param touch_num touch pad index
|
||||
* @param threshold threshold of touchpad count, refer to touch_pad_set_trigger_mode to see how to set trigger mode.
|
||||
* @return
|
||||
* - ESP_OK on success
|
||||
* - ESP_ERR_INVALID_ARG if argument is wrong
|
||||
*/
|
||||
esp_err_t touch_pad_set_thresh(touch_pad_t touch_num, uint16_t threshold);
|
||||
|
||||
/**
|
||||
* @brief Get touch sensor interrupt threshold
|
||||
* @param touch_num touch pad index
|
||||
* @param threshold pointer to accept threshold
|
||||
* @return
|
||||
* - ESP_OK on success
|
||||
* - ESP_ERR_INVALID_ARG if argument is wrong
|
||||
*/
|
||||
esp_err_t touch_pad_get_thresh(touch_pad_t touch_num, uint16_t *threshold);
|
||||
|
||||
/**
|
||||
* @brief Set touch sensor interrupt trigger mode.
|
||||
* Interrupt can be triggered either when counter result is less than
|
||||
* threshold or when counter result is more than threshold.
|
||||
* @param mode touch sensor interrupt trigger mode
|
||||
* @return
|
||||
* - ESP_OK on success
|
||||
* - ESP_ERR_INVALID_ARG if argument is wrong
|
||||
*/
|
||||
esp_err_t touch_pad_set_trigger_mode(touch_trigger_mode_t mode);
|
||||
|
||||
/**
|
||||
* @brief Get touch sensor interrupt trigger mode
|
||||
* @param mode pointer to accept touch sensor interrupt trigger mode
|
||||
* @return
|
||||
* - ESP_OK on success
|
||||
*/
|
||||
esp_err_t touch_pad_get_trigger_mode(touch_trigger_mode_t *mode);
|
||||
|
||||
/**
|
||||
* @brief Set touch sensor interrupt trigger source. There are two sets of touch signals.
|
||||
* Set1 and set2 can be mapped to several touch signals. Either set will be triggered
|
||||
* if at least one of its touch signal is 'touched'. The interrupt can be configured to be generated
|
||||
* if set1 is triggered, or only if both sets are triggered.
|
||||
* @param src touch sensor interrupt trigger source
|
||||
* @return
|
||||
* - ESP_OK on success
|
||||
* - ESP_ERR_INVALID_ARG if argument is wrong
|
||||
*/
|
||||
esp_err_t touch_pad_set_trigger_source(touch_trigger_src_t src);
|
||||
|
||||
/**
|
||||
* @brief Get touch sensor interrupt trigger source
|
||||
* @param src pointer to accept touch sensor interrupt trigger source
|
||||
* @return
|
||||
* - ESP_OK on success
|
||||
*/
|
||||
esp_err_t touch_pad_get_trigger_source(touch_trigger_src_t *src);
|
||||
|
||||
/**
|
||||
* @brief Set touch sensor group mask.
|
||||
* Touch pad module has two sets of signals, 'Touched' signal is triggered only if
|
||||
* at least one of touch pad in this group is "touched".
|
||||
* This function will set the register bits according to the given bitmask.
|
||||
* @param set1_mask bitmask of touch sensor signal group1, it's a 10-bit value
|
||||
* @param set2_mask bitmask of touch sensor signal group2, it's a 10-bit value
|
||||
* @param en_mask bitmask of touch sensor work enable, it's a 10-bit value
|
||||
* @return
|
||||
* - ESP_OK on success
|
||||
* - ESP_ERR_INVALID_ARG if argument is wrong
|
||||
*/
|
||||
esp_err_t touch_pad_set_group_mask(uint16_t set1_mask, uint16_t set2_mask, uint16_t en_mask);
|
||||
|
||||
/**
|
||||
* @brief Get touch sensor group mask.
|
||||
* @param set1_mask pointer to accept bitmask of touch sensor signal group1, it's a 10-bit value
|
||||
* @param set2_mask pointer to accept bitmask of touch sensor signal group2, it's a 10-bit value
|
||||
* @param en_mask pointer to accept bitmask of touch sensor work enable, it's a 10-bit value
|
||||
* @return
|
||||
* - ESP_OK on success
|
||||
*/
|
||||
esp_err_t touch_pad_get_group_mask(uint16_t *set1_mask, uint16_t *set2_mask, uint16_t *en_mask);
|
||||
|
||||
/**
|
||||
* @brief Clear touch sensor group mask.
|
||||
* Touch pad module has two sets of signals, Interrupt is triggered only if
|
||||
* at least one of touch pad in this group is "touched".
|
||||
* This function will clear the register bits according to the given bitmask.
|
||||
* @param set1_mask bitmask touch sensor signal group1, it's a 10-bit value
|
||||
* @param set2_mask bitmask touch sensor signal group2, it's a 10-bit value
|
||||
* @param en_mask bitmask of touch sensor work enable, it's a 10-bit value
|
||||
* @return
|
||||
* - ESP_OK on success
|
||||
* - ESP_ERR_INVALID_ARG if argument is wrong
|
||||
*/
|
||||
esp_err_t touch_pad_clear_group_mask(uint16_t set1_mask, uint16_t set2_mask, uint16_t en_mask);
|
||||
|
||||
/**
|
||||
* @brief To enable touch pad interrupt
|
||||
* @return
|
||||
* - ESP_OK on success
|
||||
*/
|
||||
esp_err_t touch_pad_intr_enable(void);
|
||||
|
||||
/**
|
||||
* @brief To disable touch pad interrupt
|
||||
* @return
|
||||
* - ESP_OK on success
|
||||
*/
|
||||
esp_err_t touch_pad_intr_disable(void);
|
||||
|
||||
/**
|
||||
* @brief To clear touch pad interrupt
|
||||
* @return
|
||||
* - ESP_OK on success
|
||||
*/
|
||||
esp_err_t touch_pad_intr_clear(void);
|
||||
|
||||
/**
|
||||
* @brief set touch pad filter calibration period, in ms.
|
||||
* Need to call touch_pad_filter_start before all touch filter APIs
|
||||
* @param new_period_ms filter period, in ms
|
||||
* @return
|
||||
* - ESP_OK Success
|
||||
* - ESP_ERR_INVALID_STATE driver state error
|
||||
* - ESP_ERR_INVALID_ARG parameter error
|
||||
*/
|
||||
esp_err_t touch_pad_set_filter_period(uint32_t new_period_ms);
|
||||
|
||||
/**
|
||||
* @brief get touch pad filter calibration period, in ms
|
||||
* Need to call touch_pad_filter_start before all touch filter APIs
|
||||
* @param p_period_ms pointer to accept period
|
||||
* @return
|
||||
* - ESP_OK Success
|
||||
* - ESP_ERR_INVALID_STATE driver state error
|
||||
* - ESP_ERR_INVALID_ARG parameter error
|
||||
*/
|
||||
esp_err_t touch_pad_get_filter_period(uint32_t *p_period_ms);
|
||||
|
||||
/**
|
||||
* @brief start touch pad filter function
|
||||
* This API will start a filter to process the noise in order to prevent false triggering
|
||||
* when detecting slight change of capacitance.
|
||||
* Need to call touch_pad_filter_start before all touch filter APIs
|
||||
*
|
||||
* @note This filter uses FreeRTOS timer, which is dispatched from a task with
|
||||
* priority 1 by default on CPU 0. So if some application task with higher priority
|
||||
* takes a lot of CPU0 time, then the quality of data obtained from this filter will be affected.
|
||||
* You can adjust FreeRTOS timer task priority in menuconfig.
|
||||
* @param filter_period_ms filter calibration period, in ms
|
||||
* @return
|
||||
* - ESP_OK Success
|
||||
* - ESP_ERR_INVALID_ARG parameter error
|
||||
* - ESP_ERR_NO_MEM No memory for driver
|
||||
* - ESP_ERR_INVALID_STATE driver state error
|
||||
*/
|
||||
esp_err_t touch_pad_filter_start(uint32_t filter_period_ms);
|
||||
|
||||
/**
|
||||
* @brief stop touch pad filter function
|
||||
* Need to call touch_pad_filter_start before all touch filter APIs
|
||||
* @return
|
||||
* - ESP_OK Success
|
||||
* - ESP_ERR_INVALID_STATE driver state error
|
||||
*/
|
||||
esp_err_t touch_pad_filter_stop(void);
|
||||
|
||||
/**
|
||||
* @brief delete touch pad filter driver and release the memory
|
||||
* Need to call touch_pad_filter_start before all touch filter APIs
|
||||
* @return
|
||||
* - ESP_OK Success
|
||||
* - ESP_ERR_INVALID_STATE driver state error
|
||||
*/
|
||||
esp_err_t touch_pad_filter_delete(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#include "sdkconfig.h"
|
||||
#include "driver/touch_sensor_legacy.h"
|
||||
|
||||
#if !CONFIG_TOUCH_SUPPRESS_DEPRECATE_WARN
|
||||
#warning "This set of Touch APIs has been deprecated, \
|
||||
please include 'driver/touch_sens.h' instead. \
|
||||
if you want to keep using the old APIs and ignore this warning, \
|
||||
you can enable 'Suppress legacy driver deprecated warning' option under 'Touch Configuration' menu in Kconfig"
|
||||
#endif
|
||||
|
@ -0,0 +1,385 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2019-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "driver/touch_sensor_common.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Configure touch pad interrupt threshold.
|
||||
*
|
||||
* @note If FSM mode is set to TOUCH_FSM_MODE_TIMER, this function will be blocked for one measurement cycle and wait for data to be valid.
|
||||
*
|
||||
* @param touch_num touch pad index
|
||||
* @param threshold interrupt threshold,
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK Success
|
||||
* - ESP_ERR_INVALID_ARG if argument wrong
|
||||
* - ESP_FAIL if touch pad not initialized
|
||||
*/
|
||||
esp_err_t touch_pad_config(touch_pad_t touch_num, uint16_t threshold);
|
||||
|
||||
/**
|
||||
* @brief get touch sensor counter value.
|
||||
* Each touch sensor has a counter to count the number of charge/discharge cycles.
|
||||
* When the pad is not 'touched', we can get a number of the counter.
|
||||
* When the pad is 'touched', the value in counter will get smaller because of the larger equivalent capacitance.
|
||||
*
|
||||
* @note This API requests hardware measurement once. If IIR filter mode is enabled,
|
||||
* please use 'touch_pad_read_raw_data' interface instead.
|
||||
*
|
||||
* @param touch_num touch pad index
|
||||
* @param touch_value pointer to accept touch sensor value
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK Success
|
||||
* - ESP_ERR_INVALID_ARG Touch pad parameter error
|
||||
* - ESP_ERR_INVALID_STATE This touch pad hardware connection is error, the value of "touch_value" is 0.
|
||||
* - ESP_FAIL Touch pad not initialized
|
||||
*/
|
||||
esp_err_t touch_pad_read(touch_pad_t touch_num, uint16_t *touch_value);
|
||||
|
||||
/**
|
||||
* @brief get filtered touch sensor counter value by IIR filter.
|
||||
*
|
||||
* @note touch_pad_filter_start has to be called before calling touch_pad_read_filtered.
|
||||
* This function can be called from ISR
|
||||
*
|
||||
* @param touch_num touch pad index
|
||||
* @param touch_value pointer to accept touch sensor value
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK Success
|
||||
* - ESP_ERR_INVALID_ARG Touch pad parameter error
|
||||
* - ESP_ERR_INVALID_STATE This touch pad hardware connection is error, the value of "touch_value" is 0.
|
||||
* - ESP_FAIL Touch pad not initialized
|
||||
*/
|
||||
esp_err_t touch_pad_read_filtered(touch_pad_t touch_num, uint16_t *touch_value);
|
||||
|
||||
/**
|
||||
* @brief get raw data (touch sensor counter value) from IIR filter process.
|
||||
* Need not request hardware measurements.
|
||||
*
|
||||
* @note touch_pad_filter_start has to be called before calling touch_pad_read_raw_data.
|
||||
* This function can be called from ISR
|
||||
*
|
||||
* @param touch_num touch pad index
|
||||
* @param touch_value pointer to accept touch sensor value
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK Success
|
||||
* - ESP_ERR_INVALID_ARG Touch pad parameter error
|
||||
* - ESP_ERR_INVALID_STATE This touch pad hardware connection is error, the value of "touch_value" is 0.
|
||||
* - ESP_FAIL Touch pad not initialized
|
||||
*/
|
||||
esp_err_t touch_pad_read_raw_data(touch_pad_t touch_num, uint16_t *touch_value);
|
||||
|
||||
/**
|
||||
* @brief Callback function that is called after each IIR filter calculation.
|
||||
* @note This callback is called in timer task in each filtering cycle.
|
||||
* @note This callback should not be blocked.
|
||||
* @param raw_value The latest raw data(touch sensor counter value) that
|
||||
* points to all channels(raw_value[0..TOUCH_PAD_MAX-1]).
|
||||
* @param filtered_value The latest IIR filtered data(calculated from raw data) that
|
||||
* points to all channels(filtered_value[0..TOUCH_PAD_MAX-1]).
|
||||
*
|
||||
*/
|
||||
typedef void (* filter_cb_t)(uint16_t *raw_value, uint16_t *filtered_value);
|
||||
|
||||
/**
|
||||
* @brief Register the callback function that is called after each IIR filter calculation.
|
||||
* @note The 'read_cb' callback is called in timer task in each filtering cycle.
|
||||
* @param read_cb Pointer to filtered callback function.
|
||||
* If the argument passed in is NULL, the callback will stop.
|
||||
* @return
|
||||
* - ESP_OK Success
|
||||
* - ESP_ERR_INVALID_ARG set error
|
||||
*/
|
||||
esp_err_t touch_pad_set_filter_read_cb(filter_cb_t read_cb);
|
||||
|
||||
/**
|
||||
* @brief Register touch-pad ISR.
|
||||
* The handler will be attached to the same CPU core that this function is running on.
|
||||
* @param fn Pointer to ISR handler
|
||||
* @param arg Parameter for ISR
|
||||
* @return
|
||||
* - ESP_OK Success ;
|
||||
* - ESP_ERR_INVALID_ARG GPIO error
|
||||
* - ESP_ERR_NO_MEM No memory
|
||||
*/
|
||||
esp_err_t touch_pad_isr_register(intr_handler_t fn, void *arg);
|
||||
|
||||
/**
|
||||
* @brief Set the clock cycles of each measurement
|
||||
* @note This function will specify the clock cycles of each measurement
|
||||
* and the clock is sourced from SOC_MOD_CLK_RTC_FAST, its default frequency is SOC_CLK_RC_FAST_FREQ_APPROX
|
||||
* The touch sensor will record the charge and discharge times during these clock cycles as the final result (raw value)
|
||||
* @note If clock cycles is too small, it may lead to inaccurate results.
|
||||
*
|
||||
* @param clock_cycle The clock cycles of each measurement
|
||||
* measure_time = clock_cycle / SOC_CLK_RC_FAST_FREQ_APPROX, the maximum measure time is 0xffff / SOC_CLK_RC_FAST_FREQ_APPROX
|
||||
* @return
|
||||
* - ESP_OK Set the clock cycle success
|
||||
*/
|
||||
esp_err_t touch_pad_set_measurement_clock_cycles(uint16_t clock_cycle);
|
||||
|
||||
/**
|
||||
* @brief Get the clock cycles of each measurement
|
||||
*
|
||||
* @param clock_cycle The clock cycles of each measurement
|
||||
* @return
|
||||
* - ESP_OK Get the clock cycle success
|
||||
* - ESP_ERR_INVALID_ARG The input parameter is NULL
|
||||
*/
|
||||
esp_err_t touch_pad_get_measurement_clock_cycles(uint16_t *clock_cycle);
|
||||
|
||||
/**
|
||||
* @brief Set the interval between two measurements
|
||||
* @note The touch sensor will sleep between two measurements
|
||||
* This function is to set the interval cycle
|
||||
* And the interval is clocked from SOC_MOD_CLK_RTC_SLOW, its default frequency is SOC_CLK_RC_SLOW_FREQ_APPROX
|
||||
*
|
||||
* @param interval_cycle The interval between two measurements
|
||||
* sleep_time = interval_cycle / SOC_CLK_RC_SLOW_FREQ_APPROX.
|
||||
* The approximate frequency value of RTC_SLOW_CLK can be obtained using rtc_clk_slow_freq_get_hz function.
|
||||
* @return
|
||||
* - ESP_OK Set interval cycle success
|
||||
*/
|
||||
esp_err_t touch_pad_set_measurement_interval(uint16_t interval_cycle);
|
||||
|
||||
/**
|
||||
* @brief Get the interval between two measurements
|
||||
*
|
||||
* @param interval_cycle The interval between two measurements
|
||||
* @return
|
||||
* - ESP_OK Get interval cycle success
|
||||
* - ESP_ERR_INVALID_ARG The input parameter is NULL
|
||||
*/
|
||||
esp_err_t touch_pad_get_measurement_interval(uint16_t *interval_cycle);
|
||||
|
||||
/**
|
||||
* @brief Set touch sensor measurement and sleep time.
|
||||
* Excessive total time will slow down the touch response.
|
||||
* Too small measurement time will not be sampled enough, resulting in inaccurate measurements.
|
||||
* @note The touch sensor will count the number of charge/discharge cycles over a fixed period of time (specified as the second parameter).
|
||||
* That means the number of cycles (raw value) will decrease as the capacity of the touch pad is increasing.
|
||||
* @note The greater the duty cycle of the measurement time, the more system power is consumed.
|
||||
*
|
||||
* @param sleep_cycle The touch sensor will sleep after each measurement.
|
||||
* sleep_cycle decide the interval between each measurement.
|
||||
* t_sleep = sleep_cycle / SOC_CLK_RC_SLOW_FREQ_APPROX.
|
||||
* The approximate frequency value of RTC_SLOW_CLK can be obtained using rtc_clk_slow_freq_get_hz function.
|
||||
* @param meas_cycle The duration of the touch sensor measurement.
|
||||
* t_meas = meas_cycle / SOC_CLK_RC_FAST_FREQ_APPROX, the maximum measure time is 0xffff / SOC_CLK_RC_FAST_FREQ_APPROX
|
||||
* @return
|
||||
* - ESP_OK on success
|
||||
*/
|
||||
esp_err_t touch_pad_set_meas_time(uint16_t sleep_cycle, uint16_t meas_cycle)
|
||||
__attribute__((deprecated("please use 'touch_pad_set_measurement_clock_cycles' and 'touch_pad_set_measurement_interval' instead")));
|
||||
|
||||
/**
|
||||
* @brief Get touch sensor measurement and sleep time
|
||||
* @param sleep_cycle Pointer to accept sleep cycle number
|
||||
* @param meas_cycle Pointer to accept measurement cycle count.
|
||||
* @return
|
||||
* - ESP_OK on success
|
||||
* - ESP_ERR_INVALID_ARG The input parameter is NULL
|
||||
*/
|
||||
esp_err_t touch_pad_get_meas_time(uint16_t *sleep_cycle, uint16_t *meas_cycle)
|
||||
__attribute__((deprecated("please use 'touch_pad_get_measurement_clock_cycles' and 'touch_pad_get_measurement_interval' instead")));
|
||||
|
||||
/**
|
||||
* @brief Trigger a touch sensor measurement, only support in SW mode of FSM
|
||||
* @return
|
||||
* - ESP_OK on success
|
||||
*/
|
||||
esp_err_t touch_pad_sw_start(void);
|
||||
|
||||
/**
|
||||
* @brief Set touch sensor interrupt threshold
|
||||
* @param touch_num touch pad index
|
||||
* @param threshold threshold of touchpad count, refer to touch_pad_set_trigger_mode to see how to set trigger mode.
|
||||
* @return
|
||||
* - ESP_OK on success
|
||||
* - ESP_ERR_INVALID_ARG if argument is wrong
|
||||
*/
|
||||
esp_err_t touch_pad_set_thresh(touch_pad_t touch_num, uint16_t threshold);
|
||||
|
||||
/**
|
||||
* @brief Get touch sensor interrupt threshold
|
||||
* @param touch_num touch pad index
|
||||
* @param threshold pointer to accept threshold
|
||||
* @return
|
||||
* - ESP_OK on success
|
||||
* - ESP_ERR_INVALID_ARG if argument is wrong
|
||||
*/
|
||||
esp_err_t touch_pad_get_thresh(touch_pad_t touch_num, uint16_t *threshold);
|
||||
|
||||
/**
|
||||
* @brief Set touch sensor interrupt trigger mode.
|
||||
* Interrupt can be triggered either when counter result is less than
|
||||
* threshold or when counter result is more than threshold.
|
||||
* @param mode touch sensor interrupt trigger mode
|
||||
* @return
|
||||
* - ESP_OK on success
|
||||
* - ESP_ERR_INVALID_ARG if argument is wrong
|
||||
*/
|
||||
esp_err_t touch_pad_set_trigger_mode(touch_trigger_mode_t mode);
|
||||
|
||||
/**
|
||||
* @brief Get touch sensor interrupt trigger mode
|
||||
* @param mode pointer to accept touch sensor interrupt trigger mode
|
||||
* @return
|
||||
* - ESP_OK on success
|
||||
*/
|
||||
esp_err_t touch_pad_get_trigger_mode(touch_trigger_mode_t *mode);
|
||||
|
||||
/**
|
||||
* @brief Set touch sensor interrupt trigger source. There are two sets of touch signals.
|
||||
* Set1 and set2 can be mapped to several touch signals. Either set will be triggered
|
||||
* if at least one of its touch signal is 'touched'. The interrupt can be configured to be generated
|
||||
* if set1 is triggered, or only if both sets are triggered.
|
||||
* @param src touch sensor interrupt trigger source
|
||||
* @return
|
||||
* - ESP_OK on success
|
||||
* - ESP_ERR_INVALID_ARG if argument is wrong
|
||||
*/
|
||||
esp_err_t touch_pad_set_trigger_source(touch_trigger_src_t src);
|
||||
|
||||
/**
|
||||
* @brief Get touch sensor interrupt trigger source
|
||||
* @param src pointer to accept touch sensor interrupt trigger source
|
||||
* @return
|
||||
* - ESP_OK on success
|
||||
*/
|
||||
esp_err_t touch_pad_get_trigger_source(touch_trigger_src_t *src);
|
||||
|
||||
/**
|
||||
* @brief Set touch sensor group mask.
|
||||
* Touch pad module has two sets of signals, 'Touched' signal is triggered only if
|
||||
* at least one of touch pad in this group is "touched".
|
||||
* This function will set the register bits according to the given bitmask.
|
||||
* @param set1_mask bitmask of touch sensor signal group1, it's a 10-bit value
|
||||
* @param set2_mask bitmask of touch sensor signal group2, it's a 10-bit value
|
||||
* @param en_mask bitmask of touch sensor work enable, it's a 10-bit value
|
||||
* @return
|
||||
* - ESP_OK on success
|
||||
* - ESP_ERR_INVALID_ARG if argument is wrong
|
||||
*/
|
||||
esp_err_t touch_pad_set_group_mask(uint16_t set1_mask, uint16_t set2_mask, uint16_t en_mask);
|
||||
|
||||
/**
|
||||
* @brief Get touch sensor group mask.
|
||||
* @param set1_mask pointer to accept bitmask of touch sensor signal group1, it's a 10-bit value
|
||||
* @param set2_mask pointer to accept bitmask of touch sensor signal group2, it's a 10-bit value
|
||||
* @param en_mask pointer to accept bitmask of touch sensor work enable, it's a 10-bit value
|
||||
* @return
|
||||
* - ESP_OK on success
|
||||
*/
|
||||
esp_err_t touch_pad_get_group_mask(uint16_t *set1_mask, uint16_t *set2_mask, uint16_t *en_mask);
|
||||
|
||||
/**
|
||||
* @brief Clear touch sensor group mask.
|
||||
* Touch pad module has two sets of signals, Interrupt is triggered only if
|
||||
* at least one of touch pad in this group is "touched".
|
||||
* This function will clear the register bits according to the given bitmask.
|
||||
* @param set1_mask bitmask touch sensor signal group1, it's a 10-bit value
|
||||
* @param set2_mask bitmask touch sensor signal group2, it's a 10-bit value
|
||||
* @param en_mask bitmask of touch sensor work enable, it's a 10-bit value
|
||||
* @return
|
||||
* - ESP_OK on success
|
||||
* - ESP_ERR_INVALID_ARG if argument is wrong
|
||||
*/
|
||||
esp_err_t touch_pad_clear_group_mask(uint16_t set1_mask, uint16_t set2_mask, uint16_t en_mask);
|
||||
|
||||
/**
|
||||
* @brief To enable touch pad interrupt
|
||||
* @return
|
||||
* - ESP_OK on success
|
||||
*/
|
||||
esp_err_t touch_pad_intr_enable(void);
|
||||
|
||||
/**
|
||||
* @brief To disable touch pad interrupt
|
||||
* @return
|
||||
* - ESP_OK on success
|
||||
*/
|
||||
esp_err_t touch_pad_intr_disable(void);
|
||||
|
||||
/**
|
||||
* @brief To clear touch pad interrupt
|
||||
* @return
|
||||
* - ESP_OK on success
|
||||
*/
|
||||
esp_err_t touch_pad_intr_clear(void);
|
||||
|
||||
/**
|
||||
* @brief set touch pad filter calibration period, in ms.
|
||||
* Need to call touch_pad_filter_start before all touch filter APIs
|
||||
* @param new_period_ms filter period, in ms
|
||||
* @return
|
||||
* - ESP_OK Success
|
||||
* - ESP_ERR_INVALID_STATE driver state error
|
||||
* - ESP_ERR_INVALID_ARG parameter error
|
||||
*/
|
||||
esp_err_t touch_pad_set_filter_period(uint32_t new_period_ms);
|
||||
|
||||
/**
|
||||
* @brief get touch pad filter calibration period, in ms
|
||||
* Need to call touch_pad_filter_start before all touch filter APIs
|
||||
* @param p_period_ms pointer to accept period
|
||||
* @return
|
||||
* - ESP_OK Success
|
||||
* - ESP_ERR_INVALID_STATE driver state error
|
||||
* - ESP_ERR_INVALID_ARG parameter error
|
||||
*/
|
||||
esp_err_t touch_pad_get_filter_period(uint32_t *p_period_ms);
|
||||
|
||||
/**
|
||||
* @brief start touch pad filter function
|
||||
* This API will start a filter to process the noise in order to prevent false triggering
|
||||
* when detecting slight change of capacitance.
|
||||
* Need to call touch_pad_filter_start before all touch filter APIs
|
||||
*
|
||||
* @note This filter uses FreeRTOS timer, which is dispatched from a task with
|
||||
* priority 1 by default on CPU 0. So if some application task with higher priority
|
||||
* takes a lot of CPU0 time, then the quality of data obtained from this filter will be affected.
|
||||
* You can adjust FreeRTOS timer task priority in menuconfig.
|
||||
* @param filter_period_ms filter calibration period, in ms
|
||||
* @return
|
||||
* - ESP_OK Success
|
||||
* - ESP_ERR_INVALID_ARG parameter error
|
||||
* - ESP_ERR_NO_MEM No memory for driver
|
||||
* - ESP_ERR_INVALID_STATE driver state error
|
||||
*/
|
||||
esp_err_t touch_pad_filter_start(uint32_t filter_period_ms);
|
||||
|
||||
/**
|
||||
* @brief stop touch pad filter function
|
||||
* Need to call touch_pad_filter_start before all touch filter APIs
|
||||
* @return
|
||||
* - ESP_OK Success
|
||||
* - ESP_ERR_INVALID_STATE driver state error
|
||||
*/
|
||||
esp_err_t touch_pad_filter_stop(void);
|
||||
|
||||
/**
|
||||
* @brief delete touch pad filter driver and release the memory
|
||||
* Need to call touch_pad_filter_start before all touch filter APIs
|
||||
* @return
|
||||
* - ESP_OK Success
|
||||
* - ESP_ERR_INVALID_STATE driver state error
|
||||
*/
|
||||
esp_err_t touch_pad_filter_delete(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2016-2022 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2016-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@ -17,7 +17,7 @@
|
||||
#include "esp_timer.h"
|
||||
#include "esp_intr_alloc.h"
|
||||
#include "driver/rtc_io.h"
|
||||
#include "driver/touch_pad.h"
|
||||
#include "driver/touch_sensor_legacy.h"
|
||||
#include "esp_private/rtc_ctrl.h"
|
||||
#include "driver/gpio.h"
|
||||
#include "esp_check.h"
|
||||
@ -522,3 +522,19 @@ err:
|
||||
xSemaphoreGive(rtc_touch_mux);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#if !CONFIG_TOUCH_SKIP_LEGACY_CONFLICT_CHECK
|
||||
/**
|
||||
* @brief This function will be called during start up, to check that the new touch driver is not running along with the legacy touch driver
|
||||
*/
|
||||
static __attribute__((constructor)) void check_touch_driver_conflict(void)
|
||||
{
|
||||
extern __attribute__((weak)) esp_err_t touch_sensor_new_controller(const void*, void *);
|
||||
/* If the new Touch driver is linked, the weak function will point to the actual function in the new driver, otherwise it is NULL*/
|
||||
if ((void *)touch_sensor_new_controller != NULL) {
|
||||
ESP_EARLY_LOGE("legacy_touch_driver", "CONFLICT! The new touch driver can't work along with the legacy touch driver");
|
||||
abort();
|
||||
}
|
||||
ESP_EARLY_LOGW("legacy_touch_driver", "legacy touch driver is deprecated, please migrate to use driver/touch_sens.h");
|
||||
}
|
||||
#endif //CONFIG_TOUCH_SKIP_LEGACY_CONFLICT_CHECK
|
||||
|
@ -608,7 +608,7 @@ esp_err_t touch_pad_sleep_get_channel_num(touch_pad_t *pad_num)
|
||||
{
|
||||
TOUCH_NULL_POINTER_CHECK(pad_num, "pad_num");
|
||||
TOUCH_ENTER_CRITICAL();
|
||||
touch_hal_sleep_get_channel_num(pad_num);
|
||||
touch_hal_sleep_get_channel_num((uint32_t *)pad_num);
|
||||
TOUCH_EXIT_CRITICAL();
|
||||
return ESP_OK;
|
||||
}
|
||||
|
@ -581,7 +581,7 @@ esp_err_t touch_pad_sleep_get_channel_num(touch_pad_t *pad_num)
|
||||
{
|
||||
TOUCH_NULL_POINTER_CHECK(pad_num, "pad_num");
|
||||
TOUCH_ENTER_CRITICAL();
|
||||
touch_hal_sleep_get_channel_num(pad_num);
|
||||
touch_hal_sleep_get_channel_num((uint32_t *)pad_num);
|
||||
TOUCH_EXIT_CRITICAL();
|
||||
return ESP_OK;
|
||||
}
|
||||
|
@ -6,17 +6,21 @@ endif()
|
||||
|
||||
set(srcs)
|
||||
set(public_inc)
|
||||
set(priv_require esp_driver_gpio)
|
||||
|
||||
if(CONFIG_SOC_TOUCH_SENSOR_SUPPORTED)
|
||||
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()
|
||||
list(APPEND srcs "common/touch_sens_common.c"
|
||||
"${version_folder}/touch_version_specific.c")
|
||||
list(APPEND public_inc "include" "${version_folder}/include")
|
||||
endif()
|
||||
|
||||
# ESP32 need esp_timer to execute the software filter periodically
|
||||
if(${target} STREQUAL "esp32")
|
||||
list(APPEND priv_require esp_timer)
|
||||
endif()
|
||||
|
||||
idf_component_register(SRCS ${srcs}
|
||||
PRIV_REQUIRES esp_driver_gpio
|
||||
PRIV_REQUIRES ${priv_require}
|
||||
INCLUDE_DIRS ${public_inc}
|
||||
)
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@ -14,6 +14,7 @@
|
||||
#include "soc/touch_sensor_periph.h"
|
||||
#include "esp_private/gpio.h"
|
||||
#include "driver/touch_sens.h"
|
||||
#include "esp_private/esp_gpio_reserve.h"
|
||||
|
||||
#if SOC_TOUCH_SENSOR_VERSION <= 2
|
||||
#include "esp_private/rtc_ctrl.h"
|
||||
@ -21,7 +22,6 @@
|
||||
#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
|
||||
@ -42,6 +42,9 @@ touch_sensor_handle_t g_touch = NULL;
|
||||
static void touch_channel_pin_init(int id)
|
||||
{
|
||||
gpio_num_t pin = touch_sensor_channel_io_map[id];
|
||||
if (esp_gpio_reserve(BIT64(pin)) & BIT64(pin)) {
|
||||
ESP_LOGW(TAG, "The GPIO%d is conflict with other module", (int)pin);
|
||||
}
|
||||
gpio_config_as_analog(pin);
|
||||
}
|
||||
|
||||
@ -145,18 +148,16 @@ 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;
|
||||
#if SOC_TOUCH_SUPPORT_PROX_SENSING
|
||||
sens_handle->ch[chan_id]->prox_id = 0;
|
||||
#endif
|
||||
|
||||
/* 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);
|
||||
sens_handle->chan_mask |= 1 << chan_id;
|
||||
/* 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];
|
||||
@ -307,7 +308,12 @@ esp_err_t touch_sensor_start_continuous_scanning(touch_sensor_handle_t sens_hand
|
||||
|
||||
ESP_GOTO_ON_FALSE_ISR(sens_handle->is_enabled, ESP_ERR_INVALID_STATE, err, TAG, "Please enable the touch sensor first");
|
||||
ESP_GOTO_ON_FALSE_ISR(!sens_handle->is_started, ESP_ERR_INVALID_STATE, err, TAG, "Continuous scanning has started already");
|
||||
|
||||
#if SOC_TOUCH_SENSOR_VERSION == 1
|
||||
if (sens_handle->sw_filter_timer) {
|
||||
ESP_GOTO_ON_ERROR_ISR(esp_timer_start_periodic(sens_handle->sw_filter_timer, sens_handle->timer_interval_ms * 1000),
|
||||
err, TAG, "Failed to start the sw filter timer");
|
||||
}
|
||||
#endif
|
||||
TOUCH_ENTER_CRITICAL_SAFE(TOUCH_PERIPH_LOCK);
|
||||
sens_handle->is_started = true;
|
||||
touch_ll_enable_fsm_timer(true);
|
||||
@ -325,7 +331,11 @@ esp_err_t touch_sensor_stop_continuous_scanning(touch_sensor_handle_t sens_handl
|
||||
esp_err_t ret = ESP_OK;
|
||||
|
||||
ESP_GOTO_ON_FALSE_ISR(sens_handle->is_started, ESP_ERR_INVALID_STATE, err, TAG, "Continuous scanning not started yet");
|
||||
|
||||
#if SOC_TOUCH_SENSOR_VERSION == 1
|
||||
if (sens_handle->sw_filter_timer) {
|
||||
ESP_GOTO_ON_ERROR(esp_timer_stop(sens_handle->sw_filter_timer), err, TAG, "Failed to stop the timer");
|
||||
}
|
||||
#endif
|
||||
TOUCH_ENTER_CRITICAL_SAFE(TOUCH_PERIPH_LOCK);
|
||||
touch_ll_stop_fsm_repeated_timer();
|
||||
touch_ll_enable_fsm_timer(false);
|
||||
@ -367,11 +377,13 @@ esp_err_t touch_sensor_trigger_oneshot_scanning(touch_sensor_handle_t sens_handl
|
||||
touch_ll_trigger_oneshot_measurement();
|
||||
TOUCH_EXIT_CRITICAL(TOUCH_PERIPH_LOCK);
|
||||
while (!touch_ll_is_measure_done()) {
|
||||
#if SOC_TOUCH_SENSOR_VERSION >= 2
|
||||
if (g_touch->is_meas_timeout) {
|
||||
g_touch->is_meas_timeout = false;
|
||||
ESP_LOGW(TAG, "The measurement time on channel %d exceed the limitation", i);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
if (timeout_ms >= 0) {
|
||||
ESP_GOTO_ON_FALSE(xTaskGetTickCount() <= end_tick, ESP_ERR_TIMEOUT, err, TAG, "Wait for measurement done timeout");
|
||||
}
|
||||
@ -382,7 +394,12 @@ esp_err_t touch_sensor_trigger_oneshot_scanning(touch_sensor_handle_t sens_handl
|
||||
TOUCH_ENTER_CRITICAL(TOUCH_PERIPH_LOCK);
|
||||
touch_ll_channel_sw_measure_mask(0);
|
||||
TOUCH_EXIT_CRITICAL(TOUCH_PERIPH_LOCK);
|
||||
|
||||
#if SOC_TOUCH_SENSOR_VERSION == 1
|
||||
/* If software filter enabled, do the filter immediately after oneshot scanning */
|
||||
if (sens_handle->sw_filter_timer) {
|
||||
touch_priv_execute_sw_filter(sens_handle);
|
||||
}
|
||||
#endif
|
||||
err:
|
||||
xSemaphoreGiveRecursive(sens_handle->mutex);
|
||||
TOUCH_ENTER_CRITICAL(TOUCH_PERIPH_LOCK);
|
||||
@ -403,6 +420,11 @@ esp_err_t touch_sensor_register_callbacks(touch_sensor_handle_t sens_handle, con
|
||||
}
|
||||
ESP_RETURN_ON_FALSE(!user_ctx || esp_ptr_internal(user_ctx), ESP_ERR_INVALID_ARG, TAG, "user context not in internal RAM");
|
||||
#endif
|
||||
#if SOC_TOUCH_SENSOR_VERSION == 1
|
||||
if (sens_handle->data_filter_fn == NULL) {
|
||||
ESP_RETURN_ON_FALSE(!(callbacks->on_active || callbacks->on_inactive), ESP_ERR_INVALID_STATE, TAG, "filter has not configured");
|
||||
}
|
||||
#endif
|
||||
|
||||
esp_err_t ret = ESP_OK;
|
||||
xSemaphoreTakeRecursive(sens_handle->mutex, portMAX_DELAY);
|
||||
@ -424,14 +446,6 @@ 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_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_cfg);
|
||||
touch_priv_config_benchmark(chan_handle, benchmark_cfg);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
/* Scope: Private APIs */
|
||||
/******************************************************************************/
|
||||
@ -440,12 +454,30 @@ esp_err_t touch_sensor_get_channel_info(touch_channel_handle_t chan_handle, touc
|
||||
TOUCH_NULL_POINTER_CHECK(chan_handle);
|
||||
TOUCH_NULL_POINTER_CHECK(chan_info);
|
||||
xSemaphoreTakeRecursive(chan_handle->base->mutex, portMAX_DELAY);
|
||||
memset(chan_info, 0, sizeof(touch_chan_info_t));
|
||||
chan_info->chan_id = chan_handle->id;
|
||||
chan_info->chan_gpio = touch_sensor_channel_io_map[chan_handle->id];
|
||||
chan_info->flags.can_wake_dp_slp = chan_handle == chan_handle->base->deep_slp_chan;
|
||||
#if SOC_TOUCH_SENSOR_VERSION == 1
|
||||
// All channels on V1 can wake up deep sleep
|
||||
chan_info->flags.can_wake_dp_slp = true;
|
||||
chan_info->abs_active_thresh[0] = touch_ll_get_chan_active_threshold(chan_handle->id);
|
||||
#elif SOC_TOUCH_SENSOR_VERSION == 2
|
||||
chan_info->flags.can_wake_dp_slp = (!chan_handle->base->allow_pd) || (chan_handle == chan_handle->base->deep_slp_chan);
|
||||
chan_info->active_thresh[0] = touch_ll_get_chan_active_threshold(chan_handle->id);
|
||||
#elif SOC_TOUCH_SENSOR_VERSION == 3
|
||||
chan_info->flags.can_wake_dp_slp = (!chan_handle->base->allow_pd) || (chan_handle == chan_handle->base->deep_slp_chan);
|
||||
for (int i = 0; i < TOUCH_SAMPLE_CFG_NUM; i++) {
|
||||
chan_info->active_thresh[i] = touch_ll_get_chan_active_threshold(chan_handle->id, i);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if SOC_TOUCH_SUPPORT_PROX_SENSING
|
||||
chan_info->flags.is_proxi = chan_handle->prox_id > 0;
|
||||
#endif
|
||||
#if SOC_TOUCH_SUPPORT_WATERPROOF
|
||||
chan_info->flags.is_guard = chan_handle == chan_handle->base->guard_chan;
|
||||
chan_info->flags.is_shield = chan_handle == chan_handle->base->shield_chan;
|
||||
#endif
|
||||
xSemaphoreGiveRecursive(chan_handle->base->mutex);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@ -19,6 +19,9 @@
|
||||
#include "esp_memory_utils.h"
|
||||
#include "esp_check.h"
|
||||
#include "sdkconfig.h"
|
||||
#if SOC_TOUCH_SENSOR_VERSION == 1
|
||||
#include "esp_timer.h"
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@ -76,8 +79,16 @@ struct touch_sensor_s {
|
||||
intr_handle_t intr_handle; /*!< Interrupt handle */
|
||||
touch_event_callbacks_t cbs; /*!< Event callbacks */
|
||||
touch_channel_handle_t deep_slp_chan; /*!< The configured channel for depp sleep, will be NULL if not enable the deep sleep */
|
||||
#if SOC_TOUCH_SUPPORT_WATERPROOF
|
||||
touch_channel_handle_t guard_chan; /*!< The configured channel for the guard ring, will be NULL if not set */
|
||||
touch_channel_handle_t shield_chan; /*!< The configured channel for the shield pad, will be NULL if not set */
|
||||
#endif
|
||||
#if SOC_TOUCH_SENSOR_VERSION == 1
|
||||
uint32_t timer_interval_ms; /*!< Timer interval in milliseconds for software filter */
|
||||
esp_timer_handle_t sw_filter_timer; /*!< Software filter timer handle */
|
||||
touch_sw_filter_t data_filter_fn; /*!< Software filter function pointer */
|
||||
void *user_filter_ctx; /*!< User context that will pass to the software filter function */
|
||||
#endif
|
||||
|
||||
SemaphoreHandle_t mutex; /*!< Mutex lock to ensure thread safety */
|
||||
|
||||
@ -87,14 +98,18 @@ struct touch_sensor_s {
|
||||
struct {
|
||||
bool is_enabled : 1; /*!< Flag to indicate whether the scanning is enabled */
|
||||
bool is_started : 1; /*!< Flag to indicate whether the scanning has started */
|
||||
bool is_meas_timeout : 1; /*!< Flag to indicate whether the measurement timeout, will force to stop the current measurement if the timeout is triggered */
|
||||
bool sleep_en : 1; /*!< Flag to indicate whether the sleep wake-up feature is enabled */
|
||||
#if SOC_TOUCH_SENSOR_VERSION == 1
|
||||
bool is_below_trig; /*!< Whether the touch sensor interrupt will trigger below the trigger threshold */
|
||||
#else // SOC_TOUCH_SENSOR_VERSION >= 2
|
||||
bool allow_pd : 1; /*!< Flag to indicate whether allow RTC_PERIPH power down during the sleep */
|
||||
bool is_meas_timeout : 1; /*!< Flag to indicate whether the measurement timeout, will force to stop the current measurement if the timeout is triggered */
|
||||
bool waterproof_en : 1; /*!< Flag to indicate whether the water proof feature is enabled */
|
||||
bool immersion_proof : 1; /*!< Flag to indicate whether to disable scanning when the guard ring is triggered */
|
||||
bool proximity_en : 1; /*!< Flag to indicate whether the proximity sensing feature is enabled */
|
||||
bool timeout_en : 1; /*!< Flag to indicate whether the measurement timeout feature (hardware timeout) is enabled */
|
||||
bool denoise_en : 1; /*!< Flag to indicate whether the denoise channel feature is enabled */
|
||||
#endif
|
||||
};
|
||||
uint32_t flags;
|
||||
};
|
||||
@ -107,6 +122,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 */
|
||||
#if SOC_TOUCH_SUPPORT_PROX_SENSING
|
||||
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`,
|
||||
@ -116,6 +132,12 @@ struct touch_channel_s {
|
||||
* The value will accumulate for each scanning until it reaches `touch_proximity_config_t::scan_times`.
|
||||
* This accumulated proximity value can be read via `touch_channel_read_data` when all scanning finished.
|
||||
*/
|
||||
#endif
|
||||
#if SOC_TOUCH_SENSOR_VERSION == 1
|
||||
uint32_t abs_thresh; /*!< Absolute threshold value that evaluate whether the channel is active */
|
||||
uint32_t smooth_data; /*!< The smoothed data value, which is filtered by the software filter */
|
||||
bool is_active; /*!< Flag to indicate whether the channel is active */
|
||||
#endif
|
||||
};
|
||||
|
||||
extern touch_sensor_handle_t g_touch; /*!< Global touch sensor controller handle for `esp_driver_touch_sens` use only */
|
||||
@ -190,15 +212,14 @@ esp_err_t touch_priv_deinit_controller(touch_sensor_handle_t sens_handle);
|
||||
*/
|
||||
esp_err_t touch_priv_channel_read_data(touch_channel_handle_t chan_handle, touch_chan_data_type_t type, uint32_t *data);
|
||||
|
||||
#if SOC_TOUCH_SENSOR_VERSION == 1
|
||||
/**
|
||||
* @brief Touch sensor channel benchmark set interface
|
||||
* @note This is a private interface of `esp_driver_touch_sens`
|
||||
* It should be implemented by each hardware version
|
||||
*
|
||||
* @param[in] chan_handle The channel handle
|
||||
* @param[in] benchmark_cfg The benchmark operation
|
||||
* @brief Execute software filter for once
|
||||
* @note This is the implementation of the esp_timer callback
|
||||
* @param[in] arg the touch sensor controller handle
|
||||
*/
|
||||
void touch_priv_config_benchmark(touch_channel_handle_t chan_handle, const touch_chan_benchmark_config_t *benchmark_cfg);
|
||||
void touch_priv_execute_sw_filter(void *arg);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@ -9,4 +9,298 @@
|
||||
* Version 1 includes ESP32
|
||||
*/
|
||||
|
||||
#error "'esp_driver_touch_sens' does not support for ESP32 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 0 /*!< The minimum available channel id of the touch pad */
|
||||
#define TOUCH_MAX_CHAN_ID 9 /*!< The maximum available channel id of the touch pad */
|
||||
|
||||
/**
|
||||
* @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 = 320.0, \
|
||||
.intr_trig_mode = TOUCH_INTR_TRIG_ON_BELOW_THRESH, \
|
||||
.intr_trig_group = TOUCH_INTR_TRIG_GROUP_BOTH, \
|
||||
.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] duration_ms The measurement duration 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_V1_DEFAULT_SAMPLE_CONFIG(duration_ms, volt_low, volt_high) { \
|
||||
.charge_duration_ms = duration_ms, \
|
||||
.charge_volt_lim_h = volt_high, \
|
||||
.charge_volt_lim_l = volt_low, \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Helper macro to the default filter configurations
|
||||
*
|
||||
*/
|
||||
#define TOUCH_SENSOR_DEFAULT_FILTER_CONFIG() { \
|
||||
.interval_ms = 10, \
|
||||
.data_filter_fn = NULL, /* Set NULL to use default software filter */ \
|
||||
}
|
||||
|
||||
/**
|
||||
* @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 (need to config software filter fist) */
|
||||
} touch_chan_data_type_t;
|
||||
|
||||
/**
|
||||
* @brief Touch channel trigger group
|
||||
*
|
||||
*/
|
||||
typedef enum {
|
||||
TOUCH_CHAN_TRIG_GROUP_1 = 0x01, /*!< Channel will be added to the interrupt trigger group 1 */
|
||||
TOUCH_CHAN_TRIG_GROUP_2 = 0x02, /*!< Channel will be added to the interrupt trigger group 2 */
|
||||
TOUCH_CHAN_TRIG_GROUP_BOTH = 0x03, /*!< Channel will be added to both interrupt trigger group 1 and 2 */
|
||||
} touch_chan_trig_group_t;
|
||||
|
||||
/**
|
||||
* @brief Sample configurations of the touch sensor
|
||||
*
|
||||
*/
|
||||
typedef struct {
|
||||
float charge_duration_ms; /*!< Charge duration time of one measurement on a touch channel */
|
||||
touch_volt_lim_h_t charge_volt_lim_h; /*!< The upper voltage limit while charging a touch pad. i.e., the touch controller won't charge the touch pad higher than this high voltage limitation. */
|
||||
touch_volt_lim_l_t charge_volt_lim_l; /*!< The lower voltage limit while discharging a touch pad. i.e., the touch controller won't discharge the touch pad lower than this low voltage limitation. */
|
||||
} 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 */
|
||||
touch_intr_trig_mode_t intr_trig_mode; /*!< Interrupt trigger mode, the hardware touch interrupt can be triggered either above or below the absolute threshold */
|
||||
touch_intr_trig_group_t intr_trig_group; /*!< Which channel group can trigger the hardware touch interrupt */
|
||||
/* 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 abs_active_thresh[TOUCH_SAMPLE_CFG_NUM]; /*!< The ablolute active threshould. The ``on_active`` and ``on_hw_active`` callback will trigger when
|
||||
* - If touch_sensor_config_t::intr_trig_mode = TOUCH_INTR_TRIG_ON_BELOW_THRESH, the callback will keep triggering when the touch channel value below the threshold.
|
||||
* - If touch_sensor_config_t::intr_trig_mode = TOUCH_INTR_TRIG_ON_ABOVE_THRESH, the callback will keep triggering when the touch channel value above the threshold.
|
||||
*/
|
||||
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_chan_trig_group_t group; /*!< The channel group that the channel belongs to. The group will be used to trigger the interrupt */
|
||||
} touch_channel_config_t;
|
||||
|
||||
/**
|
||||
* @brief Touch software filter data
|
||||
*
|
||||
*/
|
||||
typedef struct {
|
||||
uint32_t prev_output; /*!< Previous output filtered data */
|
||||
uint32_t curr_input; /*!< Current input raw data that need to be filtered */
|
||||
} touch_sw_filter_data_t;
|
||||
|
||||
/**
|
||||
* @brief Touch software filter prototype
|
||||
* @note Users can customize their own filter algorithm by this prototype
|
||||
* @param[in] chan_handle The handle of the touch channel that need to be filtered
|
||||
* @param[in] filter_data The data of the software filter
|
||||
* @param[in] user_filter_ctx User customized filter context pointer
|
||||
* @return
|
||||
* - uint32_t The filtered data
|
||||
*/
|
||||
typedef uint32_t (*touch_sw_filter_t)(touch_channel_handle_t chan_handle, const touch_sw_filter_data_t *filter_data, void *user_filter_ctx);
|
||||
|
||||
/**
|
||||
* @brief The configuration of the software filter
|
||||
*
|
||||
*/
|
||||
typedef struct {
|
||||
uint32_t interval_ms; /*!< The software filter interval in milliseconds.
|
||||
* The software filter will trigger periodically based on esp_timer
|
||||
*/
|
||||
touch_sw_filter_t data_filter_fn; /*!< The data filter function pointer.
|
||||
* You can specify your own filter algorithm, or set NULL to use default software filter
|
||||
*/
|
||||
void *user_filter_ctx; /*!< User costomized filter context pointer.
|
||||
* This pointer will be passed to the second parameter of `touch_sw_filter_t` .
|
||||
* So that users can access their costomized filter context in the software filter function.
|
||||
*/
|
||||
} 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 Helper macro to the default light sleep wake-up configurations
|
||||
* @note RTC_PERIPH will keep power on during the light sleep.
|
||||
* Any enabled touch channel can wake-up the chip from light sleep.
|
||||
*/
|
||||
#define TOUCH_SENSOR_DEFAULT_LSLP_CONFIG() { \
|
||||
.slp_wakeup_lvl = TOUCH_LIGHT_SLEEP_WAKEUP, \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Helper macro to the default deep sleep wake-up configurations
|
||||
* @note RTC_PERIPH will keep power on during the deep sleep.
|
||||
* Any enabled touch channel can wake-up the chip from deep sleep.
|
||||
*/
|
||||
#define TOUCH_SENSOR_DEFAULT_DSLP_CONFIG() { \
|
||||
.slp_wakeup_lvl = TOUCH_DEEP_SLEEP_WAKEUP, \
|
||||
}
|
||||
|
||||
/**
|
||||
* @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_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 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 */
|
||||
} touch_base_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 Active event data
|
||||
*
|
||||
*/
|
||||
typedef struct {
|
||||
uint32_t active_mask; /*!< The current active channel mask.
|
||||
* 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_hw_active_event_data_t;
|
||||
|
||||
/**
|
||||
* @brief Touch sensor callbacks
|
||||
* @note Set NULL for the unused callbacks.
|
||||
* @note The Touch Sensor V1 hardware interrupt callback is different compare to other versions.
|
||||
* To align the behavior of the `on_active` and `on_inactive`, they are added as the software filter callbacks.
|
||||
* Please configure the software filter by `touch_sensor_config_filter` before using hardware interrupt.
|
||||
*
|
||||
*/
|
||||
typedef struct {
|
||||
union {
|
||||
/**
|
||||
* @brief Touch sensor on software active event callback.
|
||||
* @note This callback is triggered by the software periodical filter.
|
||||
* It callbacks 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_sw_active)(touch_sensor_handle_t sens_handle, const touch_active_event_data_t *event, void *user_ctx);
|
||||
/**
|
||||
* @brief Touch sensor on software active event callback. (Alias of `on_sw_active` for compatibility)
|
||||
* @note This callback is triggered by the software periodical filter.
|
||||
* It callbacks 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);
|
||||
};
|
||||
|
||||
union {
|
||||
/**
|
||||
* @brief Touch sensor on software inactive event callback.
|
||||
* @note This callback is triggered by the software periodical filter.
|
||||
* It callbacks when any touch channel is de-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_sw_inactive)(touch_sensor_handle_t sens_handle, const touch_inactive_event_data_t *event, void *user_ctx);
|
||||
/**
|
||||
* @brief Touch sensor on software inactive event callback. (Alias of `on_sw_active` for compatibility)
|
||||
* @note This callback is triggered by the software periodical filter.
|
||||
* It callbacks when any touch channel is de-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_inactive)(touch_sensor_handle_t sens_handle, const touch_inactive_event_data_t *event, void *user_ctx);
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Touch sensor on hardware active interrupt event callback.
|
||||
* @note This callback is triggered by the hardware interrupt.
|
||||
* It callbacks every time when any of the touch channel below or above (depended on touch_sensor_config_t::intr_trig_mode) the threshold.
|
||||
* @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_hw_active)(touch_sensor_handle_t sens_handle, const touch_hw_active_event_data_t *event, void *user_ctx);
|
||||
} touch_event_callbacks_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -0,0 +1,368 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief This file is only applicable to the touch hardware version1
|
||||
* Version 1 includes ESP32
|
||||
*/
|
||||
|
||||
#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_log.h"
|
||||
#include "esp_check.h"
|
||||
|
||||
static const char *TAG = "touch";
|
||||
|
||||
portMUX_TYPE g_touch_spinlock = portMUX_INITIALIZER_UNLOCKED;
|
||||
|
||||
/******************************************************************************
|
||||
* Scope: touch v1 impl private *
|
||||
******************************************************************************/
|
||||
#define TOUCH_DEFAULT_SW_FILTER_COEFF TOUCH_SMOOTH_IIR_FILTER_2
|
||||
|
||||
static uint32_t s_touch_default_sw_iir_filter(touch_channel_handle_t chan_handle, const touch_sw_filter_data_t *filter_data, void *user_filter_ctx)
|
||||
{
|
||||
/* Not used in the default filter algorithm */
|
||||
(void)chan_handle;
|
||||
(void)user_filter_ctx;
|
||||
/* If the previous data is 0, return current value directly */
|
||||
if (filter_data->prev_output == 0) {
|
||||
return filter_data->curr_input;
|
||||
}
|
||||
return filter_data->prev_output - (filter_data->prev_output >> TOUCH_DEFAULT_SW_FILTER_COEFF) +
|
||||
(filter_data->curr_input >> TOUCH_DEFAULT_SW_FILTER_COEFF);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* Scope: touch driver private *
|
||||
******************************************************************************/
|
||||
void touch_priv_execute_sw_filter(void* arg)
|
||||
{
|
||||
touch_sensor_handle_t sens_handle = (touch_sensor_handle_t)arg;
|
||||
uint32_t chan_mask = sens_handle->chan_mask;
|
||||
/* Read raw data and do the filtering */
|
||||
FOR_EACH_TOUCH_CHANNEL(i) {
|
||||
touch_channel_handle_t chan_handle = sens_handle->ch[i];
|
||||
if (chan_handle) {
|
||||
touch_sw_filter_data_t fdata = {
|
||||
.prev_output = chan_handle->smooth_data,
|
||||
};
|
||||
/* Read raw data */
|
||||
while (!touch_ll_is_measure_done());
|
||||
touch_ll_read_chan_data(chan_handle->id, TOUCH_LL_READ_RAW, &fdata.curr_input);
|
||||
/* Do filtering */
|
||||
chan_handle->smooth_data = sens_handle->data_filter_fn(chan_handle, &fdata, sens_handle->user_filter_ctx);
|
||||
}
|
||||
/* Break if no more enabled channels */
|
||||
chan_mask >>= 1;
|
||||
if (!chan_mask) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
chan_mask = sens_handle->chan_mask;
|
||||
/* Callback if the channel activated or de-activated */
|
||||
FOR_EACH_TOUCH_CHANNEL(i) {
|
||||
touch_channel_handle_t chan_handle = sens_handle->ch[i];
|
||||
if (chan_handle) {
|
||||
/* Prepare basic event data */
|
||||
touch_base_event_data_t base_edata = {
|
||||
.chan = chan_handle,
|
||||
.chan_id = chan_handle->id,
|
||||
};
|
||||
bool is_below = chan_handle->smooth_data < chan_handle->abs_thresh;
|
||||
/* Judge if the channel is active or inactive for now */
|
||||
bool is_active_now = sens_handle->is_below_trig ? is_below : !is_below;
|
||||
/* Inactive before but now activated */
|
||||
if (!chan_handle->is_active && is_active_now) {
|
||||
chan_handle->is_active = true;
|
||||
if (sens_handle->cbs.on_active) {
|
||||
sens_handle->cbs.on_active(sens_handle, &base_edata, sens_handle->user_ctx);
|
||||
}
|
||||
}
|
||||
/* Active before but now de-activated */
|
||||
if (chan_handle->is_active && !is_active_now) {
|
||||
chan_handle->is_active = false;
|
||||
if (sens_handle->cbs.on_inactive) {
|
||||
sens_handle->cbs.on_inactive(sens_handle, &base_edata, sens_handle->user_ctx);
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Break if no more enabled channels */
|
||||
chan_mask >>= 1;
|
||||
if (!chan_mask) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void touch_priv_enable_module(bool enable)
|
||||
{
|
||||
// Nothing to do
|
||||
// No dedicate touch sensor clock gate or power domain need to operate
|
||||
}
|
||||
|
||||
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;
|
||||
touch_hw_active_event_data_t data;
|
||||
// Only one `on_active` interrupt source, clear directly
|
||||
touch_ll_interrupt_clear(TOUCH_LL_INTR_MASK_ALL);
|
||||
touch_ll_get_active_channel_mask(&(data.active_mask));
|
||||
touch_ll_clear_active_channel_status();
|
||||
// Get the activated channels
|
||||
if (g_touch->cbs.on_hw_active) {
|
||||
need_yield |= g_touch->cbs.on_hw_active(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);
|
||||
TOUCH_NULL_POINTER_CHECK(hal_cfg->sample_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);
|
||||
|
||||
sens_handle->is_below_trig = sens_cfg->intr_trig_mode == TOUCH_INTR_TRIG_ON_BELOW_THRESH;
|
||||
hal_cfg->intr_trig_mode = sens_cfg->intr_trig_mode;
|
||||
hal_cfg->intr_trig_group = sens_cfg->intr_trig_group;
|
||||
hal_cfg->sample_cfg_num = sens_cfg->sample_cfg_num; // Only one sample cfg
|
||||
|
||||
uint32_t charge_duration_ticks = (uint32_t)(sens_cfg->sample_cfg->charge_duration_ms * src_freq_mhz * 1000);
|
||||
charge_duration_ticks = charge_duration_ticks > TOUCH_LL_CHARGE_DURATION_MAX ?
|
||||
TOUCH_LL_CHARGE_DURATION_MAX : charge_duration_ticks;
|
||||
hal_cfg->sample_cfg->charge_duration_ticks = charge_duration_ticks;
|
||||
hal_cfg->sample_cfg->charge_volt_lim_h = sens_cfg->sample_cfg->charge_volt_lim_h;
|
||||
hal_cfg->sample_cfg->charge_volt_lim_l = sens_cfg->sample_cfg->charge_volt_lim_l;
|
||||
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_sample_config_t hal_sample_cfg = {};
|
||||
touch_hal_config_t hal_cfg = {
|
||||
.sample_cfg = &hal_sample_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_ll_reset_trigger_groups();
|
||||
// Reset all channels' activate threshold according to the trigger mode in case of the mis-triggering even the channel is not enabled.
|
||||
uint32_t rst_thresh = sens_cfg->intr_trig_mode == TOUCH_INTR_TRIG_ON_BELOW_THRESH ? 0 : TOUCH_LL_ACTIVE_THRESH_MAX;
|
||||
FOR_EACH_TOUCH_CHANNEL(i) {
|
||||
touch_ll_set_chan_active_threshold(i, rst_thresh);
|
||||
}
|
||||
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->abs_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);
|
||||
chan_handle->abs_thresh = chan_cfg->abs_active_thresh[0];
|
||||
touch_ll_set_chan_active_threshold(chan_handle->id, chan_cfg->abs_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);
|
||||
if (chan_cfg->group & TOUCH_CHAN_TRIG_GROUP_1) {
|
||||
touch_ll_config_trigger_group1(chan_handle->id, true);
|
||||
}
|
||||
if (chan_cfg->group & TOUCH_CHAN_TRIG_GROUP_2) {
|
||||
touch_ll_config_trigger_group2(chan_handle->id, true);
|
||||
}
|
||||
TOUCH_EXIT_CRITICAL(TOUCH_PERIPH_LOCK);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t touch_priv_deinit_controller(touch_sensor_handle_t sens_handle)
|
||||
{
|
||||
touch_ll_reset_trigger_groups();
|
||||
/* Disable the additional functions */
|
||||
if (sens_handle->sleep_en) {
|
||||
touch_sensor_config_sleep_wakeup(sens_handle, NULL);
|
||||
}
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t 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_SMOOTH,
|
||||
ESP_ERR_INVALID_ARG, TAG, "The channel data type is invalid");
|
||||
ESP_RETURN_ON_FALSE_ISR(type == TOUCH_CHAN_DATA_TYPE_SMOOTH && chan_handle->base->data_filter_fn != NULL,
|
||||
ESP_ERR_INVALID_STATE, TAG, "The software filter has not configured");
|
||||
TOUCH_ENTER_CRITICAL_SAFE(TOUCH_PERIPH_LOCK);
|
||||
switch (type) {
|
||||
default: // fall through
|
||||
case TOUCH_CHAN_DATA_TYPE_RAW:
|
||||
// Have to wait the measure done, otherwise it might read the un-finished data
|
||||
while (!touch_ll_is_measure_done());
|
||||
touch_ll_read_chan_data(chan_handle->id, TOUCH_LL_READ_RAW, data);
|
||||
break;
|
||||
case TOUCH_CHAN_DATA_TYPE_SMOOTH:
|
||||
*data = chan_handle->smooth_data;
|
||||
break;
|
||||
}
|
||||
TOUCH_EXIT_CRITICAL_SAFE(TOUCH_PERIPH_LOCK);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* Scope: public APIs *
|
||||
******************************************************************************/
|
||||
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_sample_config_t hal_sample_cfg = {};
|
||||
touch_hal_config_t hal_cfg = {
|
||||
.sample_cfg = &hal_sample_cfg,
|
||||
};
|
||||
touch_hal_config_t *hal_cfg_ptr = NULL;
|
||||
|
||||
xSemaphoreTakeRecursive(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_GOTO_ON_ERROR(esp_sleep_enable_touchpad_wakeup(), err, TAG, "Failed to enable touch sensor 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) {
|
||||
/* 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;
|
||||
}
|
||||
} 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, false);
|
||||
TOUCH_EXIT_CRITICAL(TOUCH_PERIPH_LOCK);
|
||||
|
||||
err:
|
||||
xSemaphoreGiveRecursive(sens_handle->mutex);
|
||||
return ret;
|
||||
}
|
||||
|
||||
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);
|
||||
esp_err_t ret = ESP_OK;
|
||||
|
||||
xSemaphoreTakeRecursive(sens_handle->mutex, portMAX_DELAY);
|
||||
if (filter_cfg) {
|
||||
ESP_GOTO_ON_FALSE(filter_cfg->interval_ms, ESP_ERR_INVALID_ARG, err, TAG, "Invalid timer interval");
|
||||
if (sens_handle->sw_filter_timer == NULL) {
|
||||
esp_timer_create_args_t timer_cfg = {
|
||||
.callback = touch_priv_execute_sw_filter,
|
||||
.arg = sens_handle,
|
||||
/* Choose TASK dispatch because the filter might involve float calculation,
|
||||
and also reading the raw data might need to wait the measurement done */
|
||||
.dispatch_method = ESP_TIMER_TASK,
|
||||
.name = "touch_v1_sw_filter_timer",
|
||||
.skip_unhandled_events = true,
|
||||
};
|
||||
ESP_GOTO_ON_ERROR(esp_timer_create(&timer_cfg, &(sens_handle->sw_filter_timer)),
|
||||
err, TAG, "Failed to create the sw filter timer");
|
||||
}
|
||||
sens_handle->timer_interval_ms = filter_cfg->interval_ms;
|
||||
/* If user does not specify a filter, use the default filter instead */
|
||||
sens_handle->data_filter_fn = filter_cfg->data_filter_fn ?
|
||||
filter_cfg->data_filter_fn :
|
||||
s_touch_default_sw_iir_filter;
|
||||
sens_handle->user_filter_ctx = filter_cfg->user_filter_ctx;
|
||||
} else {
|
||||
if (sens_handle->sw_filter_timer) {
|
||||
ESP_GOTO_ON_ERROR(esp_timer_delete(sens_handle->sw_filter_timer), err, TAG, "Failed to delete the sw filter timer");
|
||||
}
|
||||
sens_handle->data_filter_fn = NULL;
|
||||
sens_handle->user_filter_ctx = NULL;
|
||||
sens_handle->timer_interval_ms = 0;
|
||||
FOR_EACH_TOUCH_CHANNEL(i) {
|
||||
if (sens_handle->ch[i]) {
|
||||
sens_handle->ch[i]->smooth_data = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
err:
|
||||
xSemaphoreGiveRecursive(sens_handle->mutex);
|
||||
return ret;
|
||||
}
|
@ -117,7 +117,7 @@ typedef struct {
|
||||
*
|
||||
*/
|
||||
typedef struct {
|
||||
uint32_t active_thresh[TOUCH_SAMPLE_CFG_NUM]; /*!< The active threshold of each sample configuration,
|
||||
uint32_t active_thresh[TOUCH_SAMPLE_CFG_NUM]; /*!< The relative active threshold of each sample configuration,
|
||||
* while the touch channel smooth value minus benchmark value exceed this threshold,
|
||||
* will be regarded as activated
|
||||
*/
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@ -207,6 +207,9 @@ esp_err_t touch_priv_config_channel(touch_channel_handle_t chan_handle, const to
|
||||
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);
|
||||
touch_chan_benchmark_config_t bm_cfg = {.do_reset = true};
|
||||
/* Reset the benchmark to overwrite the legacy benchmark during the deep sleep */
|
||||
touch_channel_config_benchmark(chan_handle, &bm_cfg);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
@ -255,13 +258,6 @@ esp_err_t touch_priv_channel_read_data(touch_channel_handle_t chan_handle, touch
|
||||
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 *
|
||||
******************************************************************************/
|
||||
@ -299,6 +295,16 @@ esp_err_t touch_sensor_config_filter(touch_sensor_handle_t sens_handle, const to
|
||||
return ret;
|
||||
}
|
||||
|
||||
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_cfg);
|
||||
if (benchmark_cfg->do_reset) {
|
||||
touch_ll_reset_chan_benchmark(BIT(chan_handle->id));
|
||||
}
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
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);
|
||||
@ -317,13 +323,18 @@ esp_err_t touch_sensor_config_sleep_wakeup(touch_sensor_handle_t sens_handle, co
|
||||
ESP_ERR_INVALID_ARG, err, TAG, "Invalid sleep level");
|
||||
/* Enabled touch sensor as wake-up source */
|
||||
ESP_GOTO_ON_ERROR(esp_sleep_enable_touchpad_wakeup(), err, TAG, "Failed to enable touch sensor wakeup");
|
||||
|
||||
/* 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) {
|
||||
if (sleep_cfg->deep_slp_allow_pd) {
|
||||
ESP_GOTO_ON_FALSE(sleep_cfg->deep_slp_chan, ESP_ERR_INVALID_ARG, err, TAG,
|
||||
"deep sleep waken channel can't be NULL when allow RTC power down");
|
||||
#if CONFIG_IDF_TARGET_ESP32S2
|
||||
/* Workaround: In deep sleep, for ESP32S2, Power down the RTC_PERIPH will change the slope configuration of Touch sensor sleep pad.
|
||||
* The configuration change will change the reading of the sleep pad, which will cause the touch wake-up sensor to trigger falsely. */
|
||||
slp_opt = ESP_PD_OPTION_ON;
|
||||
ESP_LOGW(TAG, "Keep the RTC_PERIPH power on in case the false trigger");
|
||||
#endif
|
||||
} else {
|
||||
/* Keep the RTC_PERIPH power domain on in deep sleep */
|
||||
slp_opt = ESP_PD_OPTION_ON;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@ -41,6 +41,7 @@ extern "C" {
|
||||
/**
|
||||
* @brief Helper macro to the default sample configurations
|
||||
* @note This default configuration uses `sample frequency = clock frequency / 1`
|
||||
* This helper macro mostly focus on the final result scaling
|
||||
*
|
||||
* @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
|
||||
@ -57,6 +58,28 @@ extern "C" {
|
||||
.bypass_shield_output = false, \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Helper macro to the default sample configurations
|
||||
* @note This default configuration uses `sample frequency = clock frequency / 1`
|
||||
* This helper macro mostly focus on the sawtooth wave frequency tuning
|
||||
* Recommended for the frequency hopping usage
|
||||
*
|
||||
* @param[in] res The resistance of the RC filter
|
||||
* @param[in] cap The capacitance of the RC filter
|
||||
* @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_CONFIG2(res, cap, coarse_freq_tune, fine_freq_tune) { \
|
||||
.div_num = 8, \
|
||||
.charge_times = 500, \
|
||||
.rc_filter_res = res, \
|
||||
.rc_filter_cap = cap, \
|
||||
.low_drv = fine_freq_tune, \
|
||||
.high_drv = coarse_freq_tune, \
|
||||
.bias_volt = 5, \
|
||||
.bypass_shield_output = false, \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Helper macro to the default filter configurations
|
||||
*
|
||||
@ -122,7 +145,7 @@ typedef struct {
|
||||
*
|
||||
*/
|
||||
typedef struct {
|
||||
uint32_t active_thresh[TOUCH_SAMPLE_CFG_NUM]; /*!< The active threshold of each sample configuration,
|
||||
uint32_t active_thresh[TOUCH_SAMPLE_CFG_NUM]; /*!< The relative active threshold of each sample configuration,
|
||||
* while the touch channel smooth value minus benchmark value exceed this threshold,
|
||||
* will be regarded as activated
|
||||
*/
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@ -17,6 +17,8 @@
|
||||
#include "soc/clk_tree_defs.h"
|
||||
#include "soc/touch_sensor_periph.h"
|
||||
#include "soc/rtc.h"
|
||||
#include "soc/chip_revision.h"
|
||||
#include "hal/efuse_hal.h"
|
||||
#include "hal/hal_utils.h"
|
||||
#include "driver/touch_sens.h"
|
||||
#include "esp_private/rtc_ctrl.h"
|
||||
@ -205,6 +207,9 @@ esp_err_t touch_priv_config_channel(touch_channel_handle_t chan_handle, const to
|
||||
touch_ll_set_chan_active_threshold(chan_handle->id, smp_cfg_id, chan_cfg->active_thresh[smp_cfg_id]);
|
||||
}
|
||||
TOUCH_EXIT_CRITICAL(TOUCH_PERIPH_LOCK);
|
||||
touch_chan_benchmark_config_t bm_cfg = {.do_reset = true};
|
||||
/* Reset the benchmark to overwrite the legacy benchmark during the deep sleep */
|
||||
touch_channel_config_benchmark(chan_handle, &bm_cfg);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
@ -264,13 +269,6 @@ esp_err_t touch_priv_channel_read_data(touch_channel_handle_t chan_handle, touch
|
||||
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 *
|
||||
******************************************************************************/
|
||||
@ -308,6 +306,16 @@ esp_err_t touch_sensor_config_filter(touch_sensor_handle_t sens_handle, const to
|
||||
return ret;
|
||||
}
|
||||
|
||||
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_cfg);
|
||||
if (benchmark_cfg->do_reset) {
|
||||
touch_ll_reset_chan_benchmark(BIT(chan_handle->id));
|
||||
}
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
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);
|
||||
@ -336,6 +344,14 @@ esp_err_t touch_sensor_config_sleep_wakeup(touch_sensor_handle_t sens_handle, co
|
||||
if (sleep_cfg->deep_slp_allow_pd) {
|
||||
ESP_GOTO_ON_FALSE(sleep_cfg->deep_slp_chan, ESP_ERR_INVALID_ARG, err, TAG,
|
||||
"deep sleep waken channel can't be NULL when allow RTC power down");
|
||||
#if CONFIG_IDF_TARGET_ESP32P4
|
||||
/* Due to esp32p4 eco0 hardware bug, if LP peripheral power domain is powerdowned in sleep, there will be a possibility of
|
||||
* triggering the EFUSE_CRC reset, so disable the power-down of this power domain on lightsleep for ECO0 version. */
|
||||
if (!ESP_CHIP_REV_ABOVE(efuse_hal_chip_revision(), 1)) {
|
||||
slp_opt = ESP_PD_OPTION_ON;
|
||||
ESP_LOGW(TAG, "Keep the RTC_PERIPH power on");
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
/* Keep the RTC_PERIPH power domain on in deep sleep */
|
||||
slp_opt = ESP_PD_OPTION_ON;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@ -209,19 +209,6 @@ 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 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_cfg The benchmark configurations
|
||||
* @return
|
||||
* - ESP_OK On success
|
||||
* - ESP_ERR_INVALID_ARG NULL pointer
|
||||
*/
|
||||
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
|
||||
* @note This function can be called no matter the touch sensor controller is enabled or not (i.e. ENABLED or SCANNING state).
|
||||
@ -242,6 +229,21 @@ esp_err_t touch_channel_config_benchmark(touch_channel_handle_t chan_handle, con
|
||||
*/
|
||||
esp_err_t touch_channel_read_data(touch_channel_handle_t chan_handle, touch_chan_data_type_t type, uint32_t *data);
|
||||
|
||||
#if SOC_TOUCH_SUPPORT_BENCHMARK
|
||||
/**
|
||||
* @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_cfg The benchmark configurations
|
||||
* @return
|
||||
* - ESP_OK On success
|
||||
* - ESP_ERR_INVALID_ARG NULL pointer
|
||||
*/
|
||||
esp_err_t touch_channel_config_benchmark(touch_channel_handle_t chan_handle, const touch_chan_benchmark_config_t *benchmark_cfg);
|
||||
#endif // SOC_TOUCH_SUPPORT_BENCHMARK
|
||||
|
||||
#if SOC_TOUCH_SUPPORT_WATERPROOF
|
||||
/**
|
||||
* @brief Configure the touch sensor water proof channels
|
||||
@ -309,6 +311,36 @@ esp_err_t touch_sensor_config_sleep_wakeup(touch_sensor_handle_t sens_handle, co
|
||||
esp_err_t touch_sensor_config_denoise_channel(touch_sensor_handle_t sens_handle, const touch_denoise_chan_config_t *denoise_cfg);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Touch channel information
|
||||
*
|
||||
*/
|
||||
typedef struct {
|
||||
int chan_id; /*!< Touch channel number */
|
||||
int chan_gpio; /*!< Corresponding GPIO of this channel */
|
||||
union {
|
||||
uint32_t abs_active_thresh[TOUCH_SAMPLE_CFG_NUM]; /*!< The configured absolute threshould of this channel (only used for V1) */
|
||||
uint32_t active_thresh[TOUCH_SAMPLE_CFG_NUM]; /*!< The configured relative threshould of this channel (used except V1) */
|
||||
};
|
||||
struct {
|
||||
uint32_t can_wake_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,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@ -16,8 +16,8 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define TOUCH_TOTAL_CHAN_NUM SOC_TOUCH_SENSOR_NUM /*!< The total channel number of the touch sensor */
|
||||
#define TOUCH_SAMPLE_CFG_NUM SOC_TOUCH_SAMPLE_CFG_NUM /*!< The supported max sample configuration number */
|
||||
#define TOUCH_TOTAL_CHAN_NUM SOC_TOUCH_SENSOR_NUM /*!< The total channel number of the touch sensor */
|
||||
#define TOUCH_SAMPLE_CFG_NUM SOC_TOUCH_SAMPLE_CFG_NUM /*!< The supported max sample configuration number */
|
||||
#if SOC_TOUCH_SUPPORT_PROX_SENSING
|
||||
#define TOUCH_PROXIMITY_CHAN_NUM SOC_TOUCH_PROXIMITY_CHANNEL_NUM /*!< The supported proximity channel number in proximity sensing mode */
|
||||
#endif
|
||||
@ -31,8 +31,8 @@ typedef enum {
|
||||
TOUCH_DEEP_SLEEP_WAKEUP, /*!< Enable the touch sensor to wake up the chip from deep sleep or light sleep */
|
||||
} touch_sleep_wakeup_level_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 */
|
||||
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 */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -1,45 +0,0 @@
|
||||
/*
|
||||
* 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 can_wake_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
|
@ -5,6 +5,7 @@ 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_channel_config_benchmark (noflash)
|
||||
touch_sens_version_specific: touch_priv_channel_read_data (noflash)
|
||||
touch_sens_version_specific: touch_priv_config_benchmark (noflash)
|
||||
if SOC_TOUCH_SUPPORT_BENCHMARK = y:
|
||||
touch_sens_common: touch_channel_config_benchmark (noflash)
|
||||
touch_sens_version_specific: touch_priv_config_benchmark (noflash)
|
||||
|
@ -214,7 +214,7 @@ esp_err_t esp_sleep_enable_touchpad_wakeup(void);
|
||||
*
|
||||
* @return touch pad which caused wakeup
|
||||
*/
|
||||
touch_pad_t esp_sleep_get_touchpad_wakeup_status(void);
|
||||
int esp_sleep_get_touchpad_wakeup_status(void);
|
||||
#endif // SOC_TOUCH_SENSOR_SUPPORTED
|
||||
|
||||
/**
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@ -63,7 +63,6 @@
|
||||
#include "hal/wdt_hal.h"
|
||||
#include "hal/uart_hal.h"
|
||||
#if SOC_TOUCH_SENSOR_SUPPORTED
|
||||
#include "hal/touch_sensor_hal.h"
|
||||
#include "hal/touch_sens_hal.h"
|
||||
#endif
|
||||
#include "hal/mspi_ll.h"
|
||||
@ -304,7 +303,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_VERSION >= 2
|
||||
#if SOC_TOUCH_SENSOR_SUPPORTED
|
||||
static void touch_wakeup_prepare(void);
|
||||
#endif
|
||||
#if SOC_GPIO_SUPPORT_DEEPSLEEP_WAKEUP && SOC_DEEP_SLEEP_SUPPORTED
|
||||
@ -877,7 +876,7 @@ static esp_err_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags, esp_sleep_mode_t m
|
||||
|
||||
misc_modules_sleep_prepare(pd_flags, deep_sleep);
|
||||
|
||||
#if SOC_TOUCH_SENSOR_VERSION >= 2
|
||||
#if SOC_TOUCH_SENSOR_SUPPORTED
|
||||
bool keep_rtc_power_on = false;
|
||||
if (deep_sleep) {
|
||||
if (s_config.wakeup_triggers & RTC_TOUCH_TRIG_EN) {
|
||||
@ -1733,14 +1732,11 @@ static esp_err_t timer_wakeup_prepare(int64_t sleep_duration)
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
#if SOC_TOUCH_SENSOR_VERSION >= 2
|
||||
#if SOC_TOUCH_SENSOR_SUPPORTED
|
||||
static void touch_wakeup_prepare(void)
|
||||
{
|
||||
touch_hal_prepare_deep_sleep();
|
||||
}
|
||||
#endif
|
||||
|
||||
#if SOC_TOUCH_SENSOR_SUPPORTED
|
||||
|
||||
esp_err_t esp_sleep_enable_touchpad_wakeup(void)
|
||||
{
|
||||
@ -1759,18 +1755,18 @@ esp_err_t esp_sleep_enable_touchpad_wakeup(void)
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
touch_pad_t esp_sleep_get_touchpad_wakeup_status(void)
|
||||
int esp_sleep_get_touchpad_wakeup_status(void)
|
||||
{
|
||||
if (esp_sleep_get_wakeup_cause() != ESP_SLEEP_WAKEUP_TOUCHPAD) {
|
||||
return TOUCH_PAD_MAX;
|
||||
return -1;
|
||||
}
|
||||
touch_pad_t pad_num;
|
||||
#if SOC_TOUCH_SENSOR_VERSION == 3
|
||||
touch_ll_sleep_get_channel_num((uint32_t *)(&pad_num));
|
||||
uint32_t chan_num;
|
||||
#if SOC_TOUCH_SENSOR_VERSION == 1
|
||||
touch_ll_get_active_channel_mask(&chan_num);
|
||||
#else
|
||||
touch_hal_get_wakeup_status(&pad_num);
|
||||
touch_ll_sleep_get_channel_num(&chan_num);
|
||||
#endif
|
||||
return pad_num;
|
||||
return (int)chan_num;
|
||||
}
|
||||
|
||||
#endif // SOC_TOUCH_SENSOR_SUPPORTED
|
||||
|
@ -283,15 +283,13 @@ if(NOT BOOTLOADER_BUILD AND NOT esp_tee_build)
|
||||
endif()
|
||||
|
||||
if(CONFIG_SOC_TOUCH_SENSOR_SUPPORTED)
|
||||
# Source files for legacy touch driver
|
||||
# Source files for the legacy touch hal driver
|
||||
if(CONFIG_SOC_TOUCH_SENSOR_VERSION LESS 3)
|
||||
list(APPEND srcs "${target}/touch_sensor_hal.c")
|
||||
list(APPEND srcs "touch_sensor_hal.c")
|
||||
endif()
|
||||
# Source files for touch driver-ng (currently only support ver2 & ver3)
|
||||
if(CONFIG_SOC_TOUCH_SENSOR_VERSION GREATER 1)
|
||||
list(APPEND srcs "touch_sens_hal.c")
|
||||
endif()
|
||||
# Source files for the new touch hal driver
|
||||
list(APPEND srcs "touch_sens_hal.c")
|
||||
endif()
|
||||
|
||||
if(${target} STREQUAL "esp32")
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@ -17,12 +17,13 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
#include "hal/misc.h"
|
||||
#include "hal/assert.h"
|
||||
#include "soc/touch_sensor_periph.h"
|
||||
#include "soc/sens_struct.h"
|
||||
#include "soc/rtc_io_struct.h"
|
||||
#include "soc/rtc_cntl_struct.h"
|
||||
#include "hal/touch_sensor_legacy_types.h"
|
||||
|
||||
#include "soc/soc_caps.h"
|
||||
#include "hal/touch_sens_types.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@ -30,9 +31,413 @@ extern "C" {
|
||||
|
||||
//Some register bits of touch sensor 8 and 9 are mismatched, we need to swap the bits.
|
||||
#define TOUCH_LL_BIT_SWAP(data, n, m) (((data >> n) & 0x1) == ((data >> m) & 0x1) ? (data) : ((data) ^ ((0x1 <<n) | (0x1 << m))))
|
||||
#define TOUCH_LL_BITS_SWAP(v) TOUCH_LL_BIT_SWAP(v, TOUCH_PAD_NUM8, TOUCH_PAD_NUM9)
|
||||
#define TOUCH_LL_BITS_SWAP(v) TOUCH_LL_BIT_SWAP(v, 8, 9)
|
||||
#define TOUCH_LL_CHAN_SWAP(chan) ((chan) == 8 ? 9 : ((chan) == 9 ? 8 : (chan)))
|
||||
#define TOUCH_LL_FULL_CHANNEL_MASK ((uint16_t)((1U << SOC_TOUCH_SENSOR_NUM) - 1))
|
||||
#define TOUCH_LL_READ_RAW 0x0
|
||||
|
||||
#define TOUCH_LL_PAD_MEASURE_WAIT_MAX (0xFF) /*!<The timer frequency is 8Mhz, the max value is 0xff */
|
||||
#define TOUCH_LL_CHARGE_DURATION_MAX (0xFFFF)
|
||||
#define TOUCH_LL_PAD_MEASURE_WAIT_MAX (0xFF) // The timer frequency is 8Mhz, the max value is 0xff
|
||||
#define TOUCH_LL_ACTIVE_THRESH_MAX (0xFFFF) // Max channel active threshold
|
||||
|
||||
#define TOUCH_LL_INTR_MASK_TRIGGER (1UL << 6) // Interrupt when the touch interrupt is triggered (depends on intr trigger mode)
|
||||
#define TOUCH_LL_INTR_MASK_ALL (TOUCH_LL_INTR_MASK_TRIGGER)
|
||||
|
||||
/*********************************** Interrupts *******************************/
|
||||
/**
|
||||
* Enable touch sensor interrupt by bitmask.
|
||||
*
|
||||
* @param int_mask interrupt mask
|
||||
*/
|
||||
static inline void touch_ll_interrupt_enable(uint32_t int_mask)
|
||||
{
|
||||
(void) int_mask;
|
||||
// Only one interrupt, set directly
|
||||
RTCCNTL.int_ena.rtc_touch = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable touch sensor interrupt by bitmask.
|
||||
*
|
||||
* @param int_mask interrupt mask
|
||||
*/
|
||||
static inline void touch_ll_interrupt_disable(uint32_t int_mask)
|
||||
{
|
||||
(void) int_mask;
|
||||
// Only one interrupt, clear directly
|
||||
RTCCNTL.int_ena.rtc_touch = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear touch sensor interrupt by bitmask.
|
||||
*
|
||||
* @param int_mask Pad mask to clear interrupts
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void touch_ll_interrupt_clear(uint32_t int_mask)
|
||||
{
|
||||
(void) int_mask;
|
||||
RTCCNTL.int_clr.rtc_touch = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the bitmask of touch sensor interrupt status.
|
||||
*
|
||||
* @return type interrupt type
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline uint32_t touch_ll_get_intr_status_mask(void)
|
||||
{
|
||||
// intr status bit of touch (bit7) is not same as the enable bit (bit6)
|
||||
return RTCCNTL.int_st.rtc_touch ? TOUCH_LL_INTR_MASK_TRIGGER : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set touch sensor interrupt trigger mode.
|
||||
* Interrupt can be triggered either when touch value is below the threshold (touched) or
|
||||
* or when touch value exceed the threshold (release).
|
||||
*
|
||||
* @param mode Touch sensor interrupt trigger mode.
|
||||
* - TOUCH_INTR_TRIG_ON_BELOW_THRESH: interrupt triggers when touched (touch value is below the threshold)
|
||||
* - TOUCH_INTR_TRIG_ON_ABOVE_THRESH: interrupt triggers when released (touch value is exceed the threshold)
|
||||
*/
|
||||
static inline void touch_ll_set_intr_trigger_mode(touch_intr_trig_mode_t mode)
|
||||
{
|
||||
SENS.sar_touch_ctrl1.touch_out_sel = mode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set touch sensor interrupt trigger source. There are two sets of touch signals.
|
||||
* Set1 and set2 can be mapped to several touch signals. Either set will be triggered
|
||||
* if at least one of its touch signal is 'touched'. The interrupt can be configured to be generated
|
||||
* if set1 is triggered, or only if both sets are triggered.
|
||||
*
|
||||
* @param group Touch sensor interrupt trigger group.
|
||||
*/
|
||||
static inline void touch_ll_set_intr_trigger_group(touch_intr_trig_group_t group)
|
||||
{
|
||||
SENS.sar_touch_ctrl1.touch_out_1en = group;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set touch sensor group mask.
|
||||
* Touch pad module has two sets of signals, 'Touched' signal is triggered only if
|
||||
* at least one of touch pad in this group is "touched".
|
||||
* This function will set the register bits according to the given bitmask.
|
||||
*
|
||||
* @param group1_mask bitmask of touch sensor signal group1, it's a 10-bit value
|
||||
* @param group2_mask bitmask of touch sensor signal group2, it's a 10-bit value
|
||||
*/
|
||||
static inline void touch_ll_config_trigger_group1(uint32_t touch_num, bool enable)
|
||||
{
|
||||
touch_num = TOUCH_LL_CHAN_SWAP(touch_num);
|
||||
uint32_t mask = SENS.sar_touch_enable.touch_pad_outen1;
|
||||
if (enable) {
|
||||
mask |= (1 << touch_num);
|
||||
} else {
|
||||
mask &= ~(1 << touch_num);
|
||||
}
|
||||
SENS.sar_touch_enable.touch_pad_outen1 = mask;
|
||||
}
|
||||
|
||||
static inline void touch_ll_config_trigger_group2(uint32_t touch_num, bool enable)
|
||||
{
|
||||
touch_num = TOUCH_LL_CHAN_SWAP(touch_num);
|
||||
uint32_t mask = SENS.sar_touch_enable.touch_pad_outen2;
|
||||
if (enable) {
|
||||
mask |= (1 << touch_num);
|
||||
} else {
|
||||
mask &= ~(1 << touch_num);
|
||||
}
|
||||
SENS.sar_touch_enable.touch_pad_outen2 = mask;
|
||||
}
|
||||
|
||||
static inline void touch_ll_reset_trigger_groups(void)
|
||||
{
|
||||
SENS.sar_touch_enable.touch_pad_outen1 = 0;
|
||||
SENS.sar_touch_enable.touch_pad_outen2 = 0;
|
||||
}
|
||||
|
||||
/********************************* Status Info ********************************/
|
||||
/**
|
||||
* Get touch sensor measure status. No block.
|
||||
*
|
||||
* @return
|
||||
* - If touch sensors measure done.
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline bool touch_ll_is_measure_done(void)
|
||||
{
|
||||
return (bool)SENS.sar_touch_ctrl2.touch_meas_done;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the touch sensor active channel mask, usually used in ISR to decide which channels are 'touched'.
|
||||
*
|
||||
* @param active_mask The touch channel status. e.g. Touch1 trigger status is `status_mask & (BIT1)`.
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void touch_ll_get_active_channel_mask(uint32_t *active_mask)
|
||||
{
|
||||
*active_mask = TOUCH_LL_BITS_SWAP(SENS.sar_touch_ctrl2.touch_meas_en);
|
||||
}
|
||||
|
||||
/**************************** Measurement Configuration ***********************/
|
||||
|
||||
/**
|
||||
* Set touch sensor threshold of charge cycles that triggers pad active state.
|
||||
* The threshold determines the sensitivity of the touch sensor.
|
||||
* The threshold is the original value of the trigger state minus the benchmark value.
|
||||
*
|
||||
* @note If set "TOUCH_PAD_THRESHOLD_MAX", the touch is never be triggered.
|
||||
* @param touch_num The touch pad id
|
||||
* @param thresh The threshold of charge cycles
|
||||
*/
|
||||
static inline void touch_ll_set_chan_active_threshold(uint32_t touch_num, uint32_t thresh)
|
||||
{
|
||||
// Workaround: swap chan 8 and chan 9
|
||||
touch_num = TOUCH_LL_CHAN_SWAP(touch_num);
|
||||
if (touch_num & 0x1) {
|
||||
HAL_FORCE_MODIFY_U32_REG_FIELD(SENS.touch_thresh[touch_num >> 1], l_thresh, thresh);
|
||||
} else {
|
||||
HAL_FORCE_MODIFY_U32_REG_FIELD(SENS.touch_thresh[touch_num >> 1], h_thresh, thresh);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get touch sensor threshold of charge cycles that triggers pad active state.
|
||||
* The threshold determines the sensitivity of the touch sensor.
|
||||
* The threshold is the original value of the trigger state minus the benchmark value.
|
||||
*
|
||||
* @note If set "TOUCH_PAD_THRESHOLD_MAX", the touch is never be triggered.
|
||||
* @param touch_num The touch pad id
|
||||
* @return
|
||||
* - The threshold of charge cycles
|
||||
*/
|
||||
static inline uint32_t touch_ll_get_chan_active_threshold(uint32_t touch_num)
|
||||
{
|
||||
// Workaround: swap chan 8 and chan 9
|
||||
touch_num = TOUCH_LL_CHAN_SWAP(touch_num);
|
||||
if (touch_num & 0x1) {
|
||||
return HAL_FORCE_READ_U32_REG_FIELD(SENS.touch_thresh[touch_num >> 1], l_thresh);
|
||||
} else {
|
||||
return HAL_FORCE_READ_U32_REG_FIELD(SENS.touch_thresh[touch_num >> 1], h_thresh);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the power on wait cycle
|
||||
*
|
||||
* @param wait_cycles
|
||||
*/
|
||||
static inline void touch_ll_set_power_on_wait_cycle(uint32_t wait_cycles)
|
||||
{
|
||||
//the waiting cycles (in 8MHz) between TOUCH_START and TOUCH_XPD
|
||||
HAL_FORCE_MODIFY_U32_REG_FIELD(SENS.sar_touch_ctrl1, touch_xpd_wait, wait_cycles); //wait volt stable
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the duration of the charge window
|
||||
*
|
||||
* @param duration The duration of the touch channel charge / discharge window.
|
||||
* duration = meas_ticks / (8MHz), the maximum duration is 0xffff / 8M = 8.19 ms.
|
||||
*/
|
||||
static inline void touch_ll_set_charge_window_duration(uint32_t duration)
|
||||
{
|
||||
//touch sensor charge/discharge window duration= meas_cycle / 8Mhz
|
||||
HAL_FORCE_MODIFY_U32_REG_FIELD(SENS.sar_touch_ctrl1, touch_meas_delay, duration);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set touch sensor sleep time.
|
||||
*
|
||||
* @param interval_ticks The touch sensor will sleep for some cycles after each measurement.
|
||||
* interval_ticks decide the interval between each measurement.
|
||||
* t_sleep = interval_ticks / (RTC_SLOW_CLK frequency).
|
||||
* The approximate frequency value of RTC_SLOW_CLK can be obtained using rtc_clk_slow_freq_get_hz function.
|
||||
*/
|
||||
static inline void touch_ll_set_measure_interval_ticks(uint16_t interval_ticks)
|
||||
{
|
||||
//touch sensor sleep cycle Time = sleep_cycle / RTC_SLOW_CLK
|
||||
HAL_FORCE_MODIFY_U32_REG_FIELD(SENS.sar_touch_ctrl2, touch_sleep_cycles, interval_ticks);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the Touch pad charge speed.
|
||||
*
|
||||
* @param touch_num Touch channel number
|
||||
* @param charge_speed Charge speed of this touch channel
|
||||
*/
|
||||
static inline void touch_ll_set_charge_speed(uint32_t touch_num, touch_charge_speed_t charge_speed)
|
||||
{
|
||||
RTCIO.touch_pad[touch_num].dac = charge_speed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the upper limitation of the touch channel voltage while charging
|
||||
*
|
||||
* @param high_lim The high(upper) limitation of charge
|
||||
*/
|
||||
static inline void touch_ll_set_charge_voltage_high_limit(touch_volt_lim_h_t high_lim)
|
||||
{
|
||||
RTCIO.touch_cfg.drefh = (uint32_t)high_lim & 0x3;
|
||||
RTCIO.touch_cfg.drange = (uint32_t)high_lim >> 2;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the lower limitation of the touch channel voltage while discharging
|
||||
*
|
||||
* @param low_lim The lower limitation of discharge
|
||||
*/
|
||||
static inline void touch_ll_set_charge_voltage_low_limit(touch_volt_lim_l_t low_lim)
|
||||
{
|
||||
RTCIO.touch_cfg.drefl = low_lim;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the initial charge voltage of touch channel
|
||||
* i.e., the touch pad measurement start from a low voltage or a high voltage
|
||||
*
|
||||
* @param touch_num Touch channel number
|
||||
* @param init_charge_volt The initial charge voltage
|
||||
*/
|
||||
static inline void touch_ll_set_init_charge_voltage(uint32_t touch_num, touch_init_charge_volt_t init_charge_volt)
|
||||
{
|
||||
// Workaround: swap chan 8 and chan 9
|
||||
touch_num = TOUCH_LL_CHAN_SWAP(touch_num);
|
||||
RTCIO.touch_pad[touch_num].tie_opt = init_charge_volt;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable touch sensor channel. Register touch channel into touch sensor measurement group.
|
||||
* The working mode of the touch sensor is simultaneous measurement.
|
||||
* This function will set the measure bits according to the given bitmask.
|
||||
*
|
||||
* @note If set this mask, the FSM timer should be stop firstly.
|
||||
* @note The touch sensor that in scan map, should be deinit GPIO function firstly.
|
||||
* @param enable_mask bitmask of touch sensor scan group.
|
||||
* e.g. TOUCH_PAD_NUM1 -> BIT(1)
|
||||
* @return
|
||||
* - ESP_OK on success
|
||||
*/
|
||||
static inline void touch_ll_enable_channel_mask(uint16_t enable_mask)
|
||||
{
|
||||
SENS.sar_touch_enable.touch_pad_worken = enable_mask;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear all touch sensor channels active status.
|
||||
*
|
||||
* @note Generally no manual removal is required.
|
||||
*/
|
||||
static inline void touch_ll_clear_active_channel_status(void)
|
||||
{
|
||||
SENS.sar_touch_ctrl2.touch_meas_en_clr = 1;
|
||||
}
|
||||
|
||||
/********************************* FSM Operation ******************************/
|
||||
/**
|
||||
* Enable touch sensor FSM timer trigger (continuous) mode or software trigger (oneshot) mode.
|
||||
*
|
||||
* @param enable Enable FSM timer mode.
|
||||
* True: the FSM will trigger scanning repeatedly under the control of the hardware timer (continuous mode)
|
||||
* False: the FSM will trigger scanning once under the control of the software (continuous mode)
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void touch_ll_enable_fsm_timer(bool enable)
|
||||
{
|
||||
SENS.sar_touch_ctrl2.touch_start_force = !enable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Start touch sensor FSM timer to run FSM repeatedly
|
||||
* The measurement action can be triggered by the hardware timer, as well as by the software instruction.
|
||||
* @note
|
||||
* The timer should be triggered
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void touch_ll_start_fsm_repeated_timer(void)
|
||||
{
|
||||
RTCCNTL.state0.touch_slp_timer_en = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Stop touch sensor FSM timer.
|
||||
* The measurement action can be triggered by the hardware timer, as well as by the software instruction.
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void touch_ll_stop_fsm_repeated_timer(void)
|
||||
{
|
||||
RTCCNTL.state0.touch_slp_timer_en = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is the FSM repeated timer enabled.
|
||||
* @note when the timer is enabled, RTC clock should not be power down
|
||||
*
|
||||
* @return
|
||||
* - true: enabled
|
||||
* - false: disabled
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline bool touch_ll_is_fsm_repeated_timer_enabled(void)
|
||||
{
|
||||
return (bool)RTCCNTL.state0.touch_slp_timer_en;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Enable the touch sensor FSM start signal from software
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void touch_ll_trigger_oneshot_measurement(void)
|
||||
{
|
||||
SENS.sar_touch_ctrl2.touch_start_en = 1;
|
||||
SENS.sar_touch_ctrl2.touch_start_en = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Power on the channel by mask
|
||||
*
|
||||
* @param chan_mask The channel mask that needs to power on
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void touch_ll_channel_sw_measure_mask(uint16_t chan_mask)
|
||||
{
|
||||
(void) chan_mask;
|
||||
// Only for compatibility
|
||||
}
|
||||
|
||||
/************************************** Data **********************************/
|
||||
/**
|
||||
* Get the data of the touch channel according to the types
|
||||
*
|
||||
* @param touch_num touch pad index
|
||||
* @param type data type
|
||||
* 0/1: TOUCH_LL_READ_RAW, raw data of touch channel
|
||||
* 2: TOUCH_LL_READ_BENCHMARK, benchmark value of touch channel,
|
||||
* the benchmark value is the maximum during the first measurement period
|
||||
* 3: TOUCH_LL_READ_SMOOTH, the smoothed data that obtained by filtering the raw data.
|
||||
* @param data pointer to the data
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void touch_ll_read_chan_data(uint32_t touch_num, uint8_t type, uint32_t *data)
|
||||
{
|
||||
HAL_ASSERT(type == TOUCH_LL_READ_RAW);
|
||||
HAL_ASSERT(touch_num < SOC_TOUCH_SENSOR_NUM);
|
||||
touch_num = TOUCH_LL_CHAN_SWAP(touch_num);
|
||||
if (touch_num & 0x1) {
|
||||
*data = HAL_FORCE_READ_U32_REG_FIELD(SENS.touch_meas[touch_num >> 1], l_val);
|
||||
} else {
|
||||
*data = HAL_FORCE_READ_U32_REG_FIELD(SENS.touch_meas[touch_num >> 1], h_val);
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
/* Legacy APIs (to be removed in esp-idf v6.0) */
|
||||
/******************************************************************************/
|
||||
|
||||
#include "hal/touch_sensor_legacy_types.h"
|
||||
|
||||
/**
|
||||
* Swap the number of touch8 and touch9.
|
||||
@ -493,18 +898,6 @@ static inline uint32_t touch_ll_read_raw_data(touch_pad_t touch_num)
|
||||
HAL_FORCE_READ_U32_REG_FIELD(SENS.touch_meas[tp_wrap / 2], h_val));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get touch sensor measure status. No block.
|
||||
*
|
||||
* @return
|
||||
* - If touch sensors measure done.
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline bool touch_ll_is_measure_done(void)
|
||||
{
|
||||
return (bool)SENS.sar_touch_ctrl2.touch_meas_done;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@ -283,6 +283,24 @@ static inline void touch_ll_set_chan_active_threshold(uint32_t touch_num, uint8_
|
||||
HAL_FORCE_MODIFY_U32_REG_FIELD(LP_ANA_PERI.touch_padx_thn[touch_num + 1].thresh[sample_cfg_id], threshold, thresh); // codespell:ignore
|
||||
}
|
||||
|
||||
/**
|
||||
* Get touch sensor threshold of charge cycles that triggers pad active state.
|
||||
* The threshold determines the sensitivity of the touch sensor.
|
||||
* The threshold is the original value of the trigger state minus the benchmark value.
|
||||
*
|
||||
* @note If set "TOUCH_PAD_THRESHOLD_MAX", the touch is never be triggered.
|
||||
* @param touch_num The touch pad id
|
||||
* @param sample_cfg_id The sample configuration index
|
||||
* @return
|
||||
* - The threshold of charge cycles
|
||||
*/
|
||||
static inline uint32_t touch_ll_get_chan_active_threshold(uint32_t touch_num, uint8_t sample_cfg_id)
|
||||
{
|
||||
HAL_ASSERT(sample_cfg_id < SOC_TOUCH_SAMPLE_CFG_NUM);
|
||||
// Channel shift workaround
|
||||
return HAL_FORCE_READ_U32_REG_FIELD(LP_ANA_PERI.touch_padx_thn[touch_num + 1].thresh[sample_cfg_id], threshold); // codespell:ignore
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable or disable the channel that will be scanned.
|
||||
* @note The shield channel should not be enabled to scan here
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@ -200,6 +200,22 @@ static inline void touch_ll_set_chan_active_threshold(uint32_t touch_num, uint32
|
||||
SENS.touch_thresh[touch_num - 1].thresh = thresh;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get touch sensor threshold of charge cycles that triggers pad active state.
|
||||
* The threshold determines the sensitivity of the touch sensor.
|
||||
* The threshold is the original value of the trigger state minus the benchmark value.
|
||||
*
|
||||
* @note If set "TOUCH_PAD_THRESHOLD_MAX", the touch is never be triggered.
|
||||
* @param touch_num The touch pad id
|
||||
* @return
|
||||
* - The threshold of charge cycles
|
||||
*/
|
||||
static inline uint32_t touch_ll_get_chan_active_threshold(uint32_t touch_num)
|
||||
{
|
||||
HAL_ASSERT(touch_num > 0);
|
||||
return SENS.touch_thresh[touch_num - 1].thresh;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the power on wait cycle
|
||||
*
|
||||
@ -599,6 +615,17 @@ static inline void touch_ll_sleep_set_channel_num(uint32_t touch_num)
|
||||
RTCCNTL.touch_slp_thres.touch_slp_pad = touch_num;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get touch channel number for sleep pad.
|
||||
*
|
||||
* @note Only one touch sensor channel is supported in deep sleep mode.
|
||||
* @param touch_num Touch sensor channel number.
|
||||
*/
|
||||
static inline void touch_ll_sleep_get_channel_num(uint32_t *touch_num)
|
||||
{
|
||||
*touch_num = RTCCNTL.touch_slp_thres.touch_slp_pad;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable proximity sensing function for sleep channel.
|
||||
*/
|
||||
@ -1609,16 +1636,6 @@ static inline bool touch_ll_proximity_pad_check(touch_pad_t touch_num)
|
||||
}
|
||||
|
||||
/************** sleep pad setting ***********************/
|
||||
/**
|
||||
* Get touch channel number for sleep pad.
|
||||
*
|
||||
* @note Only one touch sensor channel is supported in deep sleep mode.
|
||||
* @param touch_num Touch sensor channel number.
|
||||
*/
|
||||
static inline void touch_ll_sleep_get_channel_num(touch_pad_t *touch_num)
|
||||
{
|
||||
*touch_num = (touch_pad_t)(RTCCNTL.touch_slp_thres.touch_slp_pad);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the trigger threshold of touch sensor in deep sleep.
|
||||
|
@ -151,7 +151,7 @@ void touch_hal_sleep_channel_enable(touch_pad_t pad_num, bool enable)
|
||||
|
||||
void touch_hal_sleep_channel_get_config(touch_pad_sleep_channel_t *slp_config)
|
||||
{
|
||||
touch_ll_sleep_get_channel_num(&slp_config->touch_num);
|
||||
touch_ll_sleep_get_channel_num((uint32_t *)&slp_config->touch_num);
|
||||
slp_config->en_proximity = touch_ll_sleep_is_proximity_enabled();
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@ -195,6 +195,22 @@ static inline void touch_ll_set_chan_active_threshold(uint32_t touch_num, uint32
|
||||
SENS.touch_thresh[touch_num - 1].thresh = thresh;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get touch sensor threshold of charge cycles that triggers pad active state.
|
||||
* The threshold determines the sensitivity of the touch sensor.
|
||||
* The threshold is the original value of the trigger state minus the benchmark value.
|
||||
*
|
||||
* @note If set "TOUCH_PAD_THRESHOLD_MAX", the touch is never be triggered.
|
||||
* @param touch_num The touch pad id
|
||||
* @return
|
||||
* - The threshold of charge cycles
|
||||
*/
|
||||
static inline uint32_t touch_ll_get_chan_active_threshold(uint32_t touch_num)
|
||||
{
|
||||
HAL_ASSERT(touch_num > 0);
|
||||
return SENS.touch_thresh[touch_num - 1].thresh;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the power on wait cycle
|
||||
*
|
||||
@ -609,6 +625,17 @@ static inline void touch_ll_sleep_set_channel_num(uint32_t touch_num)
|
||||
RTCCNTL.touch_slp_thres.touch_slp_pad = touch_num;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get touch channel number for sleep pad.
|
||||
*
|
||||
* @note Only one touch sensor channel is supported in deep sleep mode.
|
||||
* @param touch_num Touch sensor channel number.
|
||||
*/
|
||||
static inline void touch_ll_sleep_get_channel_num(uint32_t *touch_num)
|
||||
{
|
||||
*touch_num = RTCCNTL.touch_slp_thres.touch_slp_pad;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable proximity sensing function for sleep channel.
|
||||
*/
|
||||
@ -1646,17 +1673,6 @@ static inline bool touch_ll_proximity_pad_check(touch_pad_t touch_num)
|
||||
}
|
||||
|
||||
/************** sleep pad setting ***********************/
|
||||
/**
|
||||
* Get touch channel number for sleep pad.
|
||||
*
|
||||
* @note Only one touch sensor channel is supported in deep sleep mode.
|
||||
* @param touch_num Touch sensor channel number.
|
||||
*/
|
||||
static inline void touch_ll_sleep_get_channel_num(touch_pad_t *touch_num)
|
||||
{
|
||||
*touch_num = (touch_pad_t)(RTCCNTL.touch_slp_thres.touch_slp_pad);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the trigger threshold of touch sensor in deep sleep.
|
||||
* The threshold determines the sensitivity of the touch sensor.
|
||||
|
@ -152,7 +152,7 @@ void touch_hal_sleep_channel_enable(touch_pad_t pad_num, bool enable)
|
||||
|
||||
void touch_hal_sleep_channel_get_config(touch_pad_sleep_channel_t *slp_config)
|
||||
{
|
||||
touch_ll_sleep_get_channel_num(&slp_config->touch_num);
|
||||
touch_ll_sleep_get_channel_num((uint32_t *)&slp_config->touch_num);
|
||||
slp_config->en_proximity = touch_ll_sleep_is_proximity_enabled();
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@ -14,7 +14,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "soc/soc_caps.h"
|
||||
#if SOC_TOUCH_SENSOR_VERSION > 1
|
||||
#if SOC_TOUCH_SENSOR_SUPPORTED
|
||||
#include "hal/touch_sensor_ll.h"
|
||||
#include "hal/touch_sens_types.h"
|
||||
#endif // SOC_TOUCH_SENSOR_SUPPORTED
|
||||
@ -22,10 +22,23 @@
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#if SOC_TOUCH_SENSOR_SUPPORTED
|
||||
#if SOC_TOUCH_SENSOR_VERSION == 1
|
||||
/**
|
||||
* @brief Sample configurations of the touch sensor V1
|
||||
*/
|
||||
typedef struct {
|
||||
uint32_t charge_duration_ticks;
|
||||
touch_volt_lim_h_t charge_volt_lim_h; /*!< The upper voltage limit while charging a touch pad. i.e., the touch controller won't charge the touch pad higher than this high voltage limitation. */
|
||||
touch_volt_lim_l_t charge_volt_lim_l; /*!< The lower voltage limit while discharging a touch pad. i.e., the touch controller won't discharge the touch pad lower than this low voltage limitation. */
|
||||
} touch_hal_sample_config_v1_t;
|
||||
|
||||
#if SOC_TOUCH_SENSOR_VERSION > 1
|
||||
/**
|
||||
* @brief Alias of touch_hal_sample_config_v1_t for compatibility
|
||||
*/
|
||||
typedef touch_hal_sample_config_v1_t touch_hal_sample_config_t;
|
||||
|
||||
#if SOC_TOUCH_SENSOR_VERSION == 2
|
||||
#elif SOC_TOUCH_SENSOR_VERSION == 2
|
||||
|
||||
/**
|
||||
* @brief Sample configurations of the touch sensor V2
|
||||
@ -68,6 +81,7 @@ typedef touch_hal_sample_config_v3_t touch_hal_sample_config_t;
|
||||
|
||||
#else
|
||||
#error "Unsupported touch sensor version"
|
||||
typedef int touch_hal_sample_config_t;
|
||||
#endif
|
||||
|
||||
/**
|
||||
@ -77,11 +91,19 @@ typedef touch_hal_sample_config_v3_t touch_hal_sample_config_t;
|
||||
typedef struct {
|
||||
uint32_t power_on_wait_ticks; /*!< The waiting time between the channels power on and able to measure, to ensure the data stability */
|
||||
uint32_t meas_interval_ticks; /*!< Measurement interval of each channels */ // TODO: Test the supported range
|
||||
#if SOC_TOUCH_SENSOR_VERSION == 1
|
||||
touch_intr_trig_mode_t intr_trig_mode;
|
||||
touch_intr_trig_group_t intr_trig_group;
|
||||
#elif SOC_TOUCH_SENSOR_VERSION == 2
|
||||
uint32_t timeout_ticks; /*!< 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 the sample configurations below.
|
||||
*/
|
||||
#elif SOC_TOUCH_SENSOR_VERSION == 3
|
||||
uint32_t timeout_ticks; /*!< 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 the sample configurations below.
|
||||
*/
|
||||
#if SOC_TOUCH_SENSOR_VERSION == 3
|
||||
touch_out_mode_t output_mode; /*!< Touch channel counting mode of the binarized touch output */
|
||||
#endif // SOC_TOUCH_SENSOR_VERSION == 3
|
||||
uint32_t sample_cfg_num; /*!< The sample configuration number that used for sampling */
|
||||
@ -99,7 +121,7 @@ void touch_hal_config_controller(const touch_hal_config_t *cfg);
|
||||
* @brief Save the touch sensor hardware configuration
|
||||
* @note The saved configurations will be applied before entering deep sleep
|
||||
*
|
||||
* @param[in] deep_slp_chan The touch sensor channel that can wake-up the chip from deep sleep
|
||||
* @param[in] deep_slp_chan The touch sensor channel that can wake-up the chip from deep sleep, -1 means all enabled channel can wakeup
|
||||
* @param[in] deep_slp_cfg The hardware configuration that takes effect during the deep sleep
|
||||
* @param[in] dslp_allow_pd Whether allow RTC_PERIPH domain power down during the deep sleep
|
||||
*/
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@ -59,79 +59,79 @@ typedef enum {
|
||||
* @brief Touch sensor upper charging voltage limit
|
||||
*/
|
||||
typedef enum {
|
||||
TOUCH_VOLT_LIM_H_0V9, /*!< Touch sensor upper voltage limit is 0.9V while charging a touch pad */
|
||||
TOUCH_VOLT_LIM_H_1V0, /*!< Touch sensor upper voltage limit is 1.0V while charging a touch pad */
|
||||
TOUCH_VOLT_LIM_H_1V1, /*!< Touch sensor upper voltage limit is 1.1V while charging a touch pad */
|
||||
TOUCH_VOLT_LIM_H_1V2, /*!< Touch sensor upper voltage limit is 1.2V while charging a touch pad */
|
||||
TOUCH_VOLT_LIM_H_0V9, /*!< Touch sensor upper voltage limit is 0.9V while charging a touch pad */
|
||||
TOUCH_VOLT_LIM_H_1V0, /*!< Touch sensor upper voltage limit is 1.0V while charging a touch pad */
|
||||
TOUCH_VOLT_LIM_H_1V1, /*!< Touch sensor upper voltage limit is 1.1V while charging a touch pad */
|
||||
TOUCH_VOLT_LIM_H_1V2, /*!< Touch sensor upper voltage limit is 1.2V while charging a touch pad */
|
||||
// No 1V3
|
||||
TOUCH_VOLT_LIM_H_1V4, /*!< Touch sensor upper voltage limit is 1.4V while charging a touch pad */
|
||||
TOUCH_VOLT_LIM_H_1V5, /*!< Touch sensor upper voltage limit is 1.5V while charging a touch pad */
|
||||
TOUCH_VOLT_LIM_H_1V6, /*!< Touch sensor upper voltage limit is 1.6V while charging a touch pad */
|
||||
TOUCH_VOLT_LIM_H_1V7, /*!< Touch sensor upper voltage limit is 1.7V while charging a touch pad */
|
||||
TOUCH_VOLT_LIM_H_1V4, /*!< Touch sensor upper voltage limit is 1.4V while charging a touch pad */
|
||||
TOUCH_VOLT_LIM_H_1V5, /*!< Touch sensor upper voltage limit is 1.5V while charging a touch pad */
|
||||
TOUCH_VOLT_LIM_H_1V6, /*!< Touch sensor upper voltage limit is 1.6V while charging a touch pad */
|
||||
TOUCH_VOLT_LIM_H_1V7, /*!< Touch sensor upper voltage limit is 1.7V while charging a touch pad */
|
||||
// No 1V8
|
||||
TOUCH_VOLT_LIM_H_1V9, /*!< Touch sensor upper voltage limit is 1.9V while charging a touch pad */
|
||||
TOUCH_VOLT_LIM_H_2V0, /*!< Touch sensor upper voltage limit is 2.0V while charging a touch pad */
|
||||
TOUCH_VOLT_LIM_H_2V1, /*!< Touch sensor upper voltage limit is 2.1V while charging a touch pad */
|
||||
TOUCH_VOLT_LIM_H_2V2, /*!< Touch sensor upper voltage limit is 2.2V while charging a touch pad */
|
||||
TOUCH_VOLT_LIM_H_1V9, /*!< Touch sensor upper voltage limit is 1.9V while charging a touch pad */
|
||||
TOUCH_VOLT_LIM_H_2V0, /*!< Touch sensor upper voltage limit is 2.0V while charging a touch pad */
|
||||
TOUCH_VOLT_LIM_H_2V1, /*!< Touch sensor upper voltage limit is 2.1V while charging a touch pad */
|
||||
TOUCH_VOLT_LIM_H_2V2, /*!< Touch sensor upper voltage limit is 2.2V while charging a touch pad */
|
||||
// No 2V3
|
||||
TOUCH_VOLT_LIM_H_2V4, /*!< Touch sensor upper voltage limit is 2.4V while charging a touch pad */
|
||||
TOUCH_VOLT_LIM_H_2V5, /*!< Touch sensor upper voltage limit is 2.5V while charging a touch pad */
|
||||
TOUCH_VOLT_LIM_H_2V6, /*!< Touch sensor upper voltage limit is 2.6V while charging a touch pad */
|
||||
TOUCH_VOLT_LIM_H_2V7, /*!< Touch sensor upper voltage limit is 2.7V while charging a touch pad */
|
||||
TOUCH_VOLT_LIM_H_2V4, /*!< Touch sensor upper voltage limit is 2.4V while charging a touch pad */
|
||||
TOUCH_VOLT_LIM_H_2V5, /*!< Touch sensor upper voltage limit is 2.5V while charging a touch pad */
|
||||
TOUCH_VOLT_LIM_H_2V6, /*!< Touch sensor upper voltage limit is 2.6V while charging a touch pad */
|
||||
TOUCH_VOLT_LIM_H_2V7, /*!< Touch sensor upper voltage limit is 2.7V while charging a touch pad */
|
||||
} touch_volt_lim_h_t;
|
||||
|
||||
/**
|
||||
* @brief Touch sensor lower discharging voltage limit
|
||||
*/
|
||||
typedef enum {
|
||||
TOUCH_VOLT_LIM_L_0V5, /*!< Touch sensor lower voltage limit is 0.5V while discharging a touch pad */
|
||||
TOUCH_VOLT_LIM_L_0V6, /*!< Touch sensor lower voltage limit is 0.6V while discharging a touch pad */
|
||||
TOUCH_VOLT_LIM_L_0V7, /*!< Touch sensor lower voltage limit is 0.7V while discharging a touch pad */
|
||||
TOUCH_VOLT_LIM_L_0V8, /*!< Touch sensor lower voltage limit is 0.8V while discharging a touch pad */
|
||||
TOUCH_VOLT_LIM_L_0V5, /*!< Touch sensor lower voltage limit is 0.5V while discharging a touch pad */
|
||||
TOUCH_VOLT_LIM_L_0V6, /*!< Touch sensor lower voltage limit is 0.6V while discharging a touch pad */
|
||||
TOUCH_VOLT_LIM_L_0V7, /*!< Touch sensor lower voltage limit is 0.7V while discharging a touch pad */
|
||||
TOUCH_VOLT_LIM_L_0V8, /*!< Touch sensor lower voltage limit is 0.8V while discharging a touch pad */
|
||||
} touch_volt_lim_l_t;
|
||||
|
||||
/**
|
||||
* @brief Touch sensor charge and discharge speed
|
||||
*/
|
||||
typedef enum {
|
||||
TOUCH_CHARGE_SPEED_0 = 0, /*!< Touch sensor charge and discharge speed, no charge, always zero */
|
||||
TOUCH_CHARGE_SPEED_1 = 1, /*!< Touch sensor charge and discharge speed, slowest */
|
||||
TOUCH_CHARGE_SPEED_2 = 2, /*!< Touch sensor charge and discharge speed */
|
||||
TOUCH_CHARGE_SPEED_3 = 3, /*!< Touch sensor charge and discharge speed */
|
||||
TOUCH_CHARGE_SPEED_4 = 4, /*!< Touch sensor charge and discharge speed */
|
||||
TOUCH_CHARGE_SPEED_5 = 5, /*!< Touch sensor charge and discharge speed */
|
||||
TOUCH_CHARGE_SPEED_6 = 6, /*!< Touch sensor charge and discharge speed */
|
||||
TOUCH_CHARGE_SPEED_7 = 7, /*!< Touch sensor charge and discharge speed, fastest */
|
||||
TOUCH_CHARGE_SPEED_0 = 0, /*!< Touch sensor charge and discharge speed, no charge, always zero */
|
||||
TOUCH_CHARGE_SPEED_1 = 1, /*!< Touch sensor charge and discharge speed, slowest */
|
||||
TOUCH_CHARGE_SPEED_2 = 2, /*!< Touch sensor charge and discharge speed */
|
||||
TOUCH_CHARGE_SPEED_3 = 3, /*!< Touch sensor charge and discharge speed */
|
||||
TOUCH_CHARGE_SPEED_4 = 4, /*!< Touch sensor charge and discharge speed */
|
||||
TOUCH_CHARGE_SPEED_5 = 5, /*!< Touch sensor charge and discharge speed */
|
||||
TOUCH_CHARGE_SPEED_6 = 6, /*!< Touch sensor charge and discharge speed */
|
||||
TOUCH_CHARGE_SPEED_7 = 7, /*!< Touch sensor charge and discharge speed, fastest */
|
||||
} touch_charge_speed_t;
|
||||
|
||||
/**
|
||||
* @brief Touch sensor initial voltage before charging
|
||||
*/
|
||||
typedef enum {
|
||||
TOUCH_INIT_CHARGE_VOLT_LOW = 0, /*!< Tie the initial charge voltage to low */
|
||||
TOUCH_INIT_CHARGE_VOLT_HIGH = 1,/*!< Tie the initial charge voltage to high */
|
||||
TOUCH_INIT_CHARGE_VOLT_LOW = 0, /*!< Tie the initial charge voltage to low */
|
||||
TOUCH_INIT_CHARGE_VOLT_HIGH = 1, /*!< Tie the initial charge voltage to high */
|
||||
} touch_init_charge_volt_t;
|
||||
|
||||
/**
|
||||
* @brief Touch channel idle state configuration
|
||||
*/
|
||||
typedef enum {
|
||||
TOUCH_IDLE_CONN_HIGHZ = 0, /*!< The idle (enabled but not measuring) touch channel is at high resistance state */
|
||||
TOUCH_IDLE_CONN_GND = 1, /*!< The idle (enabled but not measuring) touch channel is connected to the ground */
|
||||
TOUCH_IDLE_CONN_HIGHZ = 0, /*!< The idle (enabled but not measuring) touch channel is at high resistance state */
|
||||
TOUCH_IDLE_CONN_GND = 1, /*!< The idle (enabled but not measuring) touch channel is connected to the ground */
|
||||
} touch_idle_conn_t;
|
||||
|
||||
/**
|
||||
* @brief Touch sensor denoise channel internal reference capacitance
|
||||
*/
|
||||
typedef enum {
|
||||
TOUCH_DENOISE_CHAN_CAP_5PF = 0, /*!< Denoise channel internal reference capacitance is 5.0pf */
|
||||
TOUCH_DENOISE_CHAN_CAP_6PF = 1, /*!< Denoise channel internal reference capacitance is 6.4pf */
|
||||
TOUCH_DENOISE_CHAN_CAP_7PF = 2, /*!< Denoise channel internal reference capacitance is 7.8pf */
|
||||
TOUCH_DENOISE_CHAN_CAP_9PF = 3, /*!< Denoise channel internal reference capacitance is 9.2pf */
|
||||
TOUCH_DENOISE_CHAN_CAP_10PF = 4, /*!< Denoise channel internal reference capacitance is 10.6pf */
|
||||
TOUCH_DENOISE_CHAN_CAP_12PF = 5, /*!< Denoise channel internal reference capacitance is 12.0pf */
|
||||
TOUCH_DENOISE_CHAN_CAP_13PF = 6, /*!< Denoise channel internal reference capacitance is 13.4pf */
|
||||
TOUCH_DENOISE_CHAN_CAP_14PF = 7, /*!< Denoise channel internal reference capacitance is 14.8pf */
|
||||
TOUCH_DENOISE_CHAN_CAP_5PF = 0, /*!< Denoise channel internal reference capacitance is 5.0pf */
|
||||
TOUCH_DENOISE_CHAN_CAP_6PF = 1, /*!< Denoise channel internal reference capacitance is 6.4pf */
|
||||
TOUCH_DENOISE_CHAN_CAP_7PF = 2, /*!< Denoise channel internal reference capacitance is 7.8pf */
|
||||
TOUCH_DENOISE_CHAN_CAP_9PF = 3, /*!< Denoise channel internal reference capacitance is 9.2pf */
|
||||
TOUCH_DENOISE_CHAN_CAP_10PF = 4, /*!< Denoise channel internal reference capacitance is 10.6pf */
|
||||
TOUCH_DENOISE_CHAN_CAP_12PF = 5, /*!< Denoise channel internal reference capacitance is 12.0pf */
|
||||
TOUCH_DENOISE_CHAN_CAP_13PF = 6, /*!< Denoise channel internal reference capacitance is 13.4pf */
|
||||
TOUCH_DENOISE_CHAN_CAP_14PF = 7, /*!< Denoise channel internal reference capacitance is 14.8pf */
|
||||
} touch_denoise_chan_cap_t;
|
||||
|
||||
/**
|
||||
@ -148,24 +148,42 @@ typedef enum {
|
||||
* @brief Touch sensor bias type
|
||||
*/
|
||||
typedef enum {
|
||||
TOUCH_BIAS_TYPE_BANDGAP, /*!< Use bandgap-bias to charge/discharge the touch channel, which is more stable but power-consuming */
|
||||
TOUCH_BIAS_TYPE_SELF, /*!< Use self-bias to charge/discharge the touch channel, which is less stable but power-saving */
|
||||
TOUCH_BIAS_TYPE_BANDGAP, /*!< Use bandgap-bias to charge/discharge the touch channel, which is more stable but power-consuming */
|
||||
TOUCH_BIAS_TYPE_SELF, /*!< Use self-bias to charge/discharge the touch channel, which is less stable but power-saving */
|
||||
} touch_bias_type_t;
|
||||
|
||||
/**
|
||||
* @brief Touch channel binarized output counting mode
|
||||
*/
|
||||
typedef enum {
|
||||
TOUCH_PAD_OUT_AS_DATA, /*!< Counting the output of touch channel as data.
|
||||
* The value will be smaller than actual value but more sensitive when the frequency of touch_out is close to the source clock
|
||||
* Normally we treat the output as data when it is lower than the sample clock
|
||||
*/
|
||||
TOUCH_PAD_OUT_AS_CLOCK, /*!< Counting the output of touch channel as clock.
|
||||
* The value is accurate but less sensitive when the frequency of touch_out is close to the source clock
|
||||
* Normally we treat the output as clock when it is higher than the sample clock
|
||||
*/
|
||||
TOUCH_PAD_OUT_AS_DATA, /*!< Counting the output of touch channel as data.
|
||||
* The value will be smaller than actual value but more sensitive when the frequency of touch_out is close to the source clock
|
||||
* Normally we treat the output as data when it is lower than the sample clock
|
||||
*/
|
||||
TOUCH_PAD_OUT_AS_CLOCK, /*!< Counting the output of touch channel as clock.
|
||||
* The value is accurate but less sensitive when the frequency of touch_out is close to the source clock
|
||||
* Normally we treat the output as clock when it is higher than the sample clock
|
||||
*/
|
||||
} touch_out_mode_t;
|
||||
|
||||
/**
|
||||
* @brief Touch interrupt trigger mode
|
||||
*
|
||||
*/
|
||||
typedef enum {
|
||||
TOUCH_INTR_TRIG_ON_BELOW_THRESH, /*!< The touch active interrupt will trigger when the measured data below the absolute threshold */
|
||||
TOUCH_INTR_TRIG_ON_ABOVE_THRESH, /*!< The touch active interrupt will trigger when the measured data above the absolute threshold */
|
||||
} touch_intr_trig_mode_t;
|
||||
|
||||
/**
|
||||
* @brief Touch interrupt trigger group
|
||||
*
|
||||
*/
|
||||
typedef enum {
|
||||
TOUCH_INTR_TRIG_GROUP_BOTH, /*!< Both channel groups can trigger the interrupt */
|
||||
TOUCH_INTR_TRIG_GROUP_1, /*!< Only the channels in group 1 can trigger the interrupt */
|
||||
} touch_intr_trig_group_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@ -26,18 +26,26 @@ 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_power_on_wait_cycle(cfg->power_on_wait_ticks);
|
||||
touch_ll_set_measure_interval_ticks(cfg->meas_interval_ticks);
|
||||
touch_ll_set_timeout(cfg->timeout_ticks);
|
||||
|
||||
#if SOC_TOUCH_SENSOR_VERSION == 2
|
||||
#if SOC_TOUCH_SENSOR_VERSION == 1
|
||||
touch_ll_set_intr_trigger_mode(cfg->intr_trig_mode);
|
||||
touch_ll_set_intr_trigger_group(cfg->intr_trig_group);
|
||||
touch_ll_set_charge_window_duration(cfg->sample_cfg->charge_duration_ticks);
|
||||
touch_ll_set_charge_voltage_high_limit(cfg->sample_cfg->charge_volt_lim_h);
|
||||
touch_ll_set_charge_voltage_low_limit(cfg->sample_cfg->charge_volt_lim_l);
|
||||
#elif SOC_TOUCH_SENSOR_VERSION == 2
|
||||
touch_ll_sleep_set_channel_num(TOUCH_LL_NULL_CHANNEL);
|
||||
touch_ll_set_timeout(cfg->timeout_ticks);
|
||||
touch_ll_set_charge_times(cfg->sample_cfg->charge_times);
|
||||
touch_ll_set_charge_voltage_high_limit(cfg->sample_cfg->charge_volt_lim_h);
|
||||
touch_ll_set_charge_voltage_low_limit(cfg->sample_cfg->charge_volt_lim_l);
|
||||
touch_ll_set_idle_channel_connection(cfg->sample_cfg->idle_conn);
|
||||
touch_ll_set_bias_type(cfg->sample_cfg->bias_type);
|
||||
#elif SOC_TOUCH_SENSOR_VERSION == 3
|
||||
touch_ll_sleep_set_channel_num(TOUCH_LL_NULL_CHANNEL);
|
||||
touch_ll_set_timeout(cfg->timeout_ticks);
|
||||
touch_ll_sample_cfg_set_engaged_num(cfg->sample_cfg_num);
|
||||
touch_ll_set_out_mode(cfg->output_mode);
|
||||
for (int i = 0; i < cfg->sample_cfg_num; i++) {
|
||||
@ -66,6 +74,26 @@ void touch_hal_save_sleep_config(int deep_slp_chan, const touch_hal_config_t *de
|
||||
}
|
||||
}
|
||||
|
||||
#if SOC_TOUCH_SENSOR_VERSION == 1
|
||||
//This function will only be called when the chip is going to deep sleep.
|
||||
static void s_touch_hal_apply_sleep_config(void)
|
||||
{
|
||||
/* Apply the particular configuration for deep sleep */
|
||||
if (s_touch_slp_obj.apply_slp_cfg) {
|
||||
/* Save the current channel threshold first, because they will be reset by hardware after the recofniguration */
|
||||
uint32_t chan_thresh[SOC_TOUCH_SENSOR_NUM] = {};
|
||||
for (int i = 0; i < SOC_TOUCH_SENSOR_NUM; i++) {
|
||||
chan_thresh[i] = touch_ll_get_chan_active_threshold(i);
|
||||
}
|
||||
/* Reconfigure the touch sensor to use the sleep configuration */
|
||||
touch_hal_config_controller(&s_touch_slp_obj.slp_cfg);
|
||||
/* Restore the channel threshold */
|
||||
for (int i = 0; i < SOC_TOUCH_SENSOR_NUM; i++) {
|
||||
touch_ll_set_chan_active_threshold(i, chan_thresh[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
//This function will only be called when the chip is going to deep sleep.
|
||||
static void s_touch_hal_apply_sleep_config(void)
|
||||
{
|
||||
@ -86,10 +114,13 @@ static void s_touch_hal_apply_sleep_config(void)
|
||||
touch_ll_sleep_set_channel_num(TOUCH_LL_NULL_CHANNEL);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void touch_hal_prepare_deep_sleep(void)
|
||||
{
|
||||
s_touch_hal_apply_sleep_config();
|
||||
#if SOC_TOUCH_SUPPORT_BENCHMARK
|
||||
touch_ll_sleep_reset_benchmark();
|
||||
#endif
|
||||
touch_ll_interrupt_clear(TOUCH_LL_INTR_MASK_ALL);
|
||||
}
|
||||
|
@ -727,6 +727,10 @@ config SOC_TOUCH_SENSOR_NUM
|
||||
int
|
||||
default 10
|
||||
|
||||
config SOC_TOUCH_SUPPORT_SLEEP_WAKEUP
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_TOUCH_SAMPLE_CFG_NUM
|
||||
int
|
||||
default 1
|
||||
|
@ -332,8 +332,8 @@
|
||||
/*-------------------------- TOUCH SENSOR CAPS -------------------------------*/
|
||||
#define SOC_TOUCH_SENSOR_VERSION (1U) /*!<Hardware version of touch sensor */
|
||||
#define SOC_TOUCH_SENSOR_NUM (10)
|
||||
|
||||
#define SOC_TOUCH_SAMPLE_CFG_NUM (1U) /*!< The sample configuration number in total, each sampler can be used to sample on one frequency */
|
||||
#define SOC_TOUCH_SUPPORT_SLEEP_WAKEUP (1)
|
||||
#define SOC_TOUCH_SAMPLE_CFG_NUM (1U) /*!< The sample configuration number in total, each sampler can be used to sample on one frequency */
|
||||
|
||||
/*-------------------------- TWAI CAPS ---------------------------------------*/
|
||||
#define SOC_TWAI_CONTROLLER_NUM 1UL
|
||||
|
@ -1711,6 +1711,10 @@ config SOC_TOUCH_SUPPORT_SLEEP_WAKEUP
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_TOUCH_SUPPORT_BENCHMARK
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_TOUCH_SUPPORT_WATERPROOF
|
||||
bool
|
||||
default y
|
||||
|
@ -633,6 +633,7 @@
|
||||
|
||||
/* Touch Sensor Features */
|
||||
#define SOC_TOUCH_SUPPORT_SLEEP_WAKEUP (1) /*!< Touch sensor supports sleep awake */
|
||||
#define SOC_TOUCH_SUPPORT_BENCHMARK (1) /*!< Touch sensor supports benchmark configuration */
|
||||
#define SOC_TOUCH_SUPPORT_WATERPROOF (1) /*!< Touch sensor supports waterproof */
|
||||
#define SOC_TOUCH_SUPPORT_PROX_SENSING (1) /*!< Touch sensor supports proximity sensing */
|
||||
#define SOC_TOUCH_PROXIMITY_CHANNEL_NUM (3) /*!< Support touch proximity channel number. */
|
||||
|
@ -819,6 +819,10 @@ config SOC_TOUCH_SENSOR_NUM
|
||||
int
|
||||
default 15
|
||||
|
||||
config SOC_TOUCH_SUPPORT_BENCHMARK
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_TOUCH_SUPPORT_SLEEP_WAKEUP
|
||||
bool
|
||||
default y
|
||||
|
@ -343,7 +343,8 @@
|
||||
/*-------------------------- TOUCH SENSOR CAPS -------------------------------*/
|
||||
#define SOC_TOUCH_SENSOR_VERSION (2) /*!< Hardware version of touch sensor */
|
||||
#define SOC_TOUCH_SENSOR_NUM (15) /*!< 15 Touch channels */
|
||||
#define SOC_TOUCH_SUPPORT_SLEEP_WAKEUP (1) /*!< Touch sensor supports sleep awake */
|
||||
#define SOC_TOUCH_SUPPORT_BENCHMARK (1) /*!< Touch sensor supports benchmark configuration */
|
||||
#define SOC_TOUCH_SUPPORT_SLEEP_WAKEUP (1) /*!< Touch sensor supports sleep awake */
|
||||
#define SOC_TOUCH_SUPPORT_WATERPROOF (1) /*!< Touch sensor supports waterproof */
|
||||
#define SOC_TOUCH_SUPPORT_PROX_SENSING (1) /*!< Touch sensor supports proximity sensing */
|
||||
#define SOC_TOUCH_SUPPORT_DENOISE_CHAN (1) /*!< Touch sensor supports denoise channel */
|
||||
|
@ -1007,6 +1007,10 @@ config SOC_TOUCH_SENSOR_NUM
|
||||
int
|
||||
default 15
|
||||
|
||||
config SOC_TOUCH_SUPPORT_BENCHMARK
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_TOUCH_SUPPORT_SLEEP_WAKEUP
|
||||
bool
|
||||
default y
|
||||
|
@ -390,7 +390,8 @@
|
||||
/*-------------------------- TOUCH SENSOR CAPS -------------------------------*/
|
||||
#define SOC_TOUCH_SENSOR_VERSION (2) /*!< Hardware version of touch sensor */
|
||||
#define SOC_TOUCH_SENSOR_NUM (15) /*!< 15 Touch channels */
|
||||
#define SOC_TOUCH_SUPPORT_SLEEP_WAKEUP (1) /*!< Touch sensor supports sleep awake */
|
||||
#define SOC_TOUCH_SUPPORT_BENCHMARK (1) /*!< Touch sensor supports benchmark configuration */
|
||||
#define SOC_TOUCH_SUPPORT_SLEEP_WAKEUP (1) /*!< Touch sensor supports sleep awake */
|
||||
#define SOC_TOUCH_SUPPORT_WATERPROOF (1) /*!< Touch sensor supports waterproof */
|
||||
#define SOC_TOUCH_SUPPORT_PROX_SENSING (1) /*!< Touch sensor supports proximity sensing */
|
||||
#define SOC_TOUCH_SUPPORT_DENOISE_CHAN (1) /*!< Touch sensor supports denoise channel */
|
||||
|
Loading…
x
Reference in New Issue
Block a user