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