From 5c2ebf4eee5978d2acac0a8dd3bc4c179010c536 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Proch=C3=A1zka?= <90197375+P-R-O-C-H-Y@users.noreply.github.com> Date: Fri, 25 Jul 2025 17:31:22 +0200 Subject: [PATCH 01/38] feat(touch): Support all touch versions in NG driver --- cores/esp32/esp32-hal-touch-ng.c | 133 +++++-- cores/esp32/esp32-hal-touch-ng.h | 42 ++- cores/esp32/esp32-hal-touch.c | 329 ------------------ cores/esp32/esp32-hal-touch.h | 103 ------ cores/esp32/esp32-hal.h | 1 - .../Touch/TouchButton/TouchButton.ino | 57 +-- .../ESP32/examples/Touch/TouchButton/ci.json | 2 +- .../Touch/TouchButtonV2/TouchButtonV2.ino | 51 --- .../examples/Touch/TouchButtonV2/ci.json | 5 - tests/validation/touch/touch.ino | 13 +- 10 files changed, 189 insertions(+), 547 deletions(-) delete mode 100644 cores/esp32/esp32-hal-touch.c delete mode 100644 cores/esp32/esp32-hal-touch.h delete mode 100644 libraries/ESP32/examples/Touch/TouchButtonV2/TouchButtonV2.ino delete mode 100644 libraries/ESP32/examples/Touch/TouchButtonV2/ci.json diff --git a/cores/esp32/esp32-hal-touch-ng.c b/cores/esp32/esp32-hal-touch-ng.c index 888a299ec0c..392f404bae6 100644 --- a/cores/esp32/esp32-hal-touch-ng.c +++ b/cores/esp32/esp32-hal-touch-ng.c @@ -14,9 +14,8 @@ #include "soc/soc_caps.h" #if SOC_TOUCH_SENSOR_SUPPORTED -#if SOC_TOUCH_SENSOR_VERSION == 3 // ESP32P4 for now +//#if SOC_TOUCH_SENSOR_VERSION == 3 // ESP32P4 for now -#include "driver/touch_sens.h" #include "esp32-hal-touch-ng.h" #include "esp32-hal-periman.h" @@ -37,11 +36,24 @@ typedef struct { static TouchInterruptHandle_t __touchInterruptHandlers[SOC_TOUCH_SENSOR_NUM] = { 0, }; - -static uint8_t _sample_num = 1; +#if SOC_TOUCH_SENSOR_VERSION == 1 // ESP32 +static uint8_t _sample_num = 1; // only one sample configuration supported +static float _duration_ms = 5.0f; +static touch_volt_lim_l_t _volt_low = TOUCH_VOLT_LIM_L_0V5; +static touch_volt_lim_h_t _volt_high = TOUCH_VOLT_LIM_H_1V7; +static touch_intr_trig_mode_t _intr_trig_mode = TOUCH_INTR_TRIG_ON_BELOW_THRESH; +#elif SOC_TOUCH_SENSOR_VERSION == 2 // ESP32S2, ESP32S3 +static uint8_t _sample_num = 1; // only one sample configuration supported +static float _duration_ms = 500.0f; +static touch_volt_lim_l_t _volt_low = TOUCH_VOLT_LIM_L_0V5; +static touch_volt_lim_h_t _volt_high = TOUCH_VOLT_LIM_H_2V2; +#elif SOC_TOUCH_SENSOR_VERSION == 3 // ESP32P4 +static uint8_t _sample_num = 1; // TODO: can be extended to multiple samples static uint32_t _div_num = 1; static uint8_t _coarse_freq_tune = 1; static uint8_t _fine_freq_tune = 1; +#endif + static uint8_t used_pads = 0; static uint32_t __touchSleepTime = 256; @@ -156,15 +168,28 @@ bool touchBenchmarkThreshold(uint8_t pad) { // Reconfigure passed pad with new threshold uint32_t benchmark[_sample_num] = {}; + #if SOC_TOUCH_SUPPORT_BENCHMARK // ESP32S2, ESP32S3,ESP32P4 if (touch_channel_read_data(touch_channel_handle[pad], TOUCH_CHAN_DATA_TYPE_BENCHMARK, benchmark) != ESP_OK) { log_e("Touch channel read data failed!"); return false; } + #else + if (touch_channel_read_data(touch_channel_handle[pad], TOUCH_CHAN_DATA_TYPE_SMOOTH, benchmark) != ESP_OK) { + log_e("Touch channel read data failed!"); + return false; + } + #endif + /* Calculate the proper active thresholds regarding the initial benchmark */ - touch_channel_config_t chan_cfg = {}; + touch_channel_config_t chan_cfg = TOUCH_CHANNEL_DEFAULT_CONFIG(); for (int i = 0; i < _sample_num; i++) { +#if SOC_TOUCH_SENSOR_VERSION == 1 // ESP32 + chan_cfg.abs_active_thresh[i] = (uint32_t)(benchmark[i] * (1 - s_thresh2bm_ratio)); + log_v("Configured [CH %d] sample %d: benchmark = %"PRIu32", threshold = %"PRIu32"\t", pad, i, benchmark[i], chan_cfg.abs_active_thresh[i]); +#else chan_cfg.active_thresh[i] = (uint32_t)(benchmark[i] * s_thresh2bm_ratio); - log_v("Configured [CH %d] sample %d: benchmark = %" PRIu32 ", threshold = %" PRIu32 "\t", pad, i, benchmark[i], chan_cfg.active_thresh[i]); + log_v("Configured [CH %d] sample %d: benchmark = %"PRIu32", threshold = %"PRIu32"\t", pad, i, benchmark[i], chan_cfg.active_thresh[i]); +#endif } /* Update the channel configuration */ if (touch_sensor_reconfig_channel(touch_channel_handle[pad], &chan_cfg) != ESP_OK) { @@ -198,21 +223,40 @@ static void __touchInit() { return; } // Support only one sample configuration for now - touch_sensor_sample_config_t single_sample_cfg = TOUCH_SENSOR_V3_DEFAULT_SAMPLE_CONFIG(_div_num, _coarse_freq_tune, _fine_freq_tune); +#if SOC_TOUCH_SENSOR_VERSION == 1 // ESP32 + touch_sensor_sample_config_t single_sample_cfg = TOUCH_SENSOR_V1_DEFAULT_SAMPLE_CONFIG(_duration_ms, _volt_low, _volt_high); +#elif SOC_TOUCH_SENSOR_VERSION == 2 // ESP32S2, ESP32S3 + touch_sensor_sample_config_t single_sample_cfg = TOUCH_SENSOR_V2_DEFAULT_SAMPLE_CONFIG(_duration_ms, _volt_low, _volt_high); +#elif SOC_TOUCH_SENSOR_VERSION == 3 // ESP32P4 + touch_sensor_sample_config_t single_sample_cfg = TOUCH_SENSOR_V3_DEFAULT_SAMPLE_CONFIG(_sample_num, _div_num, _coarse_freq_tune, _fine_freq_tune); +#endif touch_sensor_sample_config_t sample_cfg[_sample_num] = {}; sample_cfg[0] = single_sample_cfg; - /* Allocate new touch controller handle */ touch_sensor_config_t sens_cfg = { +#if SOC_TOUCH_SENSOR_VERSION == 1 // ESP32 + .power_on_wait_us = __touchSleepTime, + .meas_interval_us = __touchMeasureTime, + .intr_trig_mode = _intr_trig_mode, + .intr_trig_group = TOUCH_INTR_TRIG_GROUP_BOTH, + .sample_cfg_num = _sample_num, + .sample_cfg = sample_cfg, +#elif SOC_TOUCH_SENSOR_VERSION == 2 // ESP32S2, ESP32S3 + .power_on_wait_us = __touchSleepTime, + .meas_interval_us = __touchMeasureTime, + .max_meas_time_us = 0, + .sample_cfg_num = _sample_num, + .sample_cfg = sample_cfg, +#elif SOC_TOUCH_SENSOR_VERSION == 3 // ESP32P4 .power_on_wait_us = __touchSleepTime, .meas_interval_us = __touchMeasureTime, .max_meas_time_us = 0, .output_mode = TOUCH_PAD_OUT_AS_CLOCK, .sample_cfg_num = _sample_num, .sample_cfg = sample_cfg, +#endif }; - // touch_sensor_config_t sens_cfg = TOUCH_SENSOR_DEFAULT_BASIC_CONFIG(_sample_num, sample_cfg); if (touch_sensor_new_controller(&sens_cfg, &touch_sensor_handle) != ESP_OK) { goto err; } @@ -225,14 +269,10 @@ static void __touchInit() { } /* Register the touch sensor on_active and on_inactive callbacks */ - touch_event_callbacks_t callbacks = { - .on_active = __touchOnActiveISR, - .on_inactive = __touchOnInactiveISR, - .on_measure_done = NULL, - .on_scan_done = NULL, - .on_timeout = NULL, - .on_proximity_meas_done = NULL, - }; + touch_event_callbacks_t callbacks = {0}; + callbacks.on_active = __touchOnActiveISR; + callbacks.on_inactive = __touchOnInactiveISR; + if (touch_sensor_register_callbacks(touch_sensor_handle, &callbacks, NULL) != ESP_OK) { goto err; } @@ -253,10 +293,8 @@ static void __touchChannelInit(int pad) { // Initial setup with default Threshold __touchInterruptHandlers[pad].fn = NULL; - touch_channel_config_t chan_cfg = { - .active_thresh = {1000} // default threshold, will be updated after benchmark - }; - + touch_channel_config_t chan_cfg = TOUCH_CHANNEL_DEFAULT_CONFIG(); + if (!touchStop() || !touchDisable()) { log_e("Touch sensor stop and disable failed!"); return; @@ -323,8 +361,21 @@ static void __touchConfigInterrupt(uint8_t pin, void (*userFunc)(void), void *Ar __touchInterruptHandlers[pad].arg = NULL; } else { // attach ISR User Call - __touchInit(); - __touchChannelInit(pad); + if (perimanGetPinBus(pin, ESP32_BUS_TYPE_TOUCH) == NULL) { + perimanSetBusDeinit(ESP32_BUS_TYPE_TOUCH, touchDetachBus); + if (!perimanClearPinBus(pin)) { + log_e("Failed to clear pin bus"); + return; + } + __touchInit(); + __touchChannelInit(pad); + + if (!perimanSetPinBus(pin, ESP32_BUS_TYPE_TOUCH, (void *)(pin + 1), -1, pad)) { + touchDetachBus((void *)(pin + 1)); + log_e("Failed to set bus to Peripheral manager"); + return; + } + } __touchInterruptHandlers[pad].fn = userFunc; __touchInterruptHandlers[pad].callWithArgs = callWithArgs; __touchInterruptHandlers[pad].arg = Args; @@ -338,7 +389,11 @@ static void __touchConfigInterrupt(uint8_t pin, void (*userFunc)(void), void *Ar touch_channel_config_t chan_cfg = {}; for (int i = 0; i < _sample_num; i++) { +#if SOC_TOUCH_SENSOR_VERSION == 1 // ESP32 + chan_cfg.abs_active_thresh[i] = threshold; +#else chan_cfg.active_thresh[i] = threshold; +#endif } if (touch_sensor_reconfig_channel(touch_channel_handle[pad], &chan_cfg) != ESP_OK) { @@ -375,7 +430,6 @@ bool touchInterruptGetLastStatus(uint8_t pin) { if (pad < 0) { return false; } - return __touchInterruptHandlers[pad].lastStatusIsPressed; } @@ -405,9 +459,13 @@ void touchSleepWakeUpEnable(uint8_t pin, touch_value_t threshold) { touch_sleep_config_t deep_slp_cfg = { .slp_wakeup_lvl = TOUCH_DEEP_SLEEP_WAKEUP, +#if SOC_TOUCH_SENSOR_VERSION == 1 // ESP32 + .deep_slp_sens_cfg = NULL, // Use the original touch sensor configuration +#else // SOC_TOUCH_SENSOR_VERSION 2 and 3// ESP32S2, ESP32S3, ESP32P4 .deep_slp_chan = touch_channel_handle[pad], .deep_slp_thresh = {threshold}, .deep_slp_sens_cfg = NULL, // Use the original touch sensor configuration +#endif }; // Register the deep sleep wake-up @@ -434,6 +492,20 @@ void touchSetTiming(float measure, uint32_t sleep) { __touchMeasureTime = measure; } +#if SOC_TOUCH_SENSOR_VERSION == 1 || SOC_TOUCH_SENSOR_VERSION == 2 // ESP32, ESP32S2, ESP32S3 + +void touchSetConfig(float duration_ms, touch_volt_lim_l_t volt_low, touch_volt_lim_h_t volt_high) { + if (initialized) { + log_e("Touch sensor already initialized. Cannot set configuration."); + return; + } + _duration_ms = duration_ms; + _volt_low = volt_low; + _volt_high = volt_high; +} + +#elif SOC_TOUCH_SENSOR_VERSION == 3 // ESP32P4 + void touchSetConfig(uint32_t div_num, uint8_t coarse_freq_tune, uint8_t fine_freq_tune) { if (initialized) { log_e("Touch sensor already initialized. Cannot set configuration."); @@ -443,11 +515,22 @@ void touchSetConfig(uint32_t div_num, uint8_t coarse_freq_tune, uint8_t fine_fre _coarse_freq_tune = coarse_freq_tune; _fine_freq_tune = fine_freq_tune; } +#endif + +#if SOC_TOUCH_SENSOR_VERSION == 1 // ESP32 +void touchInterruptSetThresholdDirection(bool mustbeLower) { + if (mustbeLower) { + _intr_trig_mode = TOUCH_INTR_TRIG_ON_BELOW_THRESH; + } else { + _intr_trig_mode = TOUCH_INTR_TRIG_ON_ABOVE_THRESH; + } +} +#endif extern touch_value_t touchRead(uint8_t) __attribute__((weak, alias("__touchRead"))); extern void touchAttachInterrupt(uint8_t, voidFuncPtr, touch_value_t) __attribute__((weak, alias("__touchAttachInterrupt"))); extern void touchAttachInterruptArg(uint8_t, voidArgFuncPtr, void *, touch_value_t) __attribute__((weak, alias("__touchAttachArgsInterrupt"))); extern void touchDetachInterrupt(uint8_t) __attribute__((weak, alias("__touchDettachInterrupt"))); -#endif /* SOC_TOUCH_SENSOR_VERSION == 3 */ +//#endif /* SOC_TOUCH_SENSOR_VERSION == 3 */ #endif /* SOC_TOUCH_SENSOR_SUPPORTED */ diff --git a/cores/esp32/esp32-hal-touch-ng.h b/cores/esp32/esp32-hal-touch-ng.h index 0d4eb79ac58..23c00983092 100644 --- a/cores/esp32/esp32-hal-touch-ng.h +++ b/cores/esp32/esp32-hal-touch-ng.h @@ -22,13 +22,32 @@ #include "soc/soc_caps.h" #if SOC_TOUCH_SENSOR_SUPPORTED -#if SOC_TOUCH_SENSOR_VERSION == 3 // ESP32P4 #ifdef __cplusplus extern "C" { #endif #include "esp32-hal.h" +#include "driver/touch_sens.h" + +#if SOC_TOUCH_SENSOR_VERSION == 1 // ESP32 +#define TOUCH_CHANNEL_DEFAULT_CONFIG() { \ + .abs_active_thresh = {1000}, \ + .charge_speed = TOUCH_CHARGE_SPEED_7, \ + .init_charge_volt = TOUCH_INIT_CHARGE_VOLT_DEFAULT, \ + .group = TOUCH_CHAN_TRIG_GROUP_BOTH, \ +} +#elif SOC_TOUCH_SENSOR_VERSION == 2 // ESP32-S2 & ESP32-S3 +#define TOUCH_CHANNEL_DEFAULT_CONFIG() { \ + .active_thresh = {2000}, \ + .charge_speed = TOUCH_CHARGE_SPEED_7, \ + .init_charge_volt = TOUCH_INIT_CHARGE_VOLT_DEFAULT, \ +} +#elif SOC_TOUCH_SENSOR_VERSION == 3 // ESP32-P4 +#define TOUCH_CHANNEL_DEFAULT_CONFIG() { \ + .active_thresh = {1000}, \ +} +#endif typedef uint32_t touch_value_t; @@ -40,11 +59,31 @@ typedef uint32_t touch_value_t; **/ void touchSetTiming(float measure, uint32_t sleep); +#if SOC_TOUCH_SENSOR_VERSION == 1 || SOC_TOUCH_SENSOR_VERSION == 2 // ESP32, ESP32S2, ESP32S3 +/* + * @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 + */ +void touchSetConfig(float duration_ms, touch_volt_lim_l_t volt_low, touch_volt_lim_h_t volt_high); + +#elif SOC_TOUCH_SENSOR_VERSION == 3 // ESP32P4 /* * Tune the touch pad frequency. * Note: Must be called before setting up touch pads */ void touchSetConfig(uint32_t _div_num, uint8_t coarse_freq_tune, uint8_t fine_freq_tune); +#endif + +#if SOC_TOUCH_SENSOR_VERSION == 1 +/* + * Specific functions to ESP32 + * Tells the driver if it shall activate the ISR if the sensor is Lower or Higher than the Threshold + * Default if Lower. + * Note: Must be called before setting up touch pads + **/ +void touchInterruptSetThresholdDirection(bool mustbeLower); +#endif /* * Read touch pad value. @@ -86,6 +125,5 @@ void touchSleepWakeUpEnable(uint8_t pin, touch_value_t threshold); } #endif -#endif /* SOC_TOUCH_SENSOR_VERSION == 3 */ #endif /* SOC_TOUCH_SENSOR_SUPPORTED */ #endif /* MAIN_ESP32_HAL_TOUCH_H_ */ diff --git a/cores/esp32/esp32-hal-touch.c b/cores/esp32/esp32-hal-touch.c deleted file mode 100644 index 701bf6d16c9..00000000000 --- a/cores/esp32/esp32-hal-touch.c +++ /dev/null @@ -1,329 +0,0 @@ -// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at - -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -#include "soc/soc_caps.h" - -#if SOC_TOUCH_SENSOR_SUPPORTED -#if SOC_TOUCH_SENSOR_VERSION <= 2 // ESP32, ESP32S2, ESP32S3 - -#include "driver/touch_sensor.h" -#include "esp32-hal-touch.h" -#include "esp32-hal-periman.h" - -/* - Internal Private Touch Data Structure and Functions -*/ - -#if SOC_TOUCH_SENSOR_VERSION == 1 // ESP32 -static uint16_t __touchSleepCycles = 0x1000; -static uint16_t __touchMeasureCycles = 0x1000; -#elif SOC_TOUCH_SENSOR_VERSION == 2 // ESP32S2, ESP32S3 -static uint16_t __touchSleepCycles = TOUCH_PAD_SLEEP_CYCLE_DEFAULT; -static uint16_t __touchMeasureCycles = TOUCH_PAD_MEASURE_CYCLE_DEFAULT; -#endif - -typedef void (*voidFuncPtr)(void); -typedef void (*voidArgFuncPtr)(void *); - -typedef struct { - voidFuncPtr fn; - bool callWithArgs; - void *arg; -#if SOC_TOUCH_SENSOR_VERSION == 2 // Only for ESP32S2 and ESP32S3 - bool lastStatusIsPressed; -#endif -} TouchInterruptHandle_t; - -static TouchInterruptHandle_t __touchInterruptHandlers[SOC_TOUCH_SENSOR_NUM] = { - 0, -}; - -static uint8_t used_pads = 0; -static bool initialized = false; -static bool channels_initialized[SOC_TOUCH_SENSOR_NUM] = {false}; - -static void ARDUINO_ISR_ATTR __touchISR(void *arg) { -#if SOC_TOUCH_SENSOR_VERSION == 1 // ESP32 - uint32_t pad_intr = touch_pad_get_status(); - //clear interrupt - touch_pad_clear_status(); - // call Pad ISR User callback - for (int i = 0; i < SOC_TOUCH_SENSOR_NUM; i++) { - if ((pad_intr >> i) & 0x01) { - if (__touchInterruptHandlers[i].fn) { - // keeping backward compatibility with "void cb(void)" and with new "void cb(vooid *)" - if (__touchInterruptHandlers[i].callWithArgs) { - ((voidArgFuncPtr)__touchInterruptHandlers[i].fn)(__touchInterruptHandlers[i].arg); - } else { - __touchInterruptHandlers[i].fn(); - } - } - } - } -#elif SOC_TOUCH_SENSOR_VERSION == 2 // ESP32S2, ESP32S3 - touch_pad_intr_mask_t evt = touch_pad_read_intr_status_mask(); - uint8_t pad_num = touch_pad_get_current_meas_channel(); - if (evt & TOUCH_PAD_INTR_MASK_ACTIVE) { - // touch has been pressed / touched - __touchInterruptHandlers[pad_num].lastStatusIsPressed = true; - } - if (evt & TOUCH_PAD_INTR_MASK_INACTIVE) { - // touch has been released / untouched - __touchInterruptHandlers[pad_num].lastStatusIsPressed = false; - } - if (__touchInterruptHandlers[pad_num].fn) { - // keeping backward compatibility with "void cb(void)" and with new "void cb(vooid *)" - if (__touchInterruptHandlers[pad_num].callWithArgs) { - ((voidArgFuncPtr)__touchInterruptHandlers[pad_num].fn)(__touchInterruptHandlers[pad_num].arg); - } else { - __touchInterruptHandlers[pad_num].fn(); - } - } -#endif -} - -static void __touchSetCycles(uint16_t measure, uint16_t sleep) { - __touchSleepCycles = sleep; - __touchMeasureCycles = measure; -#if SOC_TOUCH_SENSOR_VERSION == 1 // ESP32 - touch_pad_set_measurement_clock_cycles(measure); -#elif SOC_TOUCH_SENSOR_VERSION == 2 // ESP32S2, ESP32S3 - touch_pad_set_charge_discharge_times(measure); -#endif - touch_pad_set_measurement_interval(sleep); -} - -static bool touchDetachBus(void *pin) { - int8_t pad = digitalPinToTouchChannel((int)(pin - 1)); - channels_initialized[pad] = false; - used_pads--; - if (used_pads == 0) { - if (touch_pad_deinit() != ESP_OK) //deinit touch module, as no pads are used - { - log_e("Touch module deinit failed!"); - return false; - } - initialized = false; - } - return true; -} - -static void __touchInit() { - if (initialized) { - return; - } - - esp_err_t err = ESP_OK; - -#if SOC_TOUCH_SENSOR_VERSION == 1 // ESP32 - err = touch_pad_init(); - if (err != ESP_OK) { - goto err; - } - // the next two lines will drive the touch reading values -- both will return ESP_OK - touch_pad_set_voltage(TOUCH_HVOLT_2V7, TOUCH_LVOLT_0V5, TOUCH_HVOLT_ATTEN_0V); - touch_pad_set_measurement_clock_cycles(__touchMeasureCycles); - touch_pad_set_measurement_interval(__touchSleepCycles); - // Touch Sensor Timer initiated - touch_pad_set_fsm_mode(TOUCH_FSM_MODE_TIMER); // returns ESP_OK - err = touch_pad_filter_start(10); - if (err != ESP_OK) { - goto err; - } - // keep ISR activated - it can run all together (ISR + touchRead()) - err = touch_pad_isr_register(__touchISR, NULL); - if (err != ESP_OK) { - goto err; - } - touch_pad_intr_enable(); // returns ESP_OK -#elif SOC_TOUCH_SENSOR_VERSION == 2 // ESP32S2, ESP32S3 - err = touch_pad_init(); - if (err != ESP_OK) { - goto err; - } - // the next lines will drive the touch reading values -- all os them return ESP_OK - touch_pad_set_charge_discharge_times(__touchMeasureCycles); - touch_pad_set_measurement_interval(__touchSleepCycles); - touch_pad_set_voltage(TOUCH_PAD_HIGH_VOLTAGE_THRESHOLD, TOUCH_PAD_LOW_VOLTAGE_THRESHOLD, TOUCH_PAD_ATTEN_VOLTAGE_THRESHOLD); - touch_pad_set_idle_channel_connect(TOUCH_PAD_IDLE_CH_CONNECT_DEFAULT); - touch_pad_denoise_t denoise = { - .grade = TOUCH_PAD_DENOISE_BIT4, - .cap_level = TOUCH_PAD_DENOISE_CAP_L4, - }; - touch_pad_denoise_set_config(&denoise); - touch_pad_denoise_enable(); - // Touch Sensor Timer initiated - touch_pad_set_fsm_mode(TOUCH_FSM_MODE_TIMER); // returns ESP_OK - touch_pad_fsm_start(); // returns ESP_OK - //ISR setup moved to __touchChannelInit -#endif - initialized = true; - return; -err: - log_e(" Touch sensor initialization error."); - initialized = false; - return; -} - -static void __touchChannelInit(int pad) { - if (channels_initialized[pad]) { - return; - } - -#if SOC_TOUCH_SENSOR_VERSION == 1 // ESP32 - // Initial no Threshold and setup - __touchInterruptHandlers[pad].fn = NULL; - touch_pad_config(pad, TOUCH_PAD_THRESHOLD_MAX); // returns ESP_OK -#elif SOC_TOUCH_SENSOR_VERSION == 2 // ESP32S2, ESP32S3 - // Initial no Threshold and setup - __touchInterruptHandlers[pad].fn = NULL; - touch_pad_config(pad); // returns ESP_OK - // keep ISR activated - it can run all together (ISR + touchRead()) - esp_err_t err = touch_pad_isr_register(__touchISR, NULL, TOUCH_PAD_INTR_MASK_ACTIVE | TOUCH_PAD_INTR_MASK_INACTIVE); - if (err != ESP_OK) { - log_e(" Touch sensor initialization error."); - return; - } - touch_pad_intr_enable(TOUCH_PAD_INTR_MASK_ACTIVE | TOUCH_PAD_INTR_MASK_INACTIVE); // returns ESP_OK -#endif - - channels_initialized[pad] = true; - used_pads++; - delay(20); //delay needed before reading from touch channel after config -} - -static touch_value_t __touchRead(uint8_t pin) { - int8_t pad = digitalPinToTouchChannel(pin); - if (pad < 0) { - log_e(" No touch pad on selected pin!"); - return 0; - } - - if (perimanGetPinBus(pin, ESP32_BUS_TYPE_TOUCH) == NULL) { - perimanSetBusDeinit(ESP32_BUS_TYPE_TOUCH, touchDetachBus); - if (!perimanClearPinBus(pin)) { - return 0; - } - __touchInit(); - __touchChannelInit(pad); - - if (!perimanSetPinBus(pin, ESP32_BUS_TYPE_TOUCH, (void *)(pin + 1), -1, pad)) { - touchDetachBus((void *)(pin + 1)); - return 0; - } - } - - touch_value_t touch_value; - touch_pad_read_raw_data(pad, &touch_value); - - return touch_value; -} - -static void __touchConfigInterrupt(uint8_t pin, void (*userFunc)(void), void *Args, touch_value_t threshold, bool callWithArgs) { - int8_t pad = digitalPinToTouchChannel(pin); - if (pad < 0) { - log_e(" No touch pad on selected pin!"); - return; - } - - if (userFunc == NULL) { - // detach ISR User Call - __touchInterruptHandlers[pad].fn = NULL; - threshold = TOUCH_PAD_THRESHOLD_MAX; // deactivate the ISR with SOC_TOUCH_PAD_THRESHOLD_MAX - } else { - // attach ISR User Call - __touchInit(); - __touchChannelInit(pad); - __touchInterruptHandlers[pad].fn = userFunc; - __touchInterruptHandlers[pad].callWithArgs = callWithArgs; - __touchInterruptHandlers[pad].arg = Args; - } - - touch_pad_set_thresh(pad, threshold); -} - -// it keeps backwards compatibility -static void __touchAttachInterrupt(uint8_t pin, void (*userFunc)(void), touch_value_t threshold) { - __touchConfigInterrupt(pin, userFunc, NULL, threshold, false); -} - -// new additional version of the API with User Args -static void __touchAttachArgsInterrupt(uint8_t pin, void (*userFunc)(void), void *args, touch_value_t threshold) { - __touchConfigInterrupt(pin, userFunc, args, threshold, true); -} - -// new additional API to detach touch ISR -static void __touchDettachInterrupt(uint8_t pin) { - __touchConfigInterrupt(pin, NULL, NULL, 0, false); // userFunc as NULL acts as detaching -} - -/* - External Public Touch API Functions -*/ - -#if SOC_TOUCH_SENSOR_VERSION == 1 // Only for ESP32 SoC -void touchInterruptSetThresholdDirection(bool mustbeLower) { - if (mustbeLower) { - touch_pad_set_trigger_mode(TOUCH_TRIGGER_BELOW); - } else { - touch_pad_set_trigger_mode(TOUCH_TRIGGER_ABOVE); - } -} -#elif SOC_TOUCH_SENSOR_VERSION == 2 // Only for ESP32S2 and ESP32S3 -// returns true if touch pad has been and continues pressed and false otherwise -bool touchInterruptGetLastStatus(uint8_t pin) { - int8_t pad = digitalPinToTouchChannel(pin); - if (pad < 0) { - return false; - } - - return __touchInterruptHandlers[pad].lastStatusIsPressed; -} -#endif - -void touchSleepWakeUpEnable(uint8_t pin, touch_value_t threshold) { - int8_t pad = digitalPinToTouchChannel(pin); - if (pad < 0) { - log_e(" No touch pad on selected pin!"); - return; - } - - if (perimanGetPinBus(pin, ESP32_BUS_TYPE_TOUCH) == NULL) { - perimanSetBusDeinit(ESP32_BUS_TYPE_TOUCH, touchDetachBus); - __touchInit(); - __touchChannelInit(pad); - if (!perimanSetPinBus(pin, ESP32_BUS_TYPE_TOUCH, (void *)(pin + 1), -1, pad)) { - log_e("Failed to set bus to Peripheral manager"); - touchDetachBus((void *)(pin + 1)); - return; - } - } -#if SOC_TOUCH_SENSOR_VERSION == 1 // Only for ESP32 SoC - touch_pad_set_thresh(pad, threshold); - -#elif SOC_TOUCH_SENSOR_VERSION == 2 - touch_pad_sleep_channel_enable(pad, true); - touch_pad_sleep_set_threshold(pad, threshold); - -#endif - esp_sleep_enable_touchpad_wakeup(); -} - -extern touch_value_t touchRead(uint8_t) __attribute__((weak, alias("__touchRead"))); -extern void touchAttachInterrupt(uint8_t, voidFuncPtr, touch_value_t) __attribute__((weak, alias("__touchAttachInterrupt"))); -extern void touchAttachInterruptArg(uint8_t, voidArgFuncPtr, void *, touch_value_t) __attribute__((weak, alias("__touchAttachArgsInterrupt"))); -extern void touchDetachInterrupt(uint8_t) __attribute__((weak, alias("__touchDettachInterrupt"))); -extern void touchSetCycles(uint16_t, uint16_t) __attribute__((weak, alias("__touchSetCycles"))); - -#endif /* SOC_TOUCH_SENSOR_VERSION <= 2 */ -#endif /* SOC_TOUCH_SENSOR_SUPPORTED */ diff --git a/cores/esp32/esp32-hal-touch.h b/cores/esp32/esp32-hal-touch.h deleted file mode 100644 index 4b06c7db766..00000000000 --- a/cores/esp32/esp32-hal-touch.h +++ /dev/null @@ -1,103 +0,0 @@ -/* - Arduino.h - Main include file for the Arduino SDK - Copyright (c) 2005-2013 Arduino Team. All right reserved. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef MAIN_ESP32_HAL_TOUCH_H_ -#define MAIN_ESP32_HAL_TOUCH_H_ - -#include "soc/soc_caps.h" -#if SOC_TOUCH_SENSOR_SUPPORTED -#if SOC_TOUCH_SENSOR_VERSION <= 2 // ESP32 ESP32S2 ESP32S3 - -#ifdef __cplusplus -extern "C" { -#endif - -#include "esp32-hal.h" - -#if !SOC_TOUCH_SENSOR_SUPPORTED -#error Touch IDF driver Not supported! -#endif - -#if SOC_TOUCH_SENSOR_VERSION == 1 // ESP32 -typedef uint16_t touch_value_t; -#elif SOC_TOUCH_SENSOR_VERSION == 2 // ESP32S2 ESP32S3 -typedef uint32_t touch_value_t; -#endif - -/* - * Set cycles that measurement operation takes - * The result from touchRead, threshold and detection - * accuracy depend on these values. Defaults are - * 0x1000 for measure and 0x1000 for sleep. - * With default values touchRead takes 0.5ms - * */ -void touchSetCycles(uint16_t measure, uint16_t sleep); - -/* - * Read touch pad (for ESP32 values close to 0 mean touch detected / - * for ESP32-S2/S3 higher values mean touch detected) - * You can use this method to chose a good threshold value - * to use as value for touchAttachInterrupt - * */ -touch_value_t touchRead(uint8_t pin); - -/* - * Set function to be called if touch pad value falls (ESP32) - * below the given threshold / rises (ESP32-S2/S3) by given increment (threshold). - * Use touchRead to determine a proper threshold between touched and untouched state - * */ -void touchAttachInterrupt(uint8_t pin, void (*userFunc)(void), touch_value_t threshold); -void touchAttachInterruptArg(uint8_t pin, void (*userFunc)(void *), void *arg, touch_value_t threshold); -void touchDetachInterrupt(uint8_t pin); - -/* - * Specific functions to ESP32 - * Tells the driver if it shall activate the ISR if the sensor is Lower or Higher than the Threshold - * Default if Lower. - **/ - -#if SOC_TOUCH_SENSOR_VERSION == 1 // Only for ESP32 SoC -void touchInterruptSetThresholdDirection(bool mustbeLower); -#endif - -/* - * Specific functions to ESP32-S2 and ESP32-S3 - * Returns true when the latest ISR status for the Touchpad is that it is touched (Active) - * and false when the Touchpad is untoouched (Inactive) - * This function can be used in conjunction with ISR User callback in order to take action - * as soon as the touchpad is touched and/or released - **/ - -#if SOC_TOUCH_SENSOR_VERSION == 2 // Only for ESP32S2 and ESP32S3 -// returns true if touch pad has been and continues pressed and false otherwise -bool touchInterruptGetLastStatus(uint8_t pin); -#endif - -/* - * Setup touch pad wake up from deep sleep with given threshold. - **/ -void touchSleepWakeUpEnable(uint8_t pin, touch_value_t threshold); - -#ifdef __cplusplus -} -#endif - -#endif /* SOC_TOUCH_SENSOR_VERSION <= 2 */ -#endif /* SOC_TOUCH_SENSOR_SUPPORTED */ -#endif /* MAIN_ESP32_HAL_TOUCH_H_ */ diff --git a/cores/esp32/esp32-hal.h b/cores/esp32/esp32-hal.h index 5ed99aeb205..e2ca9309fe0 100644 --- a/cores/esp32/esp32-hal.h +++ b/cores/esp32/esp32-hal.h @@ -86,7 +86,6 @@ void yield(void); #include "esp32-hal-matrix.h" #include "esp32-hal-uart.h" #include "esp32-hal-gpio.h" -#include "esp32-hal-touch.h" #include "esp32-hal-touch-ng.h" #include "esp32-hal-dac.h" #include "esp32-hal-adc.h" diff --git a/libraries/ESP32/examples/Touch/TouchButton/TouchButton.ino b/libraries/ESP32/examples/Touch/TouchButton/TouchButton.ino index 43f3bc36592..8ebe2f00cbc 100644 --- a/libraries/ESP32/examples/Touch/TouchButton/TouchButton.ino +++ b/libraries/ESP32/examples/Touch/TouchButton/TouchButton.ino @@ -3,44 +3,53 @@ This is an example how to use Touch Intrrerupts The sketch will tell when it is touched and then released as like a push-button -This method based on touchInterruptSetThresholdDirection() is only available for ESP32 +This method based on touchInterruptGetLastStatus() */ #include "Arduino.h" -int threshold = 40; -bool touchActive = false; -bool lastTouchActive = false; -bool testingLower = true; - -void gotTouchEvent() { - if (lastTouchActive != testingLower) { - touchActive = !touchActive; - testingLower = !testingLower; - // Touch ISR will be inverted: Lower <--> Higher than the Threshold after ISR event is noticed - touchInterruptSetThresholdDirection(testingLower); - } +int threshold = 0; // if 0 is used, benchmark value is used. Its by default 1,5% change, can be changed by touchSetDefaultThreshold(float percentage) +bool touch1detected = false; +bool touch2detected = false; + +void gotTouch1() { + touch1detected = true; +} + +void gotTouch2() { + touch2detected = true; } void setup() { Serial.begin(115200); delay(1000); // give me time to bring up serial monitor - Serial.println("ESP32 Touch Interrupt Test"); - touchAttachInterrupt(T2, gotTouchEvent, threshold); - // Touch ISR will be activated when touchRead is lower than the Threshold - touchInterruptSetThresholdDirection(testingLower); + //Optional: Set the threshold to 5% of the benchmark value. Only effective if threshold = 0. + touchSetDefaultThreshold(5); + + //Set the touch pads + Serial.println("\n ESP32 Touch Interrupt Test\n"); + touchAttachInterrupt(T0, gotTouch1, threshold); + touchAttachInterrupt(T2, gotTouch2, threshold); } void loop() { - if (lastTouchActive != touchActive) { - lastTouchActive = touchActive; - if (touchActive) { - Serial.println(" ---- Touch was Pressed"); + if (touch1detected) { + touch1detected = false; + if (touchInterruptGetLastStatus(T1)) { + Serial.println(" --- T1 Touched"); } else { - Serial.println(" ---- Touch was Released"); + Serial.println(" --- T1 Released"); } } - Serial.printf("T2 pin2 = %d \n", touchRead(T2)); - delay(125); + if (touch2detected) { + touch2detected = false; + if (touchInterruptGetLastStatus(T2)) { + Serial.println(" --- T2 Touched"); + } else { + Serial.println(" --- T2 Released"); + } + } + + delay(80); } diff --git a/libraries/ESP32/examples/Touch/TouchButton/ci.json b/libraries/ESP32/examples/Touch/TouchButton/ci.json index cec76a84f9d..c0ecf9fc0a5 100644 --- a/libraries/ESP32/examples/Touch/TouchButton/ci.json +++ b/libraries/ESP32/examples/Touch/TouchButton/ci.json @@ -1,5 +1,5 @@ { "requires": [ - "CONFIG_SOC_TOUCH_VERSION_1=y" + "CONFIG_SOC_TOUCH_SENSOR_SUPPORTED=y" ] } diff --git a/libraries/ESP32/examples/Touch/TouchButtonV2/TouchButtonV2.ino b/libraries/ESP32/examples/Touch/TouchButtonV2/TouchButtonV2.ino deleted file mode 100644 index df9b3f41149..00000000000 --- a/libraries/ESP32/examples/Touch/TouchButtonV2/TouchButtonV2.ino +++ /dev/null @@ -1,51 +0,0 @@ -/* - -This is an example how to use Touch Intrrerupts -The sketch will tell when it is touched and then released as like a push-button - -This method based on touchInterruptGetLastStatus() is only available for ESP32 S2 and S3 -*/ - -#include "Arduino.h" - -int threshold = 1500; // ESP32S2 -bool touch1detected = false; -bool touch2detected = false; - -void gotTouch1() { - touch1detected = true; -} - -void gotTouch2() { - touch2detected = true; -} - -void setup() { - Serial.begin(115200); - delay(1000); // give me time to bring up serial monitor - - Serial.println("\n ESP32 Touch Interrupt Test\n"); - touchAttachInterrupt(T1, gotTouch1, threshold); - touchAttachInterrupt(T2, gotTouch2, threshold); -} - -void loop() { - if (touch1detected) { - touch1detected = false; - if (touchInterruptGetLastStatus(T1)) { - Serial.println(" --- T1 Touched"); - } else { - Serial.println(" --- T1 Released"); - } - } - if (touch2detected) { - touch2detected = false; - if (touchInterruptGetLastStatus(T2)) { - Serial.println(" --- T2 Touched"); - } else { - Serial.println(" --- T2 Released"); - } - } - - delay(80); -} diff --git a/libraries/ESP32/examples/Touch/TouchButtonV2/ci.json b/libraries/ESP32/examples/Touch/TouchButtonV2/ci.json deleted file mode 100644 index 2710fa7940e..00000000000 --- a/libraries/ESP32/examples/Touch/TouchButtonV2/ci.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "requires": [ - "CONFIG_SOC_TOUCH_VERSION_2=y" - ] -} diff --git a/tests/validation/touch/touch.ino b/tests/validation/touch/touch.ino index 97aac8a65e6..2e5910fbb26 100644 --- a/tests/validation/touch/touch.ino +++ b/tests/validation/touch/touch.ino @@ -1,10 +1,6 @@ #include #include "soc/soc_caps.h" -#include "driver/touch_pad.h" - -#if SOC_TOUCH_SENSOR_VERSION == 3 #include "hal/touch_sensor_ll.h" -#endif #if CONFIG_IDF_TARGET_ESP32 @@ -82,7 +78,7 @@ void gotTouch2() { */ static void test_press_fake(touch_pad_t pad_num) { #if SOC_TOUCH_SENSOR_VERSION <= 2 - touch_pad_set_cnt_mode(pad_num, TOUCH_PAD_SLOPE_1, TOUCH_PAD_TIE_OPT_DEFAULT); + touch_ll_set_charge_speed(pad_num,TOUCH_CHARGE_SPEED_4); #else touch_ll_set_internal_capacitor(0x7f); #endif @@ -93,7 +89,7 @@ static void test_press_fake(touch_pad_t pad_num) { */ static void test_release_fake(touch_pad_t pad_num) { #if SOC_TOUCH_SENSOR_VERSION <= 2 - touch_pad_set_cnt_mode(pad_num, TOUCH_PAD_SLOPE_7, TOUCH_PAD_TIE_OPT_DEFAULT); + touch_ll_set_charge_speed(pad_num, TOUCH_CHARGE_SPEED_7); #else touch_ll_set_internal_capacitor(0); #endif @@ -192,6 +188,11 @@ void setup() { UNITY_BEGIN(); RUN_TEST(test_touch_read); + +#if SOC_TOUCH_SENSOR_VERSION == 3 + touch_ll_enable_internal_capacitor(true); +#endif + RUN_TEST(test_touch_interrtupt); RUN_TEST(test_touch_errors); UNITY_END(); From 41287a37b8a277fa1379c7d87031157074b05525 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Proch=C3=A1zka?= <90197375+P-R-O-C-H-Y@users.noreply.github.com> Date: Fri, 25 Jul 2025 18:29:35 +0200 Subject: [PATCH 02/38] fix(ci): Update touch test --- tests/validation/touch/touch.ino | 52 +++++++------------------------- 1 file changed, 11 insertions(+), 41 deletions(-) diff --git a/tests/validation/touch/touch.ino b/tests/validation/touch/touch.ino index 2e5910fbb26..315df0a5ee2 100644 --- a/tests/validation/touch/touch.ino +++ b/tests/validation/touch/touch.ino @@ -43,21 +43,14 @@ uint8_t TOUCH_GPIOS[] = {2, 3, 4, 5, 6 /*, 7, 8, 9, 10, 11, 12 ,13, 14, 15*/}; #define NO_TOUCH_GPIO 17 #endif +#define INTERRUPT_THRESHOLD 0 // Use benchmarked threshold + #if CONFIG_IDF_TARGET_ESP32 -#define RELEASED_VALUE 75 //75+ read value to pass test -#define PRESSED_VALUE 20 //20- read value to pass test -#define INTERRUPT_THRESHOLD 40 -#elif CONFIG_IDF_TARGET_ESP32S2 -#define RELEASED_VALUE 10000 //10000- read value to pass test -#define PRESSED_VALUE 42000 //40000+ read value to pass test -#define INTERRUPT_THRESHOLD 30000 -#elif CONFIG_IDF_TARGET_ESP32S3 -#define RELEASED_VALUE 25000 //25000- read value to pass test -#define PRESSED_VALUE 90000 //90000+ read value to pass test -#define INTERRUPT_THRESHOLD 80000 -#elif CONFIG_IDF_TARGET_ESP32P4 +#define PRESSED_VALUE_DIFFERENCE 200 //-200 read value difference against the unpressed value +#elif CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32S2 +#define PRESSED_VALUE_DIFFERENCE 2000 //2000+ read value difference against the unpressed value +#elif CONFIG_IDF_TARGET_ESP32P4 || CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 #define PRESSED_VALUE_DIFFERENCE 200 //200+ read value difference against the unpressed value -#define INTERRUPT_THRESHOLD 0 // Use benchmarked threshold #else #error Test not currently supported on this chip. Please adjust and try again! #endif @@ -109,31 +102,6 @@ void tearDown(void) { * Test Touch read on all available channels - compare values if reading is right */ void test_touch_read(void) { - -#if SOC_TOUCH_SENSOR_VERSION <= 2 - //TEST RELEASE STATE - for (int i = 0; i < sizeof(TOUCH_GPIOS); i++) { -#ifdef CONFIG_IDF_TARGET_ESP32 - TEST_ASSERT_GREATER_THAN(RELEASED_VALUE, touchRead(TOUCH_GPIOS[i])); -#else - TEST_ASSERT_LESS_THAN(RELEASED_VALUE, touchRead(TOUCH_GPIOS[i])); -#endif - } - - // TEST PRESS STATE - for (int j = 0; j < TEST_TOUCH_CHANNEL; j++) { - test_press_fake(touch_list[j]); - } - delay(100); - - for (int k = 0; k < sizeof(TOUCH_GPIOS); k++) { -#ifdef CONFIG_IDF_TARGET_ESP32 - TEST_ASSERT_LESS_THAN(PRESSED_VALUE, touchRead(TOUCH_GPIOS[k])); -#else - TEST_ASSERT_GREATER_THAN(PRESSED_VALUE, touchRead(TOUCH_GPIOS[k])); -#endif - } -#else //TOUCH V3 //TEST RELEASE STATE touch_value_t touch_unpressed[sizeof(TOUCH_GPIOS)]; for (int i = 0; i < sizeof(TOUCH_GPIOS); i++) { @@ -151,11 +119,14 @@ void test_touch_read(void) { touch_pressed[k] = touchRead(TOUCH_GPIOS[k]); } - // COMPARE PRESSED > UNPRESSED + // COMPARE PRESSED <-> UNPRESSED for (int l = 0; l < sizeof(TOUCH_GPIOS); l++) { +#if CONFIG_IDF_TARGET_ESP32 + TEST_ASSERT_LESS_THAN((touch_unpressed[l] - PRESSED_VALUE_DIFFERENCE), touch_pressed[l]); +#else TEST_ASSERT_GREATER_THAN((touch_unpressed[l] + PRESSED_VALUE_DIFFERENCE), touch_pressed[l]); - } #endif + } } void test_touch_interrtupt(void) { @@ -166,7 +137,6 @@ void test_touch_interrtupt(void) { test_press_fake(touch_list[0]); test_press_fake(touch_list[1]); - delay(300); touchDetachInterrupt(TOUCH_GPIOS[0]); touchDetachInterrupt(TOUCH_GPIOS[1]); From 0a3658044fa78c1f770b34c051d11855e8e25886 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Proch=C3=A1zka?= <90197375+P-R-O-C-H-Y@users.noreply.github.com> Date: Fri, 25 Jul 2025 18:42:28 +0200 Subject: [PATCH 03/38] fix(touch): Update example and fix config --- cores/esp32/esp32-hal-touch-ng.c | 4 +--- .../examples/Touch/TouchInterrupt/TouchInterrupt.ino | 10 +++++----- libraries/ESP32/examples/Touch/TouchRead/TouchRead.ino | 4 ++-- 3 files changed, 8 insertions(+), 10 deletions(-) diff --git a/cores/esp32/esp32-hal-touch-ng.c b/cores/esp32/esp32-hal-touch-ng.c index 392f404bae6..479427861a3 100644 --- a/cores/esp32/esp32-hal-touch-ng.c +++ b/cores/esp32/esp32-hal-touch-ng.c @@ -14,7 +14,6 @@ #include "soc/soc_caps.h" #if SOC_TOUCH_SENSOR_SUPPORTED -//#if SOC_TOUCH_SENSOR_VERSION == 3 // ESP32P4 for now #include "esp32-hal-touch-ng.h" #include "esp32-hal-periman.h" @@ -228,7 +227,7 @@ static void __touchInit() { #elif SOC_TOUCH_SENSOR_VERSION == 2 // ESP32S2, ESP32S3 touch_sensor_sample_config_t single_sample_cfg = TOUCH_SENSOR_V2_DEFAULT_SAMPLE_CONFIG(_duration_ms, _volt_low, _volt_high); #elif SOC_TOUCH_SENSOR_VERSION == 3 // ESP32P4 - touch_sensor_sample_config_t single_sample_cfg = TOUCH_SENSOR_V3_DEFAULT_SAMPLE_CONFIG(_sample_num, _div_num, _coarse_freq_tune, _fine_freq_tune); + touch_sensor_sample_config_t single_sample_cfg = TOUCH_SENSOR_V3_DEFAULT_SAMPLE_CONFIG(_div_num, _coarse_freq_tune, _fine_freq_tune); #endif touch_sensor_sample_config_t sample_cfg[_sample_num] = {}; sample_cfg[0] = single_sample_cfg; @@ -532,5 +531,4 @@ extern void touchAttachInterrupt(uint8_t, voidFuncPtr, touch_value_t) __attribut extern void touchAttachInterruptArg(uint8_t, voidArgFuncPtr, void *, touch_value_t) __attribute__((weak, alias("__touchAttachArgsInterrupt"))); extern void touchDetachInterrupt(uint8_t) __attribute__((weak, alias("__touchDettachInterrupt"))); -//#endif /* SOC_TOUCH_SENSOR_VERSION == 3 */ #endif /* SOC_TOUCH_SENSOR_SUPPORTED */ diff --git a/libraries/ESP32/examples/Touch/TouchInterrupt/TouchInterrupt.ino b/libraries/ESP32/examples/Touch/TouchInterrupt/TouchInterrupt.ino index 3b4e5f0b9e9..08e10dc0fac 100644 --- a/libraries/ESP32/examples/Touch/TouchInterrupt/TouchInterrupt.ino +++ b/libraries/ESP32/examples/Touch/TouchInterrupt/TouchInterrupt.ino @@ -3,11 +3,7 @@ This is an example how to use Touch Intrrerupts The bigger the threshold, the more sensible is the touch */ -#if CONFIG_IDF_TARGET_ESP32P4 -int threshold = 0; // when 0 is used, the benchmarked value will be used -#else -int threshold = 40; -#endif +int threshold = 0; // if 0 is used, benchmark value is used. Its by default 1,5% change, can be changed by touchSetDefaultThreshold(float percentage) bool touch1detected = false; bool touch2detected = false; @@ -23,6 +19,10 @@ void gotTouch2() { void setup() { Serial.begin(115200); delay(1000); // give me time to bring up serial monitor + + //Optional: Set the threshold to 5% of the benchmark value. Only effective if threshold = 0. + touchSetDefaultThreshold(5); + Serial.println("ESP32 Touch Interrupt Test"); touchAttachInterrupt(T2, gotTouch1, threshold); touchAttachInterrupt(T3, gotTouch2, threshold); diff --git a/libraries/ESP32/examples/Touch/TouchRead/TouchRead.ino b/libraries/ESP32/examples/Touch/TouchRead/TouchRead.ino index 8e93ba44691..ba221f3048f 100644 --- a/libraries/ESP32/examples/Touch/TouchRead/TouchRead.ino +++ b/libraries/ESP32/examples/Touch/TouchRead/TouchRead.ino @@ -1,5 +1,5 @@ // ESP32 Touch Test -// Just test touch pin - Touch0 is T0 which is on GPIO 4. +// Just test touch pin - Touch2 is T2 which is on GPIO 2. void setup() { Serial.begin(115200); @@ -8,6 +8,6 @@ void setup() { } void loop() { - Serial.println(touchRead(T1)); // get value using T0 + Serial.println(touchRead(T2)); // get value using T2 delay(1000); } From 09336ac7f73cc96491b98307a1e5e7f5e95898b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Proch=C3=A1zka?= <90197375+P-R-O-C-H-Y@users.noreply.github.com> Date: Fri, 25 Jul 2025 18:45:32 +0200 Subject: [PATCH 04/38] fix(touch): Use correct type --- cores/esp32/esp32-hal-touch-ng.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cores/esp32/esp32-hal-touch-ng.c b/cores/esp32/esp32-hal-touch-ng.c index 479427861a3..c3c5919a02d 100644 --- a/cores/esp32/esp32-hal-touch-ng.c +++ b/cores/esp32/esp32-hal-touch-ng.c @@ -43,7 +43,7 @@ static touch_volt_lim_h_t _volt_high = TOUCH_VOLT_LIM_H_1V7; static touch_intr_trig_mode_t _intr_trig_mode = TOUCH_INTR_TRIG_ON_BELOW_THRESH; #elif SOC_TOUCH_SENSOR_VERSION == 2 // ESP32S2, ESP32S3 static uint8_t _sample_num = 1; // only one sample configuration supported -static float _duration_ms = 500.0f; +static uint32_t _chg_times = 500; static touch_volt_lim_l_t _volt_low = TOUCH_VOLT_LIM_L_0V5; static touch_volt_lim_h_t _volt_high = TOUCH_VOLT_LIM_H_2V2; #elif SOC_TOUCH_SENSOR_VERSION == 3 // ESP32P4 @@ -225,7 +225,7 @@ static void __touchInit() { #if SOC_TOUCH_SENSOR_VERSION == 1 // ESP32 touch_sensor_sample_config_t single_sample_cfg = TOUCH_SENSOR_V1_DEFAULT_SAMPLE_CONFIG(_duration_ms, _volt_low, _volt_high); #elif SOC_TOUCH_SENSOR_VERSION == 2 // ESP32S2, ESP32S3 - touch_sensor_sample_config_t single_sample_cfg = TOUCH_SENSOR_V2_DEFAULT_SAMPLE_CONFIG(_duration_ms, _volt_low, _volt_high); + touch_sensor_sample_config_t single_sample_cfg = TOUCH_SENSOR_V2_DEFAULT_SAMPLE_CONFIG(_chg_times, _volt_low, _volt_high); #elif SOC_TOUCH_SENSOR_VERSION == 3 // ESP32P4 touch_sensor_sample_config_t single_sample_cfg = TOUCH_SENSOR_V3_DEFAULT_SAMPLE_CONFIG(_div_num, _coarse_freq_tune, _fine_freq_tune); #endif From 399094d2f805e63fefc093094624ae895d09ab02 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Proch=C3=A1zka?= <90197375+P-R-O-C-H-Y@users.noreply.github.com> Date: Fri, 25 Jul 2025 18:49:01 +0200 Subject: [PATCH 05/38] fix(touch): Remove old driver from cmake --- CMakeLists.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 3c9800dfe2b..34b1c3e77fb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -46,7 +46,6 @@ set(CORE_SRCS cores/esp32/esp32-hal-time.c cores/esp32/esp32-hal-timer.c cores/esp32/esp32-hal-tinyusb.c - cores/esp32/esp32-hal-touch.c cores/esp32/esp32-hal-touch-ng.c cores/esp32/esp32-hal-uart.c cores/esp32/esp32-hal-rmt.c From ec720a8e8d133e12466a63bdd2382fe5e46fd5f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Proch=C3=A1zka?= <90197375+P-R-O-C-H-Y@users.noreply.github.com> Date: Fri, 25 Jul 2025 18:52:46 +0200 Subject: [PATCH 06/38] fix(touch): Update touchSetConfig for S2 and S3 --- cores/esp32/esp32-hal-touch-ng.c | 15 ++++++++++++--- cores/esp32/esp32-hal-touch-ng.h | 10 +++++++++- 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/cores/esp32/esp32-hal-touch-ng.c b/cores/esp32/esp32-hal-touch-ng.c index c3c5919a02d..357db07746b 100644 --- a/cores/esp32/esp32-hal-touch-ng.c +++ b/cores/esp32/esp32-hal-touch-ng.c @@ -491,8 +491,7 @@ void touchSetTiming(float measure, uint32_t sleep) { __touchMeasureTime = measure; } -#if SOC_TOUCH_SENSOR_VERSION == 1 || SOC_TOUCH_SENSOR_VERSION == 2 // ESP32, ESP32S2, ESP32S3 - +#if SOC_TOUCH_SENSOR_VERSION == 1 // ESP32 void touchSetConfig(float duration_ms, touch_volt_lim_l_t volt_low, touch_volt_lim_h_t volt_high) { if (initialized) { log_e("Touch sensor already initialized. Cannot set configuration."); @@ -503,8 +502,18 @@ void touchSetConfig(float duration_ms, touch_volt_lim_l_t volt_low, touch_volt_l _volt_high = volt_high; } -#elif SOC_TOUCH_SENSOR_VERSION == 3 // ESP32P4 +#elif SOC_TOUCH_SENSOR_VERSION == 2 // ESP32S2, ESP32S3 +void touchSetConfig(uint32_t chg_times, touch_volt_lim_l_t volt_low, touch_volt_lim_h_t volt_high) { + if (initialized) { + log_e("Touch sensor already initialized. Cannot set configuration."); + return; + } + _chg_times = chg_times; + _volt_low = volt_low; + _volt_high = volt_high; +} +#elif SOC_TOUCH_SENSOR_VERSION == 3 // ESP32P4 void touchSetConfig(uint32_t div_num, uint8_t coarse_freq_tune, uint8_t fine_freq_tune) { if (initialized) { log_e("Touch sensor already initialized. Cannot set configuration."); diff --git a/cores/esp32/esp32-hal-touch-ng.h b/cores/esp32/esp32-hal-touch-ng.h index 23c00983092..fba69db4ec7 100644 --- a/cores/esp32/esp32-hal-touch-ng.h +++ b/cores/esp32/esp32-hal-touch-ng.h @@ -59,7 +59,7 @@ typedef uint32_t touch_value_t; **/ void touchSetTiming(float measure, uint32_t sleep); -#if SOC_TOUCH_SENSOR_VERSION == 1 || SOC_TOUCH_SENSOR_VERSION == 2 // ESP32, ESP32S2, ESP32S3 +#if SOC_TOUCH_SENSOR_VERSION == 1 // ESP32 /* * @param[in] duration_ms The measurement duration of the touch channel * @param[in] volt_low The low voltage limit of the touch channel @@ -67,6 +67,14 @@ void touchSetTiming(float measure, uint32_t sleep); */ void touchSetConfig(float duration_ms, touch_volt_lim_l_t volt_low, touch_volt_lim_h_t volt_high); +#elif SOC_TOUCH_SENSOR_VERSION == 2 // ESP32S2, ESP32S3 +/* + * @param[in] chg_times The charge times of the touch channel + * @param[in] volt_low The low voltage limit of the touch channel + * @param[in] volt_high The high voltage limit of the touch channel + */ +void touchSetConfig(uint32_t chg_times, touch_volt_lim_l_t volt_low, touch_volt_lim_h_t volt_high); + #elif SOC_TOUCH_SENSOR_VERSION == 3 // ESP32P4 /* * Tune the touch pad frequency. From 7143d08112615b1287a0f3c3da662e0ee665236c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Proch=C3=A1zka?= <90197375+P-R-O-C-H-Y@users.noreply.github.com> Date: Fri, 25 Jul 2025 19:10:47 +0200 Subject: [PATCH 07/38] fix(touch): Revert old touch driver for older IDF --- cores/esp32/esp32-hal-touch-ng.c | 2 + cores/esp32/esp32-hal-touch-ng.h | 3 + cores/esp32/esp32-hal-touch.c | 329 +++++++++++++++++++++++++++++++ cores/esp32/esp32-hal-touch.h | 104 ++++++++++ cores/esp32/esp32-hal.h | 1 + 5 files changed, 439 insertions(+) create mode 100644 cores/esp32/esp32-hal-touch.c create mode 100644 cores/esp32/esp32-hal-touch.h diff --git a/cores/esp32/esp32-hal-touch-ng.c b/cores/esp32/esp32-hal-touch-ng.c index 357db07746b..8a550f01be8 100644 --- a/cores/esp32/esp32-hal-touch-ng.c +++ b/cores/esp32/esp32-hal-touch-ng.c @@ -14,6 +14,7 @@ #include "soc/soc_caps.h" #if SOC_TOUCH_SENSOR_SUPPORTED +#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 5, 0) || SOC_TOUCH_SENSOR_VERSION == 3 #include "esp32-hal-touch-ng.h" #include "esp32-hal-periman.h" @@ -540,4 +541,5 @@ extern void touchAttachInterrupt(uint8_t, voidFuncPtr, touch_value_t) __attribut extern void touchAttachInterruptArg(uint8_t, voidArgFuncPtr, void *, touch_value_t) __attribute__((weak, alias("__touchAttachArgsInterrupt"))); extern void touchDetachInterrupt(uint8_t) __attribute__((weak, alias("__touchDettachInterrupt"))); +#endif /* ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 5, 0) || SOC_TOUCH_SENSOR_VERSION == 3 */ #endif /* SOC_TOUCH_SENSOR_SUPPORTED */ diff --git a/cores/esp32/esp32-hal-touch-ng.h b/cores/esp32/esp32-hal-touch-ng.h index fba69db4ec7..ee5ff23b9fa 100644 --- a/cores/esp32/esp32-hal-touch-ng.h +++ b/cores/esp32/esp32-hal-touch-ng.h @@ -21,7 +21,9 @@ #define MAIN_ESP32_HAL_TOUCH_NEW_H_ #include "soc/soc_caps.h" + #if SOC_TOUCH_SENSOR_SUPPORTED +#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 5, 0) || SOC_TOUCH_SENSOR_VERSION == 3 #ifdef __cplusplus extern "C" { @@ -133,5 +135,6 @@ void touchSleepWakeUpEnable(uint8_t pin, touch_value_t threshold); } #endif +#endif /* ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 5, 0) || SOC_TOUCH_SENSOR_VERSION == 3 */ #endif /* SOC_TOUCH_SENSOR_SUPPORTED */ #endif /* MAIN_ESP32_HAL_TOUCH_H_ */ diff --git a/cores/esp32/esp32-hal-touch.c b/cores/esp32/esp32-hal-touch.c new file mode 100644 index 00000000000..cc158aee634 --- /dev/null +++ b/cores/esp32/esp32-hal-touch.c @@ -0,0 +1,329 @@ +// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at + +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +#include "soc/soc_caps.h" + +#if SOC_TOUCH_SENSOR_SUPPORTED +#if ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 5, 0) && SOC_TOUCH_SENSOR_VERSION <= 2 // ESP32, ESP32S2, ESP32S3 + +#include "driver/touch_sensor.h" +#include "esp32-hal-touch.h" +#include "esp32-hal-periman.h" + +/* + Internal Private Touch Data Structure and Functions +*/ + +#if SOC_TOUCH_SENSOR_VERSION == 1 // ESP32 +static uint16_t __touchSleepCycles = 0x1000; +static uint16_t __touchMeasureCycles = 0x1000; +#elif SOC_TOUCH_SENSOR_VERSION == 2 // ESP32S2, ESP32S3 +static uint16_t __touchSleepCycles = TOUCH_PAD_SLEEP_CYCLE_DEFAULT; +static uint16_t __touchMeasureCycles = TOUCH_PAD_MEASURE_CYCLE_DEFAULT; +#endif + +typedef void (*voidFuncPtr)(void); +typedef void (*voidArgFuncPtr)(void *); + +typedef struct { + voidFuncPtr fn; + bool callWithArgs; + void *arg; +#if SOC_TOUCH_SENSOR_VERSION == 2 // Only for ESP32S2 and ESP32S3 + bool lastStatusIsPressed; +#endif +} TouchInterruptHandle_t; + +static TouchInterruptHandle_t __touchInterruptHandlers[SOC_TOUCH_SENSOR_NUM] = { + 0, +}; + +static uint8_t used_pads = 0; +static bool initialized = false; +static bool channels_initialized[SOC_TOUCH_SENSOR_NUM] = {false}; + +static void ARDUINO_ISR_ATTR __touchISR(void *arg) { +#if SOC_TOUCH_SENSOR_VERSION == 1 // ESP32 + uint32_t pad_intr = touch_pad_get_status(); + //clear interrupt + touch_pad_clear_status(); + // call Pad ISR User callback + for (int i = 0; i < SOC_TOUCH_SENSOR_NUM; i++) { + if ((pad_intr >> i) & 0x01) { + if (__touchInterruptHandlers[i].fn) { + // keeping backward compatibility with "void cb(void)" and with new "void cb(vooid *)" + if (__touchInterruptHandlers[i].callWithArgs) { + ((voidArgFuncPtr)__touchInterruptHandlers[i].fn)(__touchInterruptHandlers[i].arg); + } else { + __touchInterruptHandlers[i].fn(); + } + } + } + } +#elif SOC_TOUCH_SENSOR_VERSION == 2 // ESP32S2, ESP32S3 + touch_pad_intr_mask_t evt = touch_pad_read_intr_status_mask(); + uint8_t pad_num = touch_pad_get_current_meas_channel(); + if (evt & TOUCH_PAD_INTR_MASK_ACTIVE) { + // touch has been pressed / touched + __touchInterruptHandlers[pad_num].lastStatusIsPressed = true; + } + if (evt & TOUCH_PAD_INTR_MASK_INACTIVE) { + // touch has been released / untouched + __touchInterruptHandlers[pad_num].lastStatusIsPressed = false; + } + if (__touchInterruptHandlers[pad_num].fn) { + // keeping backward compatibility with "void cb(void)" and with new "void cb(vooid *)" + if (__touchInterruptHandlers[pad_num].callWithArgs) { + ((voidArgFuncPtr)__touchInterruptHandlers[pad_num].fn)(__touchInterruptHandlers[pad_num].arg); + } else { + __touchInterruptHandlers[pad_num].fn(); + } + } +#endif +} + +static void __touchSetCycles(uint16_t measure, uint16_t sleep) { + __touchSleepCycles = sleep; + __touchMeasureCycles = measure; +#if SOC_TOUCH_SENSOR_VERSION == 1 // ESP32 + touch_pad_set_measurement_clock_cycles(measure); +#elif SOC_TOUCH_SENSOR_VERSION == 2 // ESP32S2, ESP32S3 + touch_pad_set_charge_discharge_times(measure); +#endif + touch_pad_set_measurement_interval(sleep); +} + +static bool touchDetachBus(void *pin) { + int8_t pad = digitalPinToTouchChannel((int)(pin - 1)); + channels_initialized[pad] = false; + used_pads--; + if (used_pads == 0) { + if (touch_pad_deinit() != ESP_OK) //deinit touch module, as no pads are used + { + log_e("Touch module deinit failed!"); + return false; + } + initialized = false; + } + return true; +} + +static void __touchInit() { + if (initialized) { + return; + } + + esp_err_t err = ESP_OK; + +#if SOC_TOUCH_SENSOR_VERSION == 1 // ESP32 + err = touch_pad_init(); + if (err != ESP_OK) { + goto err; + } + // the next two lines will drive the touch reading values -- both will return ESP_OK + touch_pad_set_voltage(TOUCH_HVOLT_2V7, TOUCH_LVOLT_0V5, TOUCH_HVOLT_ATTEN_0V); + touch_pad_set_measurement_clock_cycles(__touchMeasureCycles); + touch_pad_set_measurement_interval(__touchSleepCycles); + // Touch Sensor Timer initiated + touch_pad_set_fsm_mode(TOUCH_FSM_MODE_TIMER); // returns ESP_OK + err = touch_pad_filter_start(10); + if (err != ESP_OK) { + goto err; + } + // keep ISR activated - it can run all together (ISR + touchRead()) + err = touch_pad_isr_register(__touchISR, NULL); + if (err != ESP_OK) { + goto err; + } + touch_pad_intr_enable(); // returns ESP_OK +#elif SOC_TOUCH_SENSOR_VERSION == 2 // ESP32S2, ESP32S3 + err = touch_pad_init(); + if (err != ESP_OK) { + goto err; + } + // the next lines will drive the touch reading values -- all os them return ESP_OK + touch_pad_set_charge_discharge_times(__touchMeasureCycles); + touch_pad_set_measurement_interval(__touchSleepCycles); + touch_pad_set_voltage(TOUCH_PAD_HIGH_VOLTAGE_THRESHOLD, TOUCH_PAD_LOW_VOLTAGE_THRESHOLD, TOUCH_PAD_ATTEN_VOLTAGE_THRESHOLD); + touch_pad_set_idle_channel_connect(TOUCH_PAD_IDLE_CH_CONNECT_DEFAULT); + touch_pad_denoise_t denoise = { + .grade = TOUCH_PAD_DENOISE_BIT4, + .cap_level = TOUCH_PAD_DENOISE_CAP_L4, + }; + touch_pad_denoise_set_config(&denoise); + touch_pad_denoise_enable(); + // Touch Sensor Timer initiated + touch_pad_set_fsm_mode(TOUCH_FSM_MODE_TIMER); // returns ESP_OK + touch_pad_fsm_start(); // returns ESP_OK + //ISR setup moved to __touchChannelInit +#endif + initialized = true; + return; +err: + log_e(" Touch sensor initialization error."); + initialized = false; + return; +} + +static void __touchChannelInit(int pad) { + if (channels_initialized[pad]) { + return; + } + +#if SOC_TOUCH_SENSOR_VERSION == 1 // ESP32 + // Initial no Threshold and setup + __touchInterruptHandlers[pad].fn = NULL; + touch_pad_config(pad, TOUCH_PAD_THRESHOLD_MAX); // returns ESP_OK +#elif SOC_TOUCH_SENSOR_VERSION == 2 // ESP32S2, ESP32S3 + // Initial no Threshold and setup + __touchInterruptHandlers[pad].fn = NULL; + touch_pad_config(pad); // returns ESP_OK + // keep ISR activated - it can run all together (ISR + touchRead()) + esp_err_t err = touch_pad_isr_register(__touchISR, NULL, TOUCH_PAD_INTR_MASK_ACTIVE | TOUCH_PAD_INTR_MASK_INACTIVE); + if (err != ESP_OK) { + log_e(" Touch sensor initialization error."); + return; + } + touch_pad_intr_enable(TOUCH_PAD_INTR_MASK_ACTIVE | TOUCH_PAD_INTR_MASK_INACTIVE); // returns ESP_OK +#endif + + channels_initialized[pad] = true; + used_pads++; + delay(20); //delay needed before reading from touch channel after config +} + +static touch_value_t __touchRead(uint8_t pin) { + int8_t pad = digitalPinToTouchChannel(pin); + if (pad < 0) { + log_e(" No touch pad on selected pin!"); + return 0; + } + + if (perimanGetPinBus(pin, ESP32_BUS_TYPE_TOUCH) == NULL) { + perimanSetBusDeinit(ESP32_BUS_TYPE_TOUCH, touchDetachBus); + if (!perimanClearPinBus(pin)) { + return 0; + } + __touchInit(); + __touchChannelInit(pad); + + if (!perimanSetPinBus(pin, ESP32_BUS_TYPE_TOUCH, (void *)(pin + 1), -1, pad)) { + touchDetachBus((void *)(pin + 1)); + return 0; + } + } + + touch_value_t touch_value; + touch_pad_read_raw_data(pad, &touch_value); + + return touch_value; +} + +static void __touchConfigInterrupt(uint8_t pin, void (*userFunc)(void), void *Args, touch_value_t threshold, bool callWithArgs) { + int8_t pad = digitalPinToTouchChannel(pin); + if (pad < 0) { + log_e(" No touch pad on selected pin!"); + return; + } + + if (userFunc == NULL) { + // detach ISR User Call + __touchInterruptHandlers[pad].fn = NULL; + threshold = TOUCH_PAD_THRESHOLD_MAX; // deactivate the ISR with SOC_TOUCH_PAD_THRESHOLD_MAX + } else { + // attach ISR User Call + __touchInit(); + __touchChannelInit(pad); + __touchInterruptHandlers[pad].fn = userFunc; + __touchInterruptHandlers[pad].callWithArgs = callWithArgs; + __touchInterruptHandlers[pad].arg = Args; + } + + touch_pad_set_thresh(pad, threshold); +} + +// it keeps backwards compatibility +static void __touchAttachInterrupt(uint8_t pin, void (*userFunc)(void), touch_value_t threshold) { + __touchConfigInterrupt(pin, userFunc, NULL, threshold, false); +} + +// new additional version of the API with User Args +static void __touchAttachArgsInterrupt(uint8_t pin, void (*userFunc)(void), void *args, touch_value_t threshold) { + __touchConfigInterrupt(pin, userFunc, args, threshold, true); +} + +// new additional API to detach touch ISR +static void __touchDettachInterrupt(uint8_t pin) { + __touchConfigInterrupt(pin, NULL, NULL, 0, false); // userFunc as NULL acts as detaching +} + +/* + External Public Touch API Functions +*/ + +#if SOC_TOUCH_SENSOR_VERSION == 1 // Only for ESP32 SoC +void touchInterruptSetThresholdDirection(bool mustbeLower) { + if (mustbeLower) { + touch_pad_set_trigger_mode(TOUCH_TRIGGER_BELOW); + } else { + touch_pad_set_trigger_mode(TOUCH_TRIGGER_ABOVE); + } +} +#elif SOC_TOUCH_SENSOR_VERSION == 2 // Only for ESP32S2 and ESP32S3 +// returns true if touch pad has been and continues pressed and false otherwise +bool touchInterruptGetLastStatus(uint8_t pin) { + int8_t pad = digitalPinToTouchChannel(pin); + if (pad < 0) { + return false; + } + + return __touchInterruptHandlers[pad].lastStatusIsPressed; +} +#endif + +void touchSleepWakeUpEnable(uint8_t pin, touch_value_t threshold) { + int8_t pad = digitalPinToTouchChannel(pin); + if (pad < 0) { + log_e(" No touch pad on selected pin!"); + return; + } + + if (perimanGetPinBus(pin, ESP32_BUS_TYPE_TOUCH) == NULL) { + perimanSetBusDeinit(ESP32_BUS_TYPE_TOUCH, touchDetachBus); + __touchInit(); + __touchChannelInit(pad); + if (!perimanSetPinBus(pin, ESP32_BUS_TYPE_TOUCH, (void *)(pin + 1), -1, pad)) { + log_e("Failed to set bus to Peripheral manager"); + touchDetachBus((void *)(pin + 1)); + return; + } + } +#if SOC_TOUCH_SENSOR_VERSION == 1 // Only for ESP32 SoC + touch_pad_set_thresh(pad, threshold); + +#elif SOC_TOUCH_SENSOR_VERSION == 2 + touch_pad_sleep_channel_enable(pad, true); + touch_pad_sleep_set_threshold(pad, threshold); + +#endif + esp_sleep_enable_touchpad_wakeup(); +} + +extern touch_value_t touchRead(uint8_t) __attribute__((weak, alias("__touchRead"))); +extern void touchAttachInterrupt(uint8_t, voidFuncPtr, touch_value_t) __attribute__((weak, alias("__touchAttachInterrupt"))); +extern void touchAttachInterruptArg(uint8_t, voidArgFuncPtr, void *, touch_value_t) __attribute__((weak, alias("__touchAttachArgsInterrupt"))); +extern void touchDetachInterrupt(uint8_t) __attribute__((weak, alias("__touchDettachInterrupt"))); +extern void touchSetCycles(uint16_t, uint16_t) __attribute__((weak, alias("__touchSetCycles"))); + +#endif /* ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 5, 0) && SOC_TOUCH_SENSOR_VERSION <= 2 */ +#endif /* SOC_TOUCH_SENSOR_SUPPORTED */ \ No newline at end of file diff --git a/cores/esp32/esp32-hal-touch.h b/cores/esp32/esp32-hal-touch.h new file mode 100644 index 00000000000..709691ef658 --- /dev/null +++ b/cores/esp32/esp32-hal-touch.h @@ -0,0 +1,104 @@ +/* + Arduino.h - Main include file for the Arduino SDK + Copyright (c) 2005-2013 Arduino Team. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef MAIN_ESP32_HAL_TOUCH_H_ +#define MAIN_ESP32_HAL_TOUCH_H_ + +#include "soc/soc_caps.h" + +#if SOC_TOUCH_SENSOR_SUPPORTED +#if ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 5, 0) && SOC_TOUCH_SENSOR_VERSION <= 2 // ESP32, ESP32S2, ESP32S3 + +#ifdef __cplusplus +extern "C" { +#endif + +#include "esp32-hal.h" + +#if !SOC_TOUCH_SENSOR_SUPPORTED +#error Touch IDF driver Not supported! +#endif + +#if SOC_TOUCH_SENSOR_VERSION == 1 // ESP32 +typedef uint16_t touch_value_t; +#elif SOC_TOUCH_SENSOR_VERSION == 2 // ESP32S2 ESP32S3 +typedef uint32_t touch_value_t; +#endif + +/* + * Set cycles that measurement operation takes + * The result from touchRead, threshold and detection + * accuracy depend on these values. Defaults are + * 0x1000 for measure and 0x1000 for sleep. + * With default values touchRead takes 0.5ms + * */ +void touchSetCycles(uint16_t measure, uint16_t sleep); + +/* + * Read touch pad (for ESP32 values close to 0 mean touch detected / + * for ESP32-S2/S3 higher values mean touch detected) + * You can use this method to chose a good threshold value + * to use as value for touchAttachInterrupt + * */ +touch_value_t touchRead(uint8_t pin); + +/* + * Set function to be called if touch pad value falls (ESP32) + * below the given threshold / rises (ESP32-S2/S3) by given increment (threshold). + * Use touchRead to determine a proper threshold between touched and untouched state + * */ +void touchAttachInterrupt(uint8_t pin, void (*userFunc)(void), touch_value_t threshold); +void touchAttachInterruptArg(uint8_t pin, void (*userFunc)(void *), void *arg, touch_value_t threshold); +void touchDetachInterrupt(uint8_t pin); + +/* + * Specific functions to ESP32 + * Tells the driver if it shall activate the ISR if the sensor is Lower or Higher than the Threshold + * Default if Lower. + **/ + +#if SOC_TOUCH_SENSOR_VERSION == 1 // Only for ESP32 SoC +void touchInterruptSetThresholdDirection(bool mustbeLower); +#endif + +/* + * Specific functions to ESP32-S2 and ESP32-S3 + * Returns true when the latest ISR status for the Touchpad is that it is touched (Active) + * and false when the Touchpad is untoouched (Inactive) + * This function can be used in conjunction with ISR User callback in order to take action + * as soon as the touchpad is touched and/or released + **/ + +#if SOC_TOUCH_SENSOR_VERSION == 2 // Only for ESP32S2 and ESP32S3 +// returns true if touch pad has been and continues pressed and false otherwise +bool touchInterruptGetLastStatus(uint8_t pin); +#endif + +/* + * Setup touch pad wake up from deep sleep with given threshold. + **/ +void touchSleepWakeUpEnable(uint8_t pin, touch_value_t threshold); + +#ifdef __cplusplus +} +#endif + +#endif /* ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 5, 0) && SOC_TOUCH_SENSOR_VERSION <= 2 */ +#endif /* SOC_TOUCH_SENSOR_SUPPORTED */ +#endif /* MAIN_ESP32_HAL_TOUCH_H_ */ diff --git a/cores/esp32/esp32-hal.h b/cores/esp32/esp32-hal.h index e2ca9309fe0..5ed99aeb205 100644 --- a/cores/esp32/esp32-hal.h +++ b/cores/esp32/esp32-hal.h @@ -86,6 +86,7 @@ void yield(void); #include "esp32-hal-matrix.h" #include "esp32-hal-uart.h" #include "esp32-hal-gpio.h" +#include "esp32-hal-touch.h" #include "esp32-hal-touch-ng.h" #include "esp32-hal-dac.h" #include "esp32-hal-adc.h" From f691a428270247ec893daf2bf315532c7e037695 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Proch=C3=A1zka?= <90197375+P-R-O-C-H-Y@users.noreply.github.com> Date: Fri, 25 Jul 2025 19:14:11 +0200 Subject: [PATCH 08/38] fix(touch): Add missing include --- cores/esp32/esp32-hal-touch-ng.c | 1 + cores/esp32/esp32-hal-touch-ng.h | 1 + cores/esp32/esp32-hal-touch.c | 1 + cores/esp32/esp32-hal-touch.h | 1 + 4 files changed, 4 insertions(+) diff --git a/cores/esp32/esp32-hal-touch-ng.c b/cores/esp32/esp32-hal-touch-ng.c index 8a550f01be8..483a444b4a0 100644 --- a/cores/esp32/esp32-hal-touch-ng.c +++ b/cores/esp32/esp32-hal-touch-ng.c @@ -12,6 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. #include "soc/soc_caps.h" +#include "esp_idf_version.h" #if SOC_TOUCH_SENSOR_SUPPORTED #if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 5, 0) || SOC_TOUCH_SENSOR_VERSION == 3 diff --git a/cores/esp32/esp32-hal-touch-ng.h b/cores/esp32/esp32-hal-touch-ng.h index ee5ff23b9fa..988fdccda00 100644 --- a/cores/esp32/esp32-hal-touch-ng.h +++ b/cores/esp32/esp32-hal-touch-ng.h @@ -21,6 +21,7 @@ #define MAIN_ESP32_HAL_TOUCH_NEW_H_ #include "soc/soc_caps.h" +#include "esp_idf_version.h" #if SOC_TOUCH_SENSOR_SUPPORTED #if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 5, 0) || SOC_TOUCH_SENSOR_VERSION == 3 diff --git a/cores/esp32/esp32-hal-touch.c b/cores/esp32/esp32-hal-touch.c index cc158aee634..e611fa557f1 100644 --- a/cores/esp32/esp32-hal-touch.c +++ b/cores/esp32/esp32-hal-touch.c @@ -12,6 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. #include "soc/soc_caps.h" +#include "esp_idf_version.h" #if SOC_TOUCH_SENSOR_SUPPORTED #if ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 5, 0) && SOC_TOUCH_SENSOR_VERSION <= 2 // ESP32, ESP32S2, ESP32S3 diff --git a/cores/esp32/esp32-hal-touch.h b/cores/esp32/esp32-hal-touch.h index 709691ef658..44c99dce206 100644 --- a/cores/esp32/esp32-hal-touch.h +++ b/cores/esp32/esp32-hal-touch.h @@ -21,6 +21,7 @@ #define MAIN_ESP32_HAL_TOUCH_H_ #include "soc/soc_caps.h" +#include "esp_idf_version.h" #if SOC_TOUCH_SENSOR_SUPPORTED #if ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 5, 0) && SOC_TOUCH_SENSOR_VERSION <= 2 // ESP32, ESP32S2, ESP32S3 From 04459faf480c9fc81043741c6f277276485ccdfb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Proch=C3=A1zka?= <90197375+P-R-O-C-H-Y@users.noreply.github.com> Date: Fri, 25 Jul 2025 19:49:14 +0200 Subject: [PATCH 09/38] fix(touch): Update test and example --- CMakeLists.txt | 1 + .../examples/Touch/TouchButton/TouchButton.ino | 2 +- tests/validation/touch/touch.ino | 17 +++++++++++------ 3 files changed, 13 insertions(+), 7 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 34b1c3e77fb..3c9800dfe2b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -46,6 +46,7 @@ set(CORE_SRCS cores/esp32/esp32-hal-time.c cores/esp32/esp32-hal-timer.c cores/esp32/esp32-hal-tinyusb.c + cores/esp32/esp32-hal-touch.c cores/esp32/esp32-hal-touch-ng.c cores/esp32/esp32-hal-uart.c cores/esp32/esp32-hal-rmt.c diff --git a/libraries/ESP32/examples/Touch/TouchButton/TouchButton.ino b/libraries/ESP32/examples/Touch/TouchButton/TouchButton.ino index 8ebe2f00cbc..ac2b641be40 100644 --- a/libraries/ESP32/examples/Touch/TouchButton/TouchButton.ino +++ b/libraries/ESP32/examples/Touch/TouchButton/TouchButton.ino @@ -29,7 +29,7 @@ void setup() { //Set the touch pads Serial.println("\n ESP32 Touch Interrupt Test\n"); - touchAttachInterrupt(T0, gotTouch1, threshold); + touchAttachInterrupt(T1, gotTouch1, threshold); touchAttachInterrupt(T2, gotTouch2, threshold); } diff --git a/tests/validation/touch/touch.ino b/tests/validation/touch/touch.ino index 315df0a5ee2..abe450a27ab 100644 --- a/tests/validation/touch/touch.ino +++ b/tests/validation/touch/touch.ino @@ -4,28 +4,30 @@ #if CONFIG_IDF_TARGET_ESP32 -#define TEST_TOUCH_CHANNEL (9) +#define TEST_TOUCH_CHANNEL (7) static touch_pad_t touch_list[TEST_TOUCH_CHANNEL] = { TOUCH_PAD_NUM0, //TOUCH_PAD_NUM1 is GPIO0, for download. - TOUCH_PAD_NUM2, TOUCH_PAD_NUM3, TOUCH_PAD_NUM4, TOUCH_PAD_NUM5, TOUCH_PAD_NUM6, TOUCH_PAD_NUM7, TOUCH_PAD_NUM8, TOUCH_PAD_NUM9 + TOUCH_PAD_NUM2, TOUCH_PAD_NUM3, TOUCH_PAD_NUM4, TOUCH_PAD_NUM5, TOUCH_PAD_NUM6, TOUCH_PAD_NUM7 /*,TOUCH_PAD_NUM8, TOUCH_PAD_NUM9*/ }; -uint8_t TOUCH_GPIOS[] = {4, 2, 15, 13, 12, 14, 27, 33, 32}; +uint8_t TOUCH_GPIOS[] = {4,/* 0,*/ 2, 15, 13, 12, 14, 27/*, 33, 32*/}; #define NO_TOUCH_GPIO 25 #elif (CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3) -#define TEST_TOUCH_CHANNEL (12) //14 +#define TEST_TOUCH_CHANNEL (9) //14 static touch_pad_t touch_list[TEST_TOUCH_CHANNEL] = { TOUCH_PAD_NUM1, TOUCH_PAD_NUM2, TOUCH_PAD_NUM3, TOUCH_PAD_NUM4, TOUCH_PAD_NUM5, TOUCH_PAD_NUM6, TOUCH_PAD_NUM7, - TOUCH_PAD_NUM8, TOUCH_PAD_NUM9, TOUCH_PAD_NUM10, TOUCH_PAD_NUM11, TOUCH_PAD_NUM12 + TOUCH_PAD_NUM8, /*TOUCH_PAD_NUM9,*/ TOUCH_PAD_NUM10 + //TOUCH_PAD_NUM11, //Wrong reading + //TOUCH_PAD_NUM12, //Wrong reading //TOUCH_PAD_NUM13, //Wrong reading //TOUCH_PAD_NUM14 }; -uint8_t TOUCH_GPIOS[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 /*,13,14*/}; +uint8_t TOUCH_GPIOS[] = {1, 2, 3, 4, 5, 6, 7, 8,/*9,*/ 10/*, 11, 12, 13, 14*/}; #define NO_TOUCH_GPIO 17 @@ -120,6 +122,9 @@ void test_touch_read(void) { } // COMPARE PRESSED <-> UNPRESSED + for (int l = 0; l < sizeof(TOUCH_GPIOS); l++) { + log_v("Touch %d: %d -> %d", TOUCH_GPIOS[l], touch_unpressed[l], touch_pressed[l]); + } for (int l = 0; l < sizeof(TOUCH_GPIOS); l++) { #if CONFIG_IDF_TARGET_ESP32 TEST_ASSERT_LESS_THAN((touch_unpressed[l] - PRESSED_VALUE_DIFFERENCE), touch_pressed[l]); From 5653eb6906367bfd8132afb3f39052d15e76dc35 Mon Sep 17 00:00:00 2001 From: Nick Korotysh Date: Thu, 21 Aug 2025 11:06:56 +0200 Subject: [PATCH 10/38] refactor(ble): Pass primitive types by value There is no need to pass primitive types by reference, especially by non-const reference as it was in BLECharacteristic. Pass primitive types by value instead, as it should be, and used everywhere else except this one odd class. This allows allows to pass function result as `setValue()` argument without creating temporary variable. --- libraries/BLE/src/BLECharacteristic.cpp | 10 +++++----- libraries/BLE/src/BLECharacteristic.h | 10 +++++----- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/libraries/BLE/src/BLECharacteristic.cpp b/libraries/BLE/src/BLECharacteristic.cpp index 0234cd11cca..88a574fa177 100644 --- a/libraries/BLE/src/BLECharacteristic.cpp +++ b/libraries/BLE/src/BLECharacteristic.cpp @@ -375,14 +375,14 @@ void BLECharacteristic::setValue(String value) { setValue((uint8_t *)(value.c_str()), value.length()); } // setValue -void BLECharacteristic::setValue(uint16_t &data16) { +void BLECharacteristic::setValue(uint16_t data16) { uint8_t temp[2]; temp[0] = data16; temp[1] = data16 >> 8; setValue(temp, 2); } // setValue -void BLECharacteristic::setValue(uint32_t &data32) { +void BLECharacteristic::setValue(uint32_t data32) { uint8_t temp[4]; temp[0] = data32; temp[1] = data32 >> 8; @@ -391,7 +391,7 @@ void BLECharacteristic::setValue(uint32_t &data32) { setValue(temp, 4); } // setValue -void BLECharacteristic::setValue(int &data32) { +void BLECharacteristic::setValue(int data32) { uint8_t temp[4]; temp[0] = data32; temp[1] = data32 >> 8; @@ -400,12 +400,12 @@ void BLECharacteristic::setValue(int &data32) { setValue(temp, 4); } // setValue -void BLECharacteristic::setValue(float &data32) { +void BLECharacteristic::setValue(float data32) { float temp = data32; setValue((uint8_t *)&temp, 4); } // setValue -void BLECharacteristic::setValue(double &data64) { +void BLECharacteristic::setValue(double data64) { double temp = data64; setValue((uint8_t *)&temp, 8); } // setValue diff --git a/libraries/BLE/src/BLECharacteristic.h b/libraries/BLE/src/BLECharacteristic.h index 27df5a30c3e..580f71dc5e7 100644 --- a/libraries/BLE/src/BLECharacteristic.h +++ b/libraries/BLE/src/BLECharacteristic.h @@ -186,11 +186,11 @@ class BLECharacteristic { void setCallbacks(BLECharacteristicCallbacks *pCallbacks); void setValue(uint8_t *data, size_t size); void setValue(String value); - void setValue(uint16_t &data16); - void setValue(uint32_t &data32); - void setValue(int &data32); - void setValue(float &data32); - void setValue(double &data64); + void setValue(uint16_t data16); + void setValue(uint32_t data32); + void setValue(int data32); + void setValue(float data32); + void setValue(double data64); String toString(); uint16_t getHandle(); void setAccessPermissions(uint8_t perm); From c6517e463a53445fa389157465191419e579887b Mon Sep 17 00:00:00 2001 From: Nick Korotysh Date: Thu, 21 Aug 2025 11:17:26 +0200 Subject: [PATCH 11/38] refactor(ble): Simplify setValue() for primitive types ESP32 is little-endian architecture, so the code that filled temporary arrays created from integers basically did nothing. Pass primitives as 'buffers' to generic `setValue()` instead. Also use sizeof() instead of hardcoded sizes as the argument. --- libraries/BLE/src/BLECharacteristic.cpp | 25 +++++-------------------- 1 file changed, 5 insertions(+), 20 deletions(-) diff --git a/libraries/BLE/src/BLECharacteristic.cpp b/libraries/BLE/src/BLECharacteristic.cpp index 88a574fa177..ebf1e48a80d 100644 --- a/libraries/BLE/src/BLECharacteristic.cpp +++ b/libraries/BLE/src/BLECharacteristic.cpp @@ -376,38 +376,23 @@ void BLECharacteristic::setValue(String value) { } // setValue void BLECharacteristic::setValue(uint16_t data16) { - uint8_t temp[2]; - temp[0] = data16; - temp[1] = data16 >> 8; - setValue(temp, 2); + setValue(reinterpret_cast(&data16), sizeof(data16)); } // setValue void BLECharacteristic::setValue(uint32_t data32) { - uint8_t temp[4]; - temp[0] = data32; - temp[1] = data32 >> 8; - temp[2] = data32 >> 16; - temp[3] = data32 >> 24; - setValue(temp, 4); + setValue(reinterpret_cast(&data32), sizeof(data32)); } // setValue void BLECharacteristic::setValue(int data32) { - uint8_t temp[4]; - temp[0] = data32; - temp[1] = data32 >> 8; - temp[2] = data32 >> 16; - temp[3] = data32 >> 24; - setValue(temp, 4); + setValue(reinterpret_cast(&data32), sizeof(data32)); } // setValue void BLECharacteristic::setValue(float data32) { - float temp = data32; - setValue((uint8_t *)&temp, 4); + setValue(reinterpret_cast(&data32), sizeof(data32)); } // setValue void BLECharacteristic::setValue(double data64) { - double temp = data64; - setValue((uint8_t *)&temp, 8); + setValue(reinterpret_cast(&data64), sizeof(data64)); } // setValue /** From 273eedffc22230983e441ae414e5df61a65ed548 Mon Sep 17 00:00:00 2001 From: Nick Korotysh Date: Thu, 21 Aug 2025 12:29:12 +0200 Subject: [PATCH 12/38] refactor(ble): Pass pointer to const data to setValue() There is no technical need to pass non-const data there. Also it is a common practice to pass const data to the functions with write semantics, as they not supposed to modify the data. This allows to pass the data from read-only sources without removing the constness what is not always safe. --- libraries/BLE/src/BLECharacteristic.cpp | 2 +- libraries/BLE/src/BLECharacteristic.h | 2 +- libraries/BLE/src/BLEDescriptor.cpp | 2 +- libraries/BLE/src/BLEDescriptor.h | 2 +- libraries/BLE/src/BLEValue.cpp | 4 ++-- libraries/BLE/src/BLEValue.h | 4 ++-- 6 files changed, 8 insertions(+), 8 deletions(-) diff --git a/libraries/BLE/src/BLECharacteristic.cpp b/libraries/BLE/src/BLECharacteristic.cpp index ebf1e48a80d..29d6490f3b0 100644 --- a/libraries/BLE/src/BLECharacteristic.cpp +++ b/libraries/BLE/src/BLECharacteristic.cpp @@ -346,7 +346,7 @@ void BLECharacteristic::setReadProperty(bool value) { * @param [in] data The data to set for the characteristic. * @param [in] length The length of the data in bytes. */ -void BLECharacteristic::setValue(uint8_t *data, size_t length) { +void BLECharacteristic::setValue(const uint8_t *data, size_t length) { // The call to BLEUtils::buildHexData() doesn't output anything if the log level is not // "VERBOSE". As it is quite CPU intensive, it is much better to not call it if not needed. #if ARDUHAL_LOG_LEVEL >= ARDUHAL_LOG_LEVEL_VERBOSE diff --git a/libraries/BLE/src/BLECharacteristic.h b/libraries/BLE/src/BLECharacteristic.h index 580f71dc5e7..fc546439006 100644 --- a/libraries/BLE/src/BLECharacteristic.h +++ b/libraries/BLE/src/BLECharacteristic.h @@ -184,7 +184,7 @@ class BLECharacteristic { void indicate(); void notify(bool is_notification = true); void setCallbacks(BLECharacteristicCallbacks *pCallbacks); - void setValue(uint8_t *data, size_t size); + void setValue(const uint8_t *data, size_t size); void setValue(String value); void setValue(uint16_t data16); void setValue(uint32_t data32); diff --git a/libraries/BLE/src/BLEDescriptor.cpp b/libraries/BLE/src/BLEDescriptor.cpp index 51c77bb9b49..9efd8f05083 100644 --- a/libraries/BLE/src/BLEDescriptor.cpp +++ b/libraries/BLE/src/BLEDescriptor.cpp @@ -181,7 +181,7 @@ void BLEDescriptor::setHandle(uint16_t handle) { * @param [in] data The data to set for the descriptor. * @param [in] length The length of the data in bytes. */ -void BLEDescriptor::setValue(uint8_t *data, size_t length) { +void BLEDescriptor::setValue(const uint8_t *data, size_t length) { if (length > m_value.attr_max_len) { log_e("Size %d too large, must be no bigger than %d", length, m_value.attr_max_len); return; diff --git a/libraries/BLE/src/BLEDescriptor.h b/libraries/BLE/src/BLEDescriptor.h index d0d34b24388..49ee15939af 100644 --- a/libraries/BLE/src/BLEDescriptor.h +++ b/libraries/BLE/src/BLEDescriptor.h @@ -94,7 +94,7 @@ class BLEDescriptor { void setAccessPermissions(uint8_t perm); // Set the permissions of the descriptor. void setCallbacks(BLEDescriptorCallbacks *pCallbacks); // Set callbacks to be invoked for the descriptor. - void setValue(uint8_t *data, size_t size); // Set the value of the descriptor as a pointer to data. + void setValue(const uint8_t *data, size_t size); // Set the value of the descriptor as a pointer to data. void setValue(String value); // Set the value of the descriptor as a data buffer. String toString(); // Convert the descriptor to a string representation. diff --git a/libraries/BLE/src/BLEValue.cpp b/libraries/BLE/src/BLEValue.cpp index efc97697baa..b09a5775c8d 100644 --- a/libraries/BLE/src/BLEValue.cpp +++ b/libraries/BLE/src/BLEValue.cpp @@ -48,7 +48,7 @@ void BLEValue::addPart(String part) { * @param [in] pData A message part being added. * @param [in] length The number of bytes being added. */ -void BLEValue::addPart(uint8_t *pData, size_t length) { +void BLEValue::addPart(const uint8_t *pData, size_t length) { log_v(">> addPart: length=%d", length); m_accumulation += String((char *)pData, length); } // addPart @@ -130,7 +130,7 @@ void BLEValue::setValue(String value) { * @param [in] pData The data for the current value. * @param [in] The length of the new current value. */ -void BLEValue::setValue(uint8_t *pData, size_t length) { +void BLEValue::setValue(const uint8_t *pData, size_t length) { m_value = String((char *)pData, length); } // setValue diff --git a/libraries/BLE/src/BLEValue.h b/libraries/BLE/src/BLEValue.h index 56a7a5bc4ec..cedc93e29cd 100644 --- a/libraries/BLE/src/BLEValue.h +++ b/libraries/BLE/src/BLEValue.h @@ -35,7 +35,7 @@ class BLEValue { BLEValue(); void addPart(String part); - void addPart(uint8_t *pData, size_t length); + void addPart(const uint8_t *pData, size_t length); void cancel(); void commit(); uint8_t *getData(); @@ -44,7 +44,7 @@ class BLEValue { String getValue(); void setReadOffset(uint16_t readOffset); void setValue(String value); - void setValue(uint8_t *pData, size_t length); + void setValue(const uint8_t *pData, size_t length); private: /*************************************************************************** From 5edf46419266a9abdb97370eda5c89003ee720f1 Mon Sep 17 00:00:00 2001 From: Nick Korotysh Date: Thu, 21 Aug 2025 12:40:17 +0200 Subject: [PATCH 13/38] refactor(ble): Avoid unnecessary String copies Pass String by const reference to many `setValue()` functions to avoid copying it. Even there are not so much data inside these strings, it just looks too odd to copy them every time. Also this change decreases binary size (~200 bytes in my case). --- libraries/BLE/src/BLE2901.cpp | 2 +- libraries/BLE/src/BLE2901.h | 2 +- libraries/BLE/src/BLECharacteristic.cpp | 4 ++-- libraries/BLE/src/BLECharacteristic.h | 2 +- libraries/BLE/src/BLEDescriptor.cpp | 4 ++-- libraries/BLE/src/BLEDescriptor.h | 2 +- libraries/BLE/src/BLEValue.cpp | 4 ++-- libraries/BLE/src/BLEValue.h | 4 ++-- 8 files changed, 12 insertions(+), 12 deletions(-) diff --git a/libraries/BLE/src/BLE2901.cpp b/libraries/BLE/src/BLE2901.cpp index 1fa4857ac33..3b5edb0b59f 100644 --- a/libraries/BLE/src/BLE2901.cpp +++ b/libraries/BLE/src/BLE2901.cpp @@ -47,7 +47,7 @@ BLE2901::BLE2901() : BLEDescriptor(BLEUUID((uint16_t)BLE2901_UUID)) {} /** * @brief Set the Characteristic User Description */ -void BLE2901::setDescription(String userDesc) { +void BLE2901::setDescription(const String &userDesc) { if (userDesc.length() > ESP_GATT_MAX_ATTR_LEN) { log_e("Size %d too large, must be no bigger than %d", userDesc.length(), ESP_GATT_MAX_ATTR_LEN); return; diff --git a/libraries/BLE/src/BLE2901.h b/libraries/BLE/src/BLE2901.h index 21e7cc9398c..87ce76090fe 100644 --- a/libraries/BLE/src/BLE2901.h +++ b/libraries/BLE/src/BLE2901.h @@ -40,7 +40,7 @@ class BLE2901 : public BLEDescriptor { ***************************************************************************/ BLE2901(); - void setDescription(String desc); + void setDescription(const String &desc); }; // BLE2901 #endif /* CONFIG_BLUEDROID_ENABLED || CONFIG_NIMBLE_ENABLED */ diff --git a/libraries/BLE/src/BLECharacteristic.cpp b/libraries/BLE/src/BLECharacteristic.cpp index 29d6490f3b0..83475820b58 100644 --- a/libraries/BLE/src/BLECharacteristic.cpp +++ b/libraries/BLE/src/BLECharacteristic.cpp @@ -371,8 +371,8 @@ void BLECharacteristic::setValue(const uint8_t *data, size_t length) { * @param [in] Set the value of the characteristic. * @return N/A. */ -void BLECharacteristic::setValue(String value) { - setValue((uint8_t *)(value.c_str()), value.length()); +void BLECharacteristic::setValue(const String &value) { + setValue(reinterpret_cast(value.c_str()), value.length()); } // setValue void BLECharacteristic::setValue(uint16_t data16) { diff --git a/libraries/BLE/src/BLECharacteristic.h b/libraries/BLE/src/BLECharacteristic.h index fc546439006..dc87177644f 100644 --- a/libraries/BLE/src/BLECharacteristic.h +++ b/libraries/BLE/src/BLECharacteristic.h @@ -185,7 +185,7 @@ class BLECharacteristic { void notify(bool is_notification = true); void setCallbacks(BLECharacteristicCallbacks *pCallbacks); void setValue(const uint8_t *data, size_t size); - void setValue(String value); + void setValue(const String &value); void setValue(uint16_t data16); void setValue(uint32_t data32); void setValue(int data32); diff --git a/libraries/BLE/src/BLEDescriptor.cpp b/libraries/BLE/src/BLEDescriptor.cpp index 9efd8f05083..2452f3cd45b 100644 --- a/libraries/BLE/src/BLEDescriptor.cpp +++ b/libraries/BLE/src/BLEDescriptor.cpp @@ -203,8 +203,8 @@ void BLEDescriptor::setValue(const uint8_t *data, size_t length) { * @brief Set the value of the descriptor. * @param [in] value The value of the descriptor in string form. */ -void BLEDescriptor::setValue(String value) { - setValue((uint8_t *)value.c_str(), value.length()); +void BLEDescriptor::setValue(const String &value) { + setValue(reinterpret_cast(value.c_str()), value.length()); } // setValue void BLEDescriptor::setAccessPermissions(uint8_t perm) { diff --git a/libraries/BLE/src/BLEDescriptor.h b/libraries/BLE/src/BLEDescriptor.h index 49ee15939af..83008743ae5 100644 --- a/libraries/BLE/src/BLEDescriptor.h +++ b/libraries/BLE/src/BLEDescriptor.h @@ -95,7 +95,7 @@ class BLEDescriptor { void setAccessPermissions(uint8_t perm); // Set the permissions of the descriptor. void setCallbacks(BLEDescriptorCallbacks *pCallbacks); // Set callbacks to be invoked for the descriptor. void setValue(const uint8_t *data, size_t size); // Set the value of the descriptor as a pointer to data. - void setValue(String value); // Set the value of the descriptor as a data buffer. + void setValue(const String &value); // Set the value of the descriptor as a data buffer. String toString(); // Convert the descriptor to a string representation. diff --git a/libraries/BLE/src/BLEValue.cpp b/libraries/BLE/src/BLEValue.cpp index b09a5775c8d..6559766cfea 100644 --- a/libraries/BLE/src/BLEValue.cpp +++ b/libraries/BLE/src/BLEValue.cpp @@ -37,7 +37,7 @@ BLEValue::BLEValue() { * The accumulation is a growing set of data that is added to until a commit or cancel. * @param [in] part A message part being added. */ -void BLEValue::addPart(String part) { +void BLEValue::addPart(const String &part) { log_v(">> addPart: length=%d", part.length()); m_accumulation += part; } // addPart @@ -121,7 +121,7 @@ void BLEValue::setReadOffset(uint16_t readOffset) { /** * @brief Set the current value. */ -void BLEValue::setValue(String value) { +void BLEValue::setValue(const String &value) { m_value = value; } // setValue diff --git a/libraries/BLE/src/BLEValue.h b/libraries/BLE/src/BLEValue.h index cedc93e29cd..6a1b7cfd7e4 100644 --- a/libraries/BLE/src/BLEValue.h +++ b/libraries/BLE/src/BLEValue.h @@ -34,7 +34,7 @@ class BLEValue { ***************************************************************************/ BLEValue(); - void addPart(String part); + void addPart(const String &part); void addPart(const uint8_t *pData, size_t length); void cancel(); void commit(); @@ -43,7 +43,7 @@ class BLEValue { uint16_t getReadOffset(); String getValue(); void setReadOffset(uint16_t readOffset); - void setValue(String value); + void setValue(const String &value); void setValue(const uint8_t *pData, size_t length); private: From 79760ba6775554b02bd5f12c90e94d533485d7d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Proch=C3=A1zka?= <90197375+P-R-O-C-H-Y@users.noreply.github.com> Date: Mon, 25 Aug 2025 13:22:48 +0200 Subject: [PATCH 14/38] fix(component): Require touch driver for older SoCs --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 3c9800dfe2b..ca51f66721c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -373,7 +373,7 @@ if(NOT CONFIG_ARDUINO_SELECTIVE_COMPILATION OR CONFIG_ARDUINO_SELECTIVE_OpenThre endif() endif() -if(IDF_TARGET STREQUAL "esp32p4") +if(IDF_TARGET STREQUAL "esp32" OR IDF_TARGET STREQUAL "esp32s2" OR IDF_TARGET STREQUAL "esp32s3" OR IDF_TARGET STREQUAL "esp32p4") list(APPEND requires esp_driver_touch_sens) endif() From 942a90530198402bc90c8379a993d8d060a38f0c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Proch=C3=A1zka?= <90197375+P-R-O-C-H-Y@users.noreply.github.com> Date: Mon, 25 Aug 2025 13:59:19 +0200 Subject: [PATCH 15/38] fix(ci): Add delay to isr test --- tests/validation/touch/touch.ino | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/validation/touch/touch.ino b/tests/validation/touch/touch.ino index abe450a27ab..ba31d261095 100644 --- a/tests/validation/touch/touch.ino +++ b/tests/validation/touch/touch.ino @@ -142,7 +142,8 @@ void test_touch_interrtupt(void) { test_press_fake(touch_list[0]); test_press_fake(touch_list[1]); - + delay(100); + touchDetachInterrupt(TOUCH_GPIOS[0]); touchDetachInterrupt(TOUCH_GPIOS[1]); From 6e96c1dee9420204c9bd7de0844923dedf96768e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Proch=C3=A1zka?= <90197375+P-R-O-C-H-Y@users.noreply.github.com> Date: Tue, 26 Aug 2025 08:54:28 +0200 Subject: [PATCH 16/38] ci: Increase log level --- tests/pytest.ini | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/pytest.ini b/tests/pytest.ini index b507b437727..f954423f631 100644 --- a/tests/pytest.ini +++ b/tests/pytest.ini @@ -3,11 +3,11 @@ addopts = --embedded-services esp,arduino,wokwi,qemu # log related log_cli = True -log_cli_level = INFO +log_cli_level = VERBOSE log_cli_format = %(asctime)s %(levelname)s %(message)s log_cli_date_format = %Y-%m-%d %H:%M:%S log_file = test.log -log_file_level = INFO +log_file_level = VERBOSE log_file_format = %(asctime)s %(levelname)s %(message)s log_file_date_format = %Y-%m-%d %H:%M:%S From 44c5abf642deb1cc20f7ba12f2d0f9ea573c4ebd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Proch=C3=A1zka?= <90197375+P-R-O-C-H-Y@users.noreply.github.com> Date: Tue, 26 Aug 2025 09:17:11 +0200 Subject: [PATCH 17/38] Update pytest.ini --- tests/pytest.ini | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/pytest.ini b/tests/pytest.ini index f954423f631..bdf8d59e8e4 100644 --- a/tests/pytest.ini +++ b/tests/pytest.ini @@ -3,11 +3,11 @@ addopts = --embedded-services esp,arduino,wokwi,qemu # log related log_cli = True -log_cli_level = VERBOSE +log_cli_level = DEBUG log_cli_format = %(asctime)s %(levelname)s %(message)s log_cli_date_format = %Y-%m-%d %H:%M:%S log_file = test.log -log_file_level = VERBOSE +log_file_level = DEBUG log_file_format = %(asctime)s %(levelname)s %(message)s log_file_date_format = %Y-%m-%d %H:%M:%S From b9d409fc16ba5a0600f980d6fb9d755814b150b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Proch=C3=A1zka?= <90197375+P-R-O-C-H-Y@users.noreply.github.com> Date: Tue, 26 Aug 2025 09:43:32 +0200 Subject: [PATCH 18/38] Update tests_run.sh --- .github/scripts/tests_run.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/scripts/tests_run.sh b/.github/scripts/tests_run.sh index 1c4bee79742..c217e31b261 100755 --- a/.github/scripts/tests_run.sh +++ b/.github/scripts/tests_run.sh @@ -116,13 +116,13 @@ function run_test { result=0 printf "\033[95mpytest \"%s/test_%s.py\" --build-dir \"%s\" --junit-xml=\"%s\" -o junit_suite_name=%s_%s_%s_%s%s %s\033[0m\n" "$sketchdir" "$sketchname" "$build_dir" "$report_file" "$test_type" "$platform" "$target" "$sketchname" "$i" "${extra_args[*]@Q}" - bash -c "set +e; pytest \"$sketchdir/test_$sketchname.py\" --build-dir \"$build_dir\" --junit-xml=\"$report_file\" -o junit_suite_name=${test_type}_${platform}_${target}_${sketchname}${i} ${extra_args[*]@Q}; exit \$?" || result=$? + bash -c "set +e; pytest -s \"$sketchdir/test_$sketchname.py\" --build-dir \"$build_dir\" --junit-xml=\"$report_file\" -o junit_suite_name=${test_type}_${platform}_${target}_${sketchname}${i} ${extra_args[*]@Q}; exit \$?" || result=$? printf "\n" if [ $result -ne 0 ]; then result=0 printf "\033[95mRetrying test: %s -- Config: %s\033[0m\n" "$sketchname" "$i" printf "\033[95mpytest \"%s/test_%s.py\" --build-dir \"%s\" --junit-xml=\"%s\" -o junit_suite_name=%s_%s_%s_%s%s %s\033[0m\n" "$sketchdir" "$sketchname" "$build_dir" "$report_file" "$test_type" "$platform" "$target" "$sketchname" "$i" "${extra_args[*]@Q}" - bash -c "set +e; pytest \"$sketchdir/test_$sketchname.py\" --build-dir \"$build_dir\" --junit-xml=\"$report_file\" -o junit_suite_name=${test_type}_${platform}_${target}_${sketchname}${i} ${extra_args[*]@Q}; exit \$?" || result=$? + bash -c "set +e; pytest -s \"$sketchdir/test_$sketchname.py\" --build-dir \"$build_dir\" --junit-xml=\"$report_file\" -o junit_suite_name=${test_type}_${platform}_${target}_${sketchname}${i} ${extra_args[*]@Q}; exit \$?" || result=$? printf "\n" if [ $result -ne 0 ]; then printf "\033[91mFailed test: %s -- Config: %s\033[0m\n\n" "$sketchname" "$i" From d9a8eaa3a79a549a7288ea580f17dce73a3123df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Proch=C3=A1zka?= <90197375+P-R-O-C-H-Y@users.noreply.github.com> Date: Tue, 26 Aug 2025 10:11:20 +0200 Subject: [PATCH 19/38] Update touch.ino --- tests/validation/touch/touch.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/validation/touch/touch.ino b/tests/validation/touch/touch.ino index ba31d261095..49a9ae7c8b9 100644 --- a/tests/validation/touch/touch.ino +++ b/tests/validation/touch/touch.ino @@ -123,7 +123,7 @@ void test_touch_read(void) { // COMPARE PRESSED <-> UNPRESSED for (int l = 0; l < sizeof(TOUCH_GPIOS); l++) { - log_v("Touch %d: %d -> %d", TOUCH_GPIOS[l], touch_unpressed[l], touch_pressed[l]); + log_i("Touch %d: %d -> %d", TOUCH_GPIOS[l], touch_unpressed[l], touch_pressed[l]); } for (int l = 0; l < sizeof(TOUCH_GPIOS); l++) { #if CONFIG_IDF_TARGET_ESP32 From 523fb5269472b84c7f13488ad1029499f830bfa5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Proch=C3=A1zka?= <90197375+P-R-O-C-H-Y@users.noreply.github.com> Date: Tue, 26 Aug 2025 10:37:03 +0200 Subject: [PATCH 20/38] update --- .github/scripts/tests_run.sh | 4 ++-- tests/validation/touch/touch.ino | 15 ++++++--------- 2 files changed, 8 insertions(+), 11 deletions(-) diff --git a/.github/scripts/tests_run.sh b/.github/scripts/tests_run.sh index c217e31b261..c85db2e984a 100755 --- a/.github/scripts/tests_run.sh +++ b/.github/scripts/tests_run.sh @@ -115,13 +115,13 @@ function run_test { rm "$sketchdir"/diagram.json 2>/dev/null || true result=0 - printf "\033[95mpytest \"%s/test_%s.py\" --build-dir \"%s\" --junit-xml=\"%s\" -o junit_suite_name=%s_%s_%s_%s%s %s\033[0m\n" "$sketchdir" "$sketchname" "$build_dir" "$report_file" "$test_type" "$platform" "$target" "$sketchname" "$i" "${extra_args[*]@Q}" + printf "\033[95mpytest -s \"%s/test_%s.py\" --build-dir \"%s\" --junit-xml=\"%s\" -o junit_suite_name=%s_%s_%s_%s%s %s\033[0m\n" "$sketchdir" "$sketchname" "$build_dir" "$report_file" "$test_type" "$platform" "$target" "$sketchname" "$i" "${extra_args[*]@Q}" bash -c "set +e; pytest -s \"$sketchdir/test_$sketchname.py\" --build-dir \"$build_dir\" --junit-xml=\"$report_file\" -o junit_suite_name=${test_type}_${platform}_${target}_${sketchname}${i} ${extra_args[*]@Q}; exit \$?" || result=$? printf "\n" if [ $result -ne 0 ]; then result=0 printf "\033[95mRetrying test: %s -- Config: %s\033[0m\n" "$sketchname" "$i" - printf "\033[95mpytest \"%s/test_%s.py\" --build-dir \"%s\" --junit-xml=\"%s\" -o junit_suite_name=%s_%s_%s_%s%s %s\033[0m\n" "$sketchdir" "$sketchname" "$build_dir" "$report_file" "$test_type" "$platform" "$target" "$sketchname" "$i" "${extra_args[*]@Q}" + printf "\033[95mpytest -s \"%s/test_%s.py\" --build-dir \"%s\" --junit-xml=\"%s\" -o junit_suite_name=%s_%s_%s_%s%s %s\033[0m\n" "$sketchdir" "$sketchname" "$build_dir" "$report_file" "$test_type" "$platform" "$target" "$sketchname" "$i" "${extra_args[*]@Q}" bash -c "set +e; pytest -s \"$sketchdir/test_$sketchname.py\" --build-dir \"$build_dir\" --junit-xml=\"$report_file\" -o junit_suite_name=${test_type}_${platform}_${target}_${sketchname}${i} ${extra_args[*]@Q}; exit \$?" || result=$? printf "\n" if [ $result -ne 0 ]; then diff --git a/tests/validation/touch/touch.ino b/tests/validation/touch/touch.ino index 49a9ae7c8b9..5f6ab9ac689 100644 --- a/tests/validation/touch/touch.ino +++ b/tests/validation/touch/touch.ino @@ -17,17 +17,13 @@ uint8_t TOUCH_GPIOS[] = {4,/* 0,*/ 2, 15, 13, 12, 14, 27/*, 33, 32*/}; #elif (CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3) -#define TEST_TOUCH_CHANNEL (9) //14 +#define TEST_TOUCH_CHANNEL (8) //14 static touch_pad_t touch_list[TEST_TOUCH_CHANNEL] = { - TOUCH_PAD_NUM1, TOUCH_PAD_NUM2, TOUCH_PAD_NUM3, TOUCH_PAD_NUM4, TOUCH_PAD_NUM5, TOUCH_PAD_NUM6, TOUCH_PAD_NUM7, - TOUCH_PAD_NUM8, /*TOUCH_PAD_NUM9,*/ TOUCH_PAD_NUM10 - //TOUCH_PAD_NUM11, //Wrong reading - //TOUCH_PAD_NUM12, //Wrong reading - //TOUCH_PAD_NUM13, //Wrong reading - //TOUCH_PAD_NUM14 + TOUCH_PAD_NUM1, TOUCH_PAD_NUM2, TOUCH_PAD_NUM3, TOUCH_PAD_NUM4, TOUCH_PAD_NUM5, TOUCH_PAD_NUM6, TOUCH_PAD_NUM7, TOUCH_PAD_NUM8 + /*TOUCH_PAD_NUM9, TOUCH_PAD_NUM10, TOUCH_PAD_NUM11, TOUCH_PAD_NUM12, TOUCH_PAD_NUM13, TOUCH_PAD_NUM14*/ }; -uint8_t TOUCH_GPIOS[] = {1, 2, 3, 4, 5, 6, 7, 8,/*9,*/ 10/*, 11, 12, 13, 14*/}; +uint8_t TOUCH_GPIOS[] = {1, 2, 3, 4, 5, 6, 7, 8 /*, 9, 10, 11, 12, 13, 14*/}; #define NO_TOUCH_GPIO 17 @@ -123,7 +119,8 @@ void test_touch_read(void) { // COMPARE PRESSED <-> UNPRESSED for (int l = 0; l < sizeof(TOUCH_GPIOS); l++) { - log_i("Touch %d: %d -> %d", TOUCH_GPIOS[l], touch_unpressed[l], touch_pressed[l]); + //log_i("Touch %d: %d -> %d", TOUCH_GPIOS[l], touch_unpressed[l], touch_pressed[l]); + Serial.printf("Touch %d: %d -> %d", TOUCH_GPIOS[l], touch_unpressed[l], touch_pressed[l]); } for (int l = 0; l < sizeof(TOUCH_GPIOS); l++) { #if CONFIG_IDF_TARGET_ESP32 From cd5078bd203396d9a7547c8d32197c019cb0802e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Proch=C3=A1zka?= <90197375+P-R-O-C-H-Y@users.noreply.github.com> Date: Tue, 26 Aug 2025 10:43:44 +0200 Subject: [PATCH 21/38] Update touch.ino --- tests/validation/touch/touch.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/validation/touch/touch.ino b/tests/validation/touch/touch.ino index 5f6ab9ac689..5e1180c6fd5 100644 --- a/tests/validation/touch/touch.ino +++ b/tests/validation/touch/touch.ino @@ -120,7 +120,7 @@ void test_touch_read(void) { // COMPARE PRESSED <-> UNPRESSED for (int l = 0; l < sizeof(TOUCH_GPIOS); l++) { //log_i("Touch %d: %d -> %d", TOUCH_GPIOS[l], touch_unpressed[l], touch_pressed[l]); - Serial.printf("Touch %d: %d -> %d", TOUCH_GPIOS[l], touch_unpressed[l], touch_pressed[l]); + Serial.printf("Touch %d: %lu -> %lu\n", TOUCH_GPIOS[l], touch_unpressed[l], touch_pressed[l]); } for (int l = 0; l < sizeof(TOUCH_GPIOS); l++) { #if CONFIG_IDF_TARGET_ESP32 From dad323ebc5126a4fe1a1c1672bd658dfec88212d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Proch=C3=A1zka?= <90197375+P-R-O-C-H-Y@users.noreply.github.com> Date: Tue, 26 Aug 2025 11:42:13 +0200 Subject: [PATCH 22/38] fix(touch): Stop and disable before deleting channel --- cores/esp32/esp32-hal-touch-ng.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/cores/esp32/esp32-hal-touch-ng.c b/cores/esp32/esp32-hal-touch-ng.c index 483a444b4a0..3ab403e0623 100644 --- a/cores/esp32/esp32-hal-touch-ng.c +++ b/cores/esp32/esp32-hal-touch-ng.c @@ -204,11 +204,11 @@ static bool touchDetachBus(void *pin) { int8_t pad = digitalPinToTouchChannel((int)(pin - 1)); channels_initialized[pad] = false; //disable touch pad and delete the channel + touchStop(); + touchDisable(); touch_sensor_del_channel(touch_channel_handle[pad]); used_pads--; if (used_pads == 0) { - touchStop(); - touchDisable(); if (touch_sensor_del_controller(touch_sensor_handle) != ESP_OK) //deinit touch module, as no pads are used { log_e("Touch module deinit failed!"); @@ -216,6 +216,10 @@ static bool touchDetachBus(void *pin) { } initialized = false; } + else { + touchEnable(); + touchStart(); + } return true; } From 70d0a88c56608f021eb68283991515fbb8382b90 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Proch=C3=A1zka?= <90197375+P-R-O-C-H-Y@users.noreply.github.com> Date: Tue, 26 Aug 2025 13:00:43 +0200 Subject: [PATCH 23/38] ci: Test multiple touch reads --- tests/validation/touch/touch.ino | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/tests/validation/touch/touch.ino b/tests/validation/touch/touch.ino index 5e1180c6fd5..94c0daf8c94 100644 --- a/tests/validation/touch/touch.ino +++ b/tests/validation/touch/touch.ino @@ -102,8 +102,12 @@ void tearDown(void) { void test_touch_read(void) { //TEST RELEASE STATE touch_value_t touch_unpressed[sizeof(TOUCH_GPIOS)]; + touch_value_t touch_unpressed_2[sizeof(TOUCH_GPIOS)]; + touch_value_t touch_unpressed_3[sizeof(TOUCH_GPIOS)]; for (int i = 0; i < sizeof(TOUCH_GPIOS); i++) { touch_unpressed[i] = touchRead(TOUCH_GPIOS[i]); + touch_unpressed_2[i] = touchRead(TOUCH_GPIOS[i]); + touch_unpressed_3[i] = touchRead(TOUCH_GPIOS[i]); } // TEST PRESS STATE @@ -113,14 +117,20 @@ void test_touch_read(void) { delay(100); touch_value_t touch_pressed[sizeof(TOUCH_GPIOS)]; + touch_value_t touch_pressed_2[sizeof(TOUCH_GPIOS)]; + touch_value_t touch_pressed_3[sizeof(TOUCH_GPIOS)]; for (int k = 0; k < sizeof(TOUCH_GPIOS); k++) { touch_pressed[k] = touchRead(TOUCH_GPIOS[k]); + touch_pressed_2[k] = touchRead(TOUCH_GPIOS[k]); + touch_pressed_3[k] = touchRead(TOUCH_GPIOS[k]); } // COMPARE PRESSED <-> UNPRESSED for (int l = 0; l < sizeof(TOUCH_GPIOS); l++) { //log_i("Touch %d: %d -> %d", TOUCH_GPIOS[l], touch_unpressed[l], touch_pressed[l]); - Serial.printf("Touch %d: %lu -> %lu\n", TOUCH_GPIOS[l], touch_unpressed[l], touch_pressed[l]); + Serial.printf("1. Touch %d: %lu -> %lu\n", TOUCH_GPIOS[l], touch_unpressed[l], touch_pressed[l]); + Serial.printf("2. Touch %d: %lu -> %lu\n", TOUCH_GPIOS[l], touch_unpressed_2[l], touch_pressed_2[l]); + Serial.printf("3. Touch %d: %lu -> %lu\n", TOUCH_GPIOS[l], touch_unpressed_3[l], touch_pressed_3[l]); } for (int l = 0; l < sizeof(TOUCH_GPIOS); l++) { #if CONFIG_IDF_TARGET_ESP32 @@ -159,13 +169,12 @@ void setup() { ; } - UNITY_BEGIN(); - RUN_TEST(test_touch_read); - #if SOC_TOUCH_SENSOR_VERSION == 3 touch_ll_enable_internal_capacitor(true); #endif + UNITY_BEGIN(); + RUN_TEST(test_touch_read); RUN_TEST(test_touch_interrtupt); RUN_TEST(test_touch_errors); UNITY_END(); From 6b177262ebcabb764f4acef5142cfc474bbb1b78 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Proch=C3=A1zka?= <90197375+P-R-O-C-H-Y@users.noreply.github.com> Date: Tue, 26 Aug 2025 13:27:26 +0200 Subject: [PATCH 24/38] Revert "ci: Test multiple touch reads" This reverts commit 70d0a88c56608f021eb68283991515fbb8382b90. --- tests/validation/touch/touch.ino | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) diff --git a/tests/validation/touch/touch.ino b/tests/validation/touch/touch.ino index 94c0daf8c94..5e1180c6fd5 100644 --- a/tests/validation/touch/touch.ino +++ b/tests/validation/touch/touch.ino @@ -102,12 +102,8 @@ void tearDown(void) { void test_touch_read(void) { //TEST RELEASE STATE touch_value_t touch_unpressed[sizeof(TOUCH_GPIOS)]; - touch_value_t touch_unpressed_2[sizeof(TOUCH_GPIOS)]; - touch_value_t touch_unpressed_3[sizeof(TOUCH_GPIOS)]; for (int i = 0; i < sizeof(TOUCH_GPIOS); i++) { touch_unpressed[i] = touchRead(TOUCH_GPIOS[i]); - touch_unpressed_2[i] = touchRead(TOUCH_GPIOS[i]); - touch_unpressed_3[i] = touchRead(TOUCH_GPIOS[i]); } // TEST PRESS STATE @@ -117,20 +113,14 @@ void test_touch_read(void) { delay(100); touch_value_t touch_pressed[sizeof(TOUCH_GPIOS)]; - touch_value_t touch_pressed_2[sizeof(TOUCH_GPIOS)]; - touch_value_t touch_pressed_3[sizeof(TOUCH_GPIOS)]; for (int k = 0; k < sizeof(TOUCH_GPIOS); k++) { touch_pressed[k] = touchRead(TOUCH_GPIOS[k]); - touch_pressed_2[k] = touchRead(TOUCH_GPIOS[k]); - touch_pressed_3[k] = touchRead(TOUCH_GPIOS[k]); } // COMPARE PRESSED <-> UNPRESSED for (int l = 0; l < sizeof(TOUCH_GPIOS); l++) { //log_i("Touch %d: %d -> %d", TOUCH_GPIOS[l], touch_unpressed[l], touch_pressed[l]); - Serial.printf("1. Touch %d: %lu -> %lu\n", TOUCH_GPIOS[l], touch_unpressed[l], touch_pressed[l]); - Serial.printf("2. Touch %d: %lu -> %lu\n", TOUCH_GPIOS[l], touch_unpressed_2[l], touch_pressed_2[l]); - Serial.printf("3. Touch %d: %lu -> %lu\n", TOUCH_GPIOS[l], touch_unpressed_3[l], touch_pressed_3[l]); + Serial.printf("Touch %d: %lu -> %lu\n", TOUCH_GPIOS[l], touch_unpressed[l], touch_pressed[l]); } for (int l = 0; l < sizeof(TOUCH_GPIOS); l++) { #if CONFIG_IDF_TARGET_ESP32 @@ -169,12 +159,13 @@ void setup() { ; } + UNITY_BEGIN(); + RUN_TEST(test_touch_read); + #if SOC_TOUCH_SENSOR_VERSION == 3 touch_ll_enable_internal_capacitor(true); #endif - UNITY_BEGIN(); - RUN_TEST(test_touch_read); RUN_TEST(test_touch_interrtupt); RUN_TEST(test_touch_errors); UNITY_END(); From d1ec9c83bcdc275dadfbaaef3ec09807b5a6ad84 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Proch=C3=A1zka?= <90197375+P-R-O-C-H-Y@users.noreply.github.com> Date: Tue, 26 Aug 2025 13:28:21 +0200 Subject: [PATCH 25/38] ci: revert pytest ini config --- tests/pytest.ini | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/pytest.ini b/tests/pytest.ini index bdf8d59e8e4..b507b437727 100644 --- a/tests/pytest.ini +++ b/tests/pytest.ini @@ -3,11 +3,11 @@ addopts = --embedded-services esp,arduino,wokwi,qemu # log related log_cli = True -log_cli_level = DEBUG +log_cli_level = INFO log_cli_format = %(asctime)s %(levelname)s %(message)s log_cli_date_format = %Y-%m-%d %H:%M:%S log_file = test.log -log_file_level = DEBUG +log_file_level = INFO log_file_format = %(asctime)s %(levelname)s %(message)s log_file_date_format = %Y-%m-%d %H:%M:%S From 03b5724547fe0922bbb79423cdea695b000ae34c Mon Sep 17 00:00:00 2001 From: Jakub Andrysek Date: Wed, 27 Aug 2025 11:23:19 +0200 Subject: [PATCH 26/38] feat: Add install_libs function to handle library installation from ci.json --- .github/scripts/sketch_utils.sh | 150 ++++++++++++++++++++++++++++++++ docs/en/contributing.rst | 4 + 2 files changed, 154 insertions(+) diff --git a/.github/scripts/sketch_utils.sh b/.github/scripts/sketch_utils.sh index 01ceafe9af1..596e2758e86 100755 --- a/.github/scripts/sketch_utils.sh +++ b/.github/scripts/sketch_utils.sh @@ -244,6 +244,14 @@ function build_sketch { # build_sketch [ext fi fi + # Install libraries from ci.json if they exist + install_libs -ai "$ide_path" -s "$sketchdir" -v + install_result=$? + if [ $install_result -ne 0 ]; then + echo "ERROR: Library installation failed for $sketchname" >&2 + exit $install_result + fi + ARDUINO_CACHE_DIR="$HOME/.arduino/cache.tmp" if [ -n "$ARDUINO_BUILD_DIR" ]; then build_dir="$ARDUINO_BUILD_DIR" @@ -580,6 +588,145 @@ function build_sketches { # build_sketches [-v] + local ide_path="" + local sketchdir="" + local verbose=false + + while [ -n "$1" ]; do + case "$1" in + -ai ) shift; ide_path=$1 ;; + -s ) shift; sketchdir=$1 ;; + -v ) verbose=true ;; + * ) + echo "ERROR: Unknown argument: $1" >&2 + echo "USAGE: install_libs -ai -s [-v]" >&2 + return 1 + ;; + esac + shift + done + + if [ -z "$ide_path" ]; then + echo "ERROR: IDE path not provided" >&2 + echo "USAGE: install_libs -ai -s [-v]" >&2 + return 1 + fi + if [ -z "$sketchdir" ]; then + echo "ERROR: Sketch directory not provided" >&2 + echo "USAGE: install_libs -ai -s [-v]" >&2 + return 1 + fi + if [ ! -f "$ide_path/arduino-cli" ]; then + echo "ERROR: arduino-cli not found at $ide_path/arduino-cli" >&2 + return 1 + fi + + # No ci.json => nothing to install + if [ ! -f "$sketchdir/ci.json" ]; then + [ "$verbose" = true ] && echo "No ci.json found in $sketchdir, skipping library installation" + return 0 + fi + + # Validate JSON early + if ! jq -e . "$sketchdir/ci.json" >/dev/null 2>&1; then + echo "ERROR: $sketchdir/ci.json is not valid JSON" >&2 + return 1 + fi + + local libs_type + libs_type=$(jq -r '.libs | type' "$sketchdir/ci.json" 2>/dev/null) + if [ -z "$libs_type" ] || [ "$libs_type" = "null" ]; then + [ "$verbose" = true ] && echo "No libs field found in ci.json, skipping library installation" + return 0 + elif [ "$libs_type" != "array" ]; then + echo "ERROR: libs field in ci.json must be an array, found: $libs_type" >&2 + return 1 + fi + + local libs_count + libs_count=$(jq -r '.libs | length' "$sketchdir/ci.json" 2>/dev/null) + if [ "$libs_count" -eq 0 ]; then + [ "$verbose" = true ] && echo "libs array is empty in ci.json, skipping library installation" + return 0 + fi + + echo "Installing $libs_count libraries from $sketchdir/ci.json" + + local needs_unsafe=false + local original_unsafe_setting="" + local libs + libs=$(jq -r '.libs[]? // empty' "$sketchdir/ci.json") + + # Detect if any lib is a Git URL (needs unsafe install) + for lib in $libs; do + if [[ "$lib" == https://github.com/* ]]; then + needs_unsafe=true + break + fi + done + + # Enable unsafe installs if needed, remember original setting + if [ "$needs_unsafe" = true ]; then + [ "$verbose" = true ] && echo "Checking current unsafe install setting..." + original_unsafe_setting=$("$ide_path/arduino-cli" config get library.enable_unsafe_install 2>/dev/null || echo "false") + if [ "$original_unsafe_setting" = "false" ]; then + [ "$verbose" = true ] && echo "Enabling unsafe installs for Git URLs..." + if ! "$ide_path/arduino-cli" config set library.enable_unsafe_install true >/dev/null 2>&1; then + echo "WARNING: Failed to enable unsafe installs, Git URL installs may fail" >&2 + # continue; the install will surface a real error if it matters + fi + else + [ "$verbose" = true ] && echo "Unsafe installs already enabled" + fi + fi + + local rc=0 install_status=0 output="" + for lib in $libs; do + [ "$verbose" = true ] && echo "Processing library: $lib" + + if [[ "$lib" == https://github.com/* ]]; then + [ "$verbose" = true ] && echo "Installing library from GitHub URL: $lib" + if [ "$verbose" = true ]; then + "$ide_path/arduino-cli" lib install --git-url "$lib" + install_status=$? + else + output=$("$ide_path/arduino-cli" lib install --git-url "$lib" 2>&1) + install_status=$? + [ $install_status -ne 0 ] && echo "$output" | grep -Ei "error|warning|warn" >&2 || true + fi + else + [ "$verbose" = true ] && echo "Installing library by name: $lib" + if [ "$verbose" = true ]; then + "$ide_path/arduino-cli" lib install "$lib" + install_status=$? + else + output=$("$ide_path/arduino-cli" lib install "$lib" 2>&1) + install_status=$? + [ $install_status -ne 0 ] && echo "$output" | grep -Ei "error|warning|warn" >&2 || true + fi + fi + + if [ $install_status -ne 0 ]; then + echo "ERROR: Failed to install library: $lib" >&2 + rc=$install_status + break + else + [ "$verbose" = true ] && echo "Successfully installed library: $lib" + fi + done + + # Restore unsafe setting if we changed it + if [ "$needs_unsafe" = true ] && [ "$original_unsafe_setting" = "false" ]; then + [ "$verbose" = true ] && echo "Restoring original unsafe install setting..." + "$ide_path/arduino-cli" config set library.enable_unsafe_install false >/dev/null 2>&1 || true + fi + + [ $rc -eq 0 ] && echo "Library installation completed" + return $rc +} + + USAGE=" USAGE: ${0} [command] [options] Available commands: @@ -587,6 +734,7 @@ Available commands: build: Build a sketch. chunk_build: Build a chunk of sketches. check_requirements: Check if target meets sketch requirements. + install_libs: Install libraries from ci.json file. " cmd=$1 @@ -606,6 +754,8 @@ case "$cmd" in ;; "check_requirements") check_requirements "$@" ;; + "install_libs") install_libs "$@" + ;; *) echo "ERROR: Unrecognized command" echo "$USAGE" diff --git a/docs/en/contributing.rst b/docs/en/contributing.rst index 7a7b99894eb..ae07bb57706 100644 --- a/docs/en/contributing.rst +++ b/docs/en/contributing.rst @@ -425,6 +425,10 @@ The ``ci.json`` file is used to specify how the test suite and sketches will han * ``fqbn``: A dictionary that specifies the FQBNs that will be used to compile the sketch. The key is the target name and the value is a list of FQBNs. The `default FQBNs `_ are used if this field is not specified. This overrides the default FQBNs and the ``fqbn_append`` field. +* ``libs``: A list of libraries that are required to run the test suite. The libraries will be installed automatically if they are not already present. + Libraries are installed using the ``arduino-cli lib install`` command, so you can specify libraries by name + version (e.g., ``AudioZero@1.0.0``) + or by URL (e.g., ``https://github.com/arduino-libraries/WiFi101.git``). + More information can be found in the `Arduino CLI documentation `_. The ``wifi`` test suite is a good example of how to use the ``ci.json`` file: From eac284be816495e49b677892eaa7f345a564d016 Mon Sep 17 00:00:00 2001 From: Jakub Andrysek Date: Wed, 27 Aug 2025 12:40:19 +0200 Subject: [PATCH 27/38] fix: Update install_libs function to improve error handling and remove verbose flag --- .github/scripts/sketch_utils.sh | 45 ++++++++++++++++++++++----------- 1 file changed, 30 insertions(+), 15 deletions(-) diff --git a/.github/scripts/sketch_utils.sh b/.github/scripts/sketch_utils.sh index 596e2758e86..8beb70c548b 100755 --- a/.github/scripts/sketch_utils.sh +++ b/.github/scripts/sketch_utils.sh @@ -245,7 +245,7 @@ function build_sketch { # build_sketch [ext fi # Install libraries from ci.json if they exist - install_libs -ai "$ide_path" -s "$sketchdir" -v + install_libs -ai "$ide_path" -s "$sketchdir" install_result=$? if [ $install_result -ne 0 ]; then echo "ERROR: Library installation failed for $sketchname" >&2 @@ -588,6 +588,21 @@ function build_sketches { # build_sketches &2 || printf '%s\n' "$out" >&2 + fi +} + function install_libs { # install_libs [-v] local ide_path="" local sketchdir="" @@ -622,13 +637,10 @@ function install_libs { # install_libs [-v] return 1 fi - # No ci.json => nothing to install if [ ! -f "$sketchdir/ci.json" ]; then [ "$verbose" = true ] && echo "No ci.json found in $sketchdir, skipping library installation" return 0 fi - - # Validate JSON early if ! jq -e . "$sketchdir/ci.json" >/dev/null 2>&1; then echo "ERROR: $sketchdir/ci.json is not valid JSON" >&2 return 1 @@ -658,24 +670,21 @@ function install_libs { # install_libs [-v] local libs libs=$(jq -r '.libs[]? // empty' "$sketchdir/ci.json") - # Detect if any lib is a Git URL (needs unsafe install) + # Detect any git-like URL (GitHub/GitLab/Bitbucket/self-hosted/ssh) for lib in $libs; do - if [[ "$lib" == https://github.com/* ]]; then + if is_git_like_url "$lib"; then needs_unsafe=true break fi done - # Enable unsafe installs if needed, remember original setting if [ "$needs_unsafe" = true ]; then [ "$verbose" = true ] && echo "Checking current unsafe install setting..." original_unsafe_setting=$("$ide_path/arduino-cli" config get library.enable_unsafe_install 2>/dev/null || echo "false") if [ "$original_unsafe_setting" = "false" ]; then [ "$verbose" = true ] && echo "Enabling unsafe installs for Git URLs..." - if ! "$ide_path/arduino-cli" config set library.enable_unsafe_install true >/dev/null 2>&1; then + "$ide_path/arduino-cli" config set library.enable_unsafe_install true >/dev/null 2>&1 || \ echo "WARNING: Failed to enable unsafe installs, Git URL installs may fail" >&2 - # continue; the install will surface a real error if it matters - fi else [ "$verbose" = true ] && echo "Unsafe installs already enabled" fi @@ -685,15 +694,14 @@ function install_libs { # install_libs [-v] for lib in $libs; do [ "$verbose" = true ] && echo "Processing library: $lib" - if [[ "$lib" == https://github.com/* ]]; then - [ "$verbose" = true ] && echo "Installing library from GitHub URL: $lib" + if is_git_like_url "$lib"; then + [ "$verbose" = true ] && echo "Installing library from git URL: $lib" if [ "$verbose" = true ]; then "$ide_path/arduino-cli" lib install --git-url "$lib" install_status=$? else output=$("$ide_path/arduino-cli" lib install --git-url "$lib" 2>&1) install_status=$? - [ $install_status -ne 0 ] && echo "$output" | grep -Ei "error|warning|warn" >&2 || true fi else [ "$verbose" = true ] && echo "Installing library by name: $lib" @@ -703,10 +711,18 @@ function install_libs { # install_libs [-v] else output=$("$ide_path/arduino-cli" lib install "$lib" 2>&1) install_status=$? - [ $install_status -ne 0 ] && echo "$output" | grep -Ei "error|warning|warn" >&2 || true fi fi + # Treat "already installed"/"up to date" as success (idempotent) + if [ $install_status -ne 0 ] && echo "$output" | grep -qiE 'already installed|up to date'; then + install_status=0 + fi + + if [ "$verbose" != true ]; then + print_err_warnings "$install_status" "$output" + fi + if [ $install_status -ne 0 ]; then echo "ERROR: Failed to install library: $lib" >&2 rc=$install_status @@ -716,7 +732,6 @@ function install_libs { # install_libs [-v] fi done - # Restore unsafe setting if we changed it if [ "$needs_unsafe" = true ] && [ "$original_unsafe_setting" = "false" ]; then [ "$verbose" = true ] && echo "Restoring original unsafe install setting..." "$ide_path/arduino-cli" config set library.enable_unsafe_install false >/dev/null 2>&1 || true From 28904a94473cf5221d9932fae262f92a2c153fca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Proch=C3=A1zka?= <90197375+P-R-O-C-H-Y@users.noreply.github.com> Date: Wed, 27 Aug 2025 12:44:20 +0200 Subject: [PATCH 28/38] fix(ci): Add verbose debug level to fix test --- tests/validation/touch/ci.json | 1 + tests/validation/touch/touch.ino | 6 +++--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/tests/validation/touch/ci.json b/tests/validation/touch/ci.json index 855e9bd964d..3ccb5dfabe8 100644 --- a/tests/validation/touch/ci.json +++ b/tests/validation/touch/ci.json @@ -1,4 +1,5 @@ { + "fqbn_append": "DebugLevel=verbose", "platforms": { "qemu": false, "wokwi": false diff --git a/tests/validation/touch/touch.ino b/tests/validation/touch/touch.ino index 5e1180c6fd5..b4f326be13a 100644 --- a/tests/validation/touch/touch.ino +++ b/tests/validation/touch/touch.ino @@ -4,6 +4,7 @@ #if CONFIG_IDF_TARGET_ESP32 + #define TEST_TOUCH_CHANNEL (7) static touch_pad_t touch_list[TEST_TOUCH_CHANNEL] = { TOUCH_PAD_NUM0, @@ -159,13 +160,12 @@ void setup() { ; } - UNITY_BEGIN(); - RUN_TEST(test_touch_read); - #if SOC_TOUCH_SENSOR_VERSION == 3 touch_ll_enable_internal_capacitor(true); #endif + UNITY_BEGIN(); + RUN_TEST(test_touch_read); RUN_TEST(test_touch_interrtupt); RUN_TEST(test_touch_errors); UNITY_END(); From 2a47244b139c6a36aa79d577c7296bb84be9d31e Mon Sep 17 00:00:00 2001 From: Sugar Glider Date: Wed, 27 Aug 2025 10:01:51 -0300 Subject: [PATCH 29/38] fix(ble): matches the function signature with const u8* Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- libraries/BLE/src/BLECharacteristic.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/BLE/src/BLECharacteristic.cpp b/libraries/BLE/src/BLECharacteristic.cpp index 83475820b58..50b2a025038 100644 --- a/libraries/BLE/src/BLECharacteristic.cpp +++ b/libraries/BLE/src/BLECharacteristic.cpp @@ -392,7 +392,7 @@ void BLECharacteristic::setValue(float data32) { } // setValue void BLECharacteristic::setValue(double data64) { - setValue(reinterpret_cast(&data64), sizeof(data64)); + setValue(reinterpret_cast(&data64), sizeof(data64)); } // setValue /** From dfa76738fd49d3e2c20f244920479c7882d26faf Mon Sep 17 00:00:00 2001 From: Sugar Glider Date: Wed, 27 Aug 2025 10:02:33 -0300 Subject: [PATCH 30/38] fix(ble): matches the function signature with const u8* --- libraries/BLE/src/BLECharacteristic.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/BLE/src/BLECharacteristic.cpp b/libraries/BLE/src/BLECharacteristic.cpp index 50b2a025038..5b84239be57 100644 --- a/libraries/BLE/src/BLECharacteristic.cpp +++ b/libraries/BLE/src/BLECharacteristic.cpp @@ -388,7 +388,7 @@ void BLECharacteristic::setValue(int data32) { } // setValue void BLECharacteristic::setValue(float data32) { - setValue(reinterpret_cast(&data32), sizeof(data32)); + setValue(reinterpret_cast(&data32), sizeof(data32)); } // setValue void BLECharacteristic::setValue(double data64) { From d29b0df66ee37832254eb5f23ade730b4ae551dc Mon Sep 17 00:00:00 2001 From: Sugar Glider Date: Wed, 27 Aug 2025 10:03:43 -0300 Subject: [PATCH 31/38] fix(ble): matches the function signature with const u8* --- libraries/BLE/src/BLECharacteristic.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/BLE/src/BLECharacteristic.cpp b/libraries/BLE/src/BLECharacteristic.cpp index 5b84239be57..298ad737650 100644 --- a/libraries/BLE/src/BLECharacteristic.cpp +++ b/libraries/BLE/src/BLECharacteristic.cpp @@ -384,7 +384,7 @@ void BLECharacteristic::setValue(uint32_t data32) { } // setValue void BLECharacteristic::setValue(int data32) { - setValue(reinterpret_cast(&data32), sizeof(data32)); + setValue(reinterpret_cast(&data32), sizeof(data32)); } // setValue void BLECharacteristic::setValue(float data32) { From 8dabc688c3c658a25241aaeeb5041020186960f2 Mon Sep 17 00:00:00 2001 From: Sugar Glider Date: Wed, 27 Aug 2025 10:04:19 -0300 Subject: [PATCH 32/38] fix(ble): matches the function signature with const u8* --- libraries/BLE/src/BLECharacteristic.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/BLE/src/BLECharacteristic.cpp b/libraries/BLE/src/BLECharacteristic.cpp index 298ad737650..cba31bde24d 100644 --- a/libraries/BLE/src/BLECharacteristic.cpp +++ b/libraries/BLE/src/BLECharacteristic.cpp @@ -380,7 +380,7 @@ void BLECharacteristic::setValue(uint16_t data16) { } // setValue void BLECharacteristic::setValue(uint32_t data32) { - setValue(reinterpret_cast(&data32), sizeof(data32)); + setValue(reinterpret_cast(&data32), sizeof(data32)); } // setValue void BLECharacteristic::setValue(int data32) { From d9cc33f4455966138ab686dc89f893c6ed97c908 Mon Sep 17 00:00:00 2001 From: Sugar Glider Date: Wed, 27 Aug 2025 10:04:58 -0300 Subject: [PATCH 33/38] fix(ble): matches the function signature with const u8* --- libraries/BLE/src/BLECharacteristic.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/BLE/src/BLECharacteristic.cpp b/libraries/BLE/src/BLECharacteristic.cpp index cba31bde24d..3d218e6bd13 100644 --- a/libraries/BLE/src/BLECharacteristic.cpp +++ b/libraries/BLE/src/BLECharacteristic.cpp @@ -376,7 +376,7 @@ void BLECharacteristic::setValue(const String &value) { } // setValue void BLECharacteristic::setValue(uint16_t data16) { - setValue(reinterpret_cast(&data16), sizeof(data16)); + setValue(reinterpret_cast(&data16), sizeof(data16)); } // setValue void BLECharacteristic::setValue(uint32_t data32) { From 0dccd26e27b9414a3ed8cd70b11e525c6c455016 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Proch=C3=A1zka?= <90197375+P-R-O-C-H-Y@users.noreply.github.com> Date: Wed, 27 Aug 2025 17:51:50 +0200 Subject: [PATCH 34/38] fix(touch): Commit copilot suggestions --- cores/esp32/esp32-hal-touch-ng.c | 10 ++++++++-- tests/validation/touch/touch.ino | 6 ++---- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/cores/esp32/esp32-hal-touch-ng.c b/cores/esp32/esp32-hal-touch-ng.c index 3ab403e0623..bff0f1ba987 100644 --- a/cores/esp32/esp32-hal-touch-ng.c +++ b/cores/esp32/esp32-hal-touch-ng.c @@ -204,8 +204,14 @@ static bool touchDetachBus(void *pin) { int8_t pad = digitalPinToTouchChannel((int)(pin - 1)); channels_initialized[pad] = false; //disable touch pad and delete the channel - touchStop(); - touchDisable(); + if (!touchStop()) { + log_e("touchStop() failed!"); + return false; + } + if (!touchDisable()) { + log_e("touchDisable() failed!"); + return false; + } touch_sensor_del_channel(touch_channel_handle[pad]); used_pads--; if (used_pads == 0) { diff --git a/tests/validation/touch/touch.ino b/tests/validation/touch/touch.ino index b4f326be13a..8d3a923300a 100644 --- a/tests/validation/touch/touch.ino +++ b/tests/validation/touch/touch.ino @@ -44,12 +44,10 @@ uint8_t TOUCH_GPIOS[] = {2, 3, 4, 5, 6 /*, 7, 8, 9, 10, 11, 12 ,13, 14, 15*/}; #define INTERRUPT_THRESHOLD 0 // Use benchmarked threshold -#if CONFIG_IDF_TARGET_ESP32 -#define PRESSED_VALUE_DIFFERENCE 200 //-200 read value difference against the unpressed value +#if CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32P4 +#define PRESSED_VALUE_DIFFERENCE 200 //-200 for ESP32 and +200 for ESP32P4 read value difference against the unpressed value #elif CONFIG_IDF_TARGET_ESP32S3 || CONFIG_IDF_TARGET_ESP32S2 #define PRESSED_VALUE_DIFFERENCE 2000 //2000+ read value difference against the unpressed value -#elif CONFIG_IDF_TARGET_ESP32P4 || CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 -#define PRESSED_VALUE_DIFFERENCE 200 //200+ read value difference against the unpressed value #else #error Test not currently supported on this chip. Please adjust and try again! #endif From 69549c8b2e52ce023da5e914dcb4d8bb5480540c Mon Sep 17 00:00:00 2001 From: Jakub Andrysek Date: Thu, 28 Aug 2025 11:22:13 +0200 Subject: [PATCH 35/38] feat(http-client): add support for collecting all HTTP headers, close #10802 --- .../examples/CustomHeaders/CustomHeaders.ino | 86 +++++++++++++++++++ .../HTTPClient/examples/CustomHeaders/ci.json | 6 ++ libraries/HTTPClient/src/HTTPClient.cpp | 56 ++++++------ libraries/HTTPClient/src/HTTPClient.h | 7 +- 4 files changed, 125 insertions(+), 30 deletions(-) create mode 100644 libraries/HTTPClient/examples/CustomHeaders/CustomHeaders.ino create mode 100644 libraries/HTTPClient/examples/CustomHeaders/ci.json diff --git a/libraries/HTTPClient/examples/CustomHeaders/CustomHeaders.ino b/libraries/HTTPClient/examples/CustomHeaders/CustomHeaders.ino new file mode 100644 index 00000000000..a19394ab468 --- /dev/null +++ b/libraries/HTTPClient/examples/CustomHeaders/CustomHeaders.ino @@ -0,0 +1,86 @@ +#include + +#include +#include +#include + +#define USE_SERIAL Serial + +// Enable or disable collecting all headers +#define COLLECT_ALL_HEADERS true + +void setup() { + + USE_SERIAL.begin(115200); + + USE_SERIAL.println(); + USE_SERIAL.println(); + USE_SERIAL.println(); + + for (uint8_t t = 4; t > 0; t--) { + USE_SERIAL.printf("[SETUP] WAIT %d...\n", t); + USE_SERIAL.flush(); + delay(1000); + } + + WiFi.begin("SSID", "PASSWORD"); + + while (WiFi.status() != WL_CONNECTED) { + delay(500); + USE_SERIAL.print("."); + } + USE_SERIAL.println(); + USE_SERIAL.println("Connected to WiFi: " + WiFi.SSID()); +} + +void loop() { + + HTTPClient http; + + USE_SERIAL.print("[HTTP] Preparing HTTP request...\n"); + // This page will return the headers we want to test + some others + http.begin("https://httpbingo.org/response-headers?x-custom-header=value:42"); + +#if COLLECT_ALL_HEADERS + // Collect all headers + http.collectAllHeaders(); +#else + // Collect specific headers, only that one will be stored + const char *headerKeys[] = {"x-custom-header"}; + const size_t headerKeysCount = sizeof(headerKeys) / sizeof(headerKeys[0]); + http.collectHeaders(headerKeys, headerKeysCount); +#endif + + USE_SERIAL.print("[HTTP] Sending HTTP GET request...\n"); + // start connection and send HTTP header + int httpCode = http.GET(); + + // httpCode will be negative on error + if (httpCode > 0) { + // HTTP header has been send and Server response header has been handled + USE_SERIAL.printf("[HTTP] GET response code: %d\n", httpCode); + + USE_SERIAL.println("[HTTP] Headers collected:"); + for (size_t i = 0; i < http.headers(); i++) { + USE_SERIAL.printf("[HTTP] - '%s': '%s'\n", http.headerName(i).c_str(), http.header(i).c_str()); + } + + USE_SERIAL.println("[HTTP] Has header 'x-custom-header'? " + String(http.hasHeader("x-custom-header")) + " (expected true)"); + USE_SERIAL.printf("[HTTP] x-custom-header: '%s' (expected 'value:42')\n", http.header("x-custom-header").c_str()); + USE_SERIAL.printf("[HTTP] non-existing-header: '%s' (expected empty string)\n", http.header("non-existing-header").c_str()); + +#if COLLECT_ALL_HEADERS + // Server response with multiple headers, one of them is 'server' + USE_SERIAL.println("[HTTP] Has header 'server'? " + String(http.hasHeader("server")) + " (expected true)"); + USE_SERIAL.printf("[HTTP] server: '%s'\n", http.header("server").c_str()); +#endif + + } else { + USE_SERIAL.printf("[HTTP] GET... failed, error: %s\n", http.errorToString(httpCode).c_str()); + } + + http.end(); + + Serial.println("[HTTP] end connection\n\n"); + delay(5000); +} diff --git a/libraries/HTTPClient/examples/CustomHeaders/ci.json b/libraries/HTTPClient/examples/CustomHeaders/ci.json new file mode 100644 index 00000000000..618e46bd244 --- /dev/null +++ b/libraries/HTTPClient/examples/CustomHeaders/ci.json @@ -0,0 +1,6 @@ +{ + "requires_any": [ + "CONFIG_SOC_WIFI_SUPPORTED=y", + "CONFIG_ESP_WIFI_REMOTE_ENABLED=y" + ] +} diff --git a/libraries/HTTPClient/src/HTTPClient.cpp b/libraries/HTTPClient/src/HTTPClient.cpp index 03d9a6204d5..8061042bd3f 100644 --- a/libraries/HTTPClient/src/HTTPClient.cpp +++ b/libraries/HTTPClient/src/HTTPClient.cpp @@ -90,9 +90,6 @@ HTTPClient::~HTTPClient() { if (_client) { _client->stop(); } - if (_currentHeaders) { - delete[] _currentHeaders; - } if (_tcpDeprecated) { _tcpDeprecated.reset(nullptr); } @@ -564,9 +561,12 @@ int HTTPClient::sendRequest(const char *type, uint8_t *payload, size_t size) { bool redirect = false; uint16_t redirectCount = 0; do { - // wipe out any existing headers from previous request - for (size_t i = 0; i < _headerKeysCount; i++) { - if (_currentHeaders[i].value.length() > 0) { + // wipe out any existing headers from previous request, but preserve the keys if collecting specific headers + if (_collectAllHeaders) { + _currentHeaders.clear(); + } else { + // Only clear values, keep the keys for specific header collection + for (size_t i = 0; i < _currentHeaders.size(); ++i) { _currentHeaders[i].value.clear(); } } @@ -1015,19 +1015,24 @@ void HTTPClient::addHeader(const String &name, const String &value, bool first, } } +void HTTPClient::collectAllHeaders(bool collectAll) { + _collectAllHeaders = collectAll; +} + void HTTPClient::collectHeaders(const char *headerKeys[], const size_t headerKeysCount) { - _headerKeysCount = headerKeysCount; - if (_currentHeaders) { - delete[] _currentHeaders; + if (_collectAllHeaders) { + log_w("collectHeaders is ignored when collectAllHeaders is set"); + return; } - _currentHeaders = new RequestArgument[_headerKeysCount]; - for (size_t i = 0; i < _headerKeysCount; i++) { + _currentHeaders.clear(); + _currentHeaders.resize(headerKeysCount); + for (size_t i = 0; i < headerKeysCount; i++) { _currentHeaders[i].key = headerKeys[i]; } } String HTTPClient::header(const char *name) { - for (size_t i = 0; i < _headerKeysCount; ++i) { + for (size_t i = 0; i < _currentHeaders.size(); ++i) { if (_currentHeaders[i].key.equalsIgnoreCase(name)) { return _currentHeaders[i].value; } @@ -1036,25 +1041,25 @@ String HTTPClient::header(const char *name) { } String HTTPClient::header(size_t i) { - if (i < _headerKeysCount) { + if (i < _currentHeaders.size()) { return _currentHeaders[i].value; } return String(); } String HTTPClient::headerName(size_t i) { - if (i < _headerKeysCount) { + if (i < _currentHeaders.size()) { return _currentHeaders[i].key; } return String(); } int HTTPClient::headers() { - return _headerKeysCount; + return _currentHeaders.size(); } bool HTTPClient::hasHeader(const char *name) { - for (size_t i = 0; i < _headerKeysCount; ++i) { + for (size_t i = 0; i < _currentHeaders.size(); ++i) { if ((_currentHeaders[i].key.equalsIgnoreCase(name)) && (_currentHeaders[i].value.length() > 0)) { return true; } @@ -1238,17 +1243,14 @@ int HTTPClient::handleHeaderResponse() { setCookie(date, headerValue); } - for (size_t i = 0; i < _headerKeysCount; i++) { - if (_currentHeaders[i].key.equalsIgnoreCase(headerName)) { - // Uncomment the following lines if you need to add support for multiple headers with the same key: - // if (!_currentHeaders[i].value.isEmpty()) { - // // Existing value, append this one with a comma - // _currentHeaders[i].value += ','; - // _currentHeaders[i].value += headerValue; - // } else { - _currentHeaders[i].value = headerValue; - // } - break; // We found a match, stop looking + if (_collectAllHeaders && headerName.length() > 0) { + _currentHeaders.emplace_back(headerName, headerValue); + } else { + for (size_t i = 0; i < _currentHeaders.size(); ++i) { + if (_currentHeaders[i].key.equalsIgnoreCase(headerName)) { + _currentHeaders[i].value = headerValue; + break; // We found a match, stop looking + } } } } diff --git a/libraries/HTTPClient/src/HTTPClient.h b/libraries/HTTPClient/src/HTTPClient.h index 80f6da28599..e07cd937d06 100644 --- a/libraries/HTTPClient/src/HTTPClient.h +++ b/libraries/HTTPClient/src/HTTPClient.h @@ -38,7 +38,7 @@ #include #endif // HTTPCLIENT_NOSECURE -/// Cookie jar support +/// Cookie jar and header support #include #define HTTPCLIENT_DEFAULT_TCP_TIMEOUT (5000) @@ -238,6 +238,7 @@ class HTTPClient { void addHeader(const String &name, const String &value, bool first = false, bool replace = true); /// Response handling + void collectAllHeaders(bool collectAll = true); void collectHeaders(const char *headerKeys[], const size_t headerKeysCount); String header(const char *name); // get request header value by name String header(size_t i); // get request header value by number @@ -294,6 +295,7 @@ class HTTPClient { uint16_t _tcpTimeout = HTTPCLIENT_DEFAULT_TCP_TIMEOUT; bool _useHTTP10 = false; bool _secure = false; + bool _collectAllHeaders = false; String _uri; String _protocol; @@ -304,8 +306,7 @@ class HTTPClient { String _acceptEncoding = "identity;q=1,chunked;q=0.1,*;q=0"; /// Response handling - RequestArgument *_currentHeaders = nullptr; - size_t _headerKeysCount = 0; + std::vector _currentHeaders; int _returnCode = 0; int _size = -1; From cdc46c5724f5a0e5706a204e07835f969320fb58 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Proch=C3=A1zka?= <90197375+P-R-O-C-H-Y@users.noreply.github.com> Date: Fri, 29 Aug 2025 11:42:13 +0200 Subject: [PATCH 36/38] feat(zigbee): Update esp-zigbee-lib to newest --- idf_component.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/idf_component.yml b/idf_component.yml index f9357a401f9..58377fab952 100644 --- a/idf_component.yml +++ b/idf_component.yml @@ -54,12 +54,12 @@ dependencies: espressif/esp_modem: version: "^1.1.0" espressif/esp-zboss-lib: - version: "==1.6.4" # compatible with esp-zigbee-lib 1.6.6 + version: "==1.6.4" # compatible with esp-zigbee-lib 1.6.7 require: public rules: - if: "target not in [esp32c2, esp32p4]" espressif/esp-zigbee-lib: - version: "==1.6.6" + version: "==1.6.7" require: public rules: - if: "target not in [esp32c2, esp32p4]" From 6b91048e50a6f7bb6fbef64aec7a4dc10b436d66 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci-lite[bot]" <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com> Date: Fri, 29 Aug 2025 10:11:56 +0000 Subject: [PATCH 37/38] ci(pre-commit): Apply automatic fixes --- cores/esp32/esp32-hal-touch-ng.c | 57 +++++++++---------- cores/esp32/esp32-hal-touch-ng.h | 35 +++++------- cores/esp32/esp32-hal-touch.c | 2 +- .../Touch/TouchInterrupt/TouchInterrupt.ino | 2 +- tests/validation/touch/touch.ino | 14 ++--- 5 files changed, 52 insertions(+), 58 deletions(-) diff --git a/cores/esp32/esp32-hal-touch-ng.c b/cores/esp32/esp32-hal-touch-ng.c index bff0f1ba987..98f9052d18c 100644 --- a/cores/esp32/esp32-hal-touch-ng.c +++ b/cores/esp32/esp32-hal-touch-ng.c @@ -37,19 +37,19 @@ typedef struct { static TouchInterruptHandle_t __touchInterruptHandlers[SOC_TOUCH_SENSOR_NUM] = { 0, }; -#if SOC_TOUCH_SENSOR_VERSION == 1 // ESP32 -static uint8_t _sample_num = 1; // only one sample configuration supported +#if SOC_TOUCH_SENSOR_VERSION == 1 // ESP32 +static uint8_t _sample_num = 1; // only one sample configuration supported static float _duration_ms = 5.0f; static touch_volt_lim_l_t _volt_low = TOUCH_VOLT_LIM_L_0V5; static touch_volt_lim_h_t _volt_high = TOUCH_VOLT_LIM_H_1V7; static touch_intr_trig_mode_t _intr_trig_mode = TOUCH_INTR_TRIG_ON_BELOW_THRESH; -#elif SOC_TOUCH_SENSOR_VERSION == 2 // ESP32S2, ESP32S3 -static uint8_t _sample_num = 1; // only one sample configuration supported +#elif SOC_TOUCH_SENSOR_VERSION == 2 // ESP32S2, ESP32S3 +static uint8_t _sample_num = 1; // only one sample configuration supported static uint32_t _chg_times = 500; static touch_volt_lim_l_t _volt_low = TOUCH_VOLT_LIM_L_0V5; static touch_volt_lim_h_t _volt_high = TOUCH_VOLT_LIM_H_2V2; -#elif SOC_TOUCH_SENSOR_VERSION == 3 // ESP32P4 -static uint8_t _sample_num = 1; // TODO: can be extended to multiple samples +#elif SOC_TOUCH_SENSOR_VERSION == 3 // ESP32P4 +static uint8_t _sample_num = 1; // TODO: can be extended to multiple samples static uint32_t _div_num = 1; static uint8_t _coarse_freq_tune = 1; static uint8_t _fine_freq_tune = 1; @@ -169,27 +169,27 @@ bool touchBenchmarkThreshold(uint8_t pad) { // Reconfigure passed pad with new threshold uint32_t benchmark[_sample_num] = {}; - #if SOC_TOUCH_SUPPORT_BENCHMARK // ESP32S2, ESP32S3,ESP32P4 +#if SOC_TOUCH_SUPPORT_BENCHMARK // ESP32S2, ESP32S3,ESP32P4 if (touch_channel_read_data(touch_channel_handle[pad], TOUCH_CHAN_DATA_TYPE_BENCHMARK, benchmark) != ESP_OK) { log_e("Touch channel read data failed!"); return false; } - #else +#else if (touch_channel_read_data(touch_channel_handle[pad], TOUCH_CHAN_DATA_TYPE_SMOOTH, benchmark) != ESP_OK) { log_e("Touch channel read data failed!"); return false; } - #endif +#endif /* Calculate the proper active thresholds regarding the initial benchmark */ touch_channel_config_t chan_cfg = TOUCH_CHANNEL_DEFAULT_CONFIG(); for (int i = 0; i < _sample_num; i++) { -#if SOC_TOUCH_SENSOR_VERSION == 1 // ESP32 +#if SOC_TOUCH_SENSOR_VERSION == 1 // ESP32 chan_cfg.abs_active_thresh[i] = (uint32_t)(benchmark[i] * (1 - s_thresh2bm_ratio)); - log_v("Configured [CH %d] sample %d: benchmark = %"PRIu32", threshold = %"PRIu32"\t", pad, i, benchmark[i], chan_cfg.abs_active_thresh[i]); + log_v("Configured [CH %d] sample %d: benchmark = %" PRIu32 ", threshold = %" PRIu32 "\t", pad, i, benchmark[i], chan_cfg.abs_active_thresh[i]); #else chan_cfg.active_thresh[i] = (uint32_t)(benchmark[i] * s_thresh2bm_ratio); - log_v("Configured [CH %d] sample %d: benchmark = %"PRIu32", threshold = %"PRIu32"\t", pad, i, benchmark[i], chan_cfg.active_thresh[i]); + log_v("Configured [CH %d] sample %d: benchmark = %" PRIu32 ", threshold = %" PRIu32 "\t", pad, i, benchmark[i], chan_cfg.active_thresh[i]); #endif } /* Update the channel configuration */ @@ -221,8 +221,7 @@ static bool touchDetachBus(void *pin) { return false; } initialized = false; - } - else { + } else { touchEnable(); touchStart(); } @@ -234,31 +233,31 @@ static void __touchInit() { return; } // Support only one sample configuration for now -#if SOC_TOUCH_SENSOR_VERSION == 1 // ESP32 +#if SOC_TOUCH_SENSOR_VERSION == 1 // ESP32 touch_sensor_sample_config_t single_sample_cfg = TOUCH_SENSOR_V1_DEFAULT_SAMPLE_CONFIG(_duration_ms, _volt_low, _volt_high); -#elif SOC_TOUCH_SENSOR_VERSION == 2 // ESP32S2, ESP32S3 +#elif SOC_TOUCH_SENSOR_VERSION == 2 // ESP32S2, ESP32S3 touch_sensor_sample_config_t single_sample_cfg = TOUCH_SENSOR_V2_DEFAULT_SAMPLE_CONFIG(_chg_times, _volt_low, _volt_high); -#elif SOC_TOUCH_SENSOR_VERSION == 3 // ESP32P4 +#elif SOC_TOUCH_SENSOR_VERSION == 3 // ESP32P4 touch_sensor_sample_config_t single_sample_cfg = TOUCH_SENSOR_V3_DEFAULT_SAMPLE_CONFIG(_div_num, _coarse_freq_tune, _fine_freq_tune); #endif touch_sensor_sample_config_t sample_cfg[_sample_num] = {}; sample_cfg[0] = single_sample_cfg; touch_sensor_config_t sens_cfg = { -#if SOC_TOUCH_SENSOR_VERSION == 1 // ESP32 +#if SOC_TOUCH_SENSOR_VERSION == 1 // ESP32 .power_on_wait_us = __touchSleepTime, .meas_interval_us = __touchMeasureTime, .intr_trig_mode = _intr_trig_mode, .intr_trig_group = TOUCH_INTR_TRIG_GROUP_BOTH, .sample_cfg_num = _sample_num, .sample_cfg = sample_cfg, -#elif SOC_TOUCH_SENSOR_VERSION == 2 // ESP32S2, ESP32S3 +#elif SOC_TOUCH_SENSOR_VERSION == 2 // ESP32S2, ESP32S3 .power_on_wait_us = __touchSleepTime, .meas_interval_us = __touchMeasureTime, .max_meas_time_us = 0, .sample_cfg_num = _sample_num, .sample_cfg = sample_cfg, -#elif SOC_TOUCH_SENSOR_VERSION == 3 // ESP32P4 +#elif SOC_TOUCH_SENSOR_VERSION == 3 // ESP32P4 .power_on_wait_us = __touchSleepTime, .meas_interval_us = __touchMeasureTime, .max_meas_time_us = 0, @@ -305,7 +304,7 @@ static void __touchChannelInit(int pad) { __touchInterruptHandlers[pad].fn = NULL; touch_channel_config_t chan_cfg = TOUCH_CHANNEL_DEFAULT_CONFIG(); - + if (!touchStop() || !touchDisable()) { log_e("Touch sensor stop and disable failed!"); return; @@ -400,7 +399,7 @@ static void __touchConfigInterrupt(uint8_t pin, void (*userFunc)(void), void *Ar touch_channel_config_t chan_cfg = {}; for (int i = 0; i < _sample_num; i++) { -#if SOC_TOUCH_SENSOR_VERSION == 1 // ESP32 +#if SOC_TOUCH_SENSOR_VERSION == 1 // ESP32 chan_cfg.abs_active_thresh[i] = threshold; #else chan_cfg.active_thresh[i] = threshold; @@ -470,9 +469,9 @@ void touchSleepWakeUpEnable(uint8_t pin, touch_value_t threshold) { touch_sleep_config_t deep_slp_cfg = { .slp_wakeup_lvl = TOUCH_DEEP_SLEEP_WAKEUP, -#if SOC_TOUCH_SENSOR_VERSION == 1 // ESP32 - .deep_slp_sens_cfg = NULL, // Use the original touch sensor configuration -#else // SOC_TOUCH_SENSOR_VERSION 2 and 3// ESP32S2, ESP32S3, ESP32P4 +#if SOC_TOUCH_SENSOR_VERSION == 1 // ESP32 + .deep_slp_sens_cfg = NULL, // Use the original touch sensor configuration +#else // SOC_TOUCH_SENSOR_VERSION 2 and 3// ESP32S2, ESP32S3, ESP32P4 .deep_slp_chan = touch_channel_handle[pad], .deep_slp_thresh = {threshold}, .deep_slp_sens_cfg = NULL, // Use the original touch sensor configuration @@ -503,7 +502,7 @@ void touchSetTiming(float measure, uint32_t sleep) { __touchMeasureTime = measure; } -#if SOC_TOUCH_SENSOR_VERSION == 1 // ESP32 +#if SOC_TOUCH_SENSOR_VERSION == 1 // ESP32 void touchSetConfig(float duration_ms, touch_volt_lim_l_t volt_low, touch_volt_lim_h_t volt_high) { if (initialized) { log_e("Touch sensor already initialized. Cannot set configuration."); @@ -514,7 +513,7 @@ void touchSetConfig(float duration_ms, touch_volt_lim_l_t volt_low, touch_volt_l _volt_high = volt_high; } -#elif SOC_TOUCH_SENSOR_VERSION == 2 // ESP32S2, ESP32S3 +#elif SOC_TOUCH_SENSOR_VERSION == 2 // ESP32S2, ESP32S3 void touchSetConfig(uint32_t chg_times, touch_volt_lim_l_t volt_low, touch_volt_lim_h_t volt_high) { if (initialized) { log_e("Touch sensor already initialized. Cannot set configuration."); @@ -525,7 +524,7 @@ void touchSetConfig(uint32_t chg_times, touch_volt_lim_l_t volt_low, touch_volt_ _volt_high = volt_high; } -#elif SOC_TOUCH_SENSOR_VERSION == 3 // ESP32P4 +#elif SOC_TOUCH_SENSOR_VERSION == 3 // ESP32P4 void touchSetConfig(uint32_t div_num, uint8_t coarse_freq_tune, uint8_t fine_freq_tune) { if (initialized) { log_e("Touch sensor already initialized. Cannot set configuration."); @@ -537,7 +536,7 @@ void touchSetConfig(uint32_t div_num, uint8_t coarse_freq_tune, uint8_t fine_fre } #endif -#if SOC_TOUCH_SENSOR_VERSION == 1 // ESP32 +#if SOC_TOUCH_SENSOR_VERSION == 1 // ESP32 void touchInterruptSetThresholdDirection(bool mustbeLower) { if (mustbeLower) { _intr_trig_mode = TOUCH_INTR_TRIG_ON_BELOW_THRESH; diff --git a/cores/esp32/esp32-hal-touch-ng.h b/cores/esp32/esp32-hal-touch-ng.h index 988fdccda00..ebe49466bb9 100644 --- a/cores/esp32/esp32-hal-touch-ng.h +++ b/cores/esp32/esp32-hal-touch-ng.h @@ -33,23 +33,18 @@ extern "C" { #include "esp32-hal.h" #include "driver/touch_sens.h" -#if SOC_TOUCH_SENSOR_VERSION == 1 // ESP32 -#define TOUCH_CHANNEL_DEFAULT_CONFIG() { \ - .abs_active_thresh = {1000}, \ - .charge_speed = TOUCH_CHARGE_SPEED_7, \ - .init_charge_volt = TOUCH_INIT_CHARGE_VOLT_DEFAULT, \ - .group = TOUCH_CHAN_TRIG_GROUP_BOTH, \ -} -#elif SOC_TOUCH_SENSOR_VERSION == 2 // ESP32-S2 & ESP32-S3 -#define TOUCH_CHANNEL_DEFAULT_CONFIG() { \ - .active_thresh = {2000}, \ - .charge_speed = TOUCH_CHARGE_SPEED_7, \ - .init_charge_volt = TOUCH_INIT_CHARGE_VOLT_DEFAULT, \ -} -#elif SOC_TOUCH_SENSOR_VERSION == 3 // ESP32-P4 -#define TOUCH_CHANNEL_DEFAULT_CONFIG() { \ - .active_thresh = {1000}, \ -} +#if SOC_TOUCH_SENSOR_VERSION == 1 // ESP32 +#define TOUCH_CHANNEL_DEFAULT_CONFIG() \ + { \ + .abs_active_thresh = {1000}, .charge_speed = TOUCH_CHARGE_SPEED_7, .init_charge_volt = TOUCH_INIT_CHARGE_VOLT_DEFAULT, \ + .group = TOUCH_CHAN_TRIG_GROUP_BOTH, \ + } +#elif SOC_TOUCH_SENSOR_VERSION == 2 // ESP32-S2 & ESP32-S3 +#define TOUCH_CHANNEL_DEFAULT_CONFIG() \ + { .active_thresh = {2000}, .charge_speed = TOUCH_CHARGE_SPEED_7, .init_charge_volt = TOUCH_INIT_CHARGE_VOLT_DEFAULT, } +#elif SOC_TOUCH_SENSOR_VERSION == 3 // ESP32-P4 +#define TOUCH_CHANNEL_DEFAULT_CONFIG() \ + { .active_thresh = {1000}, } #endif typedef uint32_t touch_value_t; @@ -62,7 +57,7 @@ typedef uint32_t touch_value_t; **/ void touchSetTiming(float measure, uint32_t sleep); -#if SOC_TOUCH_SENSOR_VERSION == 1 // ESP32 +#if SOC_TOUCH_SENSOR_VERSION == 1 // ESP32 /* * @param[in] duration_ms The measurement duration of the touch channel * @param[in] volt_low The low voltage limit of the touch channel @@ -70,7 +65,7 @@ void touchSetTiming(float measure, uint32_t sleep); */ void touchSetConfig(float duration_ms, touch_volt_lim_l_t volt_low, touch_volt_lim_h_t volt_high); -#elif SOC_TOUCH_SENSOR_VERSION == 2 // ESP32S2, ESP32S3 +#elif SOC_TOUCH_SENSOR_VERSION == 2 // ESP32S2, ESP32S3 /* * @param[in] chg_times The charge times of the touch channel * @param[in] volt_low The low voltage limit of the touch channel @@ -78,7 +73,7 @@ void touchSetConfig(float duration_ms, touch_volt_lim_l_t volt_low, touch_volt_l */ void touchSetConfig(uint32_t chg_times, touch_volt_lim_l_t volt_low, touch_volt_lim_h_t volt_high); -#elif SOC_TOUCH_SENSOR_VERSION == 3 // ESP32P4 +#elif SOC_TOUCH_SENSOR_VERSION == 3 // ESP32P4 /* * Tune the touch pad frequency. * Note: Must be called before setting up touch pads diff --git a/cores/esp32/esp32-hal-touch.c b/cores/esp32/esp32-hal-touch.c index e611fa557f1..10482234de0 100644 --- a/cores/esp32/esp32-hal-touch.c +++ b/cores/esp32/esp32-hal-touch.c @@ -327,4 +327,4 @@ extern void touchDetachInterrupt(uint8_t) __attribute__((weak, alias("__touchDet extern void touchSetCycles(uint16_t, uint16_t) __attribute__((weak, alias("__touchSetCycles"))); #endif /* ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 5, 0) && SOC_TOUCH_SENSOR_VERSION <= 2 */ -#endif /* SOC_TOUCH_SENSOR_SUPPORTED */ \ No newline at end of file +#endif /* SOC_TOUCH_SENSOR_SUPPORTED */ diff --git a/libraries/ESP32/examples/Touch/TouchInterrupt/TouchInterrupt.ino b/libraries/ESP32/examples/Touch/TouchInterrupt/TouchInterrupt.ino index 08e10dc0fac..130026d1ad7 100644 --- a/libraries/ESP32/examples/Touch/TouchInterrupt/TouchInterrupt.ino +++ b/libraries/ESP32/examples/Touch/TouchInterrupt/TouchInterrupt.ino @@ -22,7 +22,7 @@ void setup() { //Optional: Set the threshold to 5% of the benchmark value. Only effective if threshold = 0. touchSetDefaultThreshold(5); - + Serial.println("ESP32 Touch Interrupt Test"); touchAttachInterrupt(T2, gotTouch1, threshold); touchAttachInterrupt(T3, gotTouch2, threshold); diff --git a/tests/validation/touch/touch.ino b/tests/validation/touch/touch.ino index 8d3a923300a..21ed6119c02 100644 --- a/tests/validation/touch/touch.ino +++ b/tests/validation/touch/touch.ino @@ -4,7 +4,6 @@ #if CONFIG_IDF_TARGET_ESP32 - #define TEST_TOUCH_CHANNEL (7) static touch_pad_t touch_list[TEST_TOUCH_CHANNEL] = { TOUCH_PAD_NUM0, @@ -12,7 +11,7 @@ static touch_pad_t touch_list[TEST_TOUCH_CHANNEL] = { TOUCH_PAD_NUM2, TOUCH_PAD_NUM3, TOUCH_PAD_NUM4, TOUCH_PAD_NUM5, TOUCH_PAD_NUM6, TOUCH_PAD_NUM7 /*,TOUCH_PAD_NUM8, TOUCH_PAD_NUM9*/ }; -uint8_t TOUCH_GPIOS[] = {4,/* 0,*/ 2, 15, 13, 12, 14, 27/*, 33, 32*/}; +uint8_t TOUCH_GPIOS[] = {4, /* 0,*/ 2, 15, 13, 12, 14, 27 /*, 33, 32*/}; #define NO_TOUCH_GPIO 25 @@ -20,7 +19,8 @@ uint8_t TOUCH_GPIOS[] = {4,/* 0,*/ 2, 15, 13, 12, 14, 27/*, 33, 32*/}; #define TEST_TOUCH_CHANNEL (8) //14 static touch_pad_t touch_list[TEST_TOUCH_CHANNEL] = { - TOUCH_PAD_NUM1, TOUCH_PAD_NUM2, TOUCH_PAD_NUM3, TOUCH_PAD_NUM4, TOUCH_PAD_NUM5, TOUCH_PAD_NUM6, TOUCH_PAD_NUM7, TOUCH_PAD_NUM8 + TOUCH_PAD_NUM1, TOUCH_PAD_NUM2, TOUCH_PAD_NUM3, TOUCH_PAD_NUM4, TOUCH_PAD_NUM5, + TOUCH_PAD_NUM6, TOUCH_PAD_NUM7, TOUCH_PAD_NUM8 /*TOUCH_PAD_NUM9, TOUCH_PAD_NUM10, TOUCH_PAD_NUM11, TOUCH_PAD_NUM12, TOUCH_PAD_NUM13, TOUCH_PAD_NUM14*/ }; @@ -42,7 +42,7 @@ uint8_t TOUCH_GPIOS[] = {2, 3, 4, 5, 6 /*, 7, 8, 9, 10, 11, 12 ,13, 14, 15*/}; #define NO_TOUCH_GPIO 17 #endif -#define INTERRUPT_THRESHOLD 0 // Use benchmarked threshold +#define INTERRUPT_THRESHOLD 0 // Use benchmarked threshold #if CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32P4 #define PRESSED_VALUE_DIFFERENCE 200 //-200 for ESP32 and +200 for ESP32P4 read value difference against the unpressed value @@ -68,7 +68,7 @@ void gotTouch2() { */ static void test_press_fake(touch_pad_t pad_num) { #if SOC_TOUCH_SENSOR_VERSION <= 2 - touch_ll_set_charge_speed(pad_num,TOUCH_CHARGE_SPEED_4); + touch_ll_set_charge_speed(pad_num, TOUCH_CHARGE_SPEED_4); #else touch_ll_set_internal_capacitor(0x7f); #endif @@ -79,7 +79,7 @@ static void test_press_fake(touch_pad_t pad_num) { */ static void test_release_fake(touch_pad_t pad_num) { #if SOC_TOUCH_SENSOR_VERSION <= 2 - touch_ll_set_charge_speed(pad_num, TOUCH_CHARGE_SPEED_7); + touch_ll_set_charge_speed(pad_num, TOUCH_CHARGE_SPEED_7); #else touch_ll_set_internal_capacitor(0); #endif @@ -139,7 +139,7 @@ void test_touch_interrtupt(void) { test_press_fake(touch_list[1]); delay(100); - + touchDetachInterrupt(TOUCH_GPIOS[0]); touchDetachInterrupt(TOUCH_GPIOS[1]); From a2df766fe095463d34d4da9fd7dd768e360e4267 Mon Sep 17 00:00:00 2001 From: Jakub Andrysek Date: Fri, 29 Aug 2025 15:35:39 +0200 Subject: [PATCH 38/38] refactor(CustomHeaders): replace USE_SERIAL with Serial for consistency --- .../examples/CustomHeaders/CustomHeaders.ino | 43 +++++++++---------- 1 file changed, 20 insertions(+), 23 deletions(-) diff --git a/libraries/HTTPClient/examples/CustomHeaders/CustomHeaders.ino b/libraries/HTTPClient/examples/CustomHeaders/CustomHeaders.ino index a19394ab468..a73af191fcf 100644 --- a/libraries/HTTPClient/examples/CustomHeaders/CustomHeaders.ino +++ b/libraries/HTTPClient/examples/CustomHeaders/CustomHeaders.ino @@ -1,25 +1,22 @@ #include #include -#include #include -#define USE_SERIAL Serial - // Enable or disable collecting all headers #define COLLECT_ALL_HEADERS true void setup() { - USE_SERIAL.begin(115200); + Serial.begin(115200); - USE_SERIAL.println(); - USE_SERIAL.println(); - USE_SERIAL.println(); + Serial.println(); + Serial.println(); + Serial.println(); for (uint8_t t = 4; t > 0; t--) { - USE_SERIAL.printf("[SETUP] WAIT %d...\n", t); - USE_SERIAL.flush(); + Serial.printf("[SETUP] WAIT %d...\n", t); + Serial.flush(); delay(1000); } @@ -27,17 +24,17 @@ void setup() { while (WiFi.status() != WL_CONNECTED) { delay(500); - USE_SERIAL.print("."); + Serial.print("."); } - USE_SERIAL.println(); - USE_SERIAL.println("Connected to WiFi: " + WiFi.SSID()); + Serial.println(); + Serial.println("Connected to WiFi: " + WiFi.SSID()); } void loop() { HTTPClient http; - USE_SERIAL.print("[HTTP] Preparing HTTP request...\n"); + Serial.print("[HTTP] Preparing HTTP request...\n"); // This page will return the headers we want to test + some others http.begin("https://httpbingo.org/response-headers?x-custom-header=value:42"); @@ -51,32 +48,32 @@ void loop() { http.collectHeaders(headerKeys, headerKeysCount); #endif - USE_SERIAL.print("[HTTP] Sending HTTP GET request...\n"); + Serial.print("[HTTP] Sending HTTP GET request...\n"); // start connection and send HTTP header int httpCode = http.GET(); // httpCode will be negative on error if (httpCode > 0) { // HTTP header has been send and Server response header has been handled - USE_SERIAL.printf("[HTTP] GET response code: %d\n", httpCode); + Serial.printf("[HTTP] GET response code: %d\n", httpCode); - USE_SERIAL.println("[HTTP] Headers collected:"); + Serial.println("[HTTP] Headers collected:"); for (size_t i = 0; i < http.headers(); i++) { - USE_SERIAL.printf("[HTTP] - '%s': '%s'\n", http.headerName(i).c_str(), http.header(i).c_str()); + Serial.printf("[HTTP] - '%s': '%s'\n", http.headerName(i).c_str(), http.header(i).c_str()); } - USE_SERIAL.println("[HTTP] Has header 'x-custom-header'? " + String(http.hasHeader("x-custom-header")) + " (expected true)"); - USE_SERIAL.printf("[HTTP] x-custom-header: '%s' (expected 'value:42')\n", http.header("x-custom-header").c_str()); - USE_SERIAL.printf("[HTTP] non-existing-header: '%s' (expected empty string)\n", http.header("non-existing-header").c_str()); + Serial.println("[HTTP] Has header 'x-custom-header'? " + String(http.hasHeader("x-custom-header")) + " (expected true)"); + Serial.printf("[HTTP] x-custom-header: '%s' (expected 'value:42')\n", http.header("x-custom-header").c_str()); + Serial.printf("[HTTP] non-existing-header: '%s' (expected empty string)\n", http.header("non-existing-header").c_str()); #if COLLECT_ALL_HEADERS // Server response with multiple headers, one of them is 'server' - USE_SERIAL.println("[HTTP] Has header 'server'? " + String(http.hasHeader("server")) + " (expected true)"); - USE_SERIAL.printf("[HTTP] server: '%s'\n", http.header("server").c_str()); + Serial.println("[HTTP] Has header 'server'? " + String(http.hasHeader("server")) + " (expected true)"); + Serial.printf("[HTTP] server: '%s'\n", http.header("server").c_str()); #endif } else { - USE_SERIAL.printf("[HTTP] GET... failed, error: %s\n", http.errorToString(httpCode).c_str()); + Serial.printf("[HTTP] GET... failed, error: %s\n", http.errorToString(httpCode).c_str()); } http.end();