diff --git a/main.c b/main.c index a1aeab8..711ccfe 100644 --- a/main.c +++ b/main.c @@ -19,8 +19,9 @@ #define PA7_SET_MASK 0x80 ///< Red LED /** @} */ -#define MAIN_LOOP_SLEEP 10U // Main loop delay in ms (system tick) -#define BUTTON_PRESS_DURATION 1000U // Button needs to be pressed for at least 1000ms +#define MAIN_LOOP_SLEEP 10U // Main loop delay in ms (system tick) +#define BUTTON_LONG_PRESS_DURATION_MS 1000U // Long press detection threshold +#define BUTTON_IGNORE_DURATION_MS 1000U // Time that the button is ignored after a long press /** @brief Convert milliseconds to system ticks (integer division). */ #define MS_TO_TICKS(ms) ((ms) / MAIN_LOOP_SLEEP) @@ -30,7 +31,7 @@ volatile bool bLedEnabled = true; volatile bool bBtnPressed = false; // Function forward declarations -void blinkLed(void); +void blinkLed(bool resetCounters); static inline void leds_off(void); static inline void leds_on(void); static void handleSwitch(void); @@ -74,15 +75,21 @@ int main(void) if (bLedEnabledOld != bLedEnabled) { + // A long press detected --> confirm with a blink bLedEnabledOld = bLedEnabled; leds_off(); - _delay_ms(1000); + _delay_ms(BUTTON_IGNORE_DURATION_MS / 10); + leds_on(); + _delay_ms(BUTTON_IGNORE_DURATION_MS / 10); + leds_off(); + _delay_ms(BUTTON_IGNORE_DURATION_MS); + blinkLed(true); // reset the persistent counters } else { if ((bLedEnabled) && (!bBtnPressed)) { - blinkLed(); + blinkLed(false); } } @@ -138,7 +145,7 @@ static void handleSwitch(void) pressTicks = 0; } - if (prevPressed && pressTicks >= MS_TO_TICKS(BUTTON_PRESS_DURATION)) + if (prevPressed && pressTicks >= MS_TO_TICKS(BUTTON_LONG_PRESS_DURATION_MS)) { // long press detected → toggle blinking bLedEnabled = !bLedEnabled; @@ -150,31 +157,36 @@ static void handleSwitch(void) /** * @brief LED blink state machine (bike rear light style). * - * Implements a "rounded" pulsing blink sequence: - * - * Normal cycle (~1 s total): - * - Step 0: all off, wait 100 ms - * - Step 1: LED 1–2 + 7–8 ON, wait 100 ms - * - Step 2: all LEDs ON, wait 200 ms - * - Step 3: only LED 1–2 ON, wait 100 ms - * - Step 4: all off, wait 400 ms → restart - * - * Special behavior: - * - Every 3rd cycle, after step 4, all LEDs are switched on for 300 ms. - * - * Timing is based on @ref MAIN_LOOP_SLEEP ticks. + * Normal cycle: + * 0: all off, wait 250 ms + * 2: LED 1–2 + 7–8 ON, wait 50 ms + * 5: all off, wait 100 ms + * 7: LED 1–2 + 7–8 ON, wait 50 ms + * 10: all off, wait 250 ms + * 12: LED 3–6 ON, wait 50 ms + * 14: all off, wait 100 ms + * 16: LED 3–6 ON, wait 50 ms + * 18: all off, wait 250 ms → restart + * Special: every 3rd cycle, all LEDs ON for 250 ms */ -void blinkLed(void) +void blinkLed(bool resetCounters) { - // --- precomputed constants (compile-time) --- + // --- precomputed constants --- const uint8_t T50 = MS_TO_TICKS(50); ///< 50 ms in ticks const uint8_t T100 = MS_TO_TICKS(100); ///< 100 ms in ticks const uint8_t T250 = MS_TO_TICKS(250); ///< 250 ms in ticks // --- persistent state --- - static uint16_t counter = 0; ///< counts ticks for current state - static uint8_t state = 0; ///< current step in the sequence - static uint8_t cycle = 0; ///< cycle counter (0–2) + static uint16_t counter = 0; ///< ticks for current state + static uint8_t state = 2; ///< start with first LEDs-on state + static uint8_t cycle = 0; ///< cycle counter + + if (resetCounters) + { + counter = 0; + state = 12; // start with LEDs on + cycle = 0; + } counter++;