Fix (workaround) LED blink when millis overflow + unit test

pull/131/head
D.R.racer 2021-10-15 07:10:19 +02:00 committed by DRracer
parent 8eb6240541
commit 5b9c6ec36e
2 changed files with 40 additions and 1 deletions

View File

@ -24,7 +24,11 @@ static constexpr const uint16_t fsensorDebounceMs = 10;
// LEDS // LEDS
/// The complete period of LED's blinking (i.e. ON and OFF together) /// The complete period of LED's blinking (i.e. ON and OFF together)
static constexpr uint16_t ledBlinkPeriodMs = 1000U; /// Beware - in order to keep the blink periods "handle" millis overflow seamlessly
/// keep the period a power of 2 (i.e. 256, 512, 1024).
/// If you don't, one of the LED unit tests will fail.
static constexpr uint16_t ledBlinkPeriodMs = 1024U;
static_assert(ledBlinkPeriodMs == 256 || ledBlinkPeriodMs == 512 || ledBlinkPeriodMs == 1024 || ledBlinkPeriodMs == 2048, "LED blink period should be a power of 2");
// FINDA setup // FINDA setup
static constexpr const uint16_t findaDebounceMs = 100; static constexpr const uint16_t findaDebounceMs = 100;

View File

@ -2,6 +2,7 @@
#include "leds.h" #include "leds.h"
#include "shr16.h" #include "shr16.h"
#include "../stubs/stub_timebase.h" #include "../stubs/stub_timebase.h"
#include "../../../../src/modules/timebase.h"
using Catch::Matchers::Equals; using Catch::Matchers::Equals;
@ -117,3 +118,37 @@ TEST_CASE("leds::blink0-single", "[leds]") {
TestBlink(index, color, shr16_register, true, ml::blink1); 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);
}