From 2ad0aca3a5fbc8ce4ee2970da2e004ea874489be Mon Sep 17 00:00:00 2001 From: GioCC <25667790+GioCC@users.noreply.github.com> Date: Sat, 8 Oct 2022 14:18:05 +0200 Subject: [PATCH] Use same retrigger logic for Multiplexer and InputShifter (#203) --- src/MF_DigInMux/MFDigInMux.cpp | 12 +- src/MF_DigInMux/MFDigInMux.h | 3 + src/MF_InputShifter/MFInputShifter.cpp | 145 +++++++++++-------------- src/MF_InputShifter/MFInputShifter.h | 20 ++-- 4 files changed, 88 insertions(+), 92 deletions(-) diff --git a/src/MF_DigInMux/MFDigInMux.cpp b/src/MF_DigInMux/MFDigInMux.cpp index beebbc15..2c6643dd 100644 --- a/src/MF_DigInMux/MFDigInMux.cpp +++ b/src/MF_DigInMux/MFDigInMux.cpp @@ -45,6 +45,10 @@ void MFDigInMux::attach(uint8_t dataPin, bool halfSize, char const *name) if (halfSize) bitSet(_flags, MUX_HALFSIZE); pinMode(_dataPin, INPUT_PULLUP); bitSet(_flags, MUX_INITED); + + // Initialize all inputs with current status + poll(DONT_TRIGGER, bitRead(_flags, MUX_LAZY)); + } void MFDigInMux::detach() @@ -60,11 +64,11 @@ void MFDigInMux::detach() // changed from the previously read state. void MFDigInMux::update() { - poll(true, bitRead(_flags, MUX_LAZY)); + poll(DO_TRIGGER, bitRead(_flags, MUX_LAZY)); } // Helper function for update() and retrigger() -void MFDigInMux::poll(bool detect, bool isLazy) +void MFDigInMux::poll(bool doTrigger, bool isLazy) { if (!_MUX) return; @@ -120,7 +124,7 @@ void MFDigInMux::poll(bool detect, bool isLazy) _MUX->restoreChannel(); // tidy up if (_lastState != currentState) { - if (detect) detectChanges(_lastState, currentState); + if (doTrigger) detectChanges(_lastState, currentState); _lastState = currentState; } @@ -170,7 +174,7 @@ void MFDigInMux::retrigger() // The current state for all attached modules is stored, // so future update() calls will work off whatever was read by the // retrigger flow. - poll(false, false); // just read, do not retrigger + poll(DONT_TRIGGER, false); // just read, do not retrigger // Pass 1/2: Trigger all the 'off' inputs (released buttons) first detectChanges(0x0000, _lastState); diff --git a/src/MF_DigInMux/MFDigInMux.h b/src/MF_DigInMux/MFDigInMux.h index ec04b3a1..ea625762 100644 --- a/src/MF_DigInMux/MFDigInMux.h +++ b/src/MF_DigInMux/MFDigInMux.h @@ -44,6 +44,9 @@ class MFDigInMux MUX_LAZY = 2, }; + enum { DONT_TRIGGER = 0, + DO_TRIGGER = 1 }; + static MFMuxDriver *_MUX; static MuxDigInEvent _inputHandler; diff --git a/src/MF_InputShifter/MFInputShifter.cpp b/src/MF_InputShifter/MFInputShifter.cpp index bbaa1e4e..0cdb994c 100644 --- a/src/MF_InputShifter/MFInputShifter.cpp +++ b/src/MF_InputShifter/MFInputShifter.cpp @@ -1,4 +1,4 @@ -// +// // MFInputShifter.cpp // // (C) MobiFlight Project 2022 @@ -10,32 +10,27 @@ inputShifterEvent MFInputShifter::_inputHandler = NULL; MFInputShifter::MFInputShifter(const char *name) { - _initialized = false; - _name = name; + _initialized = false; + _name = name; } // Registers a new input shifter and configures the clock, data and latch pins as well // as the number of modules to read from. void MFInputShifter::attach(uint8_t latchPin, uint8_t clockPin, uint8_t dataPin, uint8_t moduleCount, const char *name) { - _latchPin = latchPin; - _clockPin = clockPin; - _dataPin = dataPin; - _name = name; - _moduleCount = moduleCount; - - pinMode(_latchPin, OUTPUT); - pinMode(_clockPin, OUTPUT); - pinMode(_dataPin, INPUT); - _initialized = true; - -// And now initialize all buttons with the actual status - digitalWrite(_clockPin, HIGH); // Preset clock to retrieve first bit - digitalWrite(_latchPin, HIGH); // Disable input latching and enable shifting - for (int module = 0; module < _moduleCount; module++) { - _lastState[module] = shiftIn(_dataPin, _clockPin, MSBFIRST); - } - digitalWrite(_latchPin, LOW); // disable shifting and enable input latching + _latchPin = latchPin; + _clockPin = clockPin; + _dataPin = dataPin; + _name = name; + _moduleCount = moduleCount; + + pinMode(_latchPin, OUTPUT); + pinMode(_clockPin, OUTPUT); + pinMode(_dataPin, INPUT); + _initialized = true; + + // And now initialize all buttons with the actual status + poll(DONT_TRIGGER); } // Reads the values from the attached modules, compares them to the previously @@ -43,25 +38,30 @@ void MFInputShifter::attach(uint8_t latchPin, uint8_t clockPin, uint8_t dataPin, // changed from the previously read state. void MFInputShifter::update() { - digitalWrite(_clockPin, HIGH); // Preset clock to retrieve first bit - digitalWrite(_latchPin, HIGH); // Disable input latching and enable shifting - - // Multiple chained modules are handled one at a time. As shiftIn() keeps getting - // called it will pull in the data from each chained module. - for (uint8_t i = 0; i < _moduleCount; i++) { - uint8_t currentState; - - currentState = shiftIn(_dataPin, _clockPin, MSBFIRST); + poll(DO_TRIGGER); +} - // If an input changed on the current module from the last time it was read - // then hand it off to figure out which bits specifically changed. - if (currentState != _lastState[i]) { - detectChanges(_lastState[i], currentState, i); - _lastState[i] = currentState; +void MFInputShifter::poll(uint8_t doTrigger) +{ + digitalWrite(_clockPin, HIGH); // Preset clock to retrieve first bit + digitalWrite(_latchPin, HIGH); // Disable input latching and enable shifting + + // Multiple chained modules are handled one at a time. As shiftIn() keeps getting + // called it will pull in the data from each chained module. + for (uint8_t module = 0; module < _moduleCount; module++) { + uint8_t currentState; + + currentState = shiftIn(_dataPin, _clockPin, MSBFIRST); + + // If an input changed on the current module from the last time it was read + // then hand it off to figure out which bits specifically changed. + if (currentState != _lastState[module]) { + if (doTrigger) detectChanges(_lastState[module], currentState, module); + _lastState[module] = currentState; + } } - } - digitalWrite(_latchPin, LOW); // disable shifting and enable input latching + digitalWrite(_latchPin, LOW); // disable shifting and enable input latching } // Detects changes between the current state and the previously saved state @@ -69,18 +69,18 @@ void MFInputShifter::update() void MFInputShifter::detectChanges(uint8_t lastState, uint8_t currentState, uint8_t module) { for (uint8_t i = 0; i < 8; i++) { - // If last and current input state for the bit are different - // then the input changed and the handler for the bit needs to fire + // If last and current input state for the bit are different + // then the input changed and the handler for the bit needs to fire if ((lastState & 1) ^ (currentState & 1)) { - // When triggering event the pin is the actual pin on the chip offset by 8 bits for each - // module beyond the first that it's on. The state of the trigger is the bit currently - // in position 0 of currentState. - trigger(i + (module * 8), currentState & 1); + // When triggering event the pin is the actual pin on the chip offset by 8 bits for each + // module beyond the first that it's on. The state of the trigger is the bit currently + // in position 0 of currentState. + trigger(i + (module * 8), currentState & 1); + } + + lastState = lastState >> 1; + currentState = currentState >> 1; } - - lastState = lastState >> 1; - currentState = currentState >> 1; - } } // Reads the current state for all connected modules then fires @@ -88,68 +88,53 @@ void MFInputShifter::detectChanges(uint8_t lastState, uint8_t currentState, uint // press events for every pressed button. void MFInputShifter::retrigger() { - uint8_t state; - - digitalWrite(_clockPin, HIGH); // Preset clock to retrieve first bit - digitalWrite(_latchPin, HIGH); // Disable input latching and enable shifting + uint8_t state; - // The current state for all attached modules is stored in the _lastState - // array so future update() calls will work off whatever was read by the - // retrigger flow. - for (int module = 0; module < _moduleCount; module++) { - _lastState[module] = shiftIn(_dataPin, _clockPin, MSBFIRST); - } + poll(DONT_TRIGGER); - digitalWrite(_latchPin, LOW); // disable shifting and enable input latching - - // Trigger all the released buttons - for (int module = 0; module < _moduleCount; module++) { - state = _lastState[module]; + // Trigger all the released buttons + for (int module = 0; module < _moduleCount; module++) { + state = _lastState[module]; for (uint8_t i = 0; i < 8; i++) { // Only trigger if the button is in the off position if (state & 1) { - trigger(i + (module * 8), HIGH); - } - state = state >> 1; + trigger(i + (module * 8), HIGH); + } + state = state >> 1; + } } - } // Trigger all the pressed buttons for (int module = 0; module < _moduleCount; module++) { - state = _lastState[module]; + state = _lastState[module]; for (uint8_t i = 0; i < 8; i++) { // Only trigger if the button is in the on position if (!(state & 1)) { - trigger(i + (module * 8), LOW); - } + trigger(i + (module * 8), LOW); + } - state = state >> 1; + state = state >> 1; + } } - } } // Triggers the event handler for the associated input shift register pin, // if a handler is registered. void MFInputShifter::trigger(uint8_t pin, bool state) { - if (state == LOW && _inputHandler != NULL) { - (*_inputHandler)(inputShifterOnPress, pin, _name); - } else if (_inputHandler != NULL) { - (*_inputHandler)(inputShifterOnRelease, pin, _name); - } + if (!_inputHandler) return; + (*_inputHandler)((state == LOW ? inputShifterOnPress : inputShifterOnRelease), pin, _name); } // Attaches a new event handler for the specified event. void MFInputShifter::attachHandler(inputShifterEvent newHandler) { - _inputHandler = newHandler; + _inputHandler = newHandler; } void MFInputShifter::detach() { - if (!_initialized) - return; - _initialized = false; + _initialized = false; } // MFInputShifter.cpp diff --git a/src/MF_InputShifter/MFInputShifter.h b/src/MF_InputShifter/MFInputShifter.h index f36d540d..c2b5cbcc 100644 --- a/src/MF_InputShifter/MFInputShifter.h +++ b/src/MF_InputShifter/MFInputShifter.h @@ -34,14 +34,18 @@ class MFInputShifter void update(); private: - const char *_name; - uint8_t _latchPin; // SH/~LD (latch) pin - uint8_t _clockPin; // CLK (clock) pin - uint8_t _dataPin; // SDO (data) pin - uint8_t _moduleCount; // Number of 8 bit modules in series. - bool _initialized = false; - uint8_t _lastState[MAX_CHAINED_INPUT_SHIFTERS] = {0}; - + enum { DONT_TRIGGER = 0, + DO_TRIGGER = 1 }; + + const char *_name; + uint8_t _latchPin; // SH/~LD (latch) pin + uint8_t _clockPin; // CLK (clock) pin + uint8_t _dataPin; // SDO (data) pin + uint8_t _moduleCount; // Number of 8 bit modules in series. + bool _initialized = false; + uint8_t _lastState[MAX_CHAINED_INPUT_SHIFTERS] = {0}; + + void poll(uint8_t doTrigger); void detectChanges(uint8_t lastState, uint8_t currentState, uint8_t module); void trigger(uint8_t pin, bool state); static inputShifterEvent _inputHandler;