T-Lora Pager: Use InputPollable for RotaryEncoderImpl

This commit is contained in:
WillyJL
2025-09-19 22:05:18 +02:00
parent 0e26702c46
commit 54f9f7a591
2 changed files with 16 additions and 45 deletions

View File

@@ -6,11 +6,9 @@
#define ORIGIN_NAME "RotaryEncoder" #define ORIGIN_NAME "RotaryEncoder"
#define ROTARY_INTERRUPT_FLAG _BV(0)
RotaryEncoderImpl *rotaryEncoderImpl; RotaryEncoderImpl *rotaryEncoderImpl;
RotaryEncoderImpl::RotaryEncoderImpl() : concurrency::OSThread(ORIGIN_NAME), originName(ORIGIN_NAME) RotaryEncoderImpl::RotaryEncoderImpl()
{ {
rotary = nullptr; rotary = nullptr;
} }
@@ -20,7 +18,6 @@ bool RotaryEncoderImpl::init()
if (!moduleConfig.canned_message.updown1_enabled || moduleConfig.canned_message.inputbroker_pin_a == 0 || if (!moduleConfig.canned_message.updown1_enabled || moduleConfig.canned_message.inputbroker_pin_a == 0 ||
moduleConfig.canned_message.inputbroker_pin_b == 0) { moduleConfig.canned_message.inputbroker_pin_b == 0) {
// Input device is disabled. // Input device is disabled.
disable();
return false; return false;
} }
@@ -32,16 +29,11 @@ bool RotaryEncoderImpl::init()
moduleConfig.canned_message.inputbroker_pin_press); moduleConfig.canned_message.inputbroker_pin_press);
rotary->resetButton(); rotary->resetButton();
inputQueue = xQueueCreate(5, sizeof(input_broker_event));
interruptFlag = xEventGroupCreate();
interruptInstance = this; interruptInstance = this;
auto interruptHandler = []() { xEventGroupSetBits(interruptInstance->interruptFlag, ROTARY_INTERRUPT_FLAG); }; auto interruptHandler = []() { inputBroker->pollSoonRequestFromIsr(interruptInstance); };
attachInterrupt(moduleConfig.canned_message.inputbroker_pin_a, interruptHandler, CHANGE); attachInterrupt(moduleConfig.canned_message.inputbroker_pin_a, interruptHandler, CHANGE);
attachInterrupt(moduleConfig.canned_message.inputbroker_pin_b, interruptHandler, CHANGE); attachInterrupt(moduleConfig.canned_message.inputbroker_pin_b, interruptHandler, CHANGE);
attachInterrupt(moduleConfig.canned_message.inputbroker_pin_press, interruptHandler, CHANGE); attachInterrupt(moduleConfig.canned_message.inputbroker_pin_press, interruptHandler, CHANGE);
xTaskCreate(inputWorker, "rotary", 2 * 1024, this, 10, &inputWorkerTask);
inputBroker->registerSource(this);
LOG_INFO("RotaryEncoder initialized pins(%d, %d, %d), events(%d, %d, %d)", moduleConfig.canned_message.inputbroker_pin_a, LOG_INFO("RotaryEncoder initialized pins(%d, %d, %d), events(%d, %d, %d)", moduleConfig.canned_message.inputbroker_pin_a,
moduleConfig.canned_message.inputbroker_pin_b, moduleConfig.canned_message.inputbroker_pin_press, eventCw, eventCcw, moduleConfig.canned_message.inputbroker_pin_b, moduleConfig.canned_message.inputbroker_pin_press, eventCw, eventCcw,
@@ -49,50 +41,36 @@ bool RotaryEncoderImpl::init()
return true; return true;
} }
void RotaryEncoderImpl::dispatchInputs() void RotaryEncoderImpl::pollOnce()
{ {
InputEvent e{ORIGIN_NAME, INPUT_BROKER_NONE, 0, 0, 0};
static uint32_t lastPressed = millis(); static uint32_t lastPressed = millis();
if (rotary->readButton() == RotaryEncoder::ButtonState::BUTTON_PRESSED) { if (rotary->readButton() == RotaryEncoder::ButtonState::BUTTON_PRESSED) {
if (lastPressed + 200 < millis()) { if (lastPressed + 200 < millis()) {
// LOG_DEBUG("Rotary event Press"); LOG_DEBUG("Rotary event Press");
lastPressed = millis(); lastPressed = millis();
xQueueSend(inputQueue, &this->eventPressed, portMAX_DELAY); e.inputEvent = this->eventPressed;
inputBroker->queueInputEvent(&e);
} }
} }
switch (rotary->process()) { switch (rotary->process()) {
case RotaryEncoder::DIRECTION_CW: case RotaryEncoder::DIRECTION_CW:
// LOG_DEBUG("Rotary event CW"); LOG_DEBUG("Rotary event CW");
xQueueSend(inputQueue, &this->eventCw, portMAX_DELAY); e.inputEvent = this->eventCw;
inputBroker->queueInputEvent(&e);
break; break;
case RotaryEncoder::DIRECTION_CCW: case RotaryEncoder::DIRECTION_CCW:
// LOG_DEBUG("Rotary event CCW"); LOG_DEBUG("Rotary event CCW");
xQueueSend(inputQueue, &this->eventCcw, portMAX_DELAY); e.inputEvent = this->eventCcw;
inputBroker->queueInputEvent(&e);
break; break;
default: default:
break; break;
} }
} }
void RotaryEncoderImpl::inputWorker(void *p)
{
RotaryEncoderImpl *instance = (RotaryEncoderImpl *)p;
while (true) {
xEventGroupWaitBits(instance->interruptFlag, ROTARY_INTERRUPT_FLAG, pdTRUE, pdTRUE, portMAX_DELAY);
instance->dispatchInputs();
}
vTaskDelete(NULL);
}
RotaryEncoderImpl *RotaryEncoderImpl::interruptInstance; RotaryEncoderImpl *RotaryEncoderImpl::interruptInstance;
int32_t RotaryEncoderImpl::runOnce()
{
InputEvent e{originName, INPUT_BROKER_NONE, 0, 0, 0};
while (xQueueReceive(inputQueue, &e.inputEvent, 0) == pdPASS) {
this->notifyObservers(&e);
}
return 10;
}
#endif #endif

View File

@@ -10,20 +10,14 @@
class RotaryEncoder; class RotaryEncoder;
class RotaryEncoderImpl : public Observable<const InputEvent *>, public concurrency::OSThread class RotaryEncoderImpl : public InputPollable
{ {
public: public:
RotaryEncoderImpl(); RotaryEncoderImpl();
bool init(void); bool init(void);
virtual void pollOnce() override;
protected: protected:
virtual int32_t runOnce() override;
QueueHandle_t inputQueue;
void dispatchInputs(void);
TaskHandle_t inputWorkerTask;
static void inputWorker(void *p);
EventGroupHandle_t interruptFlag;
static RotaryEncoderImpl *interruptInstance; static RotaryEncoderImpl *interruptInstance;
input_broker_event eventCw = INPUT_BROKER_NONE; input_broker_event eventCw = INPUT_BROKER_NONE;
@@ -31,7 +25,6 @@ class RotaryEncoderImpl : public Observable<const InputEvent *>, public concurre
input_broker_event eventPressed = INPUT_BROKER_NONE; input_broker_event eventPressed = INPUT_BROKER_NONE;
RotaryEncoder *rotary; RotaryEncoder *rotary;
const char *originName;
}; };
extern RotaryEncoderImpl *rotaryEncoderImpl; extern RotaryEncoderImpl *rotaryEncoderImpl;