skullc-peripherals/Peripherals/Inc/peripherals_button.hpp
Erki 82f62d1650
All checks were successful
continuous-integration/drone/push Build is passing
Initial commit
2021-09-19 15:42:37 +03:00

91 lines
1.7 KiB
C++

/*
* peripherals_button.hpp
*
* Created on: Apr 17, 2021
* Author: erki
*/
#ifndef SKULLC_PERIPHERALS_BUTTON_HPP_
#define SKULLC_PERIPHERALS_BUTTON_HPP_
#include <cstdint>
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<typename G, typename H>
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_ */