boards/xtensa/esp32s2-kaluga-1: Add touch pad support

This commit is contained in:
Lucas Saavedra Vaz 2023-03-24 14:26:06 -03:00 committed by Alan Carvalho de Assis
parent 4309c6693c
commit 6227cd4fd4
8 changed files with 493 additions and 3 deletions

View File

@ -531,7 +531,11 @@ bool esp32s2_touchread(enum touch_pad_e tp)
leave_critical_section(flags);
#ifdef CONFIG_ESP32S2_TOUCH_THRESHOLD_POSEDGE
return (value < touch_pad_logic_threshold[tp]);
#else
return (value > touch_pad_logic_threshold[tp]);
#endif
}
/****************************************************************************

View File

@ -5,4 +5,52 @@
if ARCH_BOARD_ESP32S2_KALUGA_1
config ESP32S2_TOUCH
bool "Touch pads"
default n
---help---
Enable ESP32-S2 touch pad support.
if ESP32S2_TOUCH
config ESP32S2_TOUCH_THRESHOLD_POSEDGE
bool "Touch pad inverted threshold detection"
default y
---help---
Detect positive edge of touch pad threshold rather than negative edge.
config ESP32S2_TOUCH_FILTER
bool "Touch pad filter"
default n
---help---
Enable internal filter for the touch pads.
config ESP32S2_TOUCH_DENOISE
bool "Touch pad denoise"
default n
---help---
Enable internal denoise for the touch pads.
config ESP32S2_TOUCH_IRQ
bool "Enable touch pad interrupts"
select ESP32S2_RTCIO_IRQ
select ESP32S2_RT_TIMER
depends on ARCH_IRQBUTTONS
default n
---help---
Enable interrupt support for the touch pads.
config ESP32S2_TOUCH_IRQ_INTERVAL_MS
int "Minimum interrupt interval (ms)"
depends on ESP32S2_TOUCH_IRQ
default 100
---help---
Minimum interval between touch pad interrupts (in milliseconds).
As the RTC interrupts are triggered by level, this interrupt
will be constantly set off as long as the touch pad is pressed.
To avoid that, we disable the interrupt when it is triggered and
set a timer for it to be re-enabled.
endif # ESP32S2_TOUCH
endif # ARCH_BOARD_ESP32S2_KALUGA_1

View File

@ -0,0 +1,53 @@
#
# This file is autogenerated: PLEASE DO NOT EDIT IT.
#
# You can use "make menuconfig" to make any modifications to the installed .config file.
# You can then do "make savedefconfig" to generate a new defconfig file that includes your
# modifications.
#
# CONFIG_ARCH_LEDS is not set
# CONFIG_NSH_ARGCAT is not set
# CONFIG_NSH_CMDOPT_HEXDUMP is not set
CONFIG_ARCH="xtensa"
CONFIG_ARCH_BOARD="esp32s2-kaluga-1"
CONFIG_ARCH_BOARD_COMMON=y
CONFIG_ARCH_BOARD_ESP32S2_KALUGA_1=y
CONFIG_ARCH_BUTTONS=y
CONFIG_ARCH_CHIP="esp32s2"
CONFIG_ARCH_CHIP_ESP32S2=y
CONFIG_ARCH_CHIP_ESP32S2WROVER=y
CONFIG_ARCH_IRQBUTTONS=y
CONFIG_ARCH_STACKDUMP=y
CONFIG_ARCH_XTENSA=y
CONFIG_BOARD_LOOPSPERMSEC=16717
CONFIG_BUILTIN=y
CONFIG_ESP32S2_GPIO_IRQ=y
CONFIG_ESP32S2_TOUCH=y
CONFIG_ESP32S2_TOUCH_IRQ=y
CONFIG_ESP32S2_UART0=y
CONFIG_EXAMPLES_BUTTONS=y
CONFIG_FS_PROCFS=y
CONFIG_HAVE_CXX=y
CONFIG_HAVE_CXXINITIALIZE=y
CONFIG_IDLETHREAD_STACKSIZE=3072
CONFIG_INIT_ENTRYPOINT="nsh_main"
CONFIG_INPUT=y
CONFIG_INPUT_BUTTONS=y
CONFIG_INPUT_BUTTONS_LOWER=y
CONFIG_INTELHEX_BINARY=y
CONFIG_NSH_ARCHINIT=y
CONFIG_NSH_BUILTIN_APPS=y
CONFIG_NSH_FILEIOSIZE=512
CONFIG_NSH_LINELEN=64
CONFIG_NSH_READLINE=y
CONFIG_PREALLOC_TIMERS=4
CONFIG_RAM_SIZE=114688
CONFIG_RAM_START=0x20000000
CONFIG_RR_INTERVAL=200
CONFIG_SCHED_WAITPID=y
CONFIG_SPI=y
CONFIG_START_DAY=6
CONFIG_START_MONTH=12
CONFIG_START_YEAR=2011
CONFIG_SYSTEM_NSH=y
CONFIG_UART0_SERIAL_CONSOLE=y

View File

@ -43,6 +43,29 @@
# define BOARD_CLOCK_FREQUENCY 80000000
#endif
/* Button definitions *******************************************************/
#define BUTTON_BTN1 0 /* BUTTON_BOOT */
#define BUTTON_BTN1_BIT (1 << BUTTON_BTN1)
#ifdef CONFIG_ESP32S2_TOUCH
# define BUTTON_BTN2 1 /* TOUCHPAD_PHOTO */
# define BUTTON_BTN2_BIT (1 << BUTTON_BTN2)
# define BUTTON_BTN3 2 /* TOUCHPAD_PLAY */
# define BUTTON_BTN3_BIT (1 << BUTTON_BTN3)
# define BUTTON_BTN4 3 /* TOUCHPAD_RECORD */
# define BUTTON_BTN4_BIT (1 << BUTTON_BTN4)
# define BUTTON_BTN5 4 /* TOUCHPAD_NETWORK */
# define BUTTON_BTN5_BIT (1 << BUTTON_BTN5)
# define BUTTON_BTN6 5 /* TOUCHPAD_VOLUP */
# define BUTTON_BTN6_BIT (1 << BUTTON_BTN6)
# define BUTTON_BTN7 6 /* TOUCHPAD_VOLDN */
# define BUTTON_BTN7_BIT (1 << BUTTON_BTN7)
# define NUM_BUTTONS 7
#else
# define NUM_BUTTONS 1
#endif
/* LED definitions **********************************************************/
/* Define how many LEDs this board has (needed by userleds) */

View File

@ -45,6 +45,10 @@ ifeq ($(CONFIG_ESP32S2_SPI),y)
CSRCS += esp32s2_board_spi.c
endif
ifeq ($(CONFIG_ARCH_BUTTONS),y)
CSRCS += esp32s2_buttons.c
endif
DEPPATH += --dep-path board
VPATH += :board
CFLAGS += $(shell $(INCDIR) "$(CC)" $(TOPDIR)$(DELIM)arch$(DELIM)$(CONFIG_ARCH)$(DELIM)src$(DELIM)board$(DELIM)board)

View File

@ -33,11 +33,17 @@
* Pre-processor Definitions
****************************************************************************/
/* ESP32S2-DevKitC GPIOs ****************************************************/
/* ESP32S2-Kaluga-1 GPIOs ***************************************************/
/* BOOT Button */
/* Buttons */
#define BUTTON_BOOT 0
#define BUTTON_BOOT 0
#define TP_PHOTO_CHANNEL 6
#define TP_PLAY_CHANNEL 2
#define TP_RECORD_CHANNEL 5
#define TP_NETWORK_CHANNEL 11
#define TP_VOLUP_CHANNEL 1
#define TP_VOLDN_CHANNEL 3
/* TIMERS */

View File

@ -206,6 +206,16 @@ int esp32s2_bringup(void)
}
#endif
#ifdef CONFIG_INPUT_BUTTONS
/* Register the BUTTON driver */
ret = btn_lower_initialize("/dev/buttons");
if (ret < 0)
{
syslog(LOG_ERR, "ERROR: btn_lower_initialize() failed: %d\n", ret);
}
#endif
/* If we got here then perhaps not all initialization was successful, but
* at least enough succeeded to bring-up NSH with perhaps reduced
* capabilities.

View File

@ -0,0 +1,342 @@
/****************************************************************************
* boards/xtensa/esp32s2/esp32s2-kaluga-1/src/esp32s2_buttons.c
*
* 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 <nuttx/config.h>
#include <assert.h>
#include <debug.h>
#include <errno.h>
#include <stdbool.h>
#include <stdio.h>
#include <nuttx/arch.h>
#include <arch/board/board.h>
#include <nuttx/board.h>
#include <nuttx/irq.h>
#include <nuttx/signal.h>
#include <arch/irq.h>
#include "esp32s2_gpio.h"
#include "esp32s2_rtc_gpio.h"
#include "esp32s2_touch.h"
#include "esp32s2-kaluga-1.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
#ifndef ARRAY_SIZE
# define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
#endif
#define TOUCHPAD_REFH (TOUCH_HVOLT_2V7)
#define TOUCHPAD_REFL (TOUCH_LVOLT_0V5)
#define TOUCHPAD_ATTEN (TOUCH_HVOLT_ATTEN_1V)
#define TOUCHPAD_SLOPE (TOUCH_SLOPE_7)
#define TOUCHPAD_TIE_OPT (TOUCH_TIE_OPT_LOW)
#define TOUCHPAD_FSM_MODE (TOUCH_FSM_MODE_TIMER)
#define TOUCHPAD_DENOISE_GRADE (TOUCH_DENOISE_BIT4)
#define TOUCHPAD_DENOISE_CAP (TOUCH_DENOISE_CAP_L4)
#define TOUCHPAD_FILTER_MODE (TOUCH_FILTER_IIR_16)
#define TOUCHPAD_FILTER_DEBOUNCE (1)
#define TOUCHPAD_FILTER_NOISE (0)
#define TOUCHPAD_FILTER_JITTER (4)
#define TOUCHPAD_FILTER_SMH (TOUCH_SMOOTH_IIR_2)
#define TOUCHPAD_THRESHOLD (30000)
/****************************************************************************
* Private Types
****************************************************************************/
struct button_type_s
{
bool is_touchpad;
union
{
int channel;
int gpio;
} input;
};
/****************************************************************************
* Private Data
****************************************************************************/
#ifdef CONFIG_ESP32S2_TOUCH
static const struct touch_config_s tp_config =
{
.refh = TOUCHPAD_REFH,
.refl = TOUCHPAD_REFL,
.atten = TOUCHPAD_ATTEN,
.slope = TOUCHPAD_SLOPE,
.tie_opt = TOUCHPAD_TIE_OPT,
.fsm_mode = TOUCHPAD_FSM_MODE,
# ifdef CONFIG_ESP32S2_TOUCH_FILTER
.filter_mode = TOUCHPAD_FILTER_MODE,
.filter_debounce_cnt = TOUCHPAD_FILTER_DEBOUNCE,
.filter_noise_thr = TOUCHPAD_FILTER_NOISE,
.filter_jitter_step = TOUCHPAD_FILTER_JITTER,
.filter_smh_lvl = TOUCHPAD_FILTER_SMH,
# endif
# ifdef CONFIG_ESP32S2_TOUCH_DENOISE
.denoise_grade = TOUCHPAD_DENOISE_GRADE,
.denoise_cap_level = TOUCHPAD_DENOISE_CAP
# endif
};
#endif
static const struct button_type_s g_buttons[] =
{
{
.is_touchpad = false,
.input.gpio = BUTTON_BOOT
},
#ifdef CONFIG_ESP32S2_TOUCH
{
.is_touchpad = true,
.input.channel = TP_PHOTO_CHANNEL
},
{
.is_touchpad = true,
.input.channel = TP_PLAY_CHANNEL
},
{
.is_touchpad = true,
.input.channel = TP_RECORD_CHANNEL
},
{
.is_touchpad = true,
.input.channel = TP_NETWORK_CHANNEL
},
{
.is_touchpad = true,
.input.channel = TP_VOLUP_CHANNEL
},
{
.is_touchpad = true,
.input.channel = TP_VOLDN_CHANNEL
}
#endif
};
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: board_button_initialize
*
* Description:
* board_button_initialize() must be called to initialize button resources.
* After that, board_buttons() may be called to collect the current state
* of all buttons or board_button_irq() may be called to register button
* interrupt handlers.
*
****************************************************************************/
uint32_t board_button_initialize(void)
{
#ifdef CONFIG_ESP32S2_TOUCH
esp32s2_configtouch(TP_PHOTO_CHANNEL, tp_config);
esp32s2_configtouch(TP_PLAY_CHANNEL, tp_config);
esp32s2_configtouch(TP_RECORD_CHANNEL, tp_config);
esp32s2_configtouch(TP_NETWORK_CHANNEL, tp_config);
esp32s2_configtouch(TP_VOLUP_CHANNEL, tp_config);
esp32s2_configtouch(TP_VOLDN_CHANNEL, tp_config);
esp32s2_touchsetthreshold(TP_PHOTO_CHANNEL, TOUCHPAD_THRESHOLD);
esp32s2_touchsetthreshold(TP_PLAY_CHANNEL, TOUCHPAD_THRESHOLD);
esp32s2_touchsetthreshold(TP_RECORD_CHANNEL, TOUCHPAD_THRESHOLD);
esp32s2_touchsetthreshold(TP_NETWORK_CHANNEL, TOUCHPAD_THRESHOLD);
esp32s2_touchsetthreshold(TP_VOLUP_CHANNEL, TOUCHPAD_THRESHOLD);
esp32s2_touchsetthreshold(TP_VOLDN_CHANNEL, TOUCHPAD_THRESHOLD);
#endif
esp32s2_configgpio(BUTTON_BOOT, INPUT_FUNCTION_3 | PULLUP);
return NUM_BUTTONS;
}
/****************************************************************************
* Name: board_buttons
*
* Description:
* After board_button_initialize() has been called, board_buttons() may be
* called to collect the state of all buttons. board_buttons() returns an
* 8-bit bit set with each bit associated with a button. See the
* BUTTON_*_BIT definitions in board.h for the meaning of each bit.
*
****************************************************************************/
uint32_t board_buttons(void)
{
uint8_t ret = 0;
bool b0;
bool b1;
int n;
for (uint8_t btn_id = 0; btn_id < ARRAY_SIZE(g_buttons); btn_id++)
{
iinfo("Reading button %d\n", btn_id);
const struct button_type_s button_info = g_buttons[btn_id];
n = 0;
if (button_info.is_touchpad)
{
b0 = esp32s2_touchread(button_info.input.channel);
}
else
{
b0 = esp32s2_gpioread(button_info.input.gpio);
for (int i = 0; i < 10; i++)
{
up_mdelay(1);
b1 = esp32s2_gpioread(button_info.input.gpio);
if (b0 == b1)
{
n++;
}
else
{
n = 0;
}
if (3 == n)
{
break;
}
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;
}
/****************************************************************************
* Name: board_button_irq
*
* Description:
* board_button_irq() may be called to register an interrupt handler that
* will be called when a button is depressed or released. The ID value is
* a button enumeration value that uniquely identifies a button resource.
* See the BUTTON_* definitions in board.h for the meaning of enumeration
* value.
*
****************************************************************************/
#ifdef CONFIG_ARCH_IRQBUTTONS
int board_button_irq(int id, xcpt_t irqhandler, void *arg)
{
DEBUGASSERT(id < ARRAY_SIZE(g_buttons));
int ret;
struct button_type_s button_info = g_buttons[id];
#ifdef CONFIG_ESP32S2_TOUCH_IRQ
if (button_info.is_touchpad)
{
int channel = button_info.input.channel;
int irq = ESP32S2_TOUCHPAD2IRQ(channel);
if (NULL != irqhandler)
{
/* Make sure the interrupt is disabled */
esp32s2_touchirqdisable(irq);
esp32s2_touchregisterreleasecb(irqhandler);
ret = irq_attach(irq, irqhandler, arg);
if (ret < 0)
{
syslog(LOG_ERR, "ERROR: irq_attach() failed: %d\n", ret);
return ret;
}
iinfo("Attach %p to touch pad %d\n", irqhandler, channel);
iinfo("Enabling the interrupt\n");
esp32s2_touchirqenable(irq);
}
else
{
iinfo("Disabled interrupts from touch pad %d\n", channel);
esp32s2_touchirqdisable(irq);
}
return OK;
}
else
#endif
{
int pin = button_info.input.gpio;
int irq = ESP32S2_PIN2IRQ(pin);
if (NULL != irqhandler)
{
/* Make sure the interrupt is disabled */
esp32s2_gpioirqdisable(irq);
ret = irq_attach(irq, irqhandler, arg);
if (ret < 0)
{
syslog(LOG_ERR, "ERROR: irq_attach() failed: %d\n", ret);
return ret;
}
gpioinfo("Attach %p to pin %d\n", irqhandler, pin);
gpioinfo("Enabling the interrupt\n");
/* Configure the interrupt for rising and falling edges */
esp32s2_gpioirqenable(irq, GPIO_INTR_ANYEDGE);
}
else
{
gpioinfo("Disabled interrupts from pin %d\n", pin);
esp32s2_gpioirqdisable(irq);
}
return OK;
}
}
#endif