This commit is contained in:
cfif 2024-12-04 13:10:47 +03:00
commit 775aed10fb
3 changed files with 522 additions and 0 deletions

145
Inc/UserIndication.h Normal file
View File

@ -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 <cmsis_os.h>
#include <BaseTypes.h>
#include <GpioPinInterface.h>
#include <EraGlonassUveos_Indicatior.h>
#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_ */

360
Src/UserIndication.c Normal file
View File

@ -0,0 +1,360 @@
/*
* 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);
}
}

17
modular.json Normal file
View File

@ -0,0 +1,17 @@
{
"dep": [
{
"type": "git",
"provider": "NAVIGATOR_UVEOS_NATION_TELIT",
"repo": "GpioPinInterface"
}
],
"cmake": {
"inc_dirs": [
"Inc"
],
"srcs": [
"Src/**.c"
]
}
}