feat(touch): Support NG touch driver for P4 (#10448)
* feat(touch): Support NG touch driver for P4 * fix(ci): Touch test + IDF compilation fixes * fix(ci): remove debug prints from touch test * fix(ci): Fix touch test for esp32 * ci(pre-commit): Apply automatic fixes --------- Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
This commit is contained in:
parent
59ca4e2d3d
commit
7cfe470d8d
14 changed files with 643 additions and 46 deletions
|
|
@ -45,6 +45,7 @@ set(CORE_SRCS
|
|||
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
|
||||
cores/esp32/Esp.cpp
|
||||
|
|
@ -317,6 +318,10 @@ if(NOT CONFIG_ARDUINO_SELECTIVE_COMPILATION OR CONFIG_ARDUINO_SELECTIVE_OpenThre
|
|||
endif()
|
||||
endif()
|
||||
|
||||
if(IDF_TARGET STREQUAL "esp32p4")
|
||||
list(APPEND requires esp_driver_touch_sens)
|
||||
endif()
|
||||
|
||||
idf_component_register(INCLUDE_DIRS ${includedirs} PRIV_INCLUDE_DIRS ${priv_includes} SRCS ${srcs} REQUIRES ${requires} PRIV_REQUIRES ${priv_requires})
|
||||
|
||||
if(NOT CONFIG_FREERTOS_HZ EQUAL 1000 AND NOT "$ENV{ARDUINO_SKIP_TICK_CHECK}")
|
||||
|
|
|
|||
453
cores/esp32/esp32-hal-touch-ng.c
Normal file
453
cores/esp32/esp32-hal-touch-ng.c
Normal file
|
|
@ -0,0 +1,453 @@
|
|||
// Copyright 2024 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 == 3 // ESP32P4 for now
|
||||
|
||||
#include "driver/touch_sens.h"
|
||||
#include "esp32-hal-touch-ng.h"
|
||||
#include "esp32-hal-periman.h"
|
||||
|
||||
/*
|
||||
Internal Private Touch Data Structure and Functions
|
||||
*/
|
||||
|
||||
typedef void (*voidFuncPtr)(void);
|
||||
typedef void (*voidArgFuncPtr)(void *);
|
||||
|
||||
typedef struct {
|
||||
voidFuncPtr fn;
|
||||
bool callWithArgs;
|
||||
void *arg;
|
||||
bool lastStatusIsPressed;
|
||||
} TouchInterruptHandle_t;
|
||||
|
||||
static TouchInterruptHandle_t __touchInterruptHandlers[SOC_TOUCH_SENSOR_NUM] = {
|
||||
0,
|
||||
};
|
||||
|
||||
static uint8_t _sample_num = 1;
|
||||
static uint32_t _div_num = 1;
|
||||
static uint8_t _coarse_freq_tune = 1;
|
||||
static uint8_t _fine_freq_tune = 1;
|
||||
static uint8_t used_pads = 0;
|
||||
|
||||
static uint32_t __touchSleepTime = 256;
|
||||
static float __touchMeasureTime = 32.0f;
|
||||
|
||||
static touch_sensor_config_t sensor_config;
|
||||
|
||||
static bool initialized = false;
|
||||
static bool enabled = false;
|
||||
static bool running = false;
|
||||
static bool channels_initialized[SOC_TOUCH_SENSOR_NUM] = {false};
|
||||
|
||||
static touch_sensor_handle_t touch_sensor_handle = NULL;
|
||||
static touch_channel_handle_t touch_channel_handle[SOC_TOUCH_SENSOR_NUM] = {};
|
||||
|
||||
// Active threshold to benchmark ratio. (i.e., touch will be activated when data >= benchmark * (1 + ratio))
|
||||
static float s_thresh2bm_ratio = 0.015f; // 1.5% for all channels
|
||||
|
||||
static bool ARDUINO_ISR_ATTR __touchOnActiveISR(touch_sensor_handle_t sens_handle, const touch_active_event_data_t *event, void *user_ctx) {
|
||||
uint8_t pad_num = (uint8_t)event->chan_id;
|
||||
__touchInterruptHandlers[pad_num].lastStatusIsPressed = true;
|
||||
if (__touchInterruptHandlers[pad_num].fn) {
|
||||
// keeping backward compatibility with "void cb(void)" and with new "void cb(void *)"
|
||||
if (__touchInterruptHandlers[pad_num].callWithArgs) {
|
||||
((voidArgFuncPtr)__touchInterruptHandlers[pad_num].fn)(__touchInterruptHandlers[pad_num].arg);
|
||||
} else {
|
||||
__touchInterruptHandlers[pad_num].fn();
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool ARDUINO_ISR_ATTR __touchOnInactiveISR(touch_sensor_handle_t sens_handle, const touch_inactive_event_data_t *event, void *user_ctx) {
|
||||
uint8_t pad_num = (uint8_t)event->chan_id;
|
||||
__touchInterruptHandlers[pad_num].lastStatusIsPressed = false;
|
||||
if (__touchInterruptHandlers[pad_num].fn) {
|
||||
// keeping backward compatibility with "void cb(void)" and with new "void cb(void *)"
|
||||
if (__touchInterruptHandlers[pad_num].callWithArgs) {
|
||||
((voidArgFuncPtr)__touchInterruptHandlers[pad_num].fn)(__touchInterruptHandlers[pad_num].arg);
|
||||
} else {
|
||||
__touchInterruptHandlers[pad_num].fn();
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool touchStop() {
|
||||
if (!running) { // Already stopped
|
||||
return true;
|
||||
}
|
||||
if (touch_sensor_stop_continuous_scanning(touch_sensor_handle) != ESP_OK) {
|
||||
log_e("Touch sensor stop scanning failed!");
|
||||
return false;
|
||||
}
|
||||
running = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool touchDisable() {
|
||||
if (!enabled) { // Already disabled
|
||||
return true;
|
||||
}
|
||||
if (!running && (touch_sensor_disable(touch_sensor_handle) != ESP_OK)) {
|
||||
log_e("Touch sensor still running or disable failed!");
|
||||
return false;
|
||||
}
|
||||
enabled = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool touchStart() {
|
||||
if (running) { // Already running
|
||||
return true;
|
||||
}
|
||||
if (enabled && (touch_sensor_start_continuous_scanning(touch_sensor_handle) != ESP_OK)) {
|
||||
log_e("Touch sensor not enabled or failed to start continuous scanning failed!");
|
||||
return false;
|
||||
}
|
||||
running = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool touchEnable() {
|
||||
if (enabled) { // Already enabled
|
||||
return true;
|
||||
}
|
||||
if (touch_sensor_enable(touch_sensor_handle) != ESP_OK) {
|
||||
log_e("Touch sensor enable failed!");
|
||||
return false;
|
||||
}
|
||||
enabled = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool touchBenchmarkThreshold(uint8_t pad) {
|
||||
if (!touchEnable()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Scan the enabled touch channels for several times, to make sure the initial channel data is stable */
|
||||
for (int i = 0; i < 3; i++) {
|
||||
if (touch_sensor_trigger_oneshot_scanning(touch_sensor_handle, 2000) != ESP_OK) {
|
||||
log_e("Touch sensor trigger oneshot scanning failed!");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/* Disable the touch channel to rollback the state */
|
||||
if (!touchDisable()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Reconfigure passed pad with new threshold
|
||||
uint32_t benchmark[_sample_num] = {};
|
||||
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;
|
||||
}
|
||||
/* Calculate the proper active thresholds regarding the initial benchmark */
|
||||
touch_channel_config_t chan_cfg = {};
|
||||
for (int i = 0; i < _sample_num; i++) {
|
||||
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]);
|
||||
}
|
||||
/* Update the channel configuration */
|
||||
if (touch_sensor_reconfig_channel(touch_channel_handle[pad], &chan_cfg) != ESP_OK) {
|
||||
log_e("Touch sensor threshold reconfig channel failed!");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool touchDetachBus(void *pin) {
|
||||
int8_t pad = digitalPinToTouchChannel((int)(pin - 1));
|
||||
channels_initialized[pad] = false;
|
||||
//disable touch pad and delete the channel
|
||||
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!");
|
||||
return false;
|
||||
}
|
||||
initialized = false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static void __touchInit() {
|
||||
if (initialized) {
|
||||
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);
|
||||
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 = {
|
||||
.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,
|
||||
};
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
sensor_config = sens_cfg;
|
||||
/* Configure the touch sensor filter */
|
||||
touch_sensor_filter_config_t filter_cfg = TOUCH_SENSOR_DEFAULT_FILTER_CONFIG();
|
||||
if (touch_sensor_config_filter(touch_sensor_handle, &filter_cfg) != ESP_OK) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* 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,
|
||||
};
|
||||
if (touch_sensor_register_callbacks(touch_sensor_handle, &callbacks, NULL) != ESP_OK) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
initialized = true;
|
||||
return;
|
||||
err:
|
||||
log_e(" Touch sensor initialization error.");
|
||||
initialized = false;
|
||||
return;
|
||||
}
|
||||
|
||||
static void __touchChannelInit(int pad) {
|
||||
if (channels_initialized[pad]) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 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
|
||||
};
|
||||
|
||||
if (!touchStop() || !touchDisable()) {
|
||||
log_e("Touch sensor stop and disable failed!");
|
||||
return;
|
||||
}
|
||||
|
||||
if (touch_sensor_new_channel(touch_sensor_handle, pad, &chan_cfg, &touch_channel_handle[pad]) != ESP_OK) {
|
||||
log_e("Touch sensor new channel failed!");
|
||||
return;
|
||||
}
|
||||
|
||||
// Benchmark active threshold and reconfigure pad
|
||||
if (!touchBenchmarkThreshold(pad)) {
|
||||
log_e("Touch sensor benchmark threshold failed!");
|
||||
return;
|
||||
}
|
||||
|
||||
channels_initialized[pad] = true;
|
||||
used_pads++;
|
||||
|
||||
if (!touchEnable() || !touchStart()) {
|
||||
log_e("Touch sensor enable and start failed!");
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t touch_read[_sample_num] = {};
|
||||
touch_channel_read_data(touch_channel_handle[pad], TOUCH_CHAN_DATA_TYPE_SMOOTH, touch_read);
|
||||
touch_value_t touch_value = touch_read[0]; // only one sample configuration for now
|
||||
|
||||
return touch_value;
|
||||
}
|
||||
|
||||
static void __touchConfigInterrupt(uint8_t pin, void (*userFunc)(void), void *Args, bool callWithArgs, touch_value_t threshold) {
|
||||
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;
|
||||
__touchInterruptHandlers[pad].callWithArgs = false;
|
||||
__touchInterruptHandlers[pad].arg = NULL;
|
||||
} else {
|
||||
// attach ISR User Call
|
||||
__touchInit();
|
||||
__touchChannelInit(pad);
|
||||
__touchInterruptHandlers[pad].fn = userFunc;
|
||||
__touchInterruptHandlers[pad].callWithArgs = callWithArgs;
|
||||
__touchInterruptHandlers[pad].arg = Args;
|
||||
}
|
||||
|
||||
if (threshold != 0) {
|
||||
if (!touchStop() || !touchDisable()) {
|
||||
log_e("Touch sensor stop and disable failed!");
|
||||
return;
|
||||
}
|
||||
|
||||
touch_channel_config_t chan_cfg = {};
|
||||
for (int i = 0; i < _sample_num; i++) {
|
||||
chan_cfg.active_thresh[i] = threshold;
|
||||
}
|
||||
|
||||
if (touch_sensor_reconfig_channel(touch_channel_handle[pad], &chan_cfg) != ESP_OK) {
|
||||
log_e("Touch sensor threshold reconfig channel failed!");
|
||||
}
|
||||
|
||||
if (!touchEnable() || !touchStart()) {
|
||||
log_e("Touch sensor enable and start failed!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 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
|
||||
// */
|
||||
|
||||
bool touchInterruptGetLastStatus(uint8_t pin) {
|
||||
int8_t pad = digitalPinToTouchChannel(pin);
|
||||
if (pad < 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return __touchInterruptHandlers[pad].lastStatusIsPressed;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
log_v("Touch sensor deep sleep wake-up configuration for pad %d with threshold %d", pad, threshold);
|
||||
if (!touchStop() || !touchDisable()) {
|
||||
log_e("Touch sensor stop and disable failed!");
|
||||
return;
|
||||
}
|
||||
|
||||
touch_sleep_config_t deep_slp_cfg = {
|
||||
.slp_wakeup_lvl = TOUCH_DEEP_SLEEP_WAKEUP,
|
||||
.deep_slp_chan = touch_channel_handle[pad],
|
||||
.deep_slp_thresh = {threshold},
|
||||
.deep_slp_sens_cfg = NULL, // Use the original touch sensor configuration
|
||||
};
|
||||
|
||||
// Register the deep sleep wake-up
|
||||
if (touch_sensor_config_sleep_wakeup(touch_sensor_handle, &deep_slp_cfg) != ESP_OK) {
|
||||
log_e("Touch sensor deep sleep wake-up failed!");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!touchEnable() || !touchStart()) {
|
||||
log_e("Touch sensor enable and start failed!");
|
||||
}
|
||||
}
|
||||
|
||||
void touchSetDefaultThreshold(float percentage) {
|
||||
s_thresh2bm_ratio = (float)percentage / 100.0f;
|
||||
}
|
||||
|
||||
void touchSetTiming(float measure, uint32_t sleep) {
|
||||
if (initialized) {
|
||||
log_e("Touch sensor already initialized. Cannot set cycles.");
|
||||
return;
|
||||
}
|
||||
__touchSleepTime = sleep;
|
||||
__touchMeasureTime = measure;
|
||||
}
|
||||
|
||||
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.");
|
||||
return;
|
||||
}
|
||||
_div_num = div_num;
|
||||
_coarse_freq_tune = coarse_freq_tune;
|
||||
_fine_freq_tune = fine_freq_tune;
|
||||
}
|
||||
|
||||
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_SUPPORTED */
|
||||
91
cores/esp32/esp32-hal-touch-ng.h
Normal file
91
cores/esp32/esp32-hal-touch-ng.h
Normal file
|
|
@ -0,0 +1,91 @@
|
|||
/*
|
||||
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_NEW_H_
|
||||
#define MAIN_ESP32_HAL_TOUCH_NEW_H_
|
||||
|
||||
#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"
|
||||
|
||||
typedef uint32_t touch_value_t;
|
||||
|
||||
/*
|
||||
* Set time in us that measurement operation takes
|
||||
* The result from touchRead, threshold and detection
|
||||
* accuracy depend on these values.
|
||||
* Note: must be called before setting up touch pads
|
||||
**/
|
||||
void touchSetTiming(float measure, uint32_t sleep);
|
||||
|
||||
/*
|
||||
* 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);
|
||||
|
||||
/*
|
||||
* Read touch pad value.
|
||||
* 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 rises 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);
|
||||
|
||||
/*
|
||||
* 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.
|
||||
**/
|
||||
bool touchInterruptGetLastStatus(uint8_t pin);
|
||||
|
||||
/*
|
||||
* Set the default threshold for touch pads.
|
||||
* The threshold is a percentage of the benchmark value.
|
||||
* The default value is 1.5%.
|
||||
**/
|
||||
void touchSetDefaultThreshold(float percentage);
|
||||
|
||||
/*
|
||||
* Setup touch pad wake up from deep sleep /light sleep with given threshold.
|
||||
* When light sleep is used, all used touch pads will be able to wake up the chip.
|
||||
**/
|
||||
void touchSleepWakeUpEnable(uint8_t pin, touch_value_t threshold);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* SOC_TOUCH_SENSOR_VERSION == 3 */
|
||||
#endif /* SOC_TOUCH_SENSOR_SUPPORTED */
|
||||
#endif /* MAIN_ESP32_HAL_TOUCH_H_ */
|
||||
|
|
@ -14,10 +14,8 @@
|
|||
#include "soc/soc_caps.h"
|
||||
|
||||
#if SOC_TOUCH_SENSOR_SUPPORTED
|
||||
#if SOC_TOUCH_SENSOR_VERSION == 3 // ESP32P4
|
||||
// ToDo: Implement touch sensor for ESP32P4
|
||||
#warning "Touch sensor not implemented for ESP32P4 yet"
|
||||
#else
|
||||
#if SOC_TOUCH_SENSOR_VERSION <= 2 // ESP32, ESP32S2, ESP32S3
|
||||
|
||||
#include "driver/touch_sensor.h"
|
||||
#include "esp32-hal-touch.h"
|
||||
#include "esp32-hal-periman.h"
|
||||
|
|
@ -26,10 +24,10 @@
|
|||
Internal Private Touch Data Structure and Functions
|
||||
*/
|
||||
|
||||
#if SOC_TOUCH_SENSOR_VERSION == 1 // ESP32
|
||||
#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, ESP32P4
|
||||
#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
|
||||
|
|
@ -55,7 +53,7 @@ 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
|
||||
#if SOC_TOUCH_SENSOR_VERSION == 1 // ESP32
|
||||
uint32_t pad_intr = touch_pad_get_status();
|
||||
//clear interrupt
|
||||
touch_pad_clear_status();
|
||||
|
|
@ -97,7 +95,7 @@ static void ARDUINO_ISR_ATTR __touchISR(void *arg) {
|
|||
static void __touchSetCycles(uint16_t measure, uint16_t sleep) {
|
||||
__touchSleepCycles = sleep;
|
||||
__touchMeasureCycles = measure;
|
||||
#if SOC_TOUCH_SENSOR_VERSION == 1 // ESP32
|
||||
#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);
|
||||
|
|
@ -127,7 +125,7 @@ static void __touchInit() {
|
|||
|
||||
esp_err_t err = ESP_OK;
|
||||
|
||||
#if SOC_TOUCH_SENSOR_VERSION == 1 // ESP32
|
||||
#if SOC_TOUCH_SENSOR_VERSION == 1 // ESP32
|
||||
err = touch_pad_init();
|
||||
if (err != ESP_OK) {
|
||||
goto err;
|
||||
|
|
@ -147,7 +145,7 @@ static void __touchInit() {
|
|||
if (err != ESP_OK) {
|
||||
goto err;
|
||||
}
|
||||
touch_pad_intr_enable(); // returns ESP_OK
|
||||
touch_pad_intr_enable(); // returns ESP_OK
|
||||
#elif SOC_TOUCH_SENSOR_VERSION == 2 // ESP32S2, ESP32S3
|
||||
err = touch_pad_init();
|
||||
if (err != ESP_OK) {
|
||||
|
|
@ -169,7 +167,6 @@ static void __touchInit() {
|
|||
touch_pad_fsm_start(); // returns ESP_OK
|
||||
//ISR setup moved to __touchChannelInit
|
||||
#endif
|
||||
|
||||
initialized = true;
|
||||
return;
|
||||
err:
|
||||
|
|
@ -183,11 +180,11 @@ static void __touchChannelInit(int pad) {
|
|||
return;
|
||||
}
|
||||
|
||||
#if SOC_TOUCH_SENSOR_VERSION == 1 // ESP32
|
||||
#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
|
||||
#elif SOC_TOUCH_SENSOR_VERSION == 2 // ESP32S2, ESP32S3
|
||||
// Initial no Threshold and setup
|
||||
__touchInterruptHandlers[pad].fn = NULL;
|
||||
touch_pad_config(pad); // returns ESP_OK
|
||||
|
|
@ -274,7 +271,7 @@ static void __touchDettachInterrupt(uint8_t pin) {
|
|||
External Public Touch API Functions
|
||||
*/
|
||||
|
||||
#if SOC_TOUCH_SENSOR_VERSION == 1 // Only for ESP32 SoC
|
||||
#if SOC_TOUCH_SENSOR_VERSION == 1 // Only for ESP32 SoC
|
||||
void touchInterruptSetThresholdDirection(bool mustbeLower) {
|
||||
if (mustbeLower) {
|
||||
touch_pad_set_trigger_mode(TOUCH_TRIGGER_BELOW);
|
||||
|
|
@ -328,5 +325,5 @@ extern void touchAttachInterruptArg(uint8_t, voidArgFuncPtr, void *, touch_value
|
|||
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 == 3 */
|
||||
#endif /* SOC_TOUCH_SENSOR_VERSION <= 2 */
|
||||
#endif /* SOC_TOUCH_SENSOR_SUPPORTED */
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@
|
|||
|
||||
#include "soc/soc_caps.h"
|
||||
#if SOC_TOUCH_SENSOR_SUPPORTED
|
||||
#if SOC_TOUCH_SENSOR_VERSION <= 2 // ESP32 ESP32S2 ESP32S3
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
|
@ -37,8 +38,6 @@ extern "C" {
|
|||
typedef uint16_t touch_value_t;
|
||||
#elif SOC_TOUCH_SENSOR_VERSION == 2 // ESP32S2 ESP32S3
|
||||
typedef uint32_t touch_value_t;
|
||||
#elif SOC_TOUCH_SENSOR_VERSION == 3 // ESP32P4
|
||||
typedef uint32_t touch_value_t;
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
|
@ -99,5 +98,6 @@ void touchSleepWakeUpEnable(uint8_t pin, touch_value_t threshold);
|
|||
}
|
||||
#endif
|
||||
|
||||
#endif /* SOC_TOUCH_SENSOR_VERSION <= 2 */
|
||||
#endif /* SOC_TOUCH_SENSOR_SUPPORTED */
|
||||
#endif /* MAIN_ESP32_HAL_TOUCH_H_ */
|
||||
|
|
|
|||
|
|
@ -74,6 +74,7 @@ void yield(void);
|
|||
#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"
|
||||
#include "esp32-hal-spi.h"
|
||||
|
|
|
|||
|
|
@ -106,7 +106,7 @@ int8_t gpioNumberToDigitalPin(int8_t gpioNumber);
|
|||
#define spiAttachMOSI(spi, mosi) spiAttachMOSI(spi, digitalPinToGPIONumber(mosi))
|
||||
#define spiAttachSS(spi, cs_num, ss) spiAttachSS(spi, cs_num, digitalPinToGPIONumber(ss))
|
||||
|
||||
// cores/esp32/esp32-hal-touch.h
|
||||
// cores/esp32/esp32-hal-touch.h && cores/esp32/esp32-hal-touch-ng.h
|
||||
#define touchInterruptGetLastStatus(pin) touchInterruptGetLastStatus(digitalPinToGPIONumber(pin))
|
||||
#define touchRead(pin) touchRead(digitalPinToGPIONumber(pin))
|
||||
#define touchAttachInterruptArg(pin, userFunc, arg, threshold) touchAttachInterruptArg(digitalPinToGPIONumber(pin), userFunc, arg, threshold)
|
||||
|
|
|
|||
|
|
@ -15,9 +15,11 @@ Pranav Cherukupalli <cherukupallip@gmail.com>
|
|||
*/
|
||||
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
#define THRESHOLD 40 /* Greater the value, more the sensitivity */
|
||||
#else //ESP32-S2 and ESP32-S3 + default for other chips (to be adjusted) */
|
||||
#define THRESHOLD 40 /* Greater the value, more the sensitivity */
|
||||
#elif (CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3)
|
||||
#define THRESHOLD 5000 /* Lower the value, more the sensitivity */
|
||||
#else // ESP32-P4 + default for other chips (to be adjusted) */
|
||||
#define THRESHOLD 500 /* Lower the value, more the sensitivity */
|
||||
#endif
|
||||
|
||||
RTC_DATA_ATTR int bootCount = 0;
|
||||
|
|
@ -88,7 +90,7 @@ void setup() {
|
|||
touchSleepWakeUpEnable(T3, THRESHOLD);
|
||||
touchSleepWakeUpEnable(T7, THRESHOLD);
|
||||
|
||||
#else //ESP32-S2 + ESP32-S3
|
||||
#else //ESP32-S2 + ESP32-S3 + ESP32-P4
|
||||
//Setup sleep wakeup on Touch Pad 3 (GPIO3)
|
||||
touchSleepWakeUpEnable(T3, THRESHOLD);
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@
|
|||
"targets": {
|
||||
"esp32c3": false,
|
||||
"esp32c6": false,
|
||||
"esp32h2": false,
|
||||
"esp32p4": false
|
||||
"esp32h2": false
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,7 +3,12 @@ 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
|
||||
|
||||
bool touch1detected = false;
|
||||
bool touch2detected = false;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,8 +1,5 @@
|
|||
{
|
||||
"requires": [
|
||||
"CONFIG_SOC_TOUCH_SENSOR_SUPPORTED=y"
|
||||
],
|
||||
"targets": {
|
||||
"esp32p4": false
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,8 +1,5 @@
|
|||
{
|
||||
"requires": [
|
||||
"CONFIG_SOC_TOUCH_SENSOR_SUPPORTED=y"
|
||||
],
|
||||
"targets": {
|
||||
"esp32p4": false
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,8 +5,5 @@
|
|||
},
|
||||
"requires": [
|
||||
"CONFIG_SOC_TOUCH_SENSOR_SUPPORTED=y"
|
||||
],
|
||||
"targets": {
|
||||
"esp32p4": false
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,10 @@
|
|||
#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
|
||||
|
||||
#define TEST_TOUCH_CHANNEL (9)
|
||||
|
|
@ -15,11 +19,7 @@ uint8_t TOUCH_GPIOS[] = {4, 2, 15, 13, 12, 14, 27, 33, 32};
|
|||
|
||||
#define NO_TOUCH_GPIO 25
|
||||
|
||||
#define RELEASED_VALUE 75 //75+ read value to pass test
|
||||
#define PRESSED_VALUE 20 //20- read value to pass test
|
||||
#define INTERRUPT_THRESHOLD 40
|
||||
|
||||
#else //ESP32S2 and ESP32S3
|
||||
#elif (CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3)
|
||||
|
||||
#define TEST_TOUCH_CHANNEL (12) //14
|
||||
static touch_pad_t touch_list[TEST_TOUCH_CHANNEL] = {
|
||||
|
|
@ -33,7 +33,25 @@ uint8_t TOUCH_GPIOS[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 /*,13,14*/};
|
|||
|
||||
#define NO_TOUCH_GPIO 17
|
||||
|
||||
#if CONFIG_IDF_TARGET_ESP32S2
|
||||
#else //ESP32P4
|
||||
|
||||
#define TEST_TOUCH_CHANNEL (5) //14
|
||||
static touch_pad_t touch_list[TEST_TOUCH_CHANNEL] = {
|
||||
TOUCH_PAD_NUM0, 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*/
|
||||
};
|
||||
|
||||
uint8_t TOUCH_GPIOS[] = {2, 3, 4, 5, 6 /*, 7, 8, 9, 10, 11, 12 ,13, 14, 15*/};
|
||||
|
||||
#define NO_TOUCH_GPIO 17
|
||||
#endif
|
||||
|
||||
#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
|
||||
|
|
@ -41,12 +59,13 @@ uint8_t TOUCH_GPIOS[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 /*,13,14*/};
|
|||
#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
|
||||
#define INTERRUPT_THRESHOLD 0 // Use benchmarked threshold
|
||||
#else
|
||||
#error Test not currently supported on this chip. Please adjust and try again!
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
bool touch1detected = false;
|
||||
bool touch2detected = false;
|
||||
|
||||
|
|
@ -59,17 +78,25 @@ void gotTouch2() {
|
|||
}
|
||||
|
||||
/*
|
||||
* Change the slope to get larger value from touch sensor.
|
||||
* Change the slope to get larger value from touch sensor. (Capacitor for ESP32P4)
|
||||
*/
|
||||
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);
|
||||
#else
|
||||
touch_ll_set_internal_capacitor(0x7f);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* Change the slope to get smaller value from touch sensor.
|
||||
* Change the slope to get smaller value from touch sensor. (Capacitor for ESP32P4)
|
||||
*/
|
||||
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);
|
||||
#else
|
||||
touch_ll_set_internal_capacitor(0);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* These functions are intended to be called before and after each test. */
|
||||
|
|
@ -87,6 +114,7 @@ void tearDown(void) {
|
|||
*/
|
||||
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
|
||||
|
|
@ -109,6 +137,29 @@ void test_touch_read(void) {
|
|||
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++) {
|
||||
touch_unpressed[i] = touchRead(TOUCH_GPIOS[i]);
|
||||
}
|
||||
|
||||
// TEST PRESS STATE
|
||||
for (int j = 0; j < TEST_TOUCH_CHANNEL; j++) {
|
||||
test_press_fake(touch_list[j]);
|
||||
}
|
||||
delay(100);
|
||||
|
||||
touch_value_t touch_pressed[sizeof(TOUCH_GPIOS)];
|
||||
for (int k = 0; k < sizeof(TOUCH_GPIOS); k++) {
|
||||
touch_pressed[k] = touchRead(TOUCH_GPIOS[k]);
|
||||
}
|
||||
|
||||
// COMPARE PRESSED > UNPRESSED
|
||||
for (int l = 0; l < sizeof(TOUCH_GPIOS); l++) {
|
||||
TEST_ASSERT_GREATER_THAN((touch_unpressed[l] + PRESSED_VALUE_DIFFERENCE), touch_pressed[l]);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void test_touch_interrtupt(void) {
|
||||
|
|
@ -146,4 +197,6 @@ void setup() {
|
|||
UNITY_END();
|
||||
}
|
||||
|
||||
void loop() {}
|
||||
void loop() {
|
||||
delay(10);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue