mirror of
https://github.com/yoboujon/dumber.git
synced 2025-06-08 05:40:49 +02:00
524 lines
19 KiB
C
524 lines
19 KiB
C
/**
|
|
******************************************************************************
|
|
* @file leds.c
|
|
* @brief leds driver body
|
|
* @author S. DI MERCURIO (dimercur@insa-toulouse.fr)
|
|
* @date December 2023
|
|
*
|
|
******************************************************************************
|
|
* @copyright Copyright 2023 INSA-GEI, Toulouse, France. All rights reserved.
|
|
* @copyright This project is released under the Lesser GNU Public License (LGPL-3.0-only).
|
|
*
|
|
* @copyright This file is part of "Dumber" project
|
|
*
|
|
* @copyright This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
* License as published by the Free Software Foundation; either
|
|
* version 3 of the License, or (at your option) any later version.
|
|
*
|
|
* @copyright This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* Lesser General Public License for more details.
|
|
|
|
* @copyright You should have received a copy of the GNU Lesser General Public License
|
|
* along with this program; if not, write to the Free Software Foundation,
|
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
*
|
|
******************************************************************************
|
|
*/
|
|
#include "leds.h"
|
|
|
|
/** @addtogroup Application_Software
|
|
* @{
|
|
*/
|
|
|
|
/** @addtogroup LEDS
|
|
* Leds handler is in charge of leds animation.
|
|
*
|
|
* Leds module consiste of two threads:
|
|
* - \ref LEDS_HandlerThread in charge of waiting for message in mailbox from application. Depending of the message received, animation is started, modified or stop
|
|
* - \ref LEDS_ActionThread, periodic task in charge of animating leds with configured sprites for given animation
|
|
* @{
|
|
*/
|
|
|
|
/** @addtogroup LEDS_Private Private
|
|
* @{
|
|
*/
|
|
|
|
/** @name Macro for switching ON and OFF individual led segments
|
|
*
|
|
*/
|
|
///@{
|
|
#define LEDS_On_Seg_A() HAL_GPIO_WritePin(LED_SEG_A_GPIO_Port, LED_SEG_A_Pin, GPIO_PIN_SET)
|
|
#define LEDS_On_Seg_B() HAL_GPIO_WritePin(LED_SEG_B_GPIO_Port, LED_SEG_B_Pin, GPIO_PIN_SET)
|
|
#define LEDS_On_Seg_C() HAL_GPIO_WritePin(LED_SEG_C_GPIO_Port, LED_SEG_C_Pin, GPIO_PIN_SET)
|
|
#define LEDS_On_Seg_D() HAL_GPIO_WritePin(LED_SEG_D_GPIO_Port, LED_SEG_D_Pin, GPIO_PIN_SET)
|
|
#define LEDS_On_Seg_E() HAL_GPIO_WritePin(LED_SEG_E_GPIO_Port, LED_SEG_E_Pin, GPIO_PIN_SET)
|
|
#define LEDS_On_Seg_F() HAL_GPIO_WritePin(LED_SEG_F_GPIO_Port, LED_SEG_F_Pin, GPIO_PIN_SET)
|
|
#define LEDS_On_Seg_G() HAL_GPIO_WritePin(LED_SEG_G_GPIO_Port, LED_SEG_G_Pin, GPIO_PIN_SET)
|
|
#define LEDS_On_Seg_DP() HAL_GPIO_WritePin(LED_SEG_DP_GPIO_Port, LED_SEG_DP_Pin, GPIO_PIN_SET)
|
|
|
|
#define LEDS_Off_Seg_A() HAL_GPIO_WritePin(LED_SEG_A_GPIO_Port, LED_SEG_A_Pin, GPIO_PIN_RESET)
|
|
#define LEDS_Off_Seg_B() HAL_GPIO_WritePin(LED_SEG_B_GPIO_Port, LED_SEG_B_Pin, GPIO_PIN_RESET)
|
|
#define LEDS_Off_Seg_C() HAL_GPIO_WritePin(LED_SEG_C_GPIO_Port, LED_SEG_C_Pin, GPIO_PIN_RESET)
|
|
#define LEDS_Off_Seg_D() HAL_GPIO_WritePin(LED_SEG_D_GPIO_Port, LED_SEG_D_Pin, GPIO_PIN_RESET)
|
|
#define LEDS_Off_Seg_E() HAL_GPIO_WritePin(LED_SEG_E_GPIO_Port, LED_SEG_E_Pin, GPIO_PIN_RESET)
|
|
#define LEDS_Off_Seg_F() HAL_GPIO_WritePin(LED_SEG_F_GPIO_Port, LED_SEG_F_Pin, GPIO_PIN_RESET)
|
|
#define LEDS_Off_Seg_G() HAL_GPIO_WritePin(LED_SEG_G_GPIO_Port, LED_SEG_G_Pin, GPIO_PIN_RESET)
|
|
#define LEDS_Off_Seg_DP() HAL_GPIO_WritePin(LED_SEG_DP_GPIO_Port, LED_SEG_DP_Pin, GPIO_PIN_RESET)
|
|
///@}
|
|
|
|
/** @name Macro for switching all display ON or OFF
|
|
*
|
|
*/
|
|
///@{
|
|
#define LEDS_All_Off() HAL_GPIO_WritePin(GPIOB, LED_SEG_A_Pin|LED_SEG_B_Pin|LED_SEG_C_Pin, GPIO_PIN_RESET);\
|
|
HAL_GPIO_WritePin(GPIOA, LED_SEG_D_Pin|LED_SEG_E_Pin|LED_SEG_F_Pin|LED_SEG_G_Pin|LED_SEG_DP_Pin, GPIO_PIN_RESET)
|
|
|
|
#define LEDS_All_On() HAL_GPIO_WritePin(GPIOB, LED_SEG_A_Pin|LED_SEG_B_Pin|LED_SEG_C_Pin, GPIO_PIN_SET);\
|
|
HAL_GPIO_WritePin(GPIOA, LED_SEG_D_Pin|LED_SEG_E_Pin|LED_SEG_F_Pin|LED_SEG_G_Pin|LED_SEG_DP_Pin, GPIO_PIN_SET)
|
|
///@}
|
|
|
|
/** @name List of single sprite (pattern) in animation
|
|
*
|
|
*/
|
|
///@{
|
|
#define LED_PATTERN_ALL_OFF 0
|
|
#define LED_PATTERN_BAT_SPRITE_0 1
|
|
#define LED_PATTERN_BAT_SPRITE_1 2
|
|
#define LED_PATTERN_BAT_SPRITE_2 3
|
|
#define LED_PATTERN_BAT_SPRITE_3 4
|
|
#define LED_PATTERN_IDLE_0 5
|
|
#define LED_PATTERN_IDLE_1 6
|
|
#define LED_PATTERN_RUN_0 7
|
|
#define LED_PATTERN_RUN_1 8
|
|
#define LED_PATTERN_RUN_2 9
|
|
#define LED_PATTERN_RUN_3 10
|
|
#define LED_PATTERN_RUN_4 11
|
|
#define LED_PATTERN_RUN_5 12
|
|
#define LED_PATTERN_RUN_WITH_WATCHDOG_0 13
|
|
#define LED_PATTERN_RUN_WITH_WATCHDOG_1 14
|
|
#define LED_PATTERN_RUN_WITH_WATCHDOG_2 15
|
|
#define LED_PATTERN_RUN_WITH_WATCHDOG_3 16
|
|
#define LED_PATTERN_RUN_WITH_WATCHDOG_4 17
|
|
#define LED_PATTERN_RUN_WITH_WATCHDOG_5 18
|
|
#define LED_PATTERN_ERROR 19
|
|
#define LED_PATTERN_BATTERY 20
|
|
#define LED_PATTERN_DIGIT_0 21
|
|
#define LED_PATTERN_DIGIT_1 22
|
|
#define LED_PATTERN_DIGIT_2 23
|
|
#define LED_PATTERN_DIGIT_3 24
|
|
#define LED_PATTERN_DIGIT_4 25
|
|
#define LED_PATTERN_DIGIT_5 26
|
|
#define LED_PATTERN_DIGIT_6 27
|
|
#define LED_PATTERN_DIGIT_7 28
|
|
#define LED_PATTERN_DIGIT_8 29
|
|
#define LED_PATTERN_DIGIT_9 30
|
|
#define LED_PATTERN_DIGIT_C 31
|
|
#define LED_PATTERN_DIGIT_L 32
|
|
#define LED_PATTERN_DIGIT_B 33
|
|
#define LED_PATTERN_WDT_EXP_1 34
|
|
#define LED_PATTERN_WDT_EXP_2 35
|
|
#define LED_PATTERN_DIGIT_UNKNOWN 36
|
|
|
|
#define LED_MAX_PATTERNS 37
|
|
///@}
|
|
|
|
/*
|
|
* Relation entre segment et nom
|
|
*
|
|
* Avant du robot
|
|
*
|
|
*
|
|
* D
|
|
* -----
|
|
* | |
|
|
* C | | E
|
|
* | G |
|
|
* -----
|
|
* | |
|
|
* B | | F
|
|
* | |
|
|
* -----
|
|
* A
|
|
*
|
|
*
|
|
* Arriere du robot
|
|
*
|
|
*/
|
|
|
|
/** @brief Constant array defining led configuration for all possible sprites used in animation
|
|
*
|
|
*/
|
|
uint16_t LEDS_Patterns [LED_MAX_PATTERNS][4]= {
|
|
// GPIOA ON / GPIOB ON / GPIOA OFF / GPIOB OFF
|
|
{ 0, 0, LED_SEG_D_Pin|LED_SEG_E_Pin|LED_SEG_F_Pin|LED_SEG_G_Pin|LED_SEG_DP_Pin, LED_SEG_A_Pin|LED_SEG_B_Pin|LED_SEG_C_Pin}, // All Off
|
|
{ 0, 0, LED_SEG_D_Pin|LED_SEG_E_Pin|LED_SEG_F_Pin|LED_SEG_G_Pin|LED_SEG_DP_Pin, LED_SEG_A_Pin|LED_SEG_B_Pin|LED_SEG_C_Pin}, // Bat sprite 0
|
|
{ 0, LED_SEG_A_Pin, LED_SEG_D_Pin|LED_SEG_E_Pin|LED_SEG_F_Pin|LED_SEG_G_Pin|LED_SEG_DP_Pin, LED_SEG_B_Pin|LED_SEG_C_Pin}, // Bat sprite 1
|
|
{ LED_SEG_G_Pin, LED_SEG_A_Pin, LED_SEG_D_Pin|LED_SEG_E_Pin|LED_SEG_F_Pin|LED_SEG_DP_Pin, LED_SEG_B_Pin|LED_SEG_C_Pin}, // Bat sprite 2
|
|
{ LED_SEG_D_Pin|LED_SEG_G_Pin, LED_SEG_A_Pin, LED_SEG_E_Pin|LED_SEG_F_Pin|LED_SEG_DP_Pin, LED_SEG_B_Pin|LED_SEG_C_Pin}, // Bat sprite 3
|
|
{ 0, 0, LED_SEG_D_Pin|LED_SEG_E_Pin|LED_SEG_F_Pin|LED_SEG_G_Pin|LED_SEG_DP_Pin, LED_SEG_A_Pin|LED_SEG_B_Pin|LED_SEG_C_Pin}, // Idle 0
|
|
{ LED_SEG_DP_Pin, 0, LED_SEG_D_Pin|LED_SEG_E_Pin|LED_SEG_F_Pin|LED_SEG_G_Pin, LED_SEG_A_Pin|LED_SEG_B_Pin|LED_SEG_C_Pin}, // Idle 1
|
|
{ LED_SEG_D_Pin, 0, LED_SEG_E_Pin|LED_SEG_F_Pin|LED_SEG_G_Pin|LED_SEG_DP_Pin, LED_SEG_A_Pin|LED_SEG_B_Pin|LED_SEG_C_Pin}, // Run 0
|
|
{ LED_SEG_E_Pin, 0, LED_SEG_D_Pin|LED_SEG_F_Pin|LED_SEG_G_Pin|LED_SEG_DP_Pin, LED_SEG_A_Pin|LED_SEG_B_Pin|LED_SEG_C_Pin}, // Run 1
|
|
{ LED_SEG_F_Pin, 0, LED_SEG_D_Pin|LED_SEG_E_Pin|LED_SEG_G_Pin|LED_SEG_DP_Pin, LED_SEG_A_Pin|LED_SEG_B_Pin|LED_SEG_C_Pin}, // Run 2
|
|
{ 0, LED_SEG_A_Pin, LED_SEG_D_Pin|LED_SEG_E_Pin|LED_SEG_F_Pin|LED_SEG_G_Pin|LED_SEG_DP_Pin, LED_SEG_B_Pin|LED_SEG_C_Pin}, // Run 3
|
|
{ 0, LED_SEG_B_Pin, LED_SEG_D_Pin|LED_SEG_E_Pin|LED_SEG_F_Pin|LED_SEG_G_Pin|LED_SEG_DP_Pin, LED_SEG_A_Pin|LED_SEG_C_Pin}, // Run 4
|
|
{ 0, LED_SEG_C_Pin, LED_SEG_D_Pin|LED_SEG_E_Pin|LED_SEG_F_Pin|LED_SEG_G_Pin|LED_SEG_DP_Pin, LED_SEG_A_Pin|LED_SEG_B_Pin}, // Run 5
|
|
{ LED_SEG_D_Pin|LED_SEG_DP_Pin, 0, LED_SEG_E_Pin|LED_SEG_F_Pin|LED_SEG_G_Pin, LED_SEG_A_Pin|LED_SEG_B_Pin|LED_SEG_C_Pin}, // Run with watchdog 0
|
|
{ LED_SEG_E_Pin, 0, LED_SEG_D_Pin|LED_SEG_F_Pin|LED_SEG_G_Pin|LED_SEG_DP_Pin, LED_SEG_A_Pin|LED_SEG_B_Pin|LED_SEG_C_Pin}, // Run with watchdog 1
|
|
{ LED_SEG_F_Pin|LED_SEG_DP_Pin, 0, LED_SEG_D_Pin|LED_SEG_E_Pin|LED_SEG_G_Pin, LED_SEG_A_Pin|LED_SEG_B_Pin|LED_SEG_C_Pin}, // Run with watchdog 2
|
|
{ 0, LED_SEG_A_Pin, LED_SEG_D_Pin|LED_SEG_E_Pin|LED_SEG_F_Pin|LED_SEG_G_Pin|LED_SEG_DP_Pin, LED_SEG_B_Pin|LED_SEG_C_Pin}, // Run with watchdog 3
|
|
{ LED_SEG_DP_Pin, LED_SEG_B_Pin, LED_SEG_D_Pin|LED_SEG_E_Pin|LED_SEG_F_Pin|LED_SEG_G_Pin, LED_SEG_A_Pin|LED_SEG_C_Pin}, // Run with watchdog 4
|
|
{ 0, LED_SEG_C_Pin, LED_SEG_D_Pin|LED_SEG_E_Pin|LED_SEG_F_Pin|LED_SEG_G_Pin|LED_SEG_DP_Pin, LED_SEG_A_Pin|LED_SEG_B_Pin}, // Run with watchdog 5
|
|
{ LED_SEG_D_Pin|LED_SEG_G_Pin, LED_SEG_A_Pin|LED_SEG_B_Pin|LED_SEG_C_Pin, LED_SEG_E_Pin|LED_SEG_F_Pin|LED_SEG_DP_Pin, 0}, // Error
|
|
{ LED_SEG_F_Pin|LED_SEG_G_Pin, LED_SEG_A_Pin|LED_SEG_B_Pin|LED_SEG_C_Pin, LED_SEG_D_Pin|LED_SEG_E_Pin|LED_SEG_DP_Pin, 0}, // Battery
|
|
{ LED_SEG_D_Pin|LED_SEG_E_Pin|LED_SEG_F_Pin, LED_SEG_A_Pin|LED_SEG_B_Pin|LED_SEG_C_Pin, LED_SEG_G_Pin|LED_SEG_DP_Pin, 0}, // 0
|
|
{ LED_SEG_E_Pin|LED_SEG_F_Pin, 0, LED_SEG_D_Pin|LED_SEG_G_Pin|LED_SEG_DP_Pin, LED_SEG_A_Pin|LED_SEG_B_Pin|LED_SEG_C_Pin}, // 1
|
|
{ LED_SEG_D_Pin|LED_SEG_E_Pin|LED_SEG_G_Pin, LED_SEG_A_Pin|LED_SEG_B_Pin, LED_SEG_F_Pin|LED_SEG_DP_Pin, LED_SEG_C_Pin}, // 2
|
|
{ LED_SEG_D_Pin|LED_SEG_E_Pin|LED_SEG_F_Pin|LED_SEG_G_Pin, LED_SEG_A_Pin, LED_SEG_DP_Pin, LED_SEG_B_Pin|LED_SEG_C_Pin}, // 3
|
|
{ LED_SEG_E_Pin|LED_SEG_F_Pin|LED_SEG_G_Pin, LED_SEG_C_Pin, LED_SEG_D_Pin|LED_SEG_DP_Pin, LED_SEG_A_Pin|LED_SEG_B_Pin}, // 4
|
|
{ LED_SEG_D_Pin|LED_SEG_F_Pin|LED_SEG_G_Pin, LED_SEG_A_Pin|LED_SEG_C_Pin, LED_SEG_E_Pin|LED_SEG_DP_Pin, LED_SEG_B_Pin}, // 5
|
|
{ LED_SEG_D_Pin|LED_SEG_F_Pin|LED_SEG_G_Pin, LED_SEG_A_Pin|LED_SEG_B_Pin|LED_SEG_C_Pin, LED_SEG_E_Pin|LED_SEG_DP_Pin}, // 6
|
|
{ LED_SEG_D_Pin|LED_SEG_E_Pin|LED_SEG_F_Pin, 0, LED_SEG_G_Pin|LED_SEG_DP_Pin, LED_SEG_A_Pin|LED_SEG_B_Pin|LED_SEG_C_Pin}, // 7
|
|
{ LED_SEG_D_Pin|LED_SEG_E_Pin|LED_SEG_F_Pin|LED_SEG_G_Pin, LED_SEG_A_Pin|LED_SEG_B_Pin|LED_SEG_C_Pin, LED_SEG_DP_Pin, 0}, // 8
|
|
{ LED_SEG_D_Pin|LED_SEG_E_Pin|LED_SEG_F_Pin|LED_SEG_G_Pin, LED_SEG_A_Pin|LED_SEG_C_Pin, LED_SEG_DP_Pin, LED_SEG_B_Pin}, // 9
|
|
{ LED_SEG_D_Pin, LED_SEG_A_Pin|LED_SEG_B_Pin|LED_SEG_C_Pin, LED_SEG_E_Pin|LED_SEG_F_Pin|LED_SEG_G_Pin|LED_SEG_DP_Pin, 0}, // C
|
|
{ 0, LED_SEG_A_Pin|LED_SEG_B_Pin|LED_SEG_C_Pin, LED_SEG_D_Pin|LED_SEG_E_Pin|LED_SEG_F_Pin|LED_SEG_G_Pin|LED_SEG_DP_Pin, 0},// L
|
|
{ LED_SEG_F_Pin|LED_SEG_G_Pin, LED_SEG_A_Pin|LED_SEG_B_Pin|LED_SEG_C_Pin, LED_SEG_D_Pin|LED_SEG_E_Pin|LED_SEG_DP_Pin, 0}, // b
|
|
{ LED_SEG_E_Pin, LED_SEG_B_Pin, LED_SEG_D_Pin|LED_SEG_F_Pin|LED_SEG_G_Pin|LED_SEG_DP_Pin, LED_SEG_A_Pin|LED_SEG_C_Pin}, // Watchdog expired 1
|
|
{ LED_SEG_F_Pin, LED_SEG_C_Pin, LED_SEG_D_Pin|LED_SEG_E_Pin|LED_SEG_G_Pin|LED_SEG_DP_Pin, LED_SEG_A_Pin|LED_SEG_B_Pin}, // Watchdog expired 2
|
|
{ LED_SEG_D_Pin|LED_SEG_E_Pin|LED_SEG_G_Pin, LED_SEG_B_Pin, LED_SEG_F_Pin|LED_SEG_DP_Pin, LED_SEG_A_Pin|LED_SEG_C_Pin} // ?
|
|
};
|
|
|
|
LEDS_State LEDS_Animation;
|
|
LEDS_State LEDS_AnimationAncien;
|
|
|
|
StaticTask_t xTaskLedsHandler;
|
|
|
|
/* Buffer that the task being created will use as its stack. Note this is
|
|
an array of StackType_t variables. The size of StackType_t is dependent on
|
|
the RTOS port. */
|
|
StackType_t xStackLedsHandler[ STACK_SIZE ];
|
|
TaskHandle_t xHandleLedsHandler = NULL;
|
|
|
|
StaticTask_t xTaskLedsAction;
|
|
|
|
/* Buffer that the task being created will use as its stack. Note this is
|
|
an array of StackType_t variables. The size of StackType_t is dependent on
|
|
the RTOS port. */
|
|
StackType_t xStackLedsAction[ STACK_SIZE ];
|
|
TaskHandle_t xHandleLedsAction = NULL;
|
|
|
|
void LEDS_ActionThread(void* params);
|
|
void LEDS_ShowPattern(uint8_t pattern);
|
|
void LEDS_Tests(void* params);
|
|
void LEDS_HandlerThread(void* params);
|
|
|
|
/**
|
|
* @brief Function for initializing leds animation
|
|
*
|
|
* @param None
|
|
* @retval None
|
|
*/
|
|
void LEDS_Init(void) {
|
|
LEDS_All_Off();
|
|
|
|
LEDS_Animation=leds_off;
|
|
LEDS_AnimationAncien =LEDS_Animation;
|
|
|
|
/* Mailbox is created in messages.c */
|
|
|
|
/* Create the task without using any dynamic memory allocation. */
|
|
xHandleLedsHandler = xTaskCreateStatic(
|
|
LEDS_HandlerThread, /* Function that implements the task. */
|
|
"LEDS Handler", /* Text name for the task. */
|
|
STACK_SIZE, /* Number of indexes in the xStack array. */
|
|
NULL, /* Parameter passed into the task. */
|
|
PriorityLedsHandler,/* Priority at which the task is created. */
|
|
xStackLedsHandler, /* Array to use as the task's stack. */
|
|
&xTaskLedsHandler); /* Variable to hold the task's data structure. */
|
|
|
|
vTaskResume(xHandleLedsHandler);
|
|
}
|
|
|
|
/**
|
|
* @brief Request an animation, given in parameter
|
|
*
|
|
* @remark This function wrap a message sending to leds mailbox.
|
|
* If multiple module request animation, only the laste requested animation will be taken into account
|
|
*
|
|
* @param[in] state Led animation requested
|
|
* @retval None
|
|
*/
|
|
void LEDS_Set(LEDS_State state) {
|
|
static LEDS_State leds_state;
|
|
|
|
if ((state>=leds_off) && (state <=leds_state_unknown)) {
|
|
leds_state = state;
|
|
MESSAGE_SendMailbox(LEDS_Mailbox, MSG_ID_LED_ETAT,
|
|
(QueueHandle_t)0x0, (void*) &leds_state);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @brief Apply a pattern to led
|
|
*
|
|
* @param[in] pattern Pattern to show, defined in \ref LEDS_Patterns. Use macro starting with LED_PATTERN_ as parameter
|
|
* @retval None
|
|
*/
|
|
void LEDS_ShowPattern(uint8_t pattern) {
|
|
if (pattern < LED_MAX_PATTERNS) {
|
|
HAL_GPIO_WritePin(GPIOA, LEDS_Patterns[pattern][2], GPIO_PIN_RESET);
|
|
HAL_GPIO_WritePin(GPIOB, LEDS_Patterns[pattern][3], GPIO_PIN_RESET);
|
|
|
|
if (LEDS_Patterns[pattern][0] + LEDS_Patterns[pattern][1]!=0) {
|
|
HAL_GPIO_WritePin(GPIOA, LEDS_Patterns[pattern][0], GPIO_PIN_SET);
|
|
HAL_GPIO_WritePin(GPIOB, LEDS_Patterns[pattern][1], GPIO_PIN_SET);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @brief Test task for checking animation correctness
|
|
*
|
|
* @warning Do not use in normal running condition
|
|
*
|
|
* @param[in] params Initial task parameters
|
|
* @retval None
|
|
*/
|
|
void LEDS_Tests(void* params) {
|
|
LEDS_State ledState = leds_idle;
|
|
|
|
LEDS_All_Off();
|
|
|
|
while (1) {
|
|
MESSAGE_SendMailbox(LEDS_Mailbox, MSG_ID_LED_ETAT, LEDS_Mailbox, (void*)&ledState);
|
|
vTaskDelay(pdMS_TO_TICKS(5000)); // wait 10s
|
|
|
|
ledState++;
|
|
if (ledState>leds_state_unknown) ledState=leds_idle;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @brief Message handler task
|
|
*
|
|
* Get received animation message from application and start, stop or modify animation depending on animation requested
|
|
* by controlling \ref LEDS_ActionThread task.
|
|
* If requested animation is same of currently running, no modification is done.
|
|
*
|
|
* @param[in] params Initial task parameters
|
|
* @retval None
|
|
*/
|
|
void LEDS_HandlerThread(void* params) {
|
|
MESSAGE_Typedef msg;
|
|
|
|
while (1) {
|
|
|
|
msg = MESSAGE_ReadMailbox(LEDS_Mailbox);
|
|
|
|
if (msg.id == MSG_ID_LED_ETAT) { // Si c'est bien un message de changement d'etat LEDS
|
|
LEDS_Animation = *((LEDS_State*)msg.data);
|
|
|
|
if (LEDS_Animation != LEDS_AnimationAncien) { // si le nouvel etat est different de l'ancien
|
|
// dans ce cas, on eteint les leds pour repartir sur une base saine
|
|
LEDS_AnimationAncien = LEDS_Animation;
|
|
|
|
/* If action task is running, destroy it first */
|
|
if (xHandleLedsAction!= NULL) vTaskDelete(xHandleLedsAction);
|
|
|
|
/* Create the task without using any dynamic memory allocation. */
|
|
xHandleLedsAction = xTaskCreateStatic(
|
|
LEDS_ActionThread, /* Function that implements the task. */
|
|
"LEDS Action", /* Text name for the task. */
|
|
STACK_SIZE, /* Number of indexes in the xStack array. */
|
|
NULL, /* Parameter passed into the task. */
|
|
PriorityLedsAction,/* Priority at which the task is created. */
|
|
xStackLedsAction, /* Array to use as the task's stack. */
|
|
&xTaskLedsAction); /* Variable to hold the task's data structure. */
|
|
|
|
vTaskResume(xHandleLedsAction);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @brief Animation task
|
|
*
|
|
* Periodic task (100 ms) used for animating led. Started and stopped from \ref LEDS_HandlerThread
|
|
*
|
|
* @param[in] params Initial task parameters
|
|
* @retval None
|
|
*/
|
|
void LEDS_ActionThread(void* params) {
|
|
uint8_t cnt=0;
|
|
TickType_t xLastWakeTime;
|
|
|
|
// Initialise the xLastWakeTime variable with the current time.
|
|
xLastWakeTime = xTaskGetTickCount();
|
|
|
|
LEDS_All_Off();
|
|
|
|
while (1) {
|
|
|
|
switch (LEDS_Animation) {
|
|
case leds_off:
|
|
LEDS_All_Off();
|
|
break;
|
|
case leds_idle:
|
|
if (cnt<5)
|
|
LEDS_ShowPattern(LED_PATTERN_IDLE_1);
|
|
else if (cnt<10)
|
|
LEDS_ShowPattern(LED_PATTERN_IDLE_0);
|
|
else
|
|
cnt=0;
|
|
break;
|
|
case leds_run:
|
|
if (cnt>5) cnt=0;
|
|
LEDS_ShowPattern(LED_PATTERN_RUN_0+cnt);
|
|
break;
|
|
case leds_run_with_watchdog:
|
|
if (cnt>5) cnt=0;
|
|
LEDS_ShowPattern(LED_PATTERN_RUN_WITH_WATCHDOG_0+cnt);
|
|
break;
|
|
case leds_bat_critical_low:
|
|
if (cnt<3)
|
|
LEDS_ShowPattern(LED_PATTERN_DIGIT_C);
|
|
else if (cnt<6)
|
|
LEDS_ShowPattern(LED_PATTERN_DIGIT_L);
|
|
else if (cnt <9)
|
|
LEDS_ShowPattern(LED_PATTERN_DIGIT_B);
|
|
else if (cnt <12)
|
|
LEDS_ShowPattern(LED_PATTERN_ALL_OFF);
|
|
else
|
|
cnt=0;
|
|
break;
|
|
case leds_bat_low:
|
|
if (!(cnt%2))
|
|
LEDS_ShowPattern(LED_PATTERN_BAT_SPRITE_1);
|
|
else
|
|
LEDS_ShowPattern(LED_PATTERN_ALL_OFF);
|
|
break;
|
|
case leds_bat_med:
|
|
if (cnt<3)
|
|
LEDS_ShowPattern(LED_PATTERN_BAT_SPRITE_1);
|
|
else if (cnt<6)
|
|
LEDS_ShowPattern(LED_PATTERN_BAT_SPRITE_2);
|
|
else
|
|
cnt=0;
|
|
break;
|
|
case leds_bat_high:
|
|
if (cnt<3)
|
|
LEDS_ShowPattern(LED_PATTERN_BAT_SPRITE_1);
|
|
else if (cnt<6)
|
|
LEDS_ShowPattern(LED_PATTERN_BAT_SPRITE_2);
|
|
else if (cnt <9)
|
|
LEDS_ShowPattern(LED_PATTERN_BAT_SPRITE_3);
|
|
else
|
|
cnt=3;
|
|
break;
|
|
case leds_bat_charge_low:
|
|
if (cnt<3)
|
|
LEDS_ShowPattern(LED_PATTERN_BAT_SPRITE_1);
|
|
else if (cnt<6)
|
|
LEDS_ShowPattern(LED_PATTERN_BAT_SPRITE_2);
|
|
else if (cnt<9)
|
|
LEDS_ShowPattern(LED_PATTERN_BAT_SPRITE_3);
|
|
else if (cnt<12)
|
|
LEDS_ShowPattern(LED_PATTERN_ALL_OFF);
|
|
else
|
|
cnt=0;
|
|
break;
|
|
case leds_bat_charge_med:
|
|
if (cnt<3)
|
|
LEDS_ShowPattern(LED_PATTERN_BAT_SPRITE_2);
|
|
else if (cnt<6)
|
|
LEDS_ShowPattern(LED_PATTERN_BAT_SPRITE_3);
|
|
else if (cnt <9)
|
|
LEDS_ShowPattern(LED_PATTERN_BAT_SPRITE_1);
|
|
else
|
|
cnt=0;
|
|
break;
|
|
case leds_bat_charge_high:
|
|
if (cnt<3)
|
|
LEDS_ShowPattern(LED_PATTERN_BAT_SPRITE_3);
|
|
else if (cnt<6)
|
|
LEDS_ShowPattern(LED_PATTERN_BAT_SPRITE_2);
|
|
else
|
|
cnt=0;
|
|
break;
|
|
case leds_bat_charge_complete:
|
|
LEDS_ShowPattern(LED_PATTERN_BAT_SPRITE_3);
|
|
|
|
cnt=0;
|
|
break;
|
|
case leds_watchdog_expired:
|
|
if (cnt<4)
|
|
LEDS_ShowPattern(LED_PATTERN_WDT_EXP_1);
|
|
else if (cnt<7)
|
|
LEDS_ShowPattern(LED_PATTERN_WDT_EXP_2);
|
|
else
|
|
cnt=0;
|
|
break;
|
|
case leds_error_1:
|
|
if (cnt<5)
|
|
LEDS_ShowPattern(LED_PATTERN_ERROR);
|
|
else if (cnt<10)
|
|
LEDS_ShowPattern(LED_PATTERN_DIGIT_1);
|
|
else
|
|
cnt=0;
|
|
break;
|
|
case leds_error_2:
|
|
if (cnt<5)
|
|
LEDS_ShowPattern(LED_PATTERN_ERROR);
|
|
else if (cnt<10)
|
|
LEDS_ShowPattern(LED_PATTERN_DIGIT_2);
|
|
else
|
|
cnt=0;
|
|
break;
|
|
case leds_error_3:
|
|
if (cnt<5)
|
|
LEDS_ShowPattern(LED_PATTERN_ERROR);
|
|
else if (cnt<10)
|
|
LEDS_ShowPattern(LED_PATTERN_DIGIT_3);
|
|
else
|
|
cnt=0;
|
|
break;
|
|
case leds_error_4:
|
|
if (cnt<5)
|
|
LEDS_ShowPattern(LED_PATTERN_ERROR);
|
|
else if (cnt<10)
|
|
LEDS_ShowPattern(LED_PATTERN_DIGIT_4);
|
|
else
|
|
cnt=0;
|
|
break;
|
|
case leds_error_5:
|
|
if (cnt<5)
|
|
LEDS_ShowPattern(LED_PATTERN_ERROR);
|
|
else if (cnt<10)
|
|
LEDS_ShowPattern(LED_PATTERN_DIGIT_5);
|
|
else
|
|
cnt=0;
|
|
break;
|
|
case leds_state_unknown:
|
|
if (cnt<3)
|
|
LEDS_ShowPattern(LED_PATTERN_DIGIT_UNKNOWN);
|
|
else if (cnt<10)
|
|
LEDS_ShowPattern(LED_PATTERN_ALL_OFF);
|
|
else
|
|
cnt=0;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
// Wait for the next cycle.
|
|
vTaskDelayUntil( &xLastWakeTime, pdMS_TO_TICKS(LEDS_DELAY));
|
|
|
|
cnt++;
|
|
}
|
|
}
|
|
|