Merge remote-tracking branch 'origin/master' into master

This commit is contained in:
rusefi 2020-09-20 14:04:33 -04:00
commit b6ab109419
4 changed files with 65 additions and 57 deletions

View File

@ -6,6 +6,6 @@ EXTERN_ENGINE;
ButtonDebounce startStopButtonDebounce; ButtonDebounce startStopButtonDebounce;
void initStartStopButton(DECLARE_ENGINE_PARAMETER_SIGNATURE) { void initStartStopButton(DECLARE_ENGINE_PARAMETER_SIGNATURE) {
/* startCrankingDuration is efitimesec_t, so we need to multiply by 1000 to get milliseconds */ /* startCrankingDuration is efitimesec_t, so we need to multiply it by 1000 to get milliseconds*/
startStopButtonDebounce.init((CONFIG(startCrankingDuration)*1000), &CONFIG(startStopButtonPin), &CONFIG(startStopButtonMode)); startStopButtonDebounce.init((CONFIG(startCrankingDuration)*1000), &CONFIG(startStopButtonPin), &CONFIG(startStopButtonMode));
} }

View File

@ -12,91 +12,95 @@
ButtonDebounce* ButtonDebounce::s_firstDebounce = nullptr; ButtonDebounce* ButtonDebounce::s_firstDebounce = nullptr;
void ButtonDebounce::init (efitimems_t t, brain_pin_e *pin, pin_input_mode_e *mode) { /**
We need to have a separate init function because we do not have the pin or mode in the context in which the class is originally created
*/
void ButtonDebounce::init (efitimems_t threshold, brain_pin_e *pin, pin_input_mode_e *mode) {
// we need to keep track of whether we have already been initialized due to the way unit tests run.
if (!initialized) { if (!initialized) {
ButtonDebounce *listItem = s_firstDebounce; // Link us to the list that is used to track ButtonDebounce instances, so that when the configuration changes,
if (listItem == nullptr) { // they can be looped through and updated.
s_firstDebounce = this; nextDebounce = s_firstDebounce;
} else { s_firstDebounce = this;
while (listItem->nextDebounce != nullptr) {
listItem = listItem->nextDebounce;
}
listItem->nextDebounce = this;
}
} }
threshold = MS2NT(t); m_threshold = MS2NT(threshold);
timeLast = 0; timeLast = 0;
this->pin = pin; m_pin = pin;
active_pin = *pin; m_mode = mode;
this->mode = mode; startConfiguration();
active_mode = *mode;
#ifndef EFI_UNIT_TEST
// getInputMode converts from pin_input_mode_e to iomode_t
efiSetPadMode("Button", active_pin, getInputMode(active_mode));
#endif
initialized = true; initialized = true;
} }
void ButtonDebounce::updateConfigurationList () { void ButtonDebounce::stopConfigurationList () {
ButtonDebounce *listItem = s_firstDebounce; ButtonDebounce *listItem = s_firstDebounce;
while (listItem != nullptr) { while (listItem != nullptr) {
listItem->updateConfiguration(); listItem->stopConfiguration();
if (listItem->nextDebounce != nullptr) { listItem = listItem->nextDebounce;
listItem = listItem->nextDebounce;
} else {
break;
}
} }
} }
void ButtonDebounce::updateConfiguration () { void ButtonDebounce::startConfigurationList () {
ButtonDebounce *listItem = s_firstDebounce;
while (listItem != nullptr) {
listItem->startConfiguration();
listItem = listItem->nextDebounce;
}
}
void ButtonDebounce::stopConfiguration () {
// If the configuration has changed
#ifndef EFI_ACTIVE_CONFIGURATION_IN_FLASH #ifndef EFI_ACTIVE_CONFIGURATION_IN_FLASH
if (*pin != active_pin || *mode != active_mode) { if (*m_pin != active_pin || *m_mode != active_mode) {
#else #else
if (*pin != active_pin || *mode != active_mode || (isActiveConfigurationVoid && (*pin != 0 || *mode != 0))) { if (*m_pin != active_pin || *m_mode != active_mode || (isActiveConfigurationVoid && (*m_pin != 0 || *m_mode != 0))) {
#endif /* EFI_ACTIVE_CONFIGURATION_IN_FLASH */ #endif /* EFI_ACTIVE_CONFIGURATION_IN_FLASH */
#ifndef EFI_UNIT_TEST #ifndef EFI_UNIT_TEST
brain_pin_markUnused(active_pin); brain_pin_markUnused(active_pin);
efiSetPadMode("Button", *pin, getInputMode(*mode));
#endif /* EFI_UNIT_TEST */ #endif /* EFI_UNIT_TEST */
} }
active_pin = *pin; }
active_mode = *mode;
void ButtonDebounce::startConfiguration () {
#ifndef EFI_UNIT_TEST
efiSetPadMode("Button", *m_pin, getInputMode(*m_mode));
#endif
active_pin = *m_pin;
active_mode = *m_mode;
} }
/** /**
@returns true if the button is pressed, and will not return true again within the set timeout @returns true if the button is pressed, and will not return true again within the set timeout
*/ */
bool ButtonDebounce::readPinEvent() { bool ButtonDebounce::readPinEvent() {
readValue = false; storedValue = false;
return readPinState(); return readPinState();
} }
bool ButtonDebounce::readPinState() { bool ButtonDebounce::readPinState() {
if (!pin) { if (!m_pin) {
return false; return false;
} }
efitick_t timeNow = getTimeNowNt(); efitick_t timeNow = getTimeNowNt();
// If it's been less than the threshold since we were last called // If it's been less than the threshold since we were last called
if ((timeNow - timeLast) < threshold) { if ((timeNow - timeLast) < m_threshold) {
return readValue; return storedValue;
} }
// readValue is a class variable, so it needs to be reset. // storedValue is a class variable, so it needs to be reset.
// We don't actually need it to be a class variable in this method, // We don't actually need it to be a class variable in this method,
// but when a method is implemented to actually get the pin's state, // but when a method is implemented to actually get the pin's state,
// for example to implement long button presses, it will be needed. // for example to implement long button presses, it will be needed.
readValue = false; storedValue = false;
#if EFI_PROD_CODE || EFI_UNIT_TEST #if EFI_PROD_CODE || EFI_UNIT_TEST
readValue = efiReadPin(active_pin); storedValue = efiReadPin(active_pin);
#endif #endif
#if EFI_PROD_CODE #if EFI_PROD_CODE
// Invert // Invert
if (getInputMode(active_mode) == PAL_MODE_INPUT_PULLUP) { if (getInputMode(active_mode) == PAL_MODE_INPUT_PULLUP) {
readValue = !readValue; storedValue = !storedValue;
} }
#endif #endif
if (readValue) { if (storedValue) {
timeLast = timeNow; timeLast = timeNow;
} }
return readValue; return storedValue;
} }

View File

@ -1,34 +1,36 @@
/** /**
* @file debounce.h * @file debounce.h
* @brief Generic button debounce class * @brief Generic button debounce class
* https://en.wikipedia.org/wiki/Switch#Contact_bounce
* If we don't 'debounce' our button inputs, we may mistakenly
* read a single button press as multiple events.
* *
* @date Aug 31, 2020 * @date Aug 31, 2020
* @author David Holdeman, (c) 2020 * @author David Holdeman, (c) 2020
*/ */
#ifndef DEBOUNCE_INC #pragma once
#define DEBOUNCE_INC
#include "globalaccess.h" #include "globalaccess.h"
#include "io_pins.h" #include "io_pins.h"
class ButtonDebounce { class ButtonDebounce {
public: public:
void init(efitimems_t t, brain_pin_e *p, pin_input_mode_e *m); void init(efitimems_t threshold, brain_pin_e *pin, pin_input_mode_e *mode);
void updateConfiguration(); void stopConfiguration();
void startConfiguration();
bool readPinEvent(); bool readPinEvent();
bool readPinState(); bool readPinState();
static void updateConfigurationList(); static void stopConfigurationList();
static void startConfigurationList();
private: private:
efitick_t threshold; efitick_t m_threshold;
efitick_t timeLast; efitick_t timeLast;
brain_pin_e *pin; brain_pin_e *m_pin;
brain_pin_e active_pin; brain_pin_e active_pin = GPIO_UNASSIGNED;
pin_input_mode_e *mode; pin_input_mode_e *m_mode;
pin_input_mode_e active_mode; pin_input_mode_e active_mode = PI_DEFAULT;
bool readValue; bool storedValue = false;
bool initialized = false; bool initialized = false;
ButtonDebounce *nextDebounce = nullptr; ButtonDebounce *nextDebounce = nullptr;
static ButtonDebounce* s_firstDebounce; static ButtonDebounce* s_firstDebounce;
}; };
#endif /* DEBOUNCE_INC */

View File

@ -328,7 +328,7 @@ void stopSpi(spi_device_e device) {
void applyNewHardwareSettings(void) { void applyNewHardwareSettings(void) {
// all 'stop' methods need to go before we begin starting pins // all 'stop' methods need to go before we begin starting pins
ButtonDebounce::updateConfigurationList(); ButtonDebounce::stopConfigurationList();
#if EFI_SHAFT_POSITION_INPUT #if EFI_SHAFT_POSITION_INPUT
stopTriggerInputPins(); stopTriggerInputPins();
@ -401,6 +401,8 @@ void applyNewHardwareSettings(void) {
enginePins.unregisterPins(); enginePins.unregisterPins();
ButtonDebounce::startConfigurationList();
#if EFI_SHAFT_POSITION_INPUT #if EFI_SHAFT_POSITION_INPUT
startTriggerInputPins(); startTriggerInputPins();
#endif /* EFI_SHAFT_POSITION_INPUT */ #endif /* EFI_SHAFT_POSITION_INPUT */