firmware/src/input/RotaryEncoderInterruptBase.cpp

117 lines
4.0 KiB
C++
Raw Normal View History

2022-01-08 12:13:29 +00:00
#include "RotaryEncoderInterruptBase.h"
2022-05-07 10:31:21 +00:00
#include "configuration.h"
2022-01-08 12:13:29 +00:00
2022-05-07 10:31:21 +00:00
RotaryEncoderInterruptBase::RotaryEncoderInterruptBase(const char *name) : concurrency::OSThread(name)
2022-01-11 12:12:04 +00:00
{
2022-01-11 15:02:55 +00:00
this->_originName = name;
2022-01-11 12:12:04 +00:00
}
void RotaryEncoderInterruptBase::init(
2022-05-07 10:31:21 +00:00
uint8_t pinA, uint8_t pinB, uint8_t pinPress, char eventCw, char eventCcw, char eventPressed,
// std::function<void(void)> onIntA, std::function<void(void)> onIntB, std::function<void(void)> onIntPress) :
2022-01-11 12:12:04 +00:00
void (*onIntA)(), void (*onIntB)(), void (*onIntPress)())
2022-01-08 12:13:29 +00:00
{
this->_pinA = pinA;
this->_pinB = pinB;
this->_eventCw = eventCw;
this->_eventCcw = eventCcw;
this->_eventPressed = eventPressed;
pinMode(pinPress, INPUT_PULLUP);
pinMode(this->_pinA, INPUT_PULLUP);
pinMode(this->_pinB, INPUT_PULLUP);
2022-01-11 12:12:04 +00:00
2022-05-07 10:31:21 +00:00
// attachInterrupt(pinPress, onIntPress, RISING);
2022-01-08 12:13:29 +00:00
attachInterrupt(pinPress, onIntPress, RISING);
attachInterrupt(this->_pinA, onIntA, CHANGE);
attachInterrupt(this->_pinB, onIntB, CHANGE);
2022-01-11 12:12:04 +00:00
2022-01-08 12:13:29 +00:00
this->rotaryLevelA = digitalRead(this->_pinA);
this->rotaryLevelB = digitalRead(this->_pinB);
LOG_INFO("Rotary initialized (%d, %d, %d)\n", this->_pinA, this->_pinB, pinPress);
2022-01-08 12:13:29 +00:00
}
int32_t RotaryEncoderInterruptBase::runOnce()
{
2022-01-11 15:02:55 +00:00
InputEvent e;
e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_NONE;
2022-01-13 13:06:10 +00:00
e.source = this->_originName;
2022-01-11 15:02:55 +00:00
2022-05-07 10:31:21 +00:00
if (this->action == ROTARY_ACTION_PRESSED) {
2022-12-30 02:41:37 +00:00
LOG_DEBUG("Rotary event Press\n");
2022-01-09 09:08:31 +00:00
e.inputEvent = this->_eventPressed;
2022-05-07 10:31:21 +00:00
} else if (this->action == ROTARY_ACTION_CW) {
2022-12-30 02:41:37 +00:00
LOG_DEBUG("Rotary event CW\n");
2022-01-09 09:08:31 +00:00
e.inputEvent = this->_eventCw;
2022-05-07 10:31:21 +00:00
} else if (this->action == ROTARY_ACTION_CCW) {
2022-12-30 02:41:37 +00:00
LOG_DEBUG("Rotary event CCW\n");
2022-01-09 09:08:31 +00:00
e.inputEvent = this->_eventCcw;
2022-01-11 15:02:55 +00:00
}
if (e.inputEvent != meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_NONE) {
2022-01-09 09:08:31 +00:00
this->notifyObservers(&e);
}
2022-01-11 15:02:55 +00:00
2022-01-09 09:08:31 +00:00
this->action = ROTARY_ACTION_NONE;
return INT32_MAX;
2022-01-08 12:13:29 +00:00
}
void RotaryEncoderInterruptBase::intPressHandler()
{
2022-01-09 09:08:31 +00:00
this->action = ROTARY_ACTION_PRESSED;
2022-01-13 11:51:36 +00:00
setIntervalFromNow(20); // TODO: this modifies a non-volatile variable!
2022-01-08 12:13:29 +00:00
}
void RotaryEncoderInterruptBase::intAHandler()
{
// CW rotation (at least on most common rotary encoders)
int currentLevelA = digitalRead(this->_pinA);
2022-05-07 10:31:21 +00:00
if (this->rotaryLevelA == currentLevelA) {
2022-01-08 12:13:29 +00:00
return;
}
this->rotaryLevelA = currentLevelA;
2022-05-07 10:31:21 +00:00
this->rotaryStateCCW = intHandler(currentLevelA == HIGH, this->rotaryLevelB, ROTARY_ACTION_CCW, this->rotaryStateCCW);
2022-01-08 12:13:29 +00:00
}
void RotaryEncoderInterruptBase::intBHandler()
{
// CW rotation (at least on most common rotary encoders)
int currentLevelB = digitalRead(this->_pinB);
2022-05-07 10:31:21 +00:00
if (this->rotaryLevelB == currentLevelB) {
2022-01-08 12:13:29 +00:00
return;
}
this->rotaryLevelB = currentLevelB;
2022-05-07 10:31:21 +00:00
this->rotaryStateCW = intHandler(currentLevelB == HIGH, this->rotaryLevelA, ROTARY_ACTION_CW, this->rotaryStateCW);
2022-01-12 21:50:37 +00:00
}
/**
* @brief Rotary action implementation.
* We assume, the following pin setup:
* A --||
2022-05-07 10:31:21 +00:00
* GND --||]========
2022-01-12 21:50:37 +00:00
* B --||
2022-05-07 10:31:21 +00:00
*
2022-01-12 21:50:37 +00:00
* @return The new state for rotary pin.
*/
2022-05-07 10:31:21 +00:00
RotaryEncoderInterruptBaseStateType RotaryEncoderInterruptBase::intHandler(bool actualPinRaising, int otherPinLevel,
RotaryEncoderInterruptBaseActionType action,
RotaryEncoderInterruptBaseStateType state)
2022-01-12 21:50:37 +00:00
{
2022-05-07 10:31:21 +00:00
RotaryEncoderInterruptBaseStateType newState = state;
if (actualPinRaising && (otherPinLevel == LOW)) {
if (state == ROTARY_EVENT_CLEARED) {
2022-01-12 21:50:37 +00:00
newState = ROTARY_EVENT_OCCURRED;
2022-05-07 10:31:21 +00:00
if ((this->action != ROTARY_ACTION_PRESSED) && (this->action != action)) {
2022-01-12 21:50:37 +00:00
this->action = action;
2022-01-08 12:13:29 +00:00
}
}
2022-05-07 10:31:21 +00:00
} else if (!actualPinRaising && (otherPinLevel == HIGH)) {
2022-01-08 12:13:29 +00:00
// Logic to prevent bouncing.
2022-01-12 21:50:37 +00:00
newState = ROTARY_EVENT_CLEARED;
2022-01-08 12:13:29 +00:00
}
2022-01-13 11:51:36 +00:00
setIntervalFromNow(50); // TODO: this modifies a non-volatile variable!
2022-01-12 21:50:37 +00:00
return newState;
2022-01-08 12:13:29 +00:00
}