diff --git a/src/input/UpDownInterruptBase.cpp b/src/input/UpDownInterruptBase.cpp new file mode 100644 index 000000000..2bbff8c53 --- /dev/null +++ b/src/input/UpDownInterruptBase.cpp @@ -0,0 +1,67 @@ +#include "configuration.h" +#include "UpDownInterruptBase.h" + +UpDownInterruptBase::UpDownInterruptBase( + const char *name) : + concurrency::OSThread(name) +{ + this->_originName = name; +} + +void UpDownInterruptBase::init( + uint8_t pinDown, uint8_t pinUp, uint8_t pinPress, + char eventDown, char eventUp, char eventPressed, + void (*onIntDown)(), void (*onIntUp)(), void (*onIntPress)()) +{ + this->_pinDown = pinDown; + this->_pinUp = pinUp; + this->_eventDown = eventDown; + this->_eventUp = eventUp; + this->_eventPressed = eventPressed; + + pinMode(pinPress, INPUT_PULLUP); + pinMode(this->_pinDown, INPUT_PULLUP); + pinMode(this->_pinUp, INPUT_PULLUP); + + attachInterrupt(pinPress, onIntPress, RISING); + attachInterrupt(this->_pinDown, onIntDown, RISING); + attachInterrupt(this->_pinUp, onIntUp, RISING); + + DEBUG_MSG("GPIO initialized (%d, %d, %d)\n", + this->_pinDown, this->_pinUp, pinPress); +} + +int32_t UpDownInterruptBase::runOnce() +{ + return 30000; // TODO: technically this can be MAX_INT +} + +void UpDownInterruptBase::intPressHandler() +{ + InputEvent e; + e.source = this->_originName; + DEBUG_MSG("GPIO event Press\n"); + e.inputEvent = this->_eventPressed; + this->notifyObservers(&e); + setIntervalFromNow(20); // TODO: this modifies a non-volatile variable! +} + +void UpDownInterruptBase::intDownHandler() +{ + InputEvent e; + e.source = this->_originName; + DEBUG_MSG("GPIO event Down\n"); + e.inputEvent = this->_eventDown; + this->notifyObservers(&e); + setIntervalFromNow(20); +} + +void UpDownInterruptBase::intUpHandler() +{ + InputEvent e; + e.source = this->_originName; + DEBUG_MSG("GPIO event Up\n"); + e.inputEvent = this->_eventUp; + this->notifyObservers(&e); + setIntervalFromNow(20); +} diff --git a/src/input/UpDownInterruptBase.h b/src/input/UpDownInterruptBase.h new file mode 100644 index 000000000..dd2c9f101 --- /dev/null +++ b/src/input/UpDownInterruptBase.h @@ -0,0 +1,30 @@ +#pragma once + +#include "SinglePortModule.h" // TODO: what header file to include? +#include "InputBroker.h" + +class UpDownInterruptBase : + public Observable, + private concurrency::OSThread +{ + public: + explicit UpDownInterruptBase( + const char *name); + void init( + uint8_t pinDown, uint8_t pinUp, uint8_t pinPress, + char eventDown, char eventUp, char eventPressed, + void (*onIntDown)(), void (*onIntUp)(), void (*onIntPress)()); + void intPressHandler(); + void intDownHandler(); + void intUpHandler(); + + protected: + virtual int32_t runOnce() override; + private: + uint8_t _pinDown = 0; + uint8_t _pinUp = 0; + char _eventDown = InputEventChar_KEY_NONE; + char _eventUp = InputEventChar_KEY_NONE; + char _eventPressed = InputEventChar_KEY_NONE; + const char *_originName; +}; diff --git a/src/input/UpDownInterruptImpl1.cpp b/src/input/UpDownInterruptImpl1.cpp new file mode 100644 index 000000000..4d8916fb1 --- /dev/null +++ b/src/input/UpDownInterruptImpl1.cpp @@ -0,0 +1,52 @@ +#include "UpDownInterruptImpl1.h" +#include "InputBroker.h" + +UpDownInterruptImpl1 *upDownInterruptImpl1; + +UpDownInterruptImpl1::UpDownInterruptImpl1() : + UpDownInterruptBase( + "upDown1") +{ +} + +void UpDownInterruptImpl1::init() +{ + + if (!radioConfig.preferences.updown1_enabled) + { + // Input device is disabled. + return; + } + + uint8_t pinUp = radioConfig.preferences.inputbroker_pin_a; + uint8_t pinDown = radioConfig.preferences.inputbroker_pin_b; + uint8_t pinPress = radioConfig.preferences.inputbroker_pin_press; + + char eventDown = + static_cast(InputEventChar_KEY_DOWN); + char eventUp = + static_cast(InputEventChar_KEY_UP); + char eventPressed = + static_cast(InputEventChar_KEY_SELECT); + + UpDownInterruptBase::init( + pinDown, pinUp, pinPress, + eventDown, eventUp, eventPressed, + UpDownInterruptImpl1::handleIntDown, + UpDownInterruptImpl1::handleIntUp, + UpDownInterruptImpl1::handleIntPressed); + inputBroker->registerSource(this); +} + +void UpDownInterruptImpl1::handleIntDown() +{ + upDownInterruptImpl1->intDownHandler(); +} +void UpDownInterruptImpl1::handleIntUp() +{ + upDownInterruptImpl1->intUpHandler(); +} +void UpDownInterruptImpl1::handleIntPressed() +{ + upDownInterruptImpl1->intPressHandler(); +} diff --git a/src/input/UpDownInterruptImpl1.h b/src/input/UpDownInterruptImpl1.h new file mode 100644 index 000000000..acdb7953c --- /dev/null +++ b/src/input/UpDownInterruptImpl1.h @@ -0,0 +1,15 @@ +#pragma once +#include "UpDownInterruptBase.h" + +class UpDownInterruptImpl1 : + public UpDownInterruptBase +{ + public: + UpDownInterruptImpl1(); + void init(); + static void handleIntDown(); + static void handleIntUp(); + static void handleIntPressed(); +}; + +extern UpDownInterruptImpl1 *upDownInterruptImpl1; diff --git a/src/modules/Modules.cpp b/src/modules/Modules.cpp index fda285ed6..3c90243cb 100644 --- a/src/modules/Modules.cpp +++ b/src/modules/Modules.cpp @@ -1,6 +1,7 @@ #include "configuration.h" #include "input/InputBroker.h" #include "input/RotaryEncoderInterruptImpl1.h" +#include "input/UpDownInterruptImpl1.h" #include "modules/AdminModule.h" #include "modules/CannedMessageModule.h" #include "modules/ExternalNotificationModule.h" @@ -37,6 +38,8 @@ void setupModules() new ReplyModule(); rotaryEncoderInterruptImpl1 = new RotaryEncoderInterruptImpl1(); rotaryEncoderInterruptImpl1->init(); + upDownInterruptImpl1 = new UpDownInterruptImpl1(); + upDownInterruptImpl1->init(); cannedMessageModule = new CannedMessageModule(); #ifndef PORTDUINO new TelemetryModule();