/* * peripherals_button.hpp * * Created on: Apr 17, 2021 * Author: erki */ #ifndef SKULLC_PERIPHERALS_BUTTON_HPP_ #define SKULLC_PERIPHERALS_BUTTON_HPP_ #include namespace Peripherals { enum class ButtonPress : std::uint32_t { NOT_PRESSED, SHORT_PRESS, LONG_PRESS }; /** * A class to abstract a button! * * Usage example: * @code * int a = 4; * @endcode * * @tparam G The class to use for GPIO. Must have members @c set(bool). * @tparam H The HAL class to use. */ template class Button { public: using gpio = G; using hal = H; gpio sw; ///< A switch instance. static constexpr std::uint32_t TIMEOUT_SHORT_PRESS = 50; static constexpr std::uint32_t TIMEOUT_LONG_PRESS = 500; Button() = delete; explicit Button(const gpio& sw) : sw(sw) {} /** * Does the do. */ void update() { const bool is_pressed = sw.read(); ButtonPress new_state = ButtonPress::NOT_PRESSED; if (is_pressed && !was_pressed_) { time_pressed_down_ = hal::getMillis(); } else if (!is_pressed && was_pressed_) { const std::uint32_t time_held = hal::getMillis() - time_pressed_down_; if (time_held > TIMEOUT_LONG_PRESS) new_state = ButtonPress::LONG_PRESS; else if (time_held > TIMEOUT_SHORT_PRESS) new_state = ButtonPress::SHORT_PRESS; time_pressed_down_ = 0; } was_pressed_ = is_pressed; current_state_ = new_state; } [[nodiscard]] ButtonPress getState() const { return current_state_; } private: bool was_pressed_ = false; std::uint32_t time_pressed_down_ = 0; ButtonPress current_state_ = ButtonPress::NOT_PRESSED; }; }// namespace Peripherals #endif /* SKULLC_PERIPHERALS_BUTTON_HPP_ */