155 lines
4.6 KiB
C++
155 lines
4.6 KiB
C++
#include "catch2/catch_all.hpp"
|
|
#include "leds.h"
|
|
#include "shr16.h"
|
|
#include "../stubs/stub_timebase.h"
|
|
#include "../../../../src/modules/timebase.h"
|
|
|
|
using Catch::Matchers::Equals;
|
|
|
|
uint16_t millis = 0;
|
|
|
|
namespace hal {
|
|
namespace shr16 {
|
|
extern uint16_t shr16_v_copy;
|
|
} // namespace shr16
|
|
} // namespace hal
|
|
|
|
/// LEDS - hardcoded
|
|
#define SHR16_LEDR0 0x0080
|
|
#define SHR16_LEDG0 0x0040
|
|
#define SHR16_LEDR1 0x8000
|
|
#define SHR16_LEDG1 0x4000
|
|
#define SHR16_LEDR2 0x2000
|
|
#define SHR16_LEDG2 0x1000
|
|
#define SHR16_LEDR3 0x0800
|
|
#define SHR16_LEDG3 0x0400
|
|
#define SHR16_LEDR4 0x0200
|
|
#define SHR16_LEDG4 0x0100
|
|
|
|
TEST_CASE("leds::single", "[leds]") {
|
|
using namespace hal::shr16;
|
|
mt::ReinitTimebase(); // reset timing
|
|
|
|
ml::LEDs leds;
|
|
|
|
uint8_t index;
|
|
ml::Color color;
|
|
uint16_t shr16_register;
|
|
std::tie(index, color, shr16_register) = GENERATE(
|
|
std::make_tuple(0, ml::green, SHR16_LEDG0),
|
|
std::make_tuple(0, ml::red, SHR16_LEDR0),
|
|
std::make_tuple(1, ml::green, SHR16_LEDG1),
|
|
std::make_tuple(1, ml::red, SHR16_LEDR1),
|
|
std::make_tuple(2, ml::green, SHR16_LEDG2),
|
|
std::make_tuple(2, ml::red, SHR16_LEDR2),
|
|
std::make_tuple(3, ml::green, SHR16_LEDG3),
|
|
std::make_tuple(3, ml::red, SHR16_LEDR3),
|
|
std::make_tuple(4, ml::green, SHR16_LEDG4),
|
|
std::make_tuple(4, ml::red, SHR16_LEDR4));
|
|
|
|
shr16.Init(); // clears the register for the test
|
|
|
|
// turn LED on
|
|
leds.SetMode(index, color, ml::on);
|
|
leds.Step();
|
|
mt::IncMillis();
|
|
CHECK(leds.LedOn(index, color) == true);
|
|
CHECK(shr16_v_copy == shr16_register);
|
|
|
|
// turn LED off
|
|
leds.SetMode(index, color, ml::off);
|
|
leds.Step();
|
|
mt::IncMillis();
|
|
CHECK(leds.LedOn(index, color) == false);
|
|
CHECK(shr16_v_copy == 0);
|
|
}
|
|
|
|
void TestBlink(uint8_t index, ml::Color color, uint16_t shr16_register, bool shouldBeOn, ml::Mode blinkMode) {
|
|
using namespace hal::shr16;
|
|
mt::ReinitTimebase(); // reset timing
|
|
ml::LEDs leds;
|
|
|
|
leds.SetMode(index, color, blinkMode);
|
|
leds.Step();
|
|
mt::IncMillis();
|
|
|
|
REQUIRE(leds.LedOn(index, color) == shouldBeOn);
|
|
CHECK(shr16_v_copy == (shouldBeOn ? shr16_register : 0));
|
|
|
|
// test 4 seconds of blinking
|
|
for (uint8_t s = 1; s < 4; ++s) {
|
|
// one second elapsed ;)
|
|
mt::IncMillis(config::ledBlinkPeriodMs / 2);
|
|
leds.Step();
|
|
shouldBeOn = !shouldBeOn;
|
|
CHECK(leds.LedOn(index, color) == shouldBeOn);
|
|
CHECK(shr16_v_copy == (shouldBeOn ? shr16_register : 0));
|
|
}
|
|
|
|
// turn LED off
|
|
leds.SetMode(index, color, ml::off);
|
|
leds.Step();
|
|
mt::IncMillis();
|
|
CHECK(leds.LedOn(index, color) == false);
|
|
CHECK(shr16_v_copy == 0);
|
|
}
|
|
|
|
TEST_CASE("leds::blink0-single", "[leds]") {
|
|
using namespace hal::shr16;
|
|
uint8_t index;
|
|
ml::Color color;
|
|
uint16_t shr16_register;
|
|
std::tie(index, color, shr16_register) = GENERATE(
|
|
std::make_tuple(0, ml::green, SHR16_LEDG0),
|
|
std::make_tuple(0, ml::red, SHR16_LEDR0),
|
|
std::make_tuple(1, ml::green, SHR16_LEDG1),
|
|
std::make_tuple(1, ml::red, SHR16_LEDR1),
|
|
std::make_tuple(2, ml::green, SHR16_LEDG2),
|
|
std::make_tuple(2, ml::red, SHR16_LEDR2),
|
|
std::make_tuple(3, ml::green, SHR16_LEDG3),
|
|
std::make_tuple(3, ml::red, SHR16_LEDR3),
|
|
std::make_tuple(4, ml::green, SHR16_LEDG4),
|
|
std::make_tuple(4, ml::red, SHR16_LEDR4));
|
|
|
|
shr16.Init(); // clears the register for the test
|
|
|
|
// set LED into blink0 mode - on in even periods of 1s intervals, starts as OFF
|
|
TestBlink(index, color, shr16_register, false, ml::blink0);
|
|
|
|
TestBlink(index, color, shr16_register, true, ml::blink1);
|
|
}
|
|
|
|
void TestBlinkOverflow(uint16_t period) {
|
|
using namespace hal::shr16;
|
|
|
|
// reset timing to a stage close to millis overflow
|
|
mt::ReinitTimebase(0x10000U - period / 2 + 1);
|
|
|
|
ml::LEDs leds;
|
|
uint8_t index = 0;
|
|
ml::Color color = ml::green;
|
|
uint16_t ms = mt::timebase.Millis();
|
|
bool shouldBeOn = ((ms / (period / 2)) & 0x01U) != 0;
|
|
uint16_t shr16_register = SHR16_LEDG0;
|
|
|
|
leds.SetMode(index, color, ml::blink0);
|
|
leds.Step();
|
|
|
|
REQUIRE(leds.LedOn(index, color) == shouldBeOn);
|
|
CHECK(shr16_v_copy == (shouldBeOn ? shr16_register : 0));
|
|
|
|
// advance timebase with overflow
|
|
mt::IncMillis(period / 2);
|
|
|
|
// the LED must have changed its state
|
|
leds.Step();
|
|
|
|
REQUIRE(leds.LedOn(index, color) != shouldBeOn);
|
|
CHECK(shr16_v_copy == (shouldBeOn ? 0 : shr16_register));
|
|
}
|
|
|
|
TEST_CASE("leds::blink0-overflow", "[leds]") {
|
|
// this is a check for a correct FW configuration
|
|
TestBlinkOverflow(config::ledBlinkPeriodMs);
|
|
}
|