361 lines
12 KiB
C
361 lines
12 KiB
C
/*
|
||
* 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);
|
||
}
|
||
}
|