adds VARIANT_TOUCHSCREEN and ENABLE_TOUCH_INT (#10815)

* addsVARIANT_TOUCHSCREEN and ENABLE_TOUCH_INT

* Remove a duplicated _getTouch function pointer
This commit is contained in:
Jonathan Bennett
2026-06-30 00:28:24 -05:00
committed by GitHub
co-authored by GitHub
parent 21dbe21745
commit 87bb149afb
6 changed files with 87 additions and 1 deletions
+1 -1
View File
@@ -885,7 +885,7 @@ void Screen::setup()
touchScreenImpl1->init();
}
}
#elif HAS_TOUCHSCREEN && !defined(USE_EINK) && !HAS_CST226SE
#elif HAS_TOUCHSCREEN && !defined(USE_EINK) && !VARIANT_TOUCHSCREEN
touchScreenImpl1 =
new TouchScreenImpl1(dispdev->getWidth(), dispdev->getHeight(), static_cast<TFTDisplay *>(dispdev)->getTouch);
touchScreenImpl1->init();
+6
View File
@@ -66,8 +66,14 @@ void TouchScreenBase::init(bool hasTouch)
int32_t TouchScreenBase::runOnce()
{
uint32_t nowMs = millis();
if (nowMs - _lastRun < 20) { // suppress too fast consecutive runOnce() executions
return 20;
}
_lastRun = nowMs;
TouchEvent e;
e.touchEvent = static_cast<char>(TOUCH_ACTION_NONE);
this->setInterval(TOUCH_POLL_INTERVAL_IDLE);
const bool fastTapMode = fastTapModeEnabled();
const bool allowLongPress = longPressEnabled();
+1
View File
@@ -53,6 +53,7 @@ class TouchScreenBase : public Observable<const InputEvent *>, public concurrenc
time_t _start; // for LONG_PRESS
uint32_t _lastTouchSeenMs; // helps suppress brief touch-controller dropouts
bool _tapped; // for DOUBLE_TAP
uint32_t _lastRun = 0; // helps suppress too fast consecutive runOnce() executions
const char *_originName;
};
+62
View File
@@ -2,7 +2,9 @@
#include "InputBroker.h"
#include "PowerFSM.h"
#include "configuration.h"
#include "main.h"
#include "modules/ExternalNotificationModule.h"
#include "sleep.h"
#include <cstring>
#ifdef MESHTASTIC_INCLUDE_NICHE_GRAPHICS
@@ -16,6 +18,28 @@
TouchScreenImpl1 *touchScreenImpl1;
// Hardware-interrupt wake on the touch IRQ line. Some touch boards
// either drive this pin differently (RAK14014 already owns this interrupt in TFTDisplay) or
// route it through an IO expander, which can't be used with attachInterrupt().
// use ENABLE_TOUCH_INT to indicate that we should enable the interrupt here.
#if defined(SCREEN_TOUCH_INT) && defined(ENABLE_TOUCH_INT)
// The touch controller pulls SCREEN_TOUCH_INT low when a new touch begins. Wake the polling
// thread immediately so the touch is handled without waiting for the next idle poll. The
// periodic poll in TouchScreenBase::runOnce() remains as a fallback. Mirrors the button
// interrupt handling in ButtonThread/InputBroker.
static void touchScreenInterruptHandler()
{
if (touchScreenImpl1) {
touchScreenImpl1->setIntervalFromNow(0);
runASAP = true;
BaseType_t higherWake = 0;
concurrency::mainDelay.interruptFromISR(&higherWake);
}
}
#endif
TouchScreenImpl1::TouchScreenImpl1(uint16_t width, uint16_t height, bool (*getTouch)(int16_t *, int16_t *))
: TouchScreenBase("touchscreen1", width, height), _getTouch(getTouch)
{
@@ -27,6 +51,7 @@ void TouchScreenImpl1::init()
if (portduino_config.touchscreenModule) {
TouchScreenBase::init(true);
inputBroker->registerSource(this);
attachTouchInterrupt();
} else {
TouchScreenBase::init(false);
}
@@ -37,9 +62,46 @@ void TouchScreenImpl1::init()
TouchScreenBase::init(true);
if (inputBroker)
inputBroker->registerSource(this);
attachTouchInterrupt();
#endif
#if defined(ENABLE_TOUCH_INT) && defined(ARCH_ESP32)
// Detach/reattach our interrupt around light sleep, so sleep.cpp can configure the touch
// pin as a wake source without our handler interfering.
lsObserver.observe(&notifyLightSleep);
lsEndObserver.observe(&notifyLightSleepEnd);
#endif
}
// Attach the touch-controller IRQ so a new touch wakes the polling thread immediately.
// No-op on boards without a usable touch interrupt line.
void TouchScreenImpl1::attachTouchInterrupt()
{
#ifdef ENABLE_TOUCH_INT
pinMode(SCREEN_TOUCH_INT, INPUT_PULLUP);
attachInterrupt(SCREEN_TOUCH_INT, touchScreenInterruptHandler, FALLING);
LOG_INFO("TouchScreen interrupt attached on pin %d", SCREEN_TOUCH_INT);
#endif
}
#ifdef ARCH_ESP32
// Detach our interrupt before light sleep; sleep.cpp configures its own wake-on-touch.
int TouchScreenImpl1::beforeLightSleep(void *unused)
{
#ifdef ENABLE_TOUCH_INT
detachInterrupt(SCREEN_TOUCH_INT);
#endif
return 0; // Indicates success
}
// Reattach our interrupt after waking from light sleep.
int TouchScreenImpl1::afterLightSleep(esp_sleep_wakeup_cause_t cause)
{
attachTouchInterrupt();
return 0; // Indicates success
}
#endif
bool TouchScreenImpl1::getTouch(int16_t &x, int16_t &y)
{
return _getTouch(&x, &y);
+16
View File
@@ -13,7 +13,23 @@ class TouchScreenImpl1 : public TouchScreenBase
bool fastTapModeEnabled() const override;
bool longPressEnabled() const override;
// Attach/detach a hardware interrupt on the touch IRQ pin (SCREEN_TOUCH_INT) so a new touch
// wakes the polling thread immediately. No-op on boards without a usable touch interrupt line.
void attachTouchInterrupt();
bool (*_getTouch)(int16_t *, int16_t *);
#ifdef ARCH_ESP32
// Detach the touch interrupt before light sleep (so sleep.cpp can own the wake config),
// and reattach it afterwards. Mirrors ButtonThread's interrupt handling.
int beforeLightSleep(void *unused);
int afterLightSleep(esp_sleep_wakeup_cause_t cause);
CallbackObserver<TouchScreenImpl1, void *> lsObserver =
CallbackObserver<TouchScreenImpl1, void *>(this, &TouchScreenImpl1::beforeLightSleep);
CallbackObserver<TouchScreenImpl1, esp_sleep_wakeup_cause_t> lsEndObserver =
CallbackObserver<TouchScreenImpl1, esp_sleep_wakeup_cause_t>(this, &TouchScreenImpl1::afterLightSleep);
#endif
};
extern TouchScreenImpl1 *touchScreenImpl1;
+1
View File
@@ -55,6 +55,7 @@
#define HAS_SPI_TFT 1
#define HAS_CST226SE 1
#define HAS_TOUCHSCREEN 1
#define VARIANT_TOUCHSCREEN 1
// #define TOUCH_IRQ 35 // broken in this version of the lib 0.3.1
#ifndef TOUCH_IRQ
#define TOUCH_IRQ -1