diff --git a/Documentation/platforms/risc-v/esp32p4/index.rst b/Documentation/platforms/risc-v/esp32p4/index.rst index 03aef9e2c8920..5533384d22517 100644 --- a/Documentation/platforms/risc-v/esp32p4/index.rst +++ b/Documentation/platforms/risc-v/esp32p4/index.rst @@ -379,7 +379,7 @@ LP GPIO No LP Timers No LP ADC Yes Temperature Yes Internal temperature sensor -Touch Sensor No +Touch Sensor Yes eFuse Yes Virtual eFuses supported ================= ======= ================================== diff --git a/arch/risc-v/src/common/espressif/CMakeLists.txt b/arch/risc-v/src/common/espressif/CMakeLists.txt index 928e09226ce05..8de8efcd28345 100644 --- a/arch/risc-v/src/common/espressif/CMakeLists.txt +++ b/arch/risc-v/src/common/espressif/CMakeLists.txt @@ -213,7 +213,7 @@ if(DEFINED ENV{ESP_HAL_3RDPARTY_VERSION}) CACHE STRING "ESP HAL 3rdparty version") else() set(ESP_HAL_3RDPARTY_VERSION - 627f38f94c1084b6b2d90ce09c0ce5517e8eaed7 + 9e9626fe059689a24e8d12f4b72d5ab2791de194 CACHE STRING "ESP HAL 3rdparty version") endif() diff --git a/arch/risc-v/src/common/espressif/Kconfig b/arch/risc-v/src/common/espressif/Kconfig index 1f35df66b4d56..603e6e88c13fd 100644 --- a/arch/risc-v/src/common/espressif/Kconfig +++ b/arch/risc-v/src/common/espressif/Kconfig @@ -1553,6 +1553,14 @@ config PM_UART_WAKEUP_CHAR_SEQ endmenu # PM UART Wakeup Sources +config PM_TOUCH_WAKEUP + bool "PM Touch Wakeup" + depends on ESPRESSIF_TOUCH + default n + ---help--- + Enable touch sensor wakeup functionality. + This allows the system to wake up from PM_STANDBY or PM_SLEEP + config PM_ALARM_SEC int "PM_STANDBY delay (seconds)" default 15 @@ -1685,6 +1693,13 @@ config ESPRESSIF_AES_ACCELERATOR ---help--- Enable AES accelerator support. +config ESPRESSIF_TOUCH + bool "Touch sensor" + default n + depends on ARCH_CHIP_ESP32P4 + ---help--- + Enable touch sensor support. + config ESPRESSIF_ADC bool "Analog-to-digital converter (ADC)" default n @@ -3795,6 +3810,136 @@ endif # PWM_MULTICHAN && PWM_NCHANNELS > 1 endmenu # LEDC configuration +menu "Touch Sensor Configuration" + depends on ESPRESSIF_TOUCH + +config ESP_TOUCH_CHANNEL1 + bool "Touch Sensor Channel 1(IO2)" + default n + ---help--- + Enable touch sensor channel 1 (IO2). + +config ESP_TOUCH_CHANNEL2 + bool "Touch Sensor Channel 2(IO3)" + default n + ---help--- + Enable touch sensor channel 2 (IO3). + +config ESP_TOUCH_CHANNEL3 + bool "Touch Sensor Channel 3(IO4)" + default n + ---help--- + Enable touch sensor channel 3 (IO4). + +config ESP_TOUCH_CHANNEL4 + bool "Touch Sensor Channel 4(IO5)" + default n + ---help--- + Enable touch sensor channel 4 (IO5). + +config ESP_TOUCH_CHANNEL5 + bool "Touch Sensor Channel 5(IO6)" + default n + ---help--- + Enable touch sensor channel 5 (IO6). + +config ESP_TOUCH_CHANNEL6 + bool "Touch Sensor Channel 6(IO7)" + default n + ---help--- + Enable touch sensor channel 6 (IO7). + +config ESP_TOUCH_CHANNEL7 + bool "Touch Sensor Channel 7(IO8)" + default n + ---help--- + Enable touch sensor channel 7 (IO8). + +config ESP_TOUCH_CHANNEL8 + bool "Touch Sensor Channel 8(IO9)" + default n + ---help--- + Enable touch sensor channel 8 (IO9). + +config ESP_TOUCH_CHANNEL9 + bool "Touch Sensor Channel 9(IO10)" + default n + ---help--- + Enable touch sensor channel 9 (IO10). + +config ESP_TOUCH_CHANNEL10 + bool "Touch Sensor Channel 10(IO11)" + default n + ---help--- + Enable touch sensor channel 10 (IO11). + +config ESP_TOUCH_CHANNEL11 + bool "Touch Sensor Channel 11(IO12)" + default n + ---help--- + Enable touch sensor channel 11 (IO12). + +config ESP_TOUCH_CHANNEL12 + bool "Touch Sensor Channel 12(IO13)" + default n + ---help--- + Enable touch sensor channel 12 (IO13). + +config ESP_TOUCH_CHANNEL13 + bool "Touch Sensor Channel 13(IO14)" + default n + ---help--- + Enable touch sensor channel 13 (IO14). + +config ESP_TOUCH_CHANNEL14 + bool "Touch Sensor Channel 14(IO15)" + default n + ---help--- + Enable touch sensor channel 14 (IO15). + +choice ESP_TOUCH_MODE + prompt "Touch Sensor Mode" + default ESP_TOUCH_MODE_CONTINUOUS + ---help--- + Select operating mode for touch sensor. + +config ESP_TOUCH_MODE_ONE_SHOT + bool "One-Shot Mode" + +config ESP_TOUCH_MODE_CONTINUOUS + bool "Continuous Mode" + +endchoice # ESP_TOUCH_MODE + +config ESP_TOUCH_IRQ + bool "Enable touch pad interrupts" + depends on ARCH_IRQBUTTONS + default n + ---help--- + Enable interrupt support for the touch pads. + +config ESP_TOUCH_INVERTED + bool "Touch pad inverted threshold detection" + default n + ---help--- + Detect touch activity when read value is lower than threshold. + +config ESP_TOUCH_FILTER + bool "Touch pad filter" + default y + ---help--- + Enable internal filter for the touch pads. + +config ESP_TOUCH_DENOISE_LVL + int "Touch pad denoise level" + depends on ESP_TOUCH_FILTER + default 1 + range 0 4 + ---help--- + Internal denoise level for the touch pads. + +endmenu # Touch Sensor Configuration + menu "I2S Configuration" depends on ESPRESSIF_I2S diff --git a/arch/risc-v/src/common/espressif/Make.defs b/arch/risc-v/src/common/espressif/Make.defs index 9fafb834f5f45..9405be309e41b 100644 --- a/arch/risc-v/src/common/espressif/Make.defs +++ b/arch/risc-v/src/common/espressif/Make.defs @@ -193,6 +193,10 @@ ifeq ($(CONFIG_CRYPTO_CRYPTODEV_HARDWARE),y) CHIP_CSRCS += esp_crypto.c endif +ifeq ($(CONFIG_ESPRESSIF_TOUCH),y) + CHIP_CSRCS += esp_touch.c +endif + ifeq ($(CONFIG_ESPRESSIF_USE_LP_CORE),y) CHIP_CSRCS += esp_ulp.c endif @@ -221,7 +225,7 @@ endif ESP_HAL_3RDPARTY_REPO = esp-hal-3rdparty ifndef ESP_HAL_3RDPARTY_VERSION - ESP_HAL_3RDPARTY_VERSION = 627f38f94c1084b6b2d90ce09c0ce5517e8eaed7 + ESP_HAL_3RDPARTY_VERSION = 9e9626fe059689a24e8d12f4b72d5ab2791de194 endif ifndef ESP_HAL_3RDPARTY_URL diff --git a/arch/risc-v/src/common/espressif/esp_touch.c b/arch/risc-v/src/common/espressif/esp_touch.c new file mode 100644 index 0000000000000..475756c3a47f8 --- /dev/null +++ b/arch/risc-v/src/common/espressif/esp_touch.c @@ -0,0 +1,541 @@ +/**************************************************************************** + * arch/risc-v/src/common/espressif/esp_touch.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include +#include +#include + +#include "esp_touch.h" + +#include "esp_bit_defs.h" +#include "soc/soc_caps.h" +#include "driver/touch_version_types.h" +#include "driver/touch_sens_types.h" +#include "driver/touch_sens.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define TOUCH_CFG_DEFAULT() \ +{ \ + TOUCH_SENSOR_V3_DEFAULT_SAMPLE_CONFIG2(3, 29, 8, 3), \ + TOUCH_SENSOR_V3_DEFAULT_SAMPLE_CONFIG2(2, 88, 31, 7), \ + TOUCH_SENSOR_V3_DEFAULT_SAMPLE_CONFIG2(3, 10, 31, 7) \ +} + +#define TOUCH_CHAN_CFG_DEFAULT() \ +{ \ + .active_thresh = \ + { \ + 1000, \ + 2500, \ + 5000 \ + }, \ +} + +#define SCAN_TIMEOUT_MS 2000 +#define TOUCH_THRESH_RATIO_PERMILLE 15 + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +struct esp_touch_priv_s +{ + touch_sensor_handle_t sens_handle; /* Touch sensor handler */ + touch_channel_handle_t chan_handle[SOC_TOUCH_MAX_CHAN_ID]; /* Touch sensor channels handler */ + touch_sensor_config_t sens_cfg; /* Touch sensor configuration struct */ + touch_channel_config_t chan_cfg; /* Touch sensor channel configuration struct */ + touch_sensor_sample_config_t sample_cfg[TOUCH_SAMPLE_CFG_NUM]; /* Sample configs for sens_cfg */ + int touch_threshold[SOC_TOUCH_MAX_CHAN_ID]; /* Threshold values for touch activison */ +#ifdef CONFIG_ESP_TOUCH_IRQ + xcpt_t irq_handler[SOC_TOUCH_MAX_CHAN_ID]; /* Interrupt callback function */ + void *irq_arg[SOC_TOUCH_MAX_CHAN_ID]; /* Interrupt callback function argument */ +#endif +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static uint64_t esp_touch_get_channel_mask(void); +static int esp_touch_update_channel_thresholds(void); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static struct esp_touch_priv_s esp_touch_priv = +{ + .sens_handle = NULL, + .chan_handle = + { + 0 + }, + .sample_cfg = TOUCH_CFG_DEFAULT(), + .chan_cfg = TOUCH_CHAN_CFG_DEFAULT(), + .touch_threshold = + { + [0 ... SOC_TOUCH_MAX_CHAN_ID - 1] = 0, + }, +}; + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: esp_touch_calibrate + * + * Description: + * Do the initial scanning to initialize the touch channel data. + * Without this step, the channel data in the first read will be invalid + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void esp_touch_calibrate(void) +{ + int i; + + touch_sensor_enable(esp_touch_priv.sens_handle); + for (i = 0; i < 3; i++) + { + touch_sensor_trigger_oneshot_scanning(esp_touch_priv.sens_handle, + SCAN_TIMEOUT_MS); + } + + touch_sensor_disable(esp_touch_priv.sens_handle); + esp_touch_update_channel_thresholds(); +} + +/**************************************************************************** + * Name: esp_touch_update_channel_thresholds + * + * Description: + * Reconfigure per-sample active thresholds from benchmark values. + * This matches the IDF example flow and avoids channels booting active. + * + * Input Parameters: + * None + * + * Returned Value: + * OK on success; a negated errno value on failure. + * + ****************************************************************************/ + +static int esp_touch_update_channel_thresholds(void) +{ + int ret = OK; + int mask; + uint64_t chan_mask; + touch_channel_config_t chan_cfg = TOUCH_CHAN_CFG_DEFAULT(); + uint32_t benchmark[TOUCH_SAMPLE_CFG_NUM]; + + chan_mask = esp_touch_get_channel_mask(); + for (int i = SOC_TOUCH_MIN_CHAN_ID; i < SOC_TOUCH_MAX_CHAN_ID; i++) + { + mask = BIT(i); + if ((chan_mask & mask) == 0) + { + continue; + } + + ret = touch_channel_read_data(esp_touch_priv.chan_handle[i], + TOUCH_CHAN_DATA_TYPE_BENCHMARK, + benchmark); + if (ret != OK) + { + ierr("Failed to read benchmark for touch channel: %d\n", i); + return ret; + } + + for (int j = 0; j < TOUCH_SAMPLE_CFG_NUM; j++) + { + uint32_t thresh = (benchmark[j] * + TOUCH_THRESH_RATIO_PERMILLE) / 1000; + chan_cfg.active_thresh[j] = thresh ? thresh : 1; + } + + esp_touch_priv.touch_threshold[i] = + benchmark[0] + chan_cfg.active_thresh[0]; + ret = touch_sensor_reconfig_channel(esp_touch_priv.chan_handle[i], + &chan_cfg); + if (ret != OK) + { + ierr("Failed to reconfigure touch channel: %d\n", i); + return ret; + } + } + + return ret; +} + +/**************************************************************************** + * Name: esp_touch_get_channel_mask + * + * Description: + * Get touch channel mask value to initialize. + * + * Input Parameters: + * None + * + * Returned Value: + * A 64-bit unsigned integer where each bit corresponds to an channel + * that has been configured as a touch gpio channel. + * + ****************************************************************************/ + +static uint64_t esp_touch_get_channel_mask(void) +{ + uint64_t chan_mask = 0; + +#ifdef CONFIG_ESP_TOUCH_CHANNEL1 + chan_mask |= BIT(1); +#endif +#ifdef CONFIG_ESP_TOUCH_CHANNEL2 + chan_mask |= BIT(2); +#endif +#ifdef CONFIG_ESP_TOUCH_CHANNEL3 + chan_mask |= BIT(3); +#endif +#ifdef CONFIG_ESP_TOUCH_CHANNEL4 + chan_mask |= BIT(4); +#endif +#ifdef CONFIG_ESP_TOUCH_CHANNEL5 + chan_mask |= BIT(5); +#endif +#ifdef CONFIG_ESP_TOUCH_CHANNEL6 + chan_mask |= BIT(6); +#endif +#ifdef CONFIG_ESP_TOUCH_CHANNEL7 + chan_mask |= BIT(7); +#endif +#ifdef CONFIG_ESP_TOUCH_CHANNEL8 + chan_mask |= BIT(8); +#endif +#ifdef CONFIG_ESP_TOUCH_CHANNEL9 + chan_mask |= BIT(9); +#endif +#ifdef CONFIG_ESP_TOUCH_CHANNEL10 + chan_mask |= BIT(10); +#endif +#ifdef CONFIG_ESP_TOUCH_CHANNEL11 + chan_mask |= BIT(11); +#endif +#ifdef CONFIG_ESP_TOUCH_CHANNEL12 + chan_mask |= BIT(12); +#endif +#ifdef CONFIG_ESP_TOUCH_CHANNEL13 + chan_mask |= BIT(13); +#endif +#ifdef CONFIG_ESP_TOUCH_CHANNEL14 + chan_mask |= BIT(14); +#endif + + return chan_mask; +} + +/**************************************************************************** + * Name: esp_touch_channel_prepare + * + * Description: + * Configure touch pad channels. + * + * Input Parameters: + * button_num - Address to return number of buttons initialized + * + * Returned Value: + * OK on success; a negated errno value on failure. + * + ****************************************************************************/ + +static int esp_touch_channel_prepare(int *button_num) +{ + int ret = OK; + int buttons = 0; + int mask; + uint64_t chan_mask; + touch_chan_info_t chan_info = + { + 0 + }; + + chan_mask = esp_touch_get_channel_mask(); + for (int i = SOC_TOUCH_MIN_CHAN_ID; i < SOC_TOUCH_MAX_CHAN_ID; i++) + { + mask = BIT(i); + if ((chan_mask & mask) != 0) + { + buttons++; + ret = touch_sensor_new_channel(esp_touch_priv.sens_handle, i, + &esp_touch_priv.chan_cfg, + &esp_touch_priv.chan_handle[i]); + if (ret != OK) + { + ierr("Failed to create touch pad channel: %d\n", i); + return ret; + } + + touch_sensor_get_channel_info(esp_touch_priv.chan_handle[i], + &chan_info); + iinfo("Touch pad [CH %d] enabled on GPIO%d\n", + i, chan_info.chan_gpio); + } + } + + *button_num = buttons; + return ret; +} + +#ifdef CONFIG_ESP_TOUCH_IRQ +/**************************************************************************** + * Name: esp_touch_callback + * + * Description: + * Interrupt callback handler. + * + * Input Parameters: + * sens_handle - Touch pad handler + * event - Event information of interrupt + * user_ctx - Argument to pass to the handler + * + * Returned Value: + * False. + * + ****************************************************************************/ + +static bool esp_touch_callback(touch_sensor_handle_t sens_handle, + const touch_active_event_data_t *event, + void *user_ctx) +{ + int channel = event->chan_id; + if (esp_touch_priv.irq_handler[channel] != NULL) + { + esp_touch_priv.irq_handler[channel](channel, + (void *)event, + esp_touch_priv.irq_arg[channel]); + } + + return false; +} +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: esp_touchread + * + * Description: + * Read a touch pad channel. + * + * Input Parameters: + * channel - The touch pad channel. + * + * Returned Value: + * 0 if touch pad pressed, 1 if released. + * + ****************************************************************************/ + +bool esp_touchread(int channel) +{ + uint32_t data[TOUCH_SAMPLE_CFG_NUM]; +#ifndef CONFIG_ESP_TOUCH_MODE_CONTINUOUS + touch_sensor_trigger_oneshot_scanning(esp_touch_priv.sens_handle, + SCAN_TIMEOUT_MS); +#endif + touch_channel_read_data(esp_touch_priv.chan_handle[channel], + TOUCH_CHAN_DATA_TYPE_SMOOTH, + data); +#ifndef CONFIG_ESP_TOUCH_INVERTED + if (data[0] >= esp_touch_priv.touch_threshold[channel]) +#else + if (data[0] <= esp_touch_priv.touch_threshold[channel]) +#endif + { + return true; + } + + return false; +} + +#ifdef CONFIG_ESP_TOUCH_IRQ +/**************************************************************************** + * Name: esp_touchirqattach + * + * Description: + * Attach an interrupt handler to specified channel. + * + * Input Parameters: + * channel - Touch pad channel number + * handler - Interrupt handler function + * arg - Argument to pass to the handler + * + * Returned Value: + * Zero (OK) is returned on success; a negated errno value is returned + * to indicate the nature of any failure. + * + ****************************************************************************/ + +int esp_touchirqattach(int channel, xcpt_t handler, void *arg) +{ + int ret = OK; + touch_sensor_disable(esp_touch_priv.sens_handle); + touch_event_callbacks_t callbacks = + { +#ifndef CONFIG_ESP_TOUCH_INVERTED + .on_active = esp_touch_callback, +#else + .on_inactive = esp_touch_callback, +#endif + }; + + esp_touch_priv.irq_handler[channel] = handler; + esp_touch_priv.irq_arg[channel] = arg; + ret = touch_sensor_register_callbacks(esp_touch_priv.sens_handle, + &callbacks, + NULL); + touch_sensor_enable(esp_touch_priv.sens_handle); + return ret; +} + +/**************************************************************************** + * Name: esp_touchirqdetach + * + * Description: + * Detach interrupt handler from specified channel. + * + * Input Parameters: + * channel - Touch pad channel number + * + * Returned Value: + * Zero (OK) is returned on success; -1 (ERROR) in failure + * + ****************************************************************************/ + +int esp_touchirqdetach(int channel) +{ + if (channel > SOC_TOUCH_MAX_CHAN_ID) + { + ierr("Invalid channel number\n"); + return ERROR; + } + + if (esp_touch_priv.irq_handler[channel] != NULL) + { + esp_touch_priv.irq_handler[channel] = NULL; + esp_touch_priv.irq_arg[channel] = NULL; + } + + return OK; +} +#endif + +/**************************************************************************** + * Name: esp_configtouch + * + * Description: + * Configures touch pad channels. + * + * Input Parameters: + * button_num - Address to return number of buttons initialized + * + * Returned Value: + * OK on success; a negated errno value on failure. + * + ****************************************************************************/ + +int esp_configtouch(int *button_num) +{ + int ret = OK; +#ifdef CONFIG_ESP_TOUCH_FILTER + touch_sensor_filter_config_t filter_cfg = + TOUCH_SENSOR_DEFAULT_FILTER_CONFIG(); + filter_cfg.benchmark.denoise_lvl = CONFIG_ESP_TOUCH_DENOISE_LVL; +#endif +#ifdef CONFIG_PM_TOUCH_WAKEUP + touch_sleep_config_t slp_cfg = TOUCH_SENSOR_DEFAULT_DSLP_CONFIG(); +#endif + + if (esp_touch_priv.sens_handle != NULL) + { + iinfo("Touch pad driver already initialized.\n"); + return ERROR; + } + + esp_touch_priv.sens_cfg = (touch_sensor_config_t) + TOUCH_SENSOR_DEFAULT_BASIC_CONFIG(TOUCH_SAMPLE_CFG_NUM, + esp_touch_priv.sample_cfg); + + ret = touch_sensor_new_controller(&esp_touch_priv.sens_cfg, + &esp_touch_priv.sens_handle); + if (ret != OK) + { + ierr("Failed to initialize touch pad controller\n"); + return ret; + } + + ret = esp_touch_channel_prepare(button_num); + if (ret != OK) + { + ierr("Failed to initialize touch pad channels\n"); + return ret; + } + +#ifdef CONFIG_ESP_TOUCH_FILTER + touch_sensor_config_filter(esp_touch_priv.sens_handle, &filter_cfg); +#else + touch_sensor_config_filter(esp_touch_priv.sens_handle, NULL); +#endif + esp_touch_calibrate(); + +#ifdef CONFIG_PM_TOUCH_WAKEUP + touch_sensor_config_sleep_wakeup(esp_touch_priv.sens_handle, &slp_cfg); +#endif + touch_sensor_enable(esp_touch_priv.sens_handle); + +#ifdef CONFIG_ESP_TOUCH_MODE_CONTINUOUS + touch_sensor_start_continuous_scanning(esp_touch_priv.sens_handle); +#else + touch_sensor_trigger_oneshot_scanning(esp_touch_priv.sens_handle, + SCAN_TIMEOUT_MS); +#endif + return ret; +} diff --git a/arch/risc-v/src/common/espressif/esp_touch.h b/arch/risc-v/src/common/espressif/esp_touch.h new file mode 100644 index 0000000000000..0daaaf5f3ee36 --- /dev/null +++ b/arch/risc-v/src/common/espressif/esp_touch.h @@ -0,0 +1,132 @@ +/**************************************************************************** + * arch/risc-v/src/common/espressif/esp_touch.h + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you 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. + * + ****************************************************************************/ + +#ifndef __ARCH_RISCV_SRC_COMMON_ESPRESSIF_ESP_TOUCH_H +#define __ARCH_RISCV_SRC_COMMON_ESPRESSIF_ESP_TOUCH_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#ifndef __ASSEMBLY__ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: esp_configtouch + * + * Description: + * Configures touch pad channels. + * + * Input Parameters: + * button_num - Address to return number of buttons initialized + * + * Returned Value: + * OK on success; a negated errno value on failure. + * + ****************************************************************************/ + +int esp_configtouch(int *button_num); + +/**************************************************************************** + * Name: esp_touchread + * + * Description: + * Read a touch pad channel. + * + * Input Parameters: + * channel - The touch pad channel. + * + * Returned Value: + * 0 if touch pad pressed, 1 if released. + * + ****************************************************************************/ + +bool esp_touchread(int channel); + +/**************************************************************************** + * Name: esp_touchirqattach + * + * Description: + * Attach an interrupt handler to specified channel. + * + * Input Parameters: + * channel - Touch pad channel number + * handler - Interrupt handler function + * arg - Argument to pass to the handler + * + * Returned Value: + * Zero (OK) is returned on success; a negated errno value is returned + * to indicate the nature of any failure. + * + ****************************************************************************/ + +#ifdef CONFIG_ESP_TOUCH_IRQ +int esp_touchirqattach(int channel, xcpt_t handler, void *arg); +#else +# define esp_touchirqattach(channel, handler, arg) (-EINVAL) +#endif + +/**************************************************************************** + * Name: esp_touchirqdetach + * + * Description: + * Detach interrupt handler from specified channel. + * + * Input Parameters: + * channel - Touch pad channel number + * + * Returned Value: + * Zero (OK) is returned on success; -1 (ERROR) in failure + * + ****************************************************************************/ + +#ifdef CONFIG_ESP_TOUCH_IRQ +int esp_touchirqdetach(int channel); +#else +# define esp_touchirqdetach(channel) (-EINVAL) +#endif + +#ifdef __cplusplus +} +#endif +#undef EXTERN + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_RISCV_SRC_COMMON_ESPRESSIF_ESP_TOUCH_H */ diff --git a/arch/risc-v/src/esp32p4/hal_esp32p4.cmake b/arch/risc-v/src/esp32p4/hal_esp32p4.cmake index 8a994cbad334a..d7918ed8ae763 100644 --- a/arch/risc-v/src/esp32p4/hal_esp32p4.cmake +++ b/arch/risc-v/src/esp32p4/hal_esp32p4.cmake @@ -50,6 +50,11 @@ set(ESP32P4_INCLUDES ${ESP_HAL_3RDPARTY_REPO}/components/esp_blockdev/include ${ESP_HAL_3RDPARTY_REPO}/components/esp_common/include ${ESP_HAL_3RDPARTY_REPO}/components/esp_event/include + ${ESP_HAL_3RDPARTY_REPO}/components/upper_hal_touch_sens + ${ESP_HAL_3RDPARTY_REPO}/components/upper_hal_touch_sens/common + ${ESP_HAL_3RDPARTY_REPO}/components/upper_hal_touch_sens/hw_ver3 + ${ESP_HAL_3RDPARTY_REPO}/components/upper_hal_touch_sens/hw_ver3/include + ${ESP_HAL_3RDPARTY_REPO}/components/upper_hal_touch_sens/include ${ESP_HAL_3RDPARTY_REPO}/components/esp_hal_ana_conv/${CHIP_SERIES}/include ${ESP_HAL_3RDPARTY_REPO}/components/esp_hal_ana_conv/include ${ESP_HAL_3RDPARTY_REPO}/components/esp_hal_cam/${CHIP_SERIES}/include @@ -252,6 +257,9 @@ list( ${ESP_HAL_3RDPARTY_REPO}/components/esp_hal_ana_conv/${CHIP_SERIES}/temperature_sensor_periph.c ${ESP_HAL_3RDPARTY_REPO}/components/esp_hal_ana_conv/adc_hal_common.c ${ESP_HAL_3RDPARTY_REPO}/components/esp_hal_ana_conv/adc_oneshot_hal.c + ${ESP_HAL_3RDPARTY_REPO}/components/upper_hal_touch_sens/common/touch_sens_common.c + ${ESP_HAL_3RDPARTY_REPO}/components/upper_hal_touch_sens/hw_ver3/touch_version_specific.c + ${ESP_HAL_3RDPARTY_REPO}/components/esp_hal_touch_sens/${CHIP_SERIES}/touch_sensor_periph.c ${ESP_HAL_3RDPARTY_REPO}/components/esp_hal_security/aes_hal.c ${ESP_HAL_3RDPARTY_REPO}/components/esp_hal_clock/${CHIP_SERIES}/clk_tree_hal.c ${ESP_HAL_3RDPARTY_REPO}/components/esp_hal_dma/${CHIP_SERIES}/gdma_periph.c diff --git a/arch/risc-v/src/esp32p4/hal_esp32p4.mk b/arch/risc-v/src/esp32p4/hal_esp32p4.mk index 39a47c3553db1..d0d9531ceba74 100644 --- a/arch/risc-v/src/esp32p4/hal_esp32p4.mk +++ b/arch/risc-v/src/esp32p4/hal_esp32p4.mk @@ -40,6 +40,11 @@ INCLUDES += $(INCDIR_PREFIX)$(ARCH_SRCDIR)$(DELIM)chip$(DELIM)$(ESP_HAL_3RDPARTY INCLUDES += $(INCDIR_PREFIX)$(ARCH_SRCDIR)$(DELIM)chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)esp_blockdev$(DELIM)include INCLUDES += $(INCDIR_PREFIX)$(ARCH_SRCDIR)$(DELIM)chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)esp_common$(DELIM)include INCLUDES += $(INCDIR_PREFIX)$(ARCH_SRCDIR)$(DELIM)chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)esp_event$(DELIM)include +INCLUDES += $(INCDIR_PREFIX)$(ARCH_SRCDIR)$(DELIM)chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)upper_hal_touch_sens +INCLUDES += $(INCDIR_PREFIX)$(ARCH_SRCDIR)$(DELIM)chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)upper_hal_touch_sens$(DELIM)common +INCLUDES += $(INCDIR_PREFIX)$(ARCH_SRCDIR)$(DELIM)chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)upper_hal_touch_sens$(DELIM)hw_ver3 +INCLUDES += $(INCDIR_PREFIX)$(ARCH_SRCDIR)$(DELIM)chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)upper_hal_touch_sens$(DELIM)hw_ver3$(DELIM)include +INCLUDES += $(INCDIR_PREFIX)$(ARCH_SRCDIR)$(DELIM)chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)upper_hal_touch_sens$(DELIM)include INCLUDES += $(INCDIR_PREFIX)$(ARCH_SRCDIR)$(DELIM)chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)esp_hal_ana_conv$(DELIM)$(CHIP_SERIES)$(DELIM)include INCLUDES += $(INCDIR_PREFIX)$(ARCH_SRCDIR)$(DELIM)chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)esp_hal_ana_conv$(DELIM)include INCLUDES += $(INCDIR_PREFIX)$(ARCH_SRCDIR)$(DELIM)chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)esp_hal_cam$(DELIM)$(CHIP_SERIES)$(DELIM)include @@ -210,6 +215,9 @@ CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)efus CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)esp_adc$(DELIM)$(CHIP_SERIES)$(DELIM)curve_fitting_coefficients.c CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)esp_adc$(DELIM)adc_cali_curve_fitting.c CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)esp_adc$(DELIM)adc_cali.c +CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)upper_hal_touch_sens$(DELIM)common$(DELIM)touch_sens_common.c +CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)upper_hal_touch_sens$(DELIM)hw_ver3$(DELIM)touch_version_specific.c +CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)esp_hal_touch_sens$(DELIM)$(CHIP_SERIES)$(DELIM)touch_sensor_periph.c CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)esp_hal_ana_conv$(DELIM)$(CHIP_SERIES)$(DELIM)adc_periph.c CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)esp_hal_ana_conv$(DELIM)$(CHIP_SERIES)$(DELIM)temperature_sensor_periph.c CHIP_CSRCS += chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)esp_hal_ana_conv$(DELIM)adc_hal_common.c diff --git a/boards/risc-v/esp32p4/esp32p4-function-ev-board/src/esp32p4_buttons.c b/boards/risc-v/esp32p4/esp32p4-function-ev-board/src/esp32p4_buttons.c index 5a8c0adde4465..2634f1de36ac0 100644 --- a/boards/risc-v/esp32p4/esp32p4-function-ev-board/src/esp32p4_buttons.c +++ b/boards/risc-v/esp32p4/esp32p4-function-ev-board/src/esp32p4_buttons.c @@ -42,16 +42,136 @@ #include #include #include +#include /* Arch */ #include "espressif/esp_gpio.h" +#ifdef CONFIG_ESPRESSIF_TOUCH +# include "espressif/esp_touch.h" +#endif /* Board */ #include "esp32p4-function-ev-board.h" #include +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +struct button_type_s +{ + bool is_touchpad; + union + { + int channel; + int gpio; + } input; +}; + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static const struct button_type_s g_buttons[] = +{ + { + .is_touchpad = false, + .input.gpio = BUTTON_BOOT + }, +#ifdef CONFIG_ESPRESSIF_TOUCH +# ifdef CONFIG_ESP_TOUCH_CHANNEL1 + { + .is_touchpad = true, + .input.channel = 1 + }, +# endif +# ifdef CONFIG_ESP_TOUCH_CHANNEL2 + { + .is_touchpad = true, + .input.channel = 2 + }, +# endif +# ifdef CONFIG_ESP_TOUCH_CHANNEL3 + { + .is_touchpad = true, + .input.channel = 3 + }, +# endif +# ifdef CONFIG_ESP_TOUCH_CHANNEL4 + { + .is_touchpad = true, + .input.channel = 4 + }, +# endif +# ifdef CONFIG_ESP_TOUCH_CHANNEL5 + { + .is_touchpad = true, + .input.channel = 5 + }, +# endif +# ifdef CONFIG_ESP_TOUCH_CHANNEL6 + { + .is_touchpad = true, + .input.channel = 6 + }, +# endif +# ifdef CONFIG_ESP_TOUCH_CHANNEL7 + { + .is_touchpad = true, + .input.channel = 7 + }, +# endif +# ifdef CONFIG_ESP_TOUCH_CHANNEL8 + { + .is_touchpad = true, + .input.channel = 8 + }, +# endif +# ifdef CONFIG_ESP_TOUCH_CHANNEL9 + { + .is_touchpad = true, + .input.channel = 9 + }, +# endif +# ifdef CONFIG_ESP_TOUCH_CHANNEL10 + { + .is_touchpad = true, + .input.channel = 10 + }, +# endif +# ifdef CONFIG_ESP_TOUCH_CHANNEL11 + { + .is_touchpad = true, + .input.channel = 11 + }, +# endif +# ifdef CONFIG_ESP_TOUCH_CHANNEL12 + { + .is_touchpad = true, + .input.channel = 12 + }, +# endif +# ifdef CONFIG_ESP_TOUCH_CHANNEL13 + { + .is_touchpad = true, + .input.channel = 13 + }, +# endif +# ifdef CONFIG_ESP_TOUCH_CHANNEL14 + { + .is_touchpad = true, + .input.channel = 14 + }, +# endif +#endif +}; + /**************************************************************************** * Public Functions ****************************************************************************/ @@ -75,8 +195,17 @@ uint32_t board_button_initialize(void) { + int button_num = 1; +#ifdef CONFIG_ESPRESSIF_TOUCH + int ret = esp_configtouch(&button_num); + if (ret == OK) + { + button_num++; + } +#endif + esp_configgpio(BUTTON_BOOT, INPUT_FUNCTION_2 | PULLUP | CHANGE); - return 1; + return button_num; } /**************************************************************************** @@ -100,39 +229,59 @@ uint32_t board_buttons(void) uint8_t ret = 0; int i = 0; int n = 0; + bool b0; + bool b1; - bool b0 = esp_gpioread(BUTTON_BOOT); - - for (i = 0; i < 10; i++) + for (uint8_t btn_id = 0; btn_id < nitems(g_buttons); btn_id++) { - up_mdelay(1); /* TODO */ + iinfo("Reading button %d\n", btn_id); + + const struct button_type_s button_info = g_buttons[btn_id]; - bool b1 = esp_gpioread(BUTTON_BOOT); + n = 0; - if (b0 == b1) +#ifdef CONFIG_ESPRESSIF_TOUCH + if (button_info.is_touchpad) { - n++; + b0 = esp_touchread(button_info.input.channel); } else +#endif { - n = 0; - } + b0 = esp_gpioread(button_info.input.gpio); - if (3 == n) - { - break; - } + for (i = 0; i < 10; i++) + { + up_mdelay(1); - b0 = b1; - } + b1 = esp_gpioread(button_info.input.gpio); - iinfo("b=%d n=%d\n", b0, n); + if (b0 == b1) + { + n++; + } + else + { + n = 0; + } - /* Low value means that the button is pressed */ + if (3 == n) + { + break; + } - if (!b0) - { - ret = 0x1; + b0 = b1; + } + } + + iinfo("b=%d n=%d\n", b0, n); + + /* Low value means that the button is pressed */ + + if (!b0) + { + ret |= (1 << btn_id); + } } return ret; @@ -164,6 +313,36 @@ uint32_t board_buttons(void) #ifdef CONFIG_ARCH_IRQBUTTONS int board_button_irq(int id, xcpt_t irqhandler, void *arg) { - return esp_gpio_irq(BUTTON_BOOT, irqhandler, arg); + DEBUGASSERT(id < nitems(g_buttons)); + + int ret = OK; + struct button_type_s button_info = g_buttons[id]; + +# ifdef CONFIG_ESP_TOUCH_IRQ + if (button_info.is_touchpad) + { + int channel = button_info.input.channel; + if (NULL != irqhandler) + { + /* Make sure the interrupt is disabled */ + + ret = esp_touchirqattach(id, irqhandler, arg); + if (ret < 0) + { + ierr("ERROR: esp_touchirqattach() failed: %d\n", + ret); + return ret; + } + + iinfo("Attach %p to touch pad %d\n", irqhandler, channel); + } + } + else +# endif + { + ret = esp_gpio_irq(button_info.input.gpio, irqhandler, arg); + } + + return ret; } #endif