Skip to content

Commit

Permalink
Use same retrigger logic for Multiplexer and InputShifter (#203)
Browse files Browse the repository at this point in the history
  • Loading branch information
GioCC authored Oct 8, 2022
1 parent a57611c commit 2ad0aca
Show file tree
Hide file tree
Showing 4 changed files with 88 additions and 92 deletions.
12 changes: 8 additions & 4 deletions src/MF_DigInMux/MFDigInMux.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand All @@ -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;

Expand Down Expand Up @@ -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;
}

Expand Down Expand Up @@ -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);
Expand Down
3 changes: 3 additions & 0 deletions src/MF_DigInMux/MFDigInMux.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,9 @@ class MFDigInMux
MUX_LAZY = 2,
};

enum { DONT_TRIGGER = 0,
DO_TRIGGER = 1 };

static MFMuxDriver *_MUX;
static MuxDigInEvent _inputHandler;

Expand Down
145 changes: 65 additions & 80 deletions src/MF_InputShifter/MFInputShifter.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//
//
// MFInputShifter.cpp
//
// (C) MobiFlight Project 2022
Expand All @@ -10,146 +10,131 @@ 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
// read values, and calls the registered event handler for any inputs that
// 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
// of a byte's worth of input.
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
// release events for every released button followed by
// 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
20 changes: 12 additions & 8 deletions src/MF_InputShifter/MFInputShifter.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down

0 comments on commit 2ad0aca

Please sign in to comment.