From 83a01aa1bcaf35afdec636ee358c81b3f5b22a2c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Hru=C5=A1ka?= Date: Tue, 2 Jan 2018 12:06:22 +0100 Subject: [PATCH] reworked the indicator engine to better support patterns --- USB/usbd_storage_if.c | 1 - cortex_handlers.c | 4 +- gex_hooks.c | 4 +- platform/lock_jumper.c | 3 ++ platform/plat_init.c | 2 +- platform/status_led.c | 118 ++++++++++++++++++++++++++++------------- platform/status_led.h | 35 ++++-------- stm32_assert.c | 2 +- tasks/task_main.c | 2 +- vfs/file_stream.c | 4 +- 10 files changed, 104 insertions(+), 71 deletions(-) diff --git a/USB/usbd_storage_if.c b/USB/usbd_storage_if.c index a5bf599..57286f8 100644 --- a/USB/usbd_storage_if.c +++ b/USB/usbd_storage_if.c @@ -223,7 +223,6 @@ int8_t STORAGE_IsReady_FS (uint8_t lun) { /* USER CODE BEGIN 4 */ // dbg("STORAGE_IsReady_FS? %d", vfs_info.MediaReady); - StatusLed_Set(STATUS_DISK_ATTACHED, vfs_info.MediaReady); // Media change - no re-plug if (vfs_info.MediaChanged) { diff --git a/cortex_handlers.c b/cortex_handlers.c index 752dcb4..edc0e8e 100644 --- a/cortex_handlers.c +++ b/cortex_handlers.c @@ -29,7 +29,7 @@ void vApplicationStackOverflowHook(TaskHandle_t xTask, signed char *pcTaskName) configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook function is called if a stack overflow is detected. */ PRINTF(tFAULT" RTOS stack overflow! tsk: %s\r\n", (char *) pcTaskName); - StatusLed_On(STATUS_FAULT); + Indicator_Effect(STATUS_FAULT); stackmon_dump(); while (1); @@ -178,7 +178,7 @@ void __attribute__((naked)) HardFault_Handler(void) #endif PRINTF(tFAULT" HARD FAULT\r\n\r\n"); - StatusLed_On(STATUS_FAULT); + Indicator_Effect(STATUS_FAULT); while (1); } diff --git a/gex_hooks.c b/gex_hooks.c index bc5d4ec..8712475 100644 --- a/gex_hooks.c +++ b/gex_hooks.c @@ -16,7 +16,7 @@ void GEX_MsTick(void) { TF_Tick(comm); - StatusLed_Tick(); + Indicator_Tick(); } /** @@ -35,7 +35,7 @@ void GEX_PreInit(void) __HAL_RCC_GPIOF_CLK_ENABLE(); #endif - StatusLed_PreInit(); + Indicator_PreInit(); DebugUart_PreInit(); dbg("\r\n\033[37;1m*** GEX "GEX_VERSION" on "GEX_PLATFORM" ***\033[m"); diff --git a/platform/lock_jumper.c b/platform/lock_jumper.c index fb2b41a..da09cd6 100644 --- a/platform/lock_jumper.c +++ b/platform/lock_jumper.c @@ -12,6 +12,7 @@ #include "framework/system_settings.h" #include "pin_utils.h" #include "lock_jumper.h" +#include "status_led.h" static bool LockJumper_ReadPin(void); @@ -61,9 +62,11 @@ static void jumper_changed(void) if (SystemSettings.editable) { // Unlock dbg("LOCK removed, enabling MSC!"); + Indicator_Effect(STATUS_DISK_ATTACHED); } else { // Lock dbg("LOCK replaced, disabling MSC!"); + Indicator_Effect(STATUS_DISK_REMOVED); if (SystemSettings.modified) { dbg("Saving settings to Flash..."); diff --git a/platform/plat_init.c b/platform/plat_init.c index 18fbbda..d6b5034 100644 --- a/platform/plat_init.c +++ b/platform/plat_init.c @@ -22,7 +22,7 @@ void plat_init(void) plat_init_resources(); // also registers unit drivers LockJumper_Init(); - StatusLed_Init(); + Indicator_Init(); DebugUart_Init(); // <- only the resource claim dbg("Loading settings ..."); diff --git a/platform/status_led.c b/platform/status_led.c index 5322ed6..7cdd9a8 100644 --- a/platform/status_led.c +++ b/platform/status_led.c @@ -7,13 +7,22 @@ #include "status_led.h" #include "pin_utils.h" -static uint32_t indicators[_INDICATOR_COUNT]; - static GPIO_TypeDef *led_periph; static uint32_t led_llpin; +static uint32_t active_effect = STATUS_NONE; +static uint32_t effect_time = 0; + +// counter of idle ticks since last indicator +// used to allow or disallow heartbeat blink (to avoid interference) +static uint32_t indicator_idle_ms = 0; +#define IDLE_FOR_HEARTBEAT_MS 2500 +#define HB_MAX_SAFE_IVAL 500 + +static uint32_t hb_elapsed = 0; + /** Early init */ -void StatusLed_PreInit(void) +void Indicator_PreInit(void) { bool suc = true; // Resolve pin @@ -28,8 +37,18 @@ void StatusLed_PreInit(void) assert_param(suc); } +static inline void led_on(void) +{ + LL_GPIO_SetOutputPin(led_periph, led_llpin); +} + +static inline void led_off(void) +{ + LL_GPIO_ResetOutputPin(led_periph, led_llpin); +} + /** Set up the LED */ -void StatusLed_Init(void) +void Indicator_Init(void) { bool suc = true; @@ -42,55 +61,82 @@ void StatusLed_Init(void) } /** Set indicator ON */ -void StatusLed_On(enum GEX_StatusIndicator indicator) +void Indicator_Effect(enum GEX_StatusIndicator indicator) { - indicators[indicator] = osWaitForever; - if (indicator == STATUS_FAULT) { - // Persistent light - LL_GPIO_SetOutputPin(led_periph, led_llpin); + // Persistent light - start immediately + led_on(); } -} -/** Set indicator OFF */ -void StatusLed_Off(enum GEX_StatusIndicator indicator) -{ - indicators[indicator] = 0; - // TODO some effect + active_effect = indicator; + effect_time = 0; } -/** Set or reset a indicator */ -void StatusLed_Set(enum GEX_StatusIndicator indicator, bool set) +void Indicator_Off(enum GEX_StatusIndicator indicator) { - if (set) { - StatusLed_On(indicator); - } else { - StatusLed_Off(indicator); + if (active_effect == indicator) { + led_off(); + active_effect = STATUS_NONE; + indicator_idle_ms = 0; } } -/** Turn indicator ON for a given interval */ -void StatusLed_Flash(enum GEX_StatusIndicator indicator, uint32_t ms) -{ - indicators[indicator] = ms; - // TODO -} - /** Millisecond tick */ -void StatusLed_Tick(void) +void Indicator_Tick(void) { - for (uint32_t i = 0; i < _INDICATOR_COUNT; i++) { - if (indicators[i] != osWaitForever && indicators[i] != 0) { - if (--indicators[i]) { - StatusLed_Off((enum GEX_StatusIndicator) i); + if (active_effect == STATUS_NONE) { + indicator_idle_ms++; + + if (hb_elapsed < HB_MAX_SAFE_IVAL && indicator_idle_ms > IDLE_FOR_HEARTBEAT_MS && + (indicator_idle_ms % 10 == 0)) { + Indicator_Effect(STATUS_HEARTBEAT); + } + } + + if (active_effect != STATUS_NONE) { + indicator_idle_ms = 0; + + if (active_effect == STATUS_HEARTBEAT) { + if (effect_time == 0) led_on(); + else if (effect_time == 50) { + led_off(); + active_effect = STATUS_NONE; } } + else if (active_effect == STATUS_DISK_ATTACHED) { + if (effect_time == 0) led_on(); + else if (effect_time == 100) led_off(); + else if (effect_time == 200) led_on(); + else if (effect_time == 700) { + led_off(); + active_effect = STATUS_NONE; + } + } + else if (active_effect == STATUS_DISK_REMOVED) { + if (effect_time == 0) led_on(); + else if (effect_time == 500) led_off(); + else if (effect_time == 600) led_on(); + else if (effect_time == 700) { + led_off(); + active_effect = STATUS_NONE; + } + } + else if (active_effect == STATUS_DISK_BUSY) { + if (effect_time == 600) { + led_off(); + active_effect = STATUS_NONE; + } + else if (effect_time % 200 == 0) led_on(); + else if (effect_time % 200 == 100) led_off(); + } + + effect_time++; } } /** Heartbeat callback from the main thread */ -void StatusLed_Heartbeat(void) +void Indicator_Heartbeat(void) { - // TODO fixme - LL_GPIO_TogglePin(led_periph, led_llpin); + hb_elapsed = 0; + // this is called every ~ 100 ms from the main loop } diff --git a/platform/status_led.h b/platform/status_led.h index 6635df6..a8e4b99 100644 --- a/platform/status_led.h +++ b/platform/status_led.h @@ -11,62 +11,47 @@ * Indicator (LED or blinking pattern) */ enum GEX_StatusIndicator { - STATUS_FAULT = 0, - STATUS_USB_CONN, - STATUS_USB_ACTIVITY, + STATUS_NONE = 0, + STATUS_FAULT, STATUS_DISK_BUSY, STATUS_DISK_ATTACHED, + STATUS_DISK_REMOVED, + STATUS_HEARTBEAT, _INDICATOR_COUNT }; /** * Early init */ -void StatusLed_PreInit(void); +void Indicator_PreInit(void); /** * Initialize the statis LED(s) */ -void StatusLed_Init(void); +void Indicator_Init(void); /** * Set indicator ON * * @param indicator */ -void StatusLed_On(enum GEX_StatusIndicator indicator); +void Indicator_Effect(enum GEX_StatusIndicator indicator); /** * Set indicator OFF * * @param indicator */ -void StatusLed_Off(enum GEX_StatusIndicator indicator); - -/** - * Indicator set or reset - * - * @param indicator - * @param set - */ -void StatusLed_Set(enum GEX_StatusIndicator indicator, bool set); - -/** - * Turn indicator ON for a given interval - * - * @param indicator - * @param ms - time ON in ms - */ -void StatusLed_Flash(enum GEX_StatusIndicator indicator, uint32_t ms); +void Indicator_Off(enum GEX_StatusIndicator indicator); /** * Ms tick for indicators */ -void StatusLed_Tick(void); +void Indicator_Tick(void); /** * Heartbeat callback from the main thread to indicate activity */ -void StatusLed_Heartbeat(void); +void Indicator_Heartbeat(void); #endif //GEX_INDICATORS_H diff --git a/stm32_assert.c b/stm32_assert.c index 8b58d74..6cfcdff 100644 --- a/stm32_assert.c +++ b/stm32_assert.c @@ -11,7 +11,7 @@ void __attribute__((noreturn)) abort_msg(const char *msg, const char *filename, { dbg("\r\n\033[31m%s:\033[m %s:%"PRIu32, msg, filename, line); vPortEnterCritical(); - StatusLed_On(STATUS_FAULT); + Indicator_Effect(STATUS_FAULT); while(1); } diff --git a/tasks/task_main.c b/tasks/task_main.c index d84db31..f280d82 100644 --- a/tasks/task_main.c +++ b/tasks/task_main.c @@ -44,7 +44,7 @@ void TaskMain(void const * argument) startTime = now; cnt++; - if (cnt%5==0) StatusLed_Heartbeat(); + Indicator_Heartbeat(); } // if no message and it just timed out, go wait some more... diff --git a/vfs/file_stream.c b/vfs/file_stream.c index d375934..a33ece2 100644 --- a/vfs/file_stream.c +++ b/vfs/file_stream.c @@ -112,7 +112,7 @@ error_t stream_open(stream_type_t stream_type) return E_INTERNAL; } - StatusLed_On(STATUS_DISK_BUSY); + Indicator_Effect(STATUS_DISK_BUSY); // TODO create a thread...? // Initialize all variables @@ -178,7 +178,7 @@ error_t stream_close(void) // set only if stream_open has been called // stream_thread_assert(); // ??? // Close stream - StatusLed_Off(STATUS_DISK_BUSY); + Indicator_Off(STATUS_DISK_BUSY); status = current_stream->close(&shared_state); stream_state = STREAM_STATE_CLOSED; return status;