#include #include "hw.h" #include "led.h" #include "rtc.h" #include "timer.h" #define LED_REFRESH_PERIOD_MS (50) #define LED_PULSE_LENGTH_MS (200) #define ERROR_BLINK_PERIOD_MS (100) #define ERROR_TOTAL_PERIOD_MS (1000) #define CIC_ERROR_BLINKS (1) #define RTC_ERROR_BLINKS (2) static bool activity_pulse = false; static int activity_pulse_timer = 0; static bool cic_error = false; static bool rtc_error = false; static bool error_active = false; static int error_timer = 0; void led_activity_on (void) { rtc_settings_t *settings = rtc_get_settings(); if (!activity_pulse && !error_active && settings->led_enabled) { hw_gpio_set(GPIO_ID_LED); } } void led_activity_off (void) { rtc_settings_t *settings = rtc_get_settings(); if (!activity_pulse && !error_active && settings->led_enabled) { hw_gpio_reset(GPIO_ID_LED); } } void led_activity_pulse (void) { activity_pulse = true; activity_pulse_timer = LED_PULSE_LENGTH_MS; } void led_blink_error (led_error_t error) { switch (error) { case LED_ERROR_CIC: cic_error = true; break; case LED_ERROR_RTC: rtc_error = true; break; } error_active = true; } void led_clear_error (led_error_t error) { switch (error) { case LED_ERROR_CIC: cic_error = false; break; case LED_ERROR_RTC: rtc_error = false; break; } } void led_init (void) { timer_countdown_start(TIMER_ID_LED, LED_REFRESH_PERIOD_MS); } void led_process (void) { if (!timer_countdown_elapsed(TIMER_ID_LED)) { return; } timer_countdown_start(TIMER_ID_LED, LED_REFRESH_PERIOD_MS); if (error_active) { int blinks = 0; if (cic_error) { blinks = CIC_ERROR_BLINKS; } else if (rtc_error) { blinks = RTC_ERROR_BLINKS; } else { activity_pulse = false; activity_pulse_timer = 0; error_active = false; error_timer = 0; hw_gpio_reset(GPIO_ID_LED); return; } bool led_on = false; for (int i = 0; i < blinks; i++) { bool lower_bound = (error_timer >= (ERROR_BLINK_PERIOD_MS * (i * 2))); bool upper_bound = (error_timer < (ERROR_BLINK_PERIOD_MS * ((i * 2) + 1))); if (lower_bound && upper_bound) { led_on = true; break; } } if (led_on) { hw_gpio_set(GPIO_ID_LED); } else { hw_gpio_reset(GPIO_ID_LED); } error_timer += LED_REFRESH_PERIOD_MS; if (error_timer >= ERROR_TOTAL_PERIOD_MS) { error_timer = 0; } return; } if (activity_pulse) { if (activity_pulse_timer > 0) { hw_gpio_set(GPIO_ID_LED); } else { activity_pulse = false; hw_gpio_reset(GPIO_ID_LED); return; } activity_pulse_timer -= LED_REFRESH_PERIOD_MS; } }