Skip to content

Commit b29198a

Browse files
lucasssvazxiaoxiang781216
authored andcommitted
arch/xtensa/esp32s3: Add support for touch pad interrupts
1 parent 9ac3e84 commit b29198a

File tree

4 files changed

+357
-25
lines changed

4 files changed

+357
-25
lines changed

arch/xtensa/src/esp32s3/esp32s3_touch.c

Lines changed: 250 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@
4646
* Pre-processor Definitions
4747
****************************************************************************/
4848

49-
#define TOUCH_GET_IO_NUM(channel) (touch_channel_to_gpio[channel])
49+
#define TOUCH_GET_IO_NUM(channel) (touch_channel_to_rtcio[channel])
5050

5151
/****************************************************************************
5252
* Private Types
@@ -69,6 +69,10 @@ struct touch_config_meas_mode_s
6969
* Private Function Prototypes
7070
****************************************************************************/
7171

72+
#ifdef CONFIG_ESP32S3_TOUCH_IRQ
73+
static int touch_interrupt(int irq, void *context, void *arg);
74+
static void touch_restore_irq(void *arg);
75+
#endif
7276
static void touch_config(enum touch_pad_e tp);
7377
static void touch_init(struct touch_config_s *config);
7478
static void touch_set_meas_mode(enum touch_pad_e tp,
@@ -84,10 +88,101 @@ static mutex_t *touch_mux = NULL;
8488
static spinlock_t lock;
8589
static uint32_t touch_pad_logic_threshold[TOUCH_SENSOR_PINS];
8690

91+
#ifdef CONFIG_ESP32S3_TOUCH_IRQ
92+
static uint16_t touch_pad_isr_enabled = 0x0000;
93+
static enum touch_intr_mask_e touch_pad_isr_types = 0x0000;
94+
static int touch_last_irq = -1;
95+
static int (*touch_release_cb)(int, void *, void *) = NULL;
96+
static struct rt_timer_args_s irq_timer_args;
97+
static struct rt_timer_s *irq_timer_handler = NULL;
98+
#endif
99+
87100
/****************************************************************************
88101
* Private Functions
89102
****************************************************************************/
90103

104+
/****************************************************************************
105+
* Name: touch_interrupt
106+
*
107+
* Description:
108+
* Touch pads interrupt handler.
109+
*
110+
* Input Parameters:
111+
* irq - Interrupt request number;
112+
* context - Context data from the ISR;
113+
* arg - Opaque pointer to the internal driver state structure.
114+
*
115+
* Returned Value:
116+
* Zero (OK) is returned on success. A negated errno value is returned on
117+
* failure.
118+
119+
*
120+
****************************************************************************/
121+
122+
#ifdef CONFIG_ESP32S3_TOUCH_IRQ
123+
static int touch_interrupt(int irq, void *context, void *arg)
124+
{
125+
uint32_t intr_mask = *((uint32_t *) context);
126+
enum touch_pad_e pad_num = touch_lh_get_current_meas_channel();
127+
touch_last_irq = ESP32S3_TOUCHPAD2IRQ(pad_num);
128+
129+
touch_lh_intr_disable(touch_pad_isr_types);
130+
131+
rt_timer_start(irq_timer_handler,
132+
CONFIG_ESP32S3_TOUCH_IRQ_INTERVAL_MS * USEC_PER_MSEC,
133+
false);
134+
135+
/* Read and clear the touch interrupt status */
136+
137+
if (intr_mask & TOUCH_INTR_MASK_TIMEOUT)
138+
{
139+
touch_lh_timer_force_done();
140+
}
141+
142+
if (intr_mask & (TOUCH_INTR_MASK_ACTIVE |
143+
TOUCH_INTR_MASK_INACTIVE))
144+
{
145+
if ((touch_pad_isr_enabled >> pad_num) & 0x1)
146+
{
147+
irq_dispatch(touch_last_irq, context);
148+
}
149+
}
150+
151+
return OK;
152+
}
153+
#endif
154+
155+
/****************************************************************************
156+
* Name: touch_restore_irq
157+
*
158+
* Description:
159+
* IRQ timer callback.
160+
* Re-enables touch IRQ after a certain time to avoid spam.
161+
*
162+
* Input Parameters:
163+
* arg - Pointer to a memory location containing the function arguments.
164+
*
165+
* Returned Value:
166+
* None.
167+
*
168+
****************************************************************************/
169+
170+
#ifdef CONFIG_ESP32S3_TOUCH_IRQ
171+
static void touch_restore_irq(void *arg)
172+
{
173+
if (touch_last_irq > 0 && touch_release_cb != NULL)
174+
{
175+
/* Call the button interrup handler again so we can detect touch pad
176+
* releases
177+
*/
178+
179+
touch_release_cb(touch_last_irq, NULL, NULL);
180+
}
181+
182+
touch_lh_intr_enable(touch_pad_isr_types);
183+
}
184+
#endif
185+
91186
/****************************************************************************
92187
* Name: touch_init
93188
*
@@ -167,6 +262,47 @@ static void touch_init(struct touch_config_s *config)
167262
touch_lh_denoise_enable();
168263
#endif
169264

265+
#ifdef CONFIG_ESP32S3_TOUCH_IRQ
266+
irq_timer_args.arg = NULL;
267+
irq_timer_args.callback = touch_restore_irq;
268+
rt_timer_create(&(irq_timer_args), &(irq_timer_handler));
269+
270+
touch_pad_isr_types = TOUCH_INTR_MASK_ACTIVE |
271+
TOUCH_INTR_MASK_INACTIVE |
272+
TOUCH_INTR_MASK_TIMEOUT;
273+
274+
int ret = 0;
275+
276+
ret |= irq_attach(ESP32S3_IRQ_RTC_TOUCH_DONE,
277+
touch_interrupt,
278+
NULL);
279+
280+
ret |= irq_attach(ESP32S3_IRQ_RTC_TOUCH_ACTIVE,
281+
touch_interrupt,
282+
NULL);
283+
284+
ret |= irq_attach(ESP32S3_IRQ_RTC_TOUCH_INACTIVE,
285+
touch_interrupt,
286+
NULL);
287+
288+
ret |= irq_attach(ESP32S3_IRQ_RTC_TOUCH_SCAN_DONE,
289+
touch_interrupt,
290+
NULL);
291+
292+
ret |= irq_attach(ESP32S3_IRQ_RTC_TOUCH_TIMEOUT,
293+
touch_interrupt,
294+
NULL);
295+
296+
ret |= irq_attach(ESP32S3_IRQ_RTC_TOUCH_APPROACH_LOOP_DONE,
297+
touch_interrupt,
298+
NULL);
299+
300+
if (ret < 0)
301+
{
302+
ierr("ERROR: irq_attach() failed.\n");
303+
}
304+
#endif
305+
170306
spin_unlock_irqrestore(&lock, flags);
171307
}
172308

@@ -300,6 +436,8 @@ static void touch_io_init(enum touch_pad_e tp)
300436

301437
int esp32s3_configtouch(enum touch_pad_e tp, struct touch_config_s config)
302438
{
439+
DEBUGASSERT(tp < TOUCH_SENSOR_PINS);
440+
303441
struct touch_config_volt_s volt_config =
304442
{
305443
.refh = config.refh,
@@ -315,10 +453,10 @@ int esp32s3_configtouch(enum touch_pad_e tp, struct touch_config_s config)
315453

316454
touch_init(&config);
317455

318-
touch_config(tp);
319456
touch_set_meas_mode(tp, &meas_config);
320457
touch_lh_set_fsm_mode(config.fsm_mode);
321458
touch_set_voltage(&volt_config);
459+
touch_config(tp);
322460
touch_lh_start_fsm();
323461

324462
return OK;
@@ -340,6 +478,31 @@ int esp32s3_configtouch(enum touch_pad_e tp, struct touch_config_s config)
340478

341479
bool esp32s3_touchread(enum touch_pad_e tp)
342480
{
481+
DEBUGASSERT(tp < TOUCH_SENSOR_PINS);
482+
483+
uint32_t value = esp32s3_touchreadraw(tp);
484+
485+
return (value > touch_pad_logic_threshold[tp]);
486+
}
487+
488+
/****************************************************************************
489+
* Name: esp32s3_touchreadraw
490+
*
491+
* Description:
492+
* Read the analog value of a touch pad channel.
493+
*
494+
* Input Parameters:
495+
* tp - The touch pad channel.
496+
*
497+
* Returned Value:
498+
* The number of charge cycles in the last measurement.
499+
*
500+
****************************************************************************/
501+
502+
uint32_t esp32s3_touchreadraw(enum touch_pad_e tp)
503+
{
504+
DEBUGASSERT(tp < TOUCH_SENSOR_PINS);
505+
343506
irqstate_t flags = spin_lock_irqsave(&lock);
344507

345508
#ifdef CONFIG_ESP32S3_TOUCH_FILTER
@@ -352,7 +515,7 @@ bool esp32s3_touchread(enum touch_pad_e tp)
352515

353516
iinfo("Touch pad %d value: %u\n", tp, value);
354517

355-
return (value > touch_pad_logic_threshold[tp]);
518+
return value;
356519
}
357520

358521
/****************************************************************************
@@ -373,11 +536,7 @@ bool esp32s3_touchread(enum touch_pad_e tp)
373536

374537
uint32_t esp32s3_touchbenchmark(enum touch_pad_e tp)
375538
{
376-
if (tp >= TOUCH_SENSOR_PINS)
377-
{
378-
ierr("Invalid touch pad!\n");
379-
return 0;
380-
}
539+
DEBUGASSERT(tp < TOUCH_SENSOR_PINS);
381540

382541
irqstate_t flags = spin_lock_irqsave(&lock);
383542

@@ -407,6 +566,8 @@ uint32_t esp32s3_touchbenchmark(enum touch_pad_e tp)
407566

408567
void esp32s3_touchsetthreshold(enum touch_pad_e tp, uint32_t threshold)
409568
{
569+
DEBUGASSERT(tp < TOUCH_SENSOR_PINS);
570+
410571
irqstate_t flags = spin_lock_irqsave(&lock);
411572

412573
touch_lh_set_threshold(tp, threshold);
@@ -416,3 +577,84 @@ void esp32s3_touchsetthreshold(enum touch_pad_e tp, uint32_t threshold)
416577

417578
iinfo("Touch pad %d threshold set to: %u\n", tp, threshold);
418579
}
580+
581+
/****************************************************************************
582+
* Name: esp32s3_touchirqenable
583+
*
584+
* Description:
585+
* Enable the interrupt for the specified touch pad.
586+
*
587+
* Input Parameters:
588+
* irq - The touch pad irq number.
589+
*
590+
* Returned Value:
591+
* None.
592+
*
593+
****************************************************************************/
594+
595+
#ifdef CONFIG_ESP32S3_TOUCH_IRQ
596+
void esp32s3_touchirqenable(int irq)
597+
{
598+
DEBUGASSERT(irq >= ESP32S3_FIRST_RTCIOIRQ_TOUCHPAD &&
599+
irq <= ESP32S3_LAST_RTCIOIRQ_TOUCHPAD);
600+
601+
int bit = ESP32S3_IRQ2TOUCHPAD(irq);
602+
603+
touch_lh_intr_disable(touch_pad_isr_types);
604+
605+
touch_pad_isr_enabled |= (UINT32_C(1) << bit);
606+
607+
touch_lh_intr_enable(touch_pad_isr_types);
608+
}
609+
#endif
610+
611+
/****************************************************************************
612+
* Name: esp32s3_touchirqdisable
613+
*
614+
* Description:
615+
* Disable the interrupt for the specified touch pad.
616+
*
617+
* Input Parameters:
618+
* irq - The touch pad irq number.
619+
*
620+
* Returned Value:
621+
* None.
622+
*
623+
****************************************************************************/
624+
625+
#ifdef CONFIG_ESP32S3_TOUCH_IRQ
626+
void esp32s3_touchirqdisable(int irq)
627+
{
628+
DEBUGASSERT(irq >= ESP32S3_FIRST_RTCIOIRQ_TOUCHPAD &&
629+
irq <= ESP32S3_LAST_RTCIOIRQ_TOUCHPAD);
630+
631+
int bit = ESP32S3_IRQ2TOUCHPAD(irq);
632+
633+
touch_lh_intr_disable(touch_pad_isr_types);
634+
635+
touch_pad_isr_enabled &= (~(UINT32_C(1) << bit));
636+
637+
touch_lh_intr_enable(touch_pad_isr_types);
638+
}
639+
#endif
640+
641+
/****************************************************************************
642+
* Name: esp32s3_touchregisterreleasecb
643+
*
644+
* Description:
645+
* Register the release callback.
646+
*
647+
* Input Parameters:
648+
* func - The handler function to be used.
649+
*
650+
* Returned Value:
651+
* None.
652+
*
653+
****************************************************************************/
654+
655+
void esp32s3_touchregisterreleasecb(int (*func)(int, void *, void *))
656+
{
657+
DEBUGASSERT(func != NULL);
658+
659+
touch_release_cb = func;
660+
}

0 commit comments

Comments
 (0)