// // Created by villuton on 01.09.2025. // #include "Indication.h" #include "SystemDelayInterface.h" /** * Инициализация паттерна индикации * В случае, если режим предполагает постоянное положения пина индикации * Выставляется флаг permanent и большее время для соответствующего состояния * @param *ptr tMod * @param timeOn uint32_t Время включенного состояния * @param timeOff uint32_t Время выключенного состояния * @param permanent bool Флаг неизменяемости состояния */ static void lIndication_ModInit(tMod *ptr, uint32_t timeOn, uint32_t timeOff, bool permanent) { ptr->timer = 0; ptr->timeOn = timeOn; ptr->timeOff = timeOff; ptr->isPermanent = permanent; ptr->pinFlag = false; if (permanent != false) { if (timeOn > timeOff) { ptr->pinFlag = true; } else { ptr->pinFlag = false; } } } /** * Функция индикации светодиода, в соответствии с каналом, * выставленном на нем режимом и таймером индикации * @param *ptr tMod * @param iterationMs uint32_t * @param *ledPin tGpioPin */ static void lIndication_ModSet(tMod *ptr, uint32_t iterationMs, tGpioPin *ledPin) { ///Если установлен перманентный режим работы if (ptr->isPermanent) { GpioPinSet(ledPin, ptr->pinFlag); return; } ///Если таймер истек ///Изменить флаг, выставляемый на пин светодиода ///Переустановить таймер, в зависимости от предыдущего установленного таймера if (ptr->timer < iterationMs) { ptr->pinFlag = !ptr->pinFlag; ptr->timer = ptr->pinFlag != false ? ptr->timer = iterationMs + ptr->timeOn : iterationMs + ptr->timeOff; } ///Если вышеперечисленные условия не выполнились, выставить пин светодиода, в соответствии с флагом GpioPinSet(ledPin, ptr->pinFlag); } /** * Функция потока индикации * @param *env tIndication */ static _Noreturn void Indication_Thread(tIndication *env) { for (;;) { env->iterationMs = SystemGetMs(); for (uint8_t i = CHRG_Ch1; i <= INDICATION_CHANEL_NUM; i++) { lIndication_ModSet(&env->mod[env->chanel[i]], env->iterationMs, &env->ledPins->tab[i]); } SystemDelayMs(INDICATION_THREAD_DELAY_MS); } } /** * Инициализация модуля индикации * @param *env tIndication * @param *ledPins tLedPins */ void Indication_Init(tIndication *env, tLedPins *ledPins) { env->ledPins = ledPins; for (uint8_t i = 0; i <= INDICATION_CHANEL_NUM; i++) { env->chanel[i] = MOD_CH_STARTUP; } lIndication_ModInit(&env->mod[MOD_CH_STARTUP], 500, 100, false); lIndication_ModInit(&env->mod[MOD_CH_ERROR], 200, 200, false); lIndication_ModInit(&env->mod[MOD_CH_OK], 0, 999, true); lIndication_ModInit(&env->mod[MOD_CH_CHARGE], 999, 0, true); } /** * Запуск потока индикации * @param *env tIndication */ void Indication_StartThread(tIndication *env) { if (!env->thread.id) { env->thread.id = osThreadNew((osThreadFunc_t) (Indication_Thread), (void *) (env), &env->thread.attr); } else { osThreadResume(env->thread.id); } } /** * Изменения режима индикации канала * @param *env tIndication * @param indicationMod eIndicationMod * @param channel eChargerChannels */ void Indication_ChanelSetMode(tIndication *env, eIndicationMod indicationMod, eChargerChannels channel) { env->chanel[channel] = indicationMod; }