Trackball revamp (#9440)

* Trackball revamp

* Use Throttle

* Volatile!
This commit is contained in:
Jonathan Bennett
2026-01-26 14:28:05 -06:00
committed by GitHub
parent c038cfe69a
commit 3d58c6e916
4 changed files with 91 additions and 41 deletions

View File

@@ -1,5 +1,7 @@
#include "TrackballInterruptBase.h"
#include "Throttle.h"
#include "configuration.h"
extern bool osk_found;
TrackballInterruptBase::TrackballInterruptBase(const char *name) : concurrency::OSThread(name), _originName(name) {}
@@ -55,6 +57,20 @@ int32_t TrackballInterruptBase::runOnce()
{
InputEvent e = {};
e.inputEvent = INPUT_BROKER_NONE;
#if TB_THRESHOLD
if (lastInterruptTime && !Throttle::isWithinTimespanMs(lastInterruptTime, 1000)) {
left_counter = 0;
right_counter = 0;
up_counter = 0;
down_counter = 0;
lastInterruptTime = 0;
}
#ifdef INPUT_DEBUG
if (left_counter > 0 || right_counter > 0 || up_counter > 0 || down_counter > 0) {
LOG_DEBUG("L %u R %u U %u D %u, time %u", left_counter, right_counter, up_counter, down_counter, millis());
}
#endif
#endif
// Handle long press detection for press button
if (pressDetected && pressStartTime > 0) {
@@ -130,23 +146,31 @@ int32_t TrackballInterruptBase::runOnce()
}
}
#if defined(T_DECK) // T-deck gets a super-simple debounce on trackball
#if TB_THRESHOLD
if (this->action == TB_ACTION_PRESSED && (!pressDetected || pressStartTime == 0)) {
// Start long press detection
pressDetected = true;
pressStartTime = millis();
// Don't send event yet, wait to see if it's a long press
} else if (this->action == TB_ACTION_UP && lastEvent == TB_ACTION_UP) {
// LOG_DEBUG("Trackball event UP");
} else if (up_counter >= TB_THRESHOLD) {
#ifdef INPUT_DEBUG
LOG_DEBUG("Trackball event UP %u", millis());
#endif
e.inputEvent = this->_eventUp;
} else if (this->action == TB_ACTION_DOWN && lastEvent == TB_ACTION_DOWN) {
// LOG_DEBUG("Trackball event DOWN");
} else if (down_counter >= TB_THRESHOLD) {
#ifdef INPUT_DEBUG
LOG_DEBUG("Trackball event DOWN %u", millis());
#endif
e.inputEvent = this->_eventDown;
} else if (this->action == TB_ACTION_LEFT && lastEvent == TB_ACTION_LEFT) {
// LOG_DEBUG("Trackball event LEFT");
} else if (left_counter >= TB_THRESHOLD) {
#ifdef INPUT_DEBUG
LOG_DEBUG("Trackball event LEFT %u", millis());
#endif
e.inputEvent = this->_eventLeft;
} else if (this->action == TB_ACTION_RIGHT && lastEvent == TB_ACTION_RIGHT) {
// LOG_DEBUG("Trackball event RIGHT");
} else if (right_counter >= TB_THRESHOLD) {
#ifdef INPUT_DEBUG
LOG_DEBUG("Trackball event RIGHT %u", millis());
#endif
e.inputEvent = this->_eventRight;
}
#else
@@ -179,6 +203,12 @@ int32_t TrackballInterruptBase::runOnce()
e.source = this->_originName;
e.kbchar = 0x00;
this->notifyObservers(&e);
#if TB_THRESHOLD
left_counter = 0;
right_counter = 0;
up_counter = 0;
down_counter = 0;
#endif
}
// Only update lastEvent for non-press actions or completed press actions
@@ -194,25 +224,49 @@ int32_t TrackballInterruptBase::runOnce()
void TrackballInterruptBase::intPressHandler()
{
this->action = TB_ACTION_PRESSED;
if (!Throttle::isWithinTimespanMs(lastInterruptTime, 10))
this->action = TB_ACTION_PRESSED;
lastInterruptTime = millis();
}
void TrackballInterruptBase::intDownHandler()
{
this->action = TB_ACTION_DOWN;
if (TB_THRESHOLD || !Throttle::isWithinTimespanMs(lastInterruptTime, 10))
this->action = TB_ACTION_DOWN;
lastInterruptTime = millis();
#if TB_THRESHOLD
down_counter++;
#endif
}
void TrackballInterruptBase::intUpHandler()
{
this->action = TB_ACTION_UP;
if (TB_THRESHOLD || !Throttle::isWithinTimespanMs(lastInterruptTime, 10))
this->action = TB_ACTION_UP;
lastInterruptTime = millis();
#if TB_THRESHOLD
up_counter++;
#endif
}
void TrackballInterruptBase::intLeftHandler()
{
this->action = TB_ACTION_LEFT;
if (TB_THRESHOLD || !Throttle::isWithinTimespanMs(lastInterruptTime, 10))
this->action = TB_ACTION_LEFT;
lastInterruptTime = millis();
#if TB_THRESHOLD
left_counter++;
#endif
}
void TrackballInterruptBase::intRightHandler()
{
this->action = TB_ACTION_RIGHT;
if (TB_THRESHOLD || !Throttle::isWithinTimespanMs(lastInterruptTime, 10))
this->action = TB_ACTION_RIGHT;
lastInterruptTime = millis();
#if TB_THRESHOLD
right_counter++;
#endif
}

View File

@@ -12,6 +12,10 @@
#endif
#endif
#ifndef TB_THRESHOLD
#define TB_THRESHOLD 0
#endif
class TrackballInterruptBase : public Observable<const InputEvent *>, public concurrency::OSThread
{
public:
@@ -25,8 +29,6 @@ class TrackballInterruptBase : public Observable<const InputEvent *>, public con
void intUpHandler();
void intLeftHandler();
void intRightHandler();
uint32_t lastTime = 0;
virtual int32_t runOnce() override;
protected:
@@ -67,4 +69,12 @@ class TrackballInterruptBase : public Observable<const InputEvent *>, public con
input_broker_event _eventPressedLong = INPUT_BROKER_NONE;
const char *_originName;
TrackballInterruptBaseActionType lastEvent = TB_ACTION_NONE;
volatile uint32_t lastInterruptTime = 0;
#if TB_THRESHOLD
volatile uint8_t left_counter = 0;
volatile uint8_t right_counter = 0;
volatile uint8_t up_counter = 0;
volatile uint8_t down_counter = 0;
#endif
};

View File

@@ -24,41 +24,26 @@ void TrackballInterruptImpl1::init(uint8_t pinDown, uint8_t pinUp, uint8_t pinLe
void TrackballInterruptImpl1::handleIntDown()
{
if (TB_DIRECTION == RISING || millis() > trackballInterruptImpl1->lastTime + 10) {
trackballInterruptImpl1->lastTime = millis();
trackballInterruptImpl1->intDownHandler();
trackballInterruptImpl1->setIntervalFromNow(20);
}
trackballInterruptImpl1->intDownHandler();
trackballInterruptImpl1->setIntervalFromNow(20);
}
void TrackballInterruptImpl1::handleIntUp()
{
if (TB_DIRECTION == RISING || millis() > trackballInterruptImpl1->lastTime + 10) {
trackballInterruptImpl1->lastTime = millis();
trackballInterruptImpl1->intUpHandler();
trackballInterruptImpl1->setIntervalFromNow(20);
}
trackballInterruptImpl1->intUpHandler();
trackballInterruptImpl1->setIntervalFromNow(20);
}
void TrackballInterruptImpl1::handleIntLeft()
{
if (TB_DIRECTION == RISING || millis() > trackballInterruptImpl1->lastTime + 10) {
trackballInterruptImpl1->lastTime = millis();
trackballInterruptImpl1->intLeftHandler();
trackballInterruptImpl1->setIntervalFromNow(20);
}
trackballInterruptImpl1->intLeftHandler();
trackballInterruptImpl1->setIntervalFromNow(20);
}
void TrackballInterruptImpl1::handleIntRight()
{
if (TB_DIRECTION == RISING || millis() > trackballInterruptImpl1->lastTime + 10) {
trackballInterruptImpl1->lastTime = millis();
trackballInterruptImpl1->intRightHandler();
trackballInterruptImpl1->setIntervalFromNow(20);
}
trackballInterruptImpl1->intRightHandler();
trackballInterruptImpl1->setIntervalFromNow(20);
}
void TrackballInterruptImpl1::handleIntPressed()
{
if (TB_DIRECTION == RISING || millis() > trackballInterruptImpl1->lastTime + 10) {
trackballInterruptImpl1->lastTime = millis();
trackballInterruptImpl1->intPressHandler();
trackballInterruptImpl1->setIntervalFromNow(20);
}
trackballInterruptImpl1->intPressHandler();
trackballInterruptImpl1->setIntervalFromNow(20);
}

View File

@@ -71,6 +71,7 @@
#define TB_RIGHT 2
#define TB_PRESS 0 // BUTTON_PIN
#define TB_DIRECTION FALLING
#define TB_THRESHOLD 3
// microphone
#define ES7210_SCK 47