1212// See the License for the specific language governing permissions and
1313// limitations under the License.
1414#include "soc/soc_caps.h"
15+ #include "esp_idf_version.h"
1516
1617#if SOC_TOUCH_SENSOR_SUPPORTED
17- #if SOC_TOUCH_SENSOR_VERSION == 3 // ESP32P4 for now
18+ #if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL ( 5 , 5 , 0 ) || SOC_TOUCH_SENSOR_VERSION == 3
1819
19- #include "driver/touch_sens.h"
2020#include "esp32-hal-touch-ng.h"
2121#include "esp32-hal-periman.h"
2222
@@ -37,11 +37,24 @@ typedef struct {
3737static TouchInterruptHandle_t __touchInterruptHandlers [SOC_TOUCH_SENSOR_NUM ] = {
3838 0 ,
3939};
40-
41- static uint8_t _sample_num = 1 ;
40+ #if SOC_TOUCH_SENSOR_VERSION == 1 // ESP32
41+ static uint8_t _sample_num = 1 ; // only one sample configuration supported
42+ static float _duration_ms = 5.0f ;
43+ static touch_volt_lim_l_t _volt_low = TOUCH_VOLT_LIM_L_0V5 ;
44+ static touch_volt_lim_h_t _volt_high = TOUCH_VOLT_LIM_H_1V7 ;
45+ static touch_intr_trig_mode_t _intr_trig_mode = TOUCH_INTR_TRIG_ON_BELOW_THRESH ;
46+ #elif SOC_TOUCH_SENSOR_VERSION == 2 // ESP32S2, ESP32S3
47+ static uint8_t _sample_num = 1 ; // only one sample configuration supported
48+ static uint32_t _chg_times = 500 ;
49+ static touch_volt_lim_l_t _volt_low = TOUCH_VOLT_LIM_L_0V5 ;
50+ static touch_volt_lim_h_t _volt_high = TOUCH_VOLT_LIM_H_2V2 ;
51+ #elif SOC_TOUCH_SENSOR_VERSION == 3 // ESP32P4
52+ static uint8_t _sample_num = 1 ; // TODO: can be extended to multiple samples
4253static uint32_t _div_num = 1 ;
4354static uint8_t _coarse_freq_tune = 1 ;
4455static uint8_t _fine_freq_tune = 1 ;
56+ #endif
57+
4558static uint8_t used_pads = 0 ;
4659
4760static uint32_t __touchSleepTime = 256 ;
@@ -156,15 +169,28 @@ bool touchBenchmarkThreshold(uint8_t pad) {
156169
157170 // Reconfigure passed pad with new threshold
158171 uint32_t benchmark [_sample_num ] = {};
172+ #if SOC_TOUCH_SUPPORT_BENCHMARK // ESP32S2, ESP32S3,ESP32P4
159173 if (touch_channel_read_data (touch_channel_handle [pad ], TOUCH_CHAN_DATA_TYPE_BENCHMARK , benchmark ) != ESP_OK ) {
160174 log_e ("Touch channel read data failed!" );
161175 return false;
162176 }
177+ #else
178+ if (touch_channel_read_data (touch_channel_handle [pad ], TOUCH_CHAN_DATA_TYPE_SMOOTH , benchmark ) != ESP_OK ) {
179+ log_e ("Touch channel read data failed!" );
180+ return false;
181+ }
182+ #endif
183+
163184 /* Calculate the proper active thresholds regarding the initial benchmark */
164- touch_channel_config_t chan_cfg = {} ;
185+ touch_channel_config_t chan_cfg = TOUCH_CHANNEL_DEFAULT_CONFIG () ;
165186 for (int i = 0 ; i < _sample_num ; i ++ ) {
187+ #if SOC_TOUCH_SENSOR_VERSION == 1 // ESP32
188+ chan_cfg .abs_active_thresh [i ] = (uint32_t )(benchmark [i ] * (1 - s_thresh2bm_ratio ));
189+ log_v ("Configured [CH %d] sample %d: benchmark = %" PRIu32 ", threshold = %" PRIu32 "\t" , pad , i , benchmark [i ], chan_cfg .abs_active_thresh [i ]);
190+ #else
166191 chan_cfg .active_thresh [i ] = (uint32_t )(benchmark [i ] * s_thresh2bm_ratio );
167192 log_v ("Configured [CH %d] sample %d: benchmark = %" PRIu32 ", threshold = %" PRIu32 "\t" , pad , i , benchmark [i ], chan_cfg .active_thresh [i ]);
193+ #endif
168194 }
169195 /* Update the channel configuration */
170196 if (touch_sensor_reconfig_channel (touch_channel_handle [pad ], & chan_cfg ) != ESP_OK ) {
@@ -178,17 +204,26 @@ static bool touchDetachBus(void *pin) {
178204 int8_t pad = digitalPinToTouchChannel ((int )(pin - 1 ));
179205 channels_initialized [pad ] = false;
180206 //disable touch pad and delete the channel
207+ if (!touchStop ()) {
208+ log_e ("touchStop() failed!" );
209+ return false;
210+ }
211+ if (!touchDisable ()) {
212+ log_e ("touchDisable() failed!" );
213+ return false;
214+ }
181215 touch_sensor_del_channel (touch_channel_handle [pad ]);
182216 used_pads -- ;
183217 if (used_pads == 0 ) {
184- touchStop ();
185- touchDisable ();
186218 if (touch_sensor_del_controller (touch_sensor_handle ) != ESP_OK ) //deinit touch module, as no pads are used
187219 {
188220 log_e ("Touch module deinit failed!" );
189221 return false;
190222 }
191223 initialized = false;
224+ } else {
225+ touchEnable ();
226+ touchStart ();
192227 }
193228 return true;
194229}
@@ -198,21 +233,40 @@ static void __touchInit() {
198233 return ;
199234 }
200235 // Support only one sample configuration for now
236+ #if SOC_TOUCH_SENSOR_VERSION == 1 // ESP32
237+ touch_sensor_sample_config_t single_sample_cfg = TOUCH_SENSOR_V1_DEFAULT_SAMPLE_CONFIG (_duration_ms , _volt_low , _volt_high );
238+ #elif SOC_TOUCH_SENSOR_VERSION == 2 // ESP32S2, ESP32S3
239+ touch_sensor_sample_config_t single_sample_cfg = TOUCH_SENSOR_V2_DEFAULT_SAMPLE_CONFIG (_chg_times , _volt_low , _volt_high );
240+ #elif SOC_TOUCH_SENSOR_VERSION == 3 // ESP32P4
201241 touch_sensor_sample_config_t single_sample_cfg = TOUCH_SENSOR_V3_DEFAULT_SAMPLE_CONFIG (_div_num , _coarse_freq_tune , _fine_freq_tune );
242+ #endif
202243 touch_sensor_sample_config_t sample_cfg [_sample_num ] = {};
203244 sample_cfg [0 ] = single_sample_cfg ;
204245
205- /* Allocate new touch controller handle */
206246 touch_sensor_config_t sens_cfg = {
247+ #if SOC_TOUCH_SENSOR_VERSION == 1 // ESP32
248+ .power_on_wait_us = __touchSleepTime ,
249+ .meas_interval_us = __touchMeasureTime ,
250+ .intr_trig_mode = _intr_trig_mode ,
251+ .intr_trig_group = TOUCH_INTR_TRIG_GROUP_BOTH ,
252+ .sample_cfg_num = _sample_num ,
253+ .sample_cfg = sample_cfg ,
254+ #elif SOC_TOUCH_SENSOR_VERSION == 2 // ESP32S2, ESP32S3
255+ .power_on_wait_us = __touchSleepTime ,
256+ .meas_interval_us = __touchMeasureTime ,
257+ .max_meas_time_us = 0 ,
258+ .sample_cfg_num = _sample_num ,
259+ .sample_cfg = sample_cfg ,
260+ #elif SOC_TOUCH_SENSOR_VERSION == 3 // ESP32P4
207261 .power_on_wait_us = __touchSleepTime ,
208262 .meas_interval_us = __touchMeasureTime ,
209263 .max_meas_time_us = 0 ,
210264 .output_mode = TOUCH_PAD_OUT_AS_CLOCK ,
211265 .sample_cfg_num = _sample_num ,
212266 .sample_cfg = sample_cfg ,
267+ #endif
213268 };
214269
215- // touch_sensor_config_t sens_cfg = TOUCH_SENSOR_DEFAULT_BASIC_CONFIG(_sample_num, sample_cfg);
216270 if (touch_sensor_new_controller (& sens_cfg , & touch_sensor_handle ) != ESP_OK ) {
217271 goto err ;
218272 }
@@ -225,14 +279,10 @@ static void __touchInit() {
225279 }
226280
227281 /* Register the touch sensor on_active and on_inactive callbacks */
228- touch_event_callbacks_t callbacks = {
229- .on_active = __touchOnActiveISR ,
230- .on_inactive = __touchOnInactiveISR ,
231- .on_measure_done = NULL ,
232- .on_scan_done = NULL ,
233- .on_timeout = NULL ,
234- .on_proximity_meas_done = NULL ,
235- };
282+ touch_event_callbacks_t callbacks = {0 };
283+ callbacks .on_active = __touchOnActiveISR ;
284+ callbacks .on_inactive = __touchOnInactiveISR ;
285+
236286 if (touch_sensor_register_callbacks (touch_sensor_handle , & callbacks , NULL ) != ESP_OK ) {
237287 goto err ;
238288 }
@@ -253,9 +303,7 @@ static void __touchChannelInit(int pad) {
253303 // Initial setup with default Threshold
254304 __touchInterruptHandlers [pad ].fn = NULL ;
255305
256- touch_channel_config_t chan_cfg = {
257- .active_thresh = {1000 } // default threshold, will be updated after benchmark
258- };
306+ touch_channel_config_t chan_cfg = TOUCH_CHANNEL_DEFAULT_CONFIG ();
259307
260308 if (!touchStop () || !touchDisable ()) {
261309 log_e ("Touch sensor stop and disable failed!" );
@@ -323,8 +371,21 @@ static void __touchConfigInterrupt(uint8_t pin, void (*userFunc)(void), void *Ar
323371 __touchInterruptHandlers [pad ].arg = NULL ;
324372 } else {
325373 // attach ISR User Call
326- __touchInit ();
327- __touchChannelInit (pad );
374+ if (perimanGetPinBus (pin , ESP32_BUS_TYPE_TOUCH ) == NULL ) {
375+ perimanSetBusDeinit (ESP32_BUS_TYPE_TOUCH , touchDetachBus );
376+ if (!perimanClearPinBus (pin )) {
377+ log_e ("Failed to clear pin bus" );
378+ return ;
379+ }
380+ __touchInit ();
381+ __touchChannelInit (pad );
382+
383+ if (!perimanSetPinBus (pin , ESP32_BUS_TYPE_TOUCH , (void * )(pin + 1 ), -1 , pad )) {
384+ touchDetachBus ((void * )(pin + 1 ));
385+ log_e ("Failed to set bus to Peripheral manager" );
386+ return ;
387+ }
388+ }
328389 __touchInterruptHandlers [pad ].fn = userFunc ;
329390 __touchInterruptHandlers [pad ].callWithArgs = callWithArgs ;
330391 __touchInterruptHandlers [pad ].arg = Args ;
@@ -338,7 +399,11 @@ static void __touchConfigInterrupt(uint8_t pin, void (*userFunc)(void), void *Ar
338399
339400 touch_channel_config_t chan_cfg = {};
340401 for (int i = 0 ; i < _sample_num ; i ++ ) {
402+ #if SOC_TOUCH_SENSOR_VERSION == 1 // ESP32
403+ chan_cfg .abs_active_thresh [i ] = threshold ;
404+ #else
341405 chan_cfg .active_thresh [i ] = threshold ;
406+ #endif
342407 }
343408
344409 if (touch_sensor_reconfig_channel (touch_channel_handle [pad ], & chan_cfg ) != ESP_OK ) {
@@ -375,7 +440,6 @@ bool touchInterruptGetLastStatus(uint8_t pin) {
375440 if (pad < 0 ) {
376441 return false;
377442 }
378-
379443 return __touchInterruptHandlers [pad ].lastStatusIsPressed ;
380444}
381445
@@ -405,9 +469,13 @@ void touchSleepWakeUpEnable(uint8_t pin, touch_value_t threshold) {
405469
406470 touch_sleep_config_t deep_slp_cfg = {
407471 .slp_wakeup_lvl = TOUCH_DEEP_SLEEP_WAKEUP ,
472+ #if SOC_TOUCH_SENSOR_VERSION == 1 // ESP32
473+ .deep_slp_sens_cfg = NULL , // Use the original touch sensor configuration
474+ #else // SOC_TOUCH_SENSOR_VERSION 2 and 3// ESP32S2, ESP32S3, ESP32P4
408475 .deep_slp_chan = touch_channel_handle [pad ],
409476 .deep_slp_thresh = {threshold },
410477 .deep_slp_sens_cfg = NULL , // Use the original touch sensor configuration
478+ #endif
411479 };
412480
413481 // Register the deep sleep wake-up
@@ -434,6 +502,29 @@ void touchSetTiming(float measure, uint32_t sleep) {
434502 __touchMeasureTime = measure ;
435503}
436504
505+ #if SOC_TOUCH_SENSOR_VERSION == 1 // ESP32
506+ void touchSetConfig (float duration_ms , touch_volt_lim_l_t volt_low , touch_volt_lim_h_t volt_high ) {
507+ if (initialized ) {
508+ log_e ("Touch sensor already initialized. Cannot set configuration." );
509+ return ;
510+ }
511+ _duration_ms = duration_ms ;
512+ _volt_low = volt_low ;
513+ _volt_high = volt_high ;
514+ }
515+
516+ #elif SOC_TOUCH_SENSOR_VERSION == 2 // ESP32S2, ESP32S3
517+ void touchSetConfig (uint32_t chg_times , touch_volt_lim_l_t volt_low , touch_volt_lim_h_t volt_high ) {
518+ if (initialized ) {
519+ log_e ("Touch sensor already initialized. Cannot set configuration." );
520+ return ;
521+ }
522+ _chg_times = chg_times ;
523+ _volt_low = volt_low ;
524+ _volt_high = volt_high ;
525+ }
526+
527+ #elif SOC_TOUCH_SENSOR_VERSION == 3 // ESP32P4
437528void touchSetConfig (uint32_t div_num , uint8_t coarse_freq_tune , uint8_t fine_freq_tune ) {
438529 if (initialized ) {
439530 log_e ("Touch sensor already initialized. Cannot set configuration." );
@@ -443,11 +534,22 @@ void touchSetConfig(uint32_t div_num, uint8_t coarse_freq_tune, uint8_t fine_fre
443534 _coarse_freq_tune = coarse_freq_tune ;
444535 _fine_freq_tune = fine_freq_tune ;
445536}
537+ #endif
538+
539+ #if SOC_TOUCH_SENSOR_VERSION == 1 // ESP32
540+ void touchInterruptSetThresholdDirection (bool mustbeLower ) {
541+ if (mustbeLower ) {
542+ _intr_trig_mode = TOUCH_INTR_TRIG_ON_BELOW_THRESH ;
543+ } else {
544+ _intr_trig_mode = TOUCH_INTR_TRIG_ON_ABOVE_THRESH ;
545+ }
546+ }
547+ #endif
446548
447549extern touch_value_t touchRead (uint8_t ) __attribute__((weak , alias ("__touchRead" )));
448550extern void touchAttachInterrupt (uint8_t , voidFuncPtr , touch_value_t ) __attribute__((weak , alias ("__touchAttachInterrupt" )));
449551extern void touchAttachInterruptArg (uint8_t , voidArgFuncPtr , void * , touch_value_t ) __attribute__((weak , alias ("__touchAttachArgsInterrupt" )));
450552extern void touchDetachInterrupt (uint8_t ) __attribute__((weak , alias ("__touchDettachInterrupt" )));
451553
452- #endif /* SOC_TOUCH_SENSOR_VERSION == 3 */
554+ #endif /* ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 5, 0) || SOC_TOUCH_SENSOR_VERSION == 3 */
453555#endif /* SOC_TOUCH_SENSOR_SUPPORTED */
0 commit comments