reworked the indicator engine to better support patterns

sipo
Ondřej Hruška 7 years ago
parent c19b185b06
commit 83a01aa1bc
Signed by: MightyPork
GPG Key ID: 2C5FD5035250423D
  1. 1
      USB/usbd_storage_if.c
  2. 4
      cortex_handlers.c
  3. 4
      gex_hooks.c
  4. 3
      platform/lock_jumper.c
  5. 2
      platform/plat_init.c
  6. 116
      platform/status_led.c
  7. 35
      platform/status_led.h
  8. 2
      stm32_assert.c
  9. 2
      tasks/task_main.c
  10. 4
      vfs/file_stream.c

@ -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) {

@ -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);
} }

@ -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");

@ -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...");

@ -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 ...");

@ -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();
}
} }
/** Set indicator OFF */ active_effect = indicator;
void StatusLed_Off(enum GEX_StatusIndicator indicator) effect_time = 0;
{
indicators[indicator] = 0;
// TODO some effect
} }
/** Set or reset a indicator */ void Indicator_Off(enum GEX_StatusIndicator indicator)
void StatusLed_Set(enum GEX_StatusIndicator indicator, bool set)
{ {
if (set) { if (active_effect == indicator) {
StatusLed_On(indicator); led_off();
} else { active_effect = STATUS_NONE;
StatusLed_Off(indicator); indicator_idle_ms = 0;
} }
} }
/** Turn indicator ON for a given interval */ /** Millisecond tick */
void StatusLed_Flash(enum GEX_StatusIndicator indicator, uint32_t ms) void Indicator_Tick(void)
{ {
indicators[indicator] = ms; if (active_effect == STATUS_NONE) {
// TODO 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);
}
} }
/** Millisecond tick */ if (active_effect != STATUS_NONE) {
void StatusLed_Tick(void) indicator_idle_ms = 0;
{
for (uint32_t i = 0; i < _INDICATOR_COUNT; i++) { if (active_effect == STATUS_HEARTBEAT) {
if (indicators[i] != osWaitForever && indicators[i] != 0) { if (effect_time == 0) led_on();
if (--indicators[i]) { else if (effect_time == 50) {
StatusLed_Off((enum GEX_StatusIndicator) i); 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
} }

@ -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

@ -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);
} }

@ -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...

@ -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;

Loading…
Cancel
Save