Compare commits
2 Commits
aae29d8e0a
...
2fcdd83124
| Author | SHA1 | Date | |
|---|---|---|---|
| 2fcdd83124 | |||
| 1dc2eb0927 |
@ -12,7 +12,7 @@ project(skullc
|
|||||||
list(APPEND CMAKE_MODULE_PATH ${CMAKE_BINARY_DIR})
|
list(APPEND CMAKE_MODULE_PATH ${CMAKE_BINARY_DIR})
|
||||||
list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake/)
|
list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake/)
|
||||||
|
|
||||||
set(CMAKE_CXX_STANDARD 14)
|
set(CMAKE_CXX_STANDARD 17)
|
||||||
list(APPEND CMAKE_CXX_FLAGS "-Wall -Wextra")
|
list(APPEND CMAKE_CXX_FLAGS "-Wall -Wextra")
|
||||||
|
|
||||||
option(WITH_TESTS "Enable unit testing." OFF)
|
option(WITH_TESTS "Enable unit testing." OFF)
|
||||||
@ -20,10 +20,7 @@ option(WITH_HAL "Enable the compiling and deployment of the HAL dependent sectio
|
|||||||
|
|
||||||
include(skullc-install)
|
include(skullc-install)
|
||||||
|
|
||||||
if(WITH_HAL)
|
|
||||||
add_subdirectory(Peripherals)
|
add_subdirectory(Peripherals)
|
||||||
endif()
|
|
||||||
|
|
||||||
add_subdirectory(Utility)
|
add_subdirectory(Utility)
|
||||||
add_subdirectory(Messaging)
|
add_subdirectory(Messaging)
|
||||||
|
|
||||||
|
|||||||
76
Peripherals/Inc/peripherals_button.hpp
Normal file
76
Peripherals/Inc/peripherals_button.hpp
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
/*
|
||||||
|
* peripherals_button.hpp
|
||||||
|
*
|
||||||
|
* Created on: Apr 17, 2021
|
||||||
|
* Author: erki
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef PERIPHERALS_BUTTON_HPP_
|
||||||
|
#define PERIPHERALS_BUTTON_HPP_
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
namespace Peripherals
|
||||||
|
{
|
||||||
|
|
||||||
|
enum class ButtonPress : std::uint32_t
|
||||||
|
{
|
||||||
|
NOT_PRESSED,
|
||||||
|
SHORT_PRESS,
|
||||||
|
LONG_PRESS
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename G, typename H>
|
||||||
|
class Button
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
using gpio = G;
|
||||||
|
using hal = H;
|
||||||
|
|
||||||
|
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)
|
||||||
|
{}
|
||||||
|
|
||||||
|
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:
|
||||||
|
gpio _sw;
|
||||||
|
|
||||||
|
bool _was_pressed = false;
|
||||||
|
std::uint32_t _time_pressed_down = 0;
|
||||||
|
ButtonPress _current_state = ButtonPress::NOT_PRESSED;
|
||||||
|
};
|
||||||
|
|
||||||
|
}// namespace Peripherals
|
||||||
|
|
||||||
|
#endif /* PERIPHERALS_BUTTON_HPP_ */
|
||||||
@ -13,12 +13,14 @@ add_executable(tests
|
|||||||
main.cpp
|
main.cpp
|
||||||
ringbuffer.cpp
|
ringbuffer.cpp
|
||||||
packet.cpp
|
packet.cpp
|
||||||
parser.cpp)
|
parser.cpp
|
||||||
|
button.cpp)
|
||||||
|
|
||||||
target_link_libraries(tests
|
target_link_libraries(tests
|
||||||
PUBLIC
|
PUBLIC
|
||||||
skullc::utility
|
skullc::utility
|
||||||
skullc::messaging
|
skullc::messaging
|
||||||
|
skullc::peripherals
|
||||||
Catch2::Catch2
|
Catch2::Catch2
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
126
Tests/button.cpp
Normal file
126
Tests/button.cpp
Normal file
@ -0,0 +1,126 @@
|
|||||||
|
//
|
||||||
|
// Created by erki on 17.04.21.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <catch2/catch.hpp>
|
||||||
|
|
||||||
|
#include "peripherals_button.hpp"
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
|
||||||
|
struct HAL
|
||||||
|
{
|
||||||
|
HAL()
|
||||||
|
{
|
||||||
|
millis = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
~HAL()
|
||||||
|
{
|
||||||
|
millis = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::uint32_t millis;
|
||||||
|
|
||||||
|
static std::uint32_t GetMillis()
|
||||||
|
{
|
||||||
|
return millis;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
std::uint32_t HAL::millis = 1;
|
||||||
|
|
||||||
|
struct Gpio
|
||||||
|
{
|
||||||
|
static bool set;
|
||||||
|
|
||||||
|
Gpio()
|
||||||
|
{
|
||||||
|
set = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Read()
|
||||||
|
{
|
||||||
|
return set;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
bool Gpio::set = false;
|
||||||
|
|
||||||
|
}// namespace
|
||||||
|
|
||||||
|
using Button = Peripherals::Button<Gpio, HAL>;
|
||||||
|
|
||||||
|
TEST_CASE("Button reads no press as NOT_PRESSED.", "[peripherals],[button]")
|
||||||
|
{
|
||||||
|
Gpio g;
|
||||||
|
HAL hal;
|
||||||
|
|
||||||
|
Button button{g};
|
||||||
|
|
||||||
|
button.update();
|
||||||
|
|
||||||
|
HAL::millis = Button::TIMEOUT_LONG_PRESS + 10;
|
||||||
|
|
||||||
|
button.update();
|
||||||
|
|
||||||
|
REQUIRE(button.getState() == Peripherals::ButtonPress::NOT_PRESSED);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("Button reads presses properly.", "[peripherals],[button]")
|
||||||
|
{
|
||||||
|
Gpio g;
|
||||||
|
HAL hal;
|
||||||
|
|
||||||
|
Button button{g};
|
||||||
|
|
||||||
|
Gpio::set = true;
|
||||||
|
button.update();
|
||||||
|
|
||||||
|
SECTION("Too short of a press is debounced.")
|
||||||
|
{
|
||||||
|
HAL::millis = Button::TIMEOUT_SHORT_PRESS - 1;
|
||||||
|
Gpio::set = false;
|
||||||
|
|
||||||
|
button.update();
|
||||||
|
|
||||||
|
REQUIRE(button.getState() == Peripherals::ButtonPress::NOT_PRESSED);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("Short press is identified properly.")
|
||||||
|
{
|
||||||
|
HAL::millis = Button::TIMEOUT_SHORT_PRESS + 2;
|
||||||
|
Gpio::set = false;
|
||||||
|
|
||||||
|
button.update();
|
||||||
|
|
||||||
|
REQUIRE(button.getState() == Peripherals::ButtonPress::SHORT_PRESS);
|
||||||
|
|
||||||
|
SECTION("Next state is NOT_PRESSED.")
|
||||||
|
{
|
||||||
|
HAL::millis += 1;
|
||||||
|
button.update();
|
||||||
|
|
||||||
|
REQUIRE(button.getState() == Peripherals::ButtonPress::NOT_PRESSED);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("Long press is identified properly.")
|
||||||
|
{
|
||||||
|
HAL::millis = Button::TIMEOUT_LONG_PRESS + 2;
|
||||||
|
Gpio::set = false;
|
||||||
|
|
||||||
|
button.update();
|
||||||
|
|
||||||
|
REQUIRE(button.getState() == Peripherals::ButtonPress::LONG_PRESS);
|
||||||
|
|
||||||
|
SECTION("Next state is NOT_PRESSED.")
|
||||||
|
{
|
||||||
|
HAL::millis += 1;
|
||||||
|
button.update();
|
||||||
|
|
||||||
|
REQUIRE(button.getState() == Peripherals::ButtonPress::NOT_PRESSED);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user