UveosOnNation_VEGA_UserIndi.../Src/UserIndication.c

361 lines
12 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
* UserIndication.c
*
* Created on: Jun 3, 2021
* Author: zemon
*/
#include "UserIndication.h"
#include <SystemDelayInterface.h>
#include <CmsisRtosThreadUtils.h>
static void UserIndication_SetModeUveos(tUserIndication *env, tEraGlonassUveosStatus mode);
static void UserIndication_OnBoard(tUserIndication *env, uint8_t flags);
static void UserIndication_Update(tUserIndication *env);
static const uint8_t BOARD_OFF = (0);
static const uint8_t BOARD_RED = (0x1 << 0);
static const uint8_t BOARD_GREEN = (0x1 << 1);
static const uint8_t BOARD_BLUE = (0x1 << 2);
uint32_t ttime = 0;
void UserIndication_Init(
tUserIndication *env,
eDeviceModes initMode,
#if USE_POLAR_DEPENDENT_BIP
tIndicationBip *uiuLed,
#else
tBipLed *uiuLed,
#endif
tOnBoardLed *onBoardLed,
tAudioPlayerInterface *audioPlay
) {
env->uiuLed = uiuLed;
env->onBoardLed = onBoardLed;
env->mode = initMode;
UserIndication_Update(env);
env->uveosIndicator.env = env;
env->uveosIndicator.show = (void *) UserIndication_SetModeUveos;
env->audioPlayer = audioPlay;
InitThreadAtrStatic(&env->thread.attr, "Indication", env->thread.controlBlock, env->thread.stack, osPriorityNormal);
env->thread.id = 0;
}
//ограничение воспроизведения одного семпла в 60с, можно увеличить до длительности большего семпла
void UserIndication_SetMode(tUserIndication *env, eDeviceModes mode) {
if (env->mode != mode) {
env->mode = mode;
UserIndication_Update(env);
}
}
#define UVEOS_TO_DEV_MODE(NAME) case UVEOS_STATUS_##NAME: UserIndication_SetMode(env, DEVICE_MODE_UVEOS_##NAME); return;
static void UserIndication_SetModeUveos(tUserIndication *env, tEraGlonassUveosStatus mode) {
switch (mode) {
UVEOS_TO_DEV_MODE(CALL_INITIATE)
UVEOS_TO_DEV_MODE(DIALING)
UVEOS_TO_DEV_MODE(MSD_TRANSMIT)
UVEOS_TO_DEV_MODE(SMS_TRANSMIT)
UVEOS_TO_DEV_MODE(CALL_ACTIVE)
UVEOS_TO_DEV_MODE(CALL_FAILURE)
UVEOS_TO_DEV_MODE(MANUAL_BEGIN)
UVEOS_TO_DEV_MODE(AUTOMATIC_BEGIN)
UVEOS_TO_DEV_MODE(TESTING_BEGIN)
default:
break;
}
}
//лучше использовать конкретные значения UIU_GREEN/UIU_RED/UIU_ORANGE
//одновременное использование через | даст оражевый цвет индикатора БИП в любом случае
void UserIndication_Uiu(tUserIndication *env, uint8_t value) {
#if USE_POLAR_DEPENDENT_BIP
if (value == UIU_GREEN ) {
GpioPinSet(&env->onBoardLed->green, true);
if(env->uiuLed->green.mode == 0){
/// green off
GpioPinSet(&env->uiuLed->green.negativ, false);
GpioPinSet(&env->uiuLed->green.positiv, true);
} else if(env->uiuLed->green.mode == 1) {
/// red off
GpioPinSet(&env->uiuLed->red.negativ, false);
GpioPinSet(&env->uiuLed->red.positiv, true);
/// green on
GpioPinSet(&env->uiuLed->green.negativ, true);
GpioPinSet(&env->uiuLed->green.positiv, false);
}
} else if (value == UIU_RED) {
GpioPinSet(&env->onBoardLed->red, true);
if(env->uiuLed->red.mode == 0){
/// red off
GpioPinSet(&env->uiuLed->red.negativ, false);
GpioPinSet(&env->uiuLed->red.positiv, true);
} else if(env->uiuLed->green.mode == 1) {
/// green off
GpioPinSet(&env->uiuLed->green.negativ, false);
GpioPinSet(&env->uiuLed->green.positiv, true);
/// red on
GpioPinSet(&env->uiuLed->red.negativ, true);
GpioPinSet(&env->uiuLed->red.positiv, false);
}
} else if (value == UIU_OFF) {
GpioPinSet(&env->onBoardLed->green, false);
GpioPinSet(&env->onBoardLed->red, false);
GpioPinSet(&env->onBoardLed->blue, false);
/// green off
GpioPinSet(&env->uiuLed->green.negativ, false);
GpioPinSet(&env->uiuLed->green.positiv, true);
/// red off
GpioPinSet(&env->uiuLed->red.negativ, false);
GpioPinSet(&env->uiuLed->red.positiv, true);
} else if (value == UIU_ORANGE) {
if ((env->uiuLed->red.mode == 0) && (env->uiuLed->green.mode == 0)) {
/// green off
GpioPinSet(&env->uiuLed->green.negativ, false);
GpioPinSet(&env->uiuLed->green.positiv, true);
/// red off
GpioPinSet(&env->uiuLed->red.negativ, false);
GpioPinSet(&env->uiuLed->red.positiv, true);
} else if (env->uiuLed->green.mode == 1) {
/// orange on
GpioPinSet(&env->uiuLed->green.negativ, true);
GpioPinSet(&env->uiuLed->green.positiv, false);
GpioPinSet(&env->uiuLed->red.negativ, true);
GpioPinSet(&env->uiuLed->red.positiv, false);
}
}
#else
if (value == UIU_GREEN ) {
GpioPinSet(&env->onBoardLed->green, true);
GpioPinSet(&env->uiuLed->red, false);
GpioPinSet(&env->uiuLed->green, true);
} else if (value == UIU_RED) {
GpioPinSet(&env->onBoardLed->red, true);
GpioPinSet(&env->uiuLed->green, false);
GpioPinSet(&env->uiuLed->red, true);
} else if (value == UIU_OFF) {
GpioPinSet(&env->onBoardLed->green, false);
GpioPinSet(&env->onBoardLed->red, false);
GpioPinSet(&env->onBoardLed->blue, false);
GpioPinSet(&env->uiuLed->green, false);
GpioPinSet(&env->uiuLed->red, false);
} else if (value == UIU_ORANGE) {
}
#endif
}
void UserIndication_BlinkLed(tUserIndication *env, uint16_t timeOut, uint8_t indicatorFirst) {
uint32_t endMs = SystemGetMs() + timeOut;
while (endMs > SystemGetMs()) {
UserIndication_Uiu(env, indicatorFirst);
}
endMs = SystemGetMs() + timeOut;
while (endMs > SystemGetMs()) {
UserIndication_Uiu(env, UIU_OFF);
}
}
void UserIndication_BlinkLeds(
tUserIndication *env,
uint16_t timeOutFirst,
uint16_t timeOutSecond,
uint8_t indicatorFirst,
uint8_t indicatorSecond
) {
uint32_t endMs = SystemGetMs() + timeOutFirst;
while (endMs > SystemGetMs()) {
UserIndication_Uiu(env, indicatorFirst);
}
endMs = SystemGetMs() + timeOutFirst;
while (endMs > SystemGetMs()) {
UserIndication_Uiu(env, UIU_OFF);
}
endMs = SystemGetMs() + timeOutSecond;
while (endMs > SystemGetMs()) {
UserIndication_Uiu(env, indicatorSecond);
}
endMs = SystemGetMs() + timeOutSecond;
while (endMs > SystemGetMs()) {
UserIndication_Uiu(env, UIU_OFF);
}
}
//можно использовать несколько флагов через | чтобы включит одновремнно разные светодиоды
//например BOARD_GREEN| BOARD_RED включит красный и зеленый светодиоды на блоке
static void UserIndication_OnBoard(tUserIndication *env, uint8_t flags) {
GpioPinSet(&env->onBoardLed->red, flags & BOARD_RED);
GpioPinSet(&env->onBoardLed->green, flags & BOARD_GREEN);
GpioPinSet(&env->onBoardLed->blue, flags & BOARD_BLUE);
}
void UserIndication_UiuError(tUserIndication *env) {
UserIndication_Uiu(env, UIU_RED);
}
tStringStatic eDeviceModesNames[] = {
StringStaticInit("Запуск"),
StringStaticInit("Тестирование"),
StringStaticInit("Ожидание загрузки GSM"),
StringStaticInit("Ошибка памяти"),
StringStaticInit("Ошибка GSM"),
StringStaticInit("Ошибка Кодека"),
StringStaticInit("Обнаружен сбой"),
StringStaticInit("Ошибка начального тестирования 1"),
StringStaticInit("Ошибка начального тестирования 2"),
StringStaticInit("ЭРА (нет ГНСС)"),
StringStaticInit("ЭРА"),
StringStaticInit("Экстренный вызов (подготовка)"),
StringStaticInit("Дозвон"),
StringStaticInit("Отправка МНД"),
StringStaticInit("Отправка SMS"),
StringStaticInit("Голосовое соединение"),
StringStaticInit("Ошибка соединения"),
StringStaticInit("Пассивный режим"),
StringStaticInit("Входящий вызов"),
StringStaticInit("Режим гараж"),
StringStaticInit("Экстренный вызов (ручной)"),
StringStaticInit("Экстренный вызов (автоматический)"),
StringStaticInit("Экстренный вызов (тестовый)"),
StringStaticInit("Зажигание включено, запуск устройства выполнен"),
};
void UserIndicationIgngStarUp(tUserIndication *env) {
bool blink = env->tick > 70000;
uint32_t endMs = SystemGetMs() + 70000;
while (endMs > SystemGetMs()) {
UserIndication_Uiu(env, UIU_RED);
}
UserIndication_Uiu(env, blink ? UIU_RED : UIU_OFF);
UserIndication_OnBoard(env, blink ? (BOARD_RED) : BOARD_OFF);
}
void UserIndicationUpdateLed(tUserIndication *env) {
switch (env->mode) {
case DEVICE_MODE_UVEOS_IGNITION_STATE: {
UserIndicationIgngStarUp(env);
break;
}
case DEVICE_MODE_FAILURE: {
UserIndication_Uiu(env, UIU_RED);
break;
}
case DEVICE_MODE_ERROR_ON_INIT_TEST1: {
UserIndication_Uiu(env, UIU_RED);
break;
}
case DEVICE_MODE_ERROR_ON_INIT_TEST2: {
UserIndication_Uiu(env, UIU_RED);
break;
}
case DEVICE_MODE_UVEOS_CALL_FAILURE: {
UserIndication_BlinkLed(env, 500 ,UIU_RED);
break;
}
case DEVICE_MODE_UVEOS_CALL_INITIATE: {
UserIndication_BlinkLed(env, 1000 ,UIU_GREEN);
break;
}
case DEVICE_MODE_UVEOS_MSD_TRANSMIT: {
UserIndication_BlinkLed(env, 500 ,UIU_GREEN);
break;
}
case DEVICE_MODE_UVEOS_CALL_ACTIVE: {
UserIndication_Uiu(env, UIU_GREEN);
break;
}
case DEVICE_MODE_UVEOS_GARAG: {
UserIndication_BlinkLeds(env, 500, 1500, UIU_GREEN, UIU_RED);
break;
}
case DEVICE_MODE_TESTING: {
UserIndication_BlinkLeds(env, 500, 500, UIU_GREEN, UIU_RED);
break;
}
case DEVICE_MODE_UVEOS_IGN_ON: {
break;
}
default: {
UserIndication_Uiu(env, UIU_OFF);
GpioPinSet(&env->onBoardLed->red, false);
GpioPinSet(&env->onBoardLed->green, false);
GpioPinSet(&env->onBoardLed->blue, false);
break;
}
}
}
static void UserIndication_Update(tUserIndication *env) {
env->currentModeName = StringStaticGetLink(&eDeviceModesNames[env->mode]);
UserIndicationUpdateLed(env);
env->tick = ((env->tick + 1) % 10);
}
static _Noreturn void UserIndication_Thread(tUserIndication *env) {
for (;;) {
UserIndication_Update(env);
SystemDelayMs(100);
}
}
void UserIndication_StartThread(tUserIndication *env) {
if (!env->thread.id) {
env->thread.id = osThreadNew((osThreadFunc_t) (UserIndication_Thread), (void *) (env), &env->thread.attr);
} else {
osThreadResume(env->thread.id);
}
}
void UserIndication_StopThread(tUserIndication *env) {
if (env->thread.id) {
osThreadSuspend(env->thread.id);
}
}