rusEFI
The most advanced open source ECU
Loading...
Searching...
No Matches
debounce.cpp
Go to the documentation of this file.
1/**
2 * @file debounce.cpp
3 * @brief Generic button debounce class
4 *
5 * @date Aug 31, 2020
6 * @author David Holdeman, (c) 2020
7 */
8#include "pch.h"
9
10#include "debounce.h"
11#include "hardware.h"
12
14
16 : m_name(name)
17{
18}
19
20/**
21We 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
22*/
23void ButtonDebounce::init (efitimems_t threshold, brain_pin_e &pin, pin_input_mode_e &mode, bool inverted) {
24 // we need to keep track of whether we have already been initialized due to the way unit tests run.
26 // Link us to the list that is used to track ButtonDebounce instances, so that when the configuration changes,
27 // they can be looped through and updated.
29 s_firstDebounce = this;
30 }
31 m_threshold = MS2NT(threshold);
32 m_pin = &pin;
33 m_mode = &mode;
34 m_inverted = inverted;
37}
38
41 int loopLimitCounter = 0;
42 while (listItem != nullptr) {
43 criticalAssertVoid(loopLimitCounter++ < 10000, "dead stopConfigurationList?");
44 listItem->stopConfiguration();
45 listItem = listItem->nextDebounce;
46 }
47}
48
51 int loopLimitCounter = 0;
52 while (listItem != nullptr) {
53 criticalAssertVoid(loopLimitCounter++ < 10000, "dead startConfigurationList?");
54 listItem->startConfiguration();
55 listItem = listItem->nextDebounce;
56 }
57}
58
60 // If the configuration has changed
61#if ! EFI_ACTIVE_CONFIGURATION_IN_FLASH
62 if (*m_pin != active_pin || *m_mode != active_mode) {
63#else
64 if (*m_pin != active_pin || *m_mode != active_mode || (isActiveConfigurationVoid && ((int)(*m_pin) != 0 || (int)(*m_mode) != 0))) {
65#endif /* EFI_ACTIVE_CONFIGURATION_IN_FLASH */
66#if EFI_PROD_CODE
68#endif /* EFI_UNIT_TEST */
70 }
71}
72
74#if EFI_PROD_CODE
78 }
79#endif
82}
83
84/**
85@returns true if the button is pressed, and will not return true again within the set timeout
86*/
89 return storedValue;
90}
91
93#if EFI_PROD_CODE || EFI_UNIT_TEST
95#else
96 return false;
97#endif
98}
99
100bool ButtonDebounce::readPinState2(bool valueWithinThreshold) {
101 if (!isBrainPinValid(*m_pin)) {
102 return false;
103 }
104 efitick_t timeNowNt = getTimeNowNt();
105 // If it's been less than the threshold since we were last called
106 if (timeLast.getElapsedNt(timeNowNt) < m_threshold) {
107 return valueWithinThreshold;
108 }
109 bool value = getPhysicalState();
110// efiPrintf("[debounce] %s value %d", m_name, value);
111 // Invert
112 if (active_mode == PI_PULLUP) {
113 value = !value;
114// efiPrintf("[debounce] %s inverted %d", m_name, value);
115 }
116 if (value) {
117 timeLast.reset();
118 }
119 return value;
120}
121
123 // code comment could be out of date:
124 // storedValue is a class variable, so it needs to be reset.
125 // We don't actually need it to be a class variable in this method,
126 // but when a method is implemented to actually get the pin's state,
127 // for example to implement long button presses, it will be needed.
129 return storedValue;
130}
131
134 while (listItem != nullptr) {
135#if EFI_PROD_CODE || EFI_UNIT_TEST
136 efiPrintf("%s timeLast %f", listItem->m_name, listItem->timeLast.getElapsedSeconds());
137 efiPrintf("physical pin state %d", listItem->getPhysicalState());
138 efiPrintf("state %d", listItem->storedValue);
139 efiPrintf("mode %d", listItem->active_mode);
140#endif
141
142 listItem = listItem->nextDebounce;
143 }
144}
145
146void initButtonDebounce() {
147#if !EFI_UNIT_TEST
149#endif /* EFI_UNIT_TEST */
150}
void efiSetPadMode(const char *msg, brain_pin_e brainPin, iomode_t mode)
void stopConfiguration()
Definition debounce.cpp:59
bool isInstanceRegisteredInGlobalList
Definition debounce.h:43
pin_input_mode_e active_mode
Definition debounce.h:40
const char *const m_name
Definition debounce.h:34
bool storedValue
Definition debounce.h:41
pin_input_mode_e * m_mode
Definition debounce.h:39
void startConfiguration()
bool readPinEvent()
Timer timeLast
Definition debounce.h:36
void init(efitimems_t threshold, brain_pin_e &pin, pin_input_mode_e &mode, bool inverted=false)
Definition debounce.cpp:23
bool getPhysicalState()
ButtonDebounce(const char *name)
Definition debounce.cpp:15
brain_pin_e active_pin
Definition debounce.h:38
bool readPinState2(bool valueWithinThreshold)
static void debug()
static void startConfigurationList()
Definition debounce.cpp:49
static ButtonDebounce * s_firstDebounce
Definition debounce.h:46
ButtonDebounce * nextDebounce
Definition debounce.h:45
static void stopConfigurationList()
Definition debounce.cpp:39
bool needsPinInitialization
Definition debounce.h:44
efidur_t m_threshold
Definition debounce.h:35
brain_pin_e * m_pin
Definition debounce.h:37
bool m_inverted
Definition debounce.h:42
bool readPinState()
void addConsoleAction(const char *token, Void callback)
Register console action without parameters.
Generic button debounce class https://en.wikipedia.org/wiki/Switch#Contact_bounce If we don't 'deboun...
void initButtonDebounce()
efitick_t getTimeNowNt()
Definition efitime.cpp:19
bool isActiveConfigurationVoid
iomode_t getInputMode(pin_input_mode_e mode)
Definition io_pins.cpp:103
bool efiReadPin(brain_pin_e pin)
Definition io_pins.cpp:89
void efiSetPadUnused(brain_pin_e brainPin)
Definition io_pins.cpp:20
bool isBrainPinValid(brain_pin_e brainPin)
pin_input_mode_e
uint32_t efitimems_t
brain_pin_e pin
Definition stm32_adc.cpp:15