From 775aed10fb710addeacd347984c82ad7090c66a4 Mon Sep 17 00:00:00 2001 From: cfif Date: Wed, 4 Dec 2024 13:10:47 +0300 Subject: [PATCH] Init --- Inc/UserIndication.h | 145 +++++++++++++++++ Src/UserIndication.c | 360 +++++++++++++++++++++++++++++++++++++++++++ modular.json | 17 ++ 3 files changed, 522 insertions(+) create mode 100644 Inc/UserIndication.h create mode 100644 Src/UserIndication.c create mode 100644 modular.json diff --git a/Inc/UserIndication.h b/Inc/UserIndication.h new file mode 100644 index 0000000..a81b344 --- /dev/null +++ b/Inc/UserIndication.h @@ -0,0 +1,145 @@ +/* + * UserIndication.h + * + * Created on: Oct 29, 2022 + * Author: xemon + */ + +#ifndef USER_INDICATION_INC_USERINDICATION_H_ +#define USER_INDICATION_INC_USERINDICATION_H_ + + + +#include +#include +#include +#include +#include "AudioPlayerInterface.h" + +#define USE_POLAR_DEPENDENT_BIP 1 + +#if USE_POLAR_DEPENDENT_BIP + typedef struct { + tGpioPin positiv; + tGpioPin negativ; + uint8_t mode; + } tRedLed; + + typedef struct { + tGpioPin positiv; + tGpioPin negativ; + uint8_t mode; + } tGreenLed; + + typedef struct { + tRedLed green; + tGreenLed red; + bool switchUILedMode; + } tIndicationBip; +#else + typedef struct { + tGpioPin red; + tGpioPin green; + } tBipLed; +#endif + + +typedef struct { + tGpioPin red; + tGpioPin green; + tGpioPin blue; +} tOnBoardLed; + +typedef enum { + DEVICE_MODE_STARTUP = 0, + DEVICE_MODE_TESTING = 1, + DEVICE_MODE_WAIT_GSM_BOOT = 2, + + DEVICE_MODE_ERROR_FLASH = 3, + DEVICE_MODE_ERROR_GSM = 4, + DEVICE_MODE_ERROR_CODEC = 5, + DEVICE_MODE_FAILURE = 6, + DEVICE_MODE_ERROR_ON_INIT_TEST1 = 7, + DEVICE_MODE_ERROR_ON_INIT_TEST2 = 8, + + DEVICE_MODE_UVEOS_ERA_WAIT_GNSS = 9, + DEVICE_MODE_UVEOS_ERA_GNSS_READY = 10, + + DEVICE_MODE_UVEOS_CALL_INITIATE = 11, + DEVICE_MODE_UVEOS_DIALING = 12, + DEVICE_MODE_UVEOS_MSD_TRANSMIT = 13, + DEVICE_MODE_UVEOS_SMS_TRANSMIT = 14, + DEVICE_MODE_UVEOS_CALL_ACTIVE = 15, + DEVICE_MODE_UVEOS_CALL_FAILURE = 16, + + DEVICE_MODE_UVEOS_PASSIVE = 17, + DEVICE_MODE_UVEOS_IN_CALL = 18, + + DEVICE_MODE_UVEOS_GARAG = 19, + + DEVICE_MODE_UVEOS_MANUAL_BEGIN = 20, + DEVICE_MODE_UVEOS_AUTOMATIC_BEGIN = 21, + DEVICE_MODE_UVEOS_TESTING_BEGIN = 22, + DEVICE_MODE_UVEOS_IGNITION_STATE = 22, + DEVICE_MODE_UVEOS_IGN_ON = 23, + +} eDeviceModes; + + +typedef struct { +#if USE_POLAR_DEPENDENT_BIP + tIndicationBip *uiuLed; //User Interface Unit (Блок интерфейса пользователя/БИП) +#else + tBipLed *uiuLed; //User Interface Unit (Блок интерфейса пользователя/БИП) +#endif + + tOnBoardLed *onBoardLed; + + eDeviceModes mode; + tStringLink currentModeName; + + tEraGlonassUveosIndicator uveosIndicator; + + uint16_t tick; + uint16_t ledRedMode; + uint16_t ledGreenMode; + tAudioPlayerInterface *audioPlayer; + + struct { + osThreadId_t id; + uint32_t stack[128]; + StaticTask_t controlBlock; + osThreadAttr_t attr; + } thread; +} tUserIndication; + + +void UserIndication_Init( + tUserIndication *env, + eDeviceModes initMode, +#if USE_POLAR_DEPENDENT_BIP + tIndicationBip *uiuLed, +#else + tBipLed *uiuLed, +#endif + tOnBoardLed *onBoardLed, + tAudioPlayerInterface *audioPlayer +); + +void UserIndication_SetMode(tUserIndication *env, eDeviceModes mode); + +void UserIndication_StartThread(tUserIndication *env); + +void UserIndication_StopThread(tUserIndication *env); + +static const uint8_t UIU_OFF = (0); +static const uint8_t UIU_RED = (0x1 << 0); +static const uint8_t UIU_GREEN = (0x1 << 1); +static const uint8_t UIU_START_SIGNAL = (0x1 << 2); +static const uint8_t UIU_ORANGE = UIU_GREEN | UIU_RED; + +void UserIndication_Uiu(tUserIndication *env, uint8_t value); + +void UserIndicationDevStarUp(tUserIndication *env); + +#endif /* USER_INDICATION_INC_USERINDICATION_H_ */ diff --git a/Src/UserIndication.c b/Src/UserIndication.c new file mode 100644 index 0000000..80663c6 --- /dev/null +++ b/Src/UserIndication.c @@ -0,0 +1,360 @@ +/* + * 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); + } +} diff --git a/modular.json b/modular.json new file mode 100644 index 0000000..2d9116b --- /dev/null +++ b/modular.json @@ -0,0 +1,17 @@ +{ + "dep": [ + { + "type": "git", + "provider": "NAVIGATOR_UVEOS_NATION_TELIT", + "repo": "GpioPinInterface" + } + ], + "cmake": { + "inc_dirs": [ + "Inc" + ], + "srcs": [ + "Src/**.c" + ] + } +} \ No newline at end of file