reworked the indicator engine to better support patterns

This commit is contained in:
2018-01-02 12:06:22 +01:00
parent c19b185b06
commit 83a01aa1bc
10 changed files with 105 additions and 72 deletions
-1
View File
@@ -223,7 +223,6 @@ int8_t STORAGE_IsReady_FS (uint8_t lun)
{ {
/* USER CODE BEGIN 4 */ /* USER CODE BEGIN 4 */
// dbg("STORAGE_IsReady_FS? %d", vfs_info.MediaReady); // dbg("STORAGE_IsReady_FS? %d", vfs_info.MediaReady);
StatusLed_Set(STATUS_DISK_ATTACHED, vfs_info.MediaReady);
// Media change - no re-plug // Media change - no re-plug
if (vfs_info.MediaChanged) { if (vfs_info.MediaChanged) {
+2 -2
View File
@@ -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 configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook function is
called if a stack overflow is detected. */ called if a stack overflow is detected. */
PRINTF(tFAULT" RTOS stack overflow! tsk: %s\r\n", (char *) pcTaskName); PRINTF(tFAULT" RTOS stack overflow! tsk: %s\r\n", (char *) pcTaskName);
StatusLed_On(STATUS_FAULT); Indicator_Effect(STATUS_FAULT);
stackmon_dump(); stackmon_dump();
while (1); while (1);
@@ -178,7 +178,7 @@ void __attribute__((naked)) HardFault_Handler(void)
#endif #endif
PRINTF(tFAULT" HARD FAULT\r\n\r\n"); PRINTF(tFAULT" HARD FAULT\r\n\r\n");
StatusLed_On(STATUS_FAULT); Indicator_Effect(STATUS_FAULT);
while (1); while (1);
} }
+2 -2
View File
@@ -16,7 +16,7 @@
void GEX_MsTick(void) void GEX_MsTick(void)
{ {
TF_Tick(comm); TF_Tick(comm);
StatusLed_Tick(); Indicator_Tick();
} }
/** /**
@@ -35,7 +35,7 @@ void GEX_PreInit(void)
__HAL_RCC_GPIOF_CLK_ENABLE(); __HAL_RCC_GPIOF_CLK_ENABLE();
#endif #endif
StatusLed_PreInit(); Indicator_PreInit();
DebugUart_PreInit(); DebugUart_PreInit();
dbg("\r\n\033[37;1m*** GEX "GEX_VERSION" on "GEX_PLATFORM" ***\033[m"); dbg("\r\n\033[37;1m*** GEX "GEX_VERSION" on "GEX_PLATFORM" ***\033[m");
+3
View File
@@ -12,6 +12,7 @@
#include "framework/system_settings.h" #include "framework/system_settings.h"
#include "pin_utils.h" #include "pin_utils.h"
#include "lock_jumper.h" #include "lock_jumper.h"
#include "status_led.h"
static bool LockJumper_ReadPin(void); static bool LockJumper_ReadPin(void);
@@ -61,9 +62,11 @@ static void jumper_changed(void)
if (SystemSettings.editable) { if (SystemSettings.editable) {
// Unlock // Unlock
dbg("LOCK removed, enabling MSC!"); dbg("LOCK removed, enabling MSC!");
Indicator_Effect(STATUS_DISK_ATTACHED);
} else { } else {
// Lock // Lock
dbg("LOCK replaced, disabling MSC!"); dbg("LOCK replaced, disabling MSC!");
Indicator_Effect(STATUS_DISK_REMOVED);
if (SystemSettings.modified) { if (SystemSettings.modified) {
dbg("Saving settings to Flash..."); dbg("Saving settings to Flash...");
+1 -1
View File
@@ -22,7 +22,7 @@ void plat_init(void)
plat_init_resources(); // also registers unit drivers plat_init_resources(); // also registers unit drivers
LockJumper_Init(); LockJumper_Init();
StatusLed_Init(); Indicator_Init();
DebugUart_Init(); // <- only the resource claim DebugUart_Init(); // <- only the resource claim
dbg("Loading settings ..."); dbg("Loading settings ...");
+83 -37
View File
@@ -7,13 +7,22 @@
#include "status_led.h" #include "status_led.h"
#include "pin_utils.h" #include "pin_utils.h"
static uint32_t indicators[_INDICATOR_COUNT];
static GPIO_TypeDef *led_periph; static GPIO_TypeDef *led_periph;
static uint32_t led_llpin; 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 */ /** Early init */
void StatusLed_PreInit(void) void Indicator_PreInit(void)
{ {
bool suc = true; bool suc = true;
// Resolve pin // Resolve pin
@@ -28,8 +37,18 @@ void StatusLed_PreInit(void)
assert_param(suc); 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 */ /** Set up the LED */
void StatusLed_Init(void) void Indicator_Init(void)
{ {
bool suc = true; bool suc = true;
@@ -42,55 +61,82 @@ void StatusLed_Init(void)
} }
/** Set indicator ON */ /** Set indicator ON */
void StatusLed_On(enum GEX_StatusIndicator indicator) void Indicator_Effect(enum GEX_StatusIndicator indicator)
{ {
indicators[indicator] = osWaitForever;
if (indicator == STATUS_FAULT) { if (indicator == STATUS_FAULT) {
// Persistent light // Persistent light - start immediately
LL_GPIO_SetOutputPin(led_periph, led_llpin); led_on();
} }
active_effect = indicator;
effect_time = 0;
} }
/** Set indicator OFF */ void Indicator_Off(enum GEX_StatusIndicator indicator)
void StatusLed_Off(enum GEX_StatusIndicator indicator)
{ {
indicators[indicator] = 0; if (active_effect == indicator) {
// TODO some effect led_off();
} active_effect = STATUS_NONE;
indicator_idle_ms = 0;
/** Set or reset a indicator */
void StatusLed_Set(enum GEX_StatusIndicator indicator, bool set)
{
if (set) {
StatusLed_On(indicator);
} else {
StatusLed_Off(indicator);
} }
} }
/** Turn indicator ON for a given interval */
void StatusLed_Flash(enum GEX_StatusIndicator indicator, uint32_t ms)
{
indicators[indicator] = ms;
// TODO
}
/** Millisecond tick */ /** Millisecond tick */
void StatusLed_Tick(void) void Indicator_Tick(void)
{ {
for (uint32_t i = 0; i < _INDICATOR_COUNT; i++) { if (active_effect == STATUS_NONE) {
if (indicators[i] != osWaitForever && indicators[i] != 0) { indicator_idle_ms++;
if (--indicators[i]) {
StatusLed_Off((enum GEX_StatusIndicator) i); 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 */ /** Heartbeat callback from the main thread */
void StatusLed_Heartbeat(void) void Indicator_Heartbeat(void)
{ {
// TODO fixme hb_elapsed = 0;
LL_GPIO_TogglePin(led_periph, led_llpin); // this is called every ~ 100 ms from the main loop
} }
+10 -25
View File
@@ -11,62 +11,47 @@
* Indicator (LED or blinking pattern) * Indicator (LED or blinking pattern)
*/ */
enum GEX_StatusIndicator { enum GEX_StatusIndicator {
STATUS_FAULT = 0, STATUS_NONE = 0,
STATUS_USB_CONN, STATUS_FAULT,
STATUS_USB_ACTIVITY,
STATUS_DISK_BUSY, STATUS_DISK_BUSY,
STATUS_DISK_ATTACHED, STATUS_DISK_ATTACHED,
STATUS_DISK_REMOVED,
STATUS_HEARTBEAT,
_INDICATOR_COUNT _INDICATOR_COUNT
}; };
/** /**
* Early init * Early init
*/ */
void StatusLed_PreInit(void); void Indicator_PreInit(void);
/** /**
* Initialize the statis LED(s) * Initialize the statis LED(s)
*/ */
void StatusLed_Init(void); void Indicator_Init(void);
/** /**
* Set indicator ON * Set indicator ON
* *
* @param indicator * @param indicator
*/ */
void StatusLed_On(enum GEX_StatusIndicator indicator); void Indicator_Effect(enum GEX_StatusIndicator indicator);
/** /**
* Set indicator OFF * Set indicator OFF
* *
* @param indicator * @param indicator
*/ */
void StatusLed_Off(enum GEX_StatusIndicator indicator); void Indicator_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);
/** /**
* Ms tick for indicators * Ms tick for indicators
*/ */
void StatusLed_Tick(void); void Indicator_Tick(void);
/** /**
* Heartbeat callback from the main thread to indicate activity * Heartbeat callback from the main thread to indicate activity
*/ */
void StatusLed_Heartbeat(void); void Indicator_Heartbeat(void);
#endif //GEX_INDICATORS_H #endif //GEX_INDICATORS_H
+1 -1
View File
@@ -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); dbg("\r\n\033[31m%s:\033[m %s:%"PRIu32, msg, filename, line);
vPortEnterCritical(); vPortEnterCritical();
StatusLed_On(STATUS_FAULT); Indicator_Effect(STATUS_FAULT);
while(1); while(1);
} }
+1 -1
View File
@@ -44,7 +44,7 @@ void TaskMain(void const * argument)
startTime = now; startTime = now;
cnt++; cnt++;
if (cnt%5==0) StatusLed_Heartbeat(); Indicator_Heartbeat();
} }
// if no message and it just timed out, go wait some more... // if no message and it just timed out, go wait some more...
+2 -2
View File
@@ -112,7 +112,7 @@ error_t stream_open(stream_type_t stream_type)
return E_INTERNAL; return E_INTERNAL;
} }
StatusLed_On(STATUS_DISK_BUSY); Indicator_Effect(STATUS_DISK_BUSY);
// TODO create a thread...? // TODO create a thread...?
// Initialize all variables // Initialize all variables
@@ -178,7 +178,7 @@ error_t stream_close(void)
// set only if stream_open has been called // set only if stream_open has been called
// stream_thread_assert(); // ??? // stream_thread_assert(); // ???
// Close stream // Close stream
StatusLed_Off(STATUS_DISK_BUSY); Indicator_Off(STATUS_DISK_BUSY);
status = current_stream->close(&shared_state); status = current_stream->close(&shared_state);
stream_state = STREAM_STATE_CLOSED; stream_state = STREAM_STATE_CLOSED;
return status; return status;