/* * UserIndication.c * * Created on: Jun 3, 2021 * Author: zemon */ #include "UserIndication.h" #include #include 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); } }