Prusa-Firmware-MMU/src/modules/debouncer.h

59 lines
1.9 KiB
C++

/// @file debouncer.h
#pragma once
#include <stdint.h>
namespace modules {
/// The debounce namespace provides a generic debouncing algorithm.
namespace debounce {
/// Implements debouncing on 2-state logic variables (true/false, high/low, on/off, pressed/unpressed)
/// Intentionally not modelled as a template to avoid code bloat
class Debouncer {
public:
/// @param debounceTimeout initial debounce timeout in milliseconds @@TODO
/// - after what time of having a pressed level the debouncer considers the level stable enough to report the Pressed state.
inline constexpr Debouncer(uint8_t debounceTimeout)
: timeLastChange(0)
, debounceTimeout(debounceTimeout) {}
/// @returns true if debounced value is currently considered as pressed
inline bool Pressed() const { return f.state == State::WaitForRelease; }
/// State machine stepping routine
void Step(uint16_t time, bool press);
private:
/// States of the debouncing automaton
/// Intentionally not modeled as an enum class
/// as it would impose additional casts which do not play well with the struct Flags
/// and would make the code less readable
enum State : uint8_t {
Waiting = 0,
Detected,
WaitForRelease,
Update
};
/// The sole purpose of this data struct is to save RAM by compressing several flags into one byte on the AVR
struct Flags {
uint8_t state : 2; ///< state of the debounced variable
uint8_t tmp : 1; ///< temporary state of variable before the debouncing state machine finishes
inline constexpr Flags()
: state(State::Waiting)
, tmp(false) {}
};
/// Flags and state of the debouncing automaton
Flags f;
/// Timestamp of the last change of raw input state for this variable
uint16_t timeLastChange;
uint8_t debounceTimeout;
};
} // namespace debounce
} // namespace modules
namespace md = modules::debounce;