143 lines
2.4 KiB
C++
143 lines
2.4 KiB
C++
#include "Led.hpp"
|
|
|
|
#include "stm.hpp"
|
|
#include "FreeRTOS.h"
|
|
#include "task.h"
|
|
|
|
#if HW_REVISION == 'B'
|
|
|
|
#define LED_STATUS_TASK_STACK_SIZE_WORDS 128
|
|
|
|
extern TIM_HandleTypeDef htim2;
|
|
|
|
enum class Mode {
|
|
Off,
|
|
On,
|
|
Blink,
|
|
Pulsating,
|
|
Error,
|
|
};
|
|
|
|
static Mode mode;
|
|
static uint8_t led_statecnt;
|
|
static int8_t led_ncnt;
|
|
|
|
static StackType_t LedStatusStack[LED_STATUS_TASK_STACK_SIZE_WORDS];
|
|
static StaticTask_t LedStatusCB;
|
|
static xTaskHandle LedStatusHandle = NULL;
|
|
|
|
static uint8_t err_cnt;
|
|
|
|
static void led_set_percentage(uint8_t val) {
|
|
uint16_t compare = val * val / 100;
|
|
TIM2->CCR1 = compare;
|
|
}
|
|
|
|
static void LedStatus(void * const argument) {
|
|
UNUSED(argument);
|
|
while (1) {
|
|
if (led_statecnt < 199) {
|
|
led_statecnt++;
|
|
} else {
|
|
led_statecnt = 0;
|
|
}
|
|
switch (mode) {
|
|
case Mode::Off:
|
|
led_set_percentage(0);
|
|
vTaskSuspend(NULL);
|
|
break;
|
|
case Mode::On:
|
|
led_set_percentage(100);
|
|
vTaskSuspend(NULL);
|
|
break;
|
|
case Mode::Error:
|
|
if (led_statecnt == 0) {
|
|
err_cnt++;
|
|
if (err_cnt > led_ncnt) {
|
|
// reached number of blinks + 1
|
|
err_cnt = 0;
|
|
}
|
|
}
|
|
if (err_cnt >= led_ncnt) {
|
|
break;
|
|
}
|
|
// fall through
|
|
/* no break */
|
|
case Mode::Blink:
|
|
if(led_statecnt < 100) {
|
|
led_set_percentage(100);
|
|
} else {
|
|
led_set_percentage(0);
|
|
}
|
|
break;
|
|
case Mode::Pulsating:
|
|
if (led_statecnt < 100) {
|
|
led_set_percentage(led_statecnt);
|
|
} else {
|
|
led_set_percentage(200 - led_statecnt);
|
|
}
|
|
break;
|
|
}
|
|
vTaskDelay(5);
|
|
}
|
|
}
|
|
#endif
|
|
|
|
void LED::Init() {
|
|
#if HW_REVISION == 'B'
|
|
led_ncnt = 0;
|
|
mode = Mode::Off;
|
|
HAL_TIM_Base_Start(&htim2);
|
|
HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_1);
|
|
|
|
LedStatusHandle = xTaskCreateStatic(LedStatus, "LedStatusTask", LED_STATUS_TASK_STACK_SIZE_WORDS,
|
|
NULL, 6, LedStatusStack, &LedStatusCB);
|
|
|
|
vTaskSuspend(LedStatusHandle);
|
|
#endif
|
|
}
|
|
|
|
void LED::Pulsating() {
|
|
#if HW_REVISION == 'B'
|
|
if(led_ncnt) {
|
|
return;
|
|
}
|
|
vTaskSuspend(LedStatusHandle);
|
|
mode = Mode::Pulsating;
|
|
vTaskResume(LedStatusHandle);
|
|
#endif
|
|
}
|
|
|
|
void LED::Off() {
|
|
#if HW_REVISION == 'B'
|
|
if(led_ncnt) {
|
|
return;
|
|
}
|
|
vTaskSuspend(LedStatusHandle);
|
|
mode = Mode::Off;
|
|
vTaskResume(LedStatusHandle);
|
|
#endif
|
|
}
|
|
|
|
void LED::Error(uint8_t code) {
|
|
#if HW_REVISION == 'B'
|
|
if(led_ncnt) {
|
|
return;
|
|
}
|
|
vTaskSuspend(LedStatusHandle);
|
|
mode = Mode::Error;
|
|
led_statecnt = 0;
|
|
err_cnt = 0;
|
|
led_ncnt = code;
|
|
vTaskResume(LedStatusHandle);
|
|
#endif
|
|
}
|
|
|
|
void LED::On() {
|
|
GPIOA->BSRR = GPIO_PIN_15;
|
|
}
|
|
|
|
void LED::Toggle() {
|
|
GPIOA->ODR ^= GPIO_PIN_15;
|
|
}
|