diff --git a/Documentation/overview.rst b/Documentation/overview.rst index 159d7450b8df682f4c2939ed9af5f4709a9198e8..26e8baa295b63dd80c98b4550a5421c73aaf458a 100644 --- a/Documentation/overview.rst +++ b/Documentation/overview.rst @@ -29,8 +29,6 @@ number of tasks that will have been keeping card10 running. These are: +--------------------+-------------------------------+----------+-------------------------------------------+ | `vInterruptsTask`_ | ``interrupts_task`` (static) | +2 | Interrupt dispatcher worker | +--------------------+-------------------------------+----------+-------------------------------------------+ -| `vLedTask`_ | -/- | +1 | LED Animations | -+--------------------+-------------------------------+----------+-------------------------------------------+ | `vMAX30001Task`_ | ``max30001_task_id`` (static) | +1 | `MAX30001`_ ECG driver | +--------------------+-------------------------------+----------+-------------------------------------------+ | `vBhi160Task`_ | ``bhi160_task_id`` (static) | +1 | `BHI160`_ sensor fusion driver | diff --git a/epicardium/main.c b/epicardium/main.c index 44c26255aac1848c2d8b1268b12402e28bb6d105..3f0f291fef2158ae869ee6d077e24376877300db 100644 --- a/epicardium/main.c +++ b/epicardium/main.c @@ -172,17 +172,6 @@ int main(void) } } - /* LEDs */ - if (xTaskCreate( - vLedTask, - (const char *)"LED", - configMINIMAL_STACK_SIZE, - NULL, - tskIDLE_PRIORITY + 1, - NULL) != pdPASS) { - panic("Failed to create %s task!", "LED"); - } - /* Lifecycle */ if (xTaskCreate( vLifecycleTask, diff --git a/epicardium/modules/personal_state.c b/epicardium/modules/personal_state.c index 285cb872dd37315bf1bb5fd227e6cab3bd968f74..a2a1730cba4fd4a6b45c1463bad8b7ad8bdfb7f4 100644 --- a/epicardium/modules/personal_state.c +++ b/epicardium/modules/personal_state.c @@ -2,20 +2,36 @@ #include "leds.h" #include "modules.h" +#include "os/work_queue.h" + +#include "FreeRTOS.h" +#include "timers.h" + #include <math.h> -uint8_t _personal_state_enabled = 0; -uint8_t personal_state = STATE_NONE; -uint8_t personal_state_persistent = 0; +static uint8_t _personal_state_enabled = 0; +static uint8_t personal_state = STATE_NONE; +static uint8_t personal_state_persistent = 0; + +static int led_animation_ticks = 0; +static int led_animation_state = 0; -int led_animation_ticks = 0; -int led_animation_state = 0; +static TimerHandle_t led_timer; +static StaticTimer_t led_timer_buffer; +static void worktick(void *data); + +static const int led_animation_rate = 1000 / 25; /* 25Hz -> 40ms*/ int personal_state_enabled() { return _personal_state_enabled; } +static void tick(TimerHandle_t xTimer) +{ + workqueue_schedule(worktick, NULL); +} + int epic_personal_state_set(uint8_t state, bool persistent) { if (state > STATE_CAMP) @@ -30,7 +46,29 @@ int epic_personal_state_set(uint8_t state, bool persistent) _personal_state_enabled = (state != STATE_NONE); personal_state_persistent = persistent; - if (was_enabled && !_personal_state_enabled) { + if (!was_enabled && _personal_state_enabled) { + // Activate + if (!led_timer) { + led_timer = xTimerCreateStatic( + "personal state", + led_animation_rate / portTICK_PERIOD_MS, + pdTRUE, + NULL, + tick, + &led_timer_buffer + ); + // since &poll_timer_buffer is not NULL, xTimerCreateStatic should allways succeed, so + // we don't need to check for poll_timer being NULL. + } + + if (xTimerIsTimerActive(led_timer) == pdFALSE) { + xTimerStart(led_timer, 0); + } + + } else if (was_enabled && !_personal_state_enabled) { + // Deactivate + xTimerStop(led_timer, 0); + // TODO: we might need a lock here to avoid a race condition leds_prep(PERSONAL_STATE_LED, 0, 0, 0); epic_leds_update(); } @@ -48,80 +86,68 @@ int epic_personal_state_is_persistent() return personal_state_persistent; } -void vLedTask(void *pvParameters) +static void worktick(void *data) { - const int led_animation_rate = 1000 / 25; /* 25Hz -> 40ms*/ - while (1) { - if (_personal_state_enabled) { - led_animation_ticks++; - if (personal_state == STATE_NO_CONTACT) { - leds_prep(PERSONAL_STATE_LED, 255, 0, 0); - } else if (personal_state == STATE_CHAOS) { - if (led_animation_state == 0) { - leds_prep( - PERSONAL_STATE_LED, 0, 0, 255 - ); - if (led_animation_ticks > - (200 / led_animation_rate)) { - led_animation_ticks = 0; - led_animation_state = 1; - } - } else if (led_animation_state == 1) { - leds_prep(PERSONAL_STATE_LED, 0, 0, 0); - if (led_animation_ticks > - (300 / led_animation_rate)) { - led_animation_ticks = 0; - led_animation_state = 2; - } - } else if (led_animation_state == 2) { - leds_prep( - PERSONAL_STATE_LED, 0, 0, 255 - ); - if (led_animation_ticks > - (1000 / led_animation_rate)) { - led_animation_ticks = 0; - led_animation_state = 3; - } - } else if (led_animation_state == 3) { - leds_prep(PERSONAL_STATE_LED, 0, 0, 0); - if (led_animation_ticks > - (300 / led_animation_rate)) { - led_animation_ticks = 0; - led_animation_state = 0; - } + if (_personal_state_enabled) { + led_animation_ticks++; + if (personal_state == STATE_NO_CONTACT) { + leds_prep(PERSONAL_STATE_LED, 255, 0, 0); + } else if (personal_state == STATE_CHAOS) { + if (led_animation_state == 0) { + leds_prep(PERSONAL_STATE_LED, 0, 0, 255); + if (led_animation_ticks > + (200 / led_animation_rate)) { + led_animation_ticks = 0; + led_animation_state = 1; + } + } else if (led_animation_state == 1) { + leds_prep(PERSONAL_STATE_LED, 0, 0, 0); + if (led_animation_ticks > + (300 / led_animation_rate)) { + led_animation_ticks = 0; + led_animation_state = 2; } - } else if (personal_state == STATE_COMMUNICATION) { - if (led_animation_state == 0) { - leds_prep( - PERSONAL_STATE_LED, 255, 255, 0 - ); - if (led_animation_ticks > - (1000 / led_animation_rate)) { - led_animation_ticks = 0; - led_animation_state = 1; - } - } else if (led_animation_state == 1) { - leds_prep(PERSONAL_STATE_LED, 0, 0, 0); - if (led_animation_ticks > - (300 / led_animation_rate)) { - led_animation_ticks = 0; - led_animation_state = 0; - } + } else if (led_animation_state == 2) { + leds_prep(PERSONAL_STATE_LED, 0, 0, 255); + if (led_animation_ticks > + (1000 / led_animation_rate)) { + led_animation_ticks = 0; + led_animation_state = 3; + } + } else if (led_animation_state == 3) { + leds_prep(PERSONAL_STATE_LED, 0, 0, 0); + if (led_animation_ticks > + (300 / led_animation_rate)) { + led_animation_ticks = 0; + led_animation_state = 0; } - } else if (personal_state == STATE_CAMP) { - leds_prep_hsv( - PERSONAL_STATE_LED, - 120.0f, - 1.0f, - fabs(sin( - led_animation_ticks / - (float)(1000 / - led_animation_rate)))); } - - epic_leds_update(); + } else if (personal_state == STATE_COMMUNICATION) { + if (led_animation_state == 0) { + leds_prep(PERSONAL_STATE_LED, 255, 255, 0); + if (led_animation_ticks > + (1000 / led_animation_rate)) { + led_animation_ticks = 0; + led_animation_state = 1; + } + } else if (led_animation_state == 1) { + leds_prep(PERSONAL_STATE_LED, 0, 0, 0); + if (led_animation_ticks > + (300 / led_animation_rate)) { + led_animation_ticks = 0; + led_animation_state = 0; + } + } + } else if (personal_state == STATE_CAMP) { + leds_prep_hsv( + PERSONAL_STATE_LED, + 120.0f, + 1.0f, + fabs(sin( + led_animation_ticks / + (float)(1000 / led_animation_rate)))); } - vTaskDelay(led_animation_rate / portTICK_PERIOD_MS); + epic_leds_update(); } }