// // Created by villuton on 17.09.2025. // #include #include "Main_Private.h" #define STORAGE_DEVICE(VAR) env->storage.nvm.device.VAR #define ADC(CH) env->adcs.tab[CH] #define INDICATION(CH) env->indication.chanel[CH] #define LOGGER &env->slog.logger #define LOG_SIGN "Main_Processing" /** * Установка пина зарядника по каналу * @param env * @param chanel * @param value */ void ChargerChanelSet(tMain *env, uint8_t chanel, bool value){ GpioPinSet(&env->gpios.chrgEnPins.tab[chanel], value); } /** * Установка пина включения акб в цепь по каналу * @param env * @param chanel * @param value */ void BatteryChanelSet(tMain *env, uint8_t chanel, bool value){ GpioPinSet(&env->gpios.batEnPins.tab[chanel], value); } /** * Процедура установки положения пинов, * в зависимости от того, идет сейчас проверка напряжения акб или нет * @param env * @param chanel * @param check */ void SetPinsModeCheck(tMain *env, uint8_t chanel, bool check){ if(check == false){ ChargerChanelSet(env,chanel,true); BatteryChanelSet(env,chanel,true); } else{ ChargerChanelSet(env,chanel,false); BatteryChanelSet(env,chanel,true); } } /** * Процедура приведения данных АЦП к напряжению * С поправкой либо на делитель, либо на калибровочный коэффициент * @param env * @param chanel * @return */ #undef LOG_SIGN #define LOG_SIGN "AdcToVoltage" static float AdcToVoltage(tMain *env, uint8_t chanel){ if(STORAGE_DEVICE(chanelCalibrationFactor[chanel]) != STORAGE_CALIBRATION_FACTOR_DEFAULT){ /// Расчет через калибровочный параметр LoggerTraceStatic(LOGGER, LOG_SIGN, "Calculation via calibration parameter") return (float ) ADC(chanel) * STORAGE_DEVICE(chanelCalibrationFactor[chanel]); } /// Расчет через коэффициент делителя LoggerTraceStatic(LOGGER, LOG_SIGN, "Calculation using the divisor coefficient") return (float ) ADC(chanel) * (STORAGE_V_ADC_THRESHOLD / STORAGE_ADC_THRESHOLD) * STORAGE_DEVICE(dividerRatio); } /** * Процедура обработки переходов режимов * в зависимости от значений считанного напряжения * @param env * @param value * @param isCheck * @return */ static eIndicationMod AdcChanelModeProcessing(tMain *env,float value, bool isCheck){ if(value <= STORAGE_DEVICE(voltageBatteryConnectThreshold)){ LoggerTraceStatic(LOGGER, LOG_SIGN, "The voltage is lower Battery Connect Threshold") LoggerTraceStatic(LOGGER, LOG_SIGN, "Set mode STARTUP") return MOD_CH_STARTUP; } if(value <= STORAGE_DEVICE(voltageBatteryLoadedThreshold)){ LoggerTraceStatic(LOGGER, LOG_SIGN, "The voltage is lower Battery Loader Threshold") LoggerTraceStatic(LOGGER, LOG_SIGN, "Set mode CHARGE") return MOD_CH_CHARGE; } if(value > STORAGE_DEVICE(voltageBatteryLoadedThreshold)){ LoggerTraceStatic(LOGGER, LOG_SIGN, "The voltage is higher Battery Loader Threshold") if(isCheck != false){ LoggerTraceStatic(LOGGER, LOG_SIGN, "Is check time") LoggerTraceStatic(LOGGER, LOG_SIGN, "Set mode OK") return MOD_CH_OK; } else{ LoggerTraceStatic(LOGGER, LOG_SIGN, "Is not check time") LoggerTraceStatic(LOGGER, LOG_SIGN, "Set mode CHARGE") return MOD_CH_CHARGE; } } return MOD_CH_ERROR; } /** * Процедура Обработчика данным с АЦП, включения/отключения зарядки и выставление режимов индикации * @param env */ #undef LOG_SIGN #define LOG_SIGN "Main_Processing" void Main_Processing(tMain *env){ ///Обновление таблицы данных каналов АЦП LoggerTraceStatic(LOGGER, LOG_SIGN, "Updating the ADC channel data table") Adcs_UpdateTab(&env->adcs); ///Проходимся в цикле по всем каналам for (int chanel = CHRG_Ch1; chanel < CHARGER_CH_NUM; chanel++) { env->processing.currentChanel = chanel; char msd_buff[30] = {0}; sprintf(msd_buff,"Current Chanel: %d \n\r", chanel+1); LoggerCnTrace(LOGGER, LOG_SIGN, msd_buff, sizeof(msd_buff)) switch (INDICATION(chanel)) { /** * В режиме стартапа предполагаем, что ожидаем подключения аккумулятора * Зарядник отключен, режим постоянной проверки */ case MOD_CH_STARTUP: LoggerTraceStatic(LOGGER, LOG_SIGN, "Current mod STARTUP") SetPinsModeCheck(env,chanel,true); INDICATION(chanel) = AdcChanelModeProcessing(env,AdcToVoltage(env, chanel), true); /** * В режиме зарядника возможен переход в любое из состояний, но переход в состояние "Заряжен" * Возможен только при флаге check = true */ case MOD_CH_CHARGE: LoggerTraceStatic(LOGGER, LOG_SIGN, "Current mod CHARGE") SetPinsModeCheck(env,chanel,env->processing.check); INDICATION(chanel) = AdcChanelModeProcessing(env,AdcToVoltage(env, chanel), env->processing.check); /** * Это режим состояния, говорящий, что АКБ заряжен */ case MOD_CH_OK: LoggerTraceStatic(LOGGER, LOG_SIGN, "Current mod OK") SetPinsModeCheck(env,chanel,true); INDICATION(chanel) = AdcChanelModeProcessing(env,AdcToVoltage(env, chanel), true); /** * Режим ошибки, по факту сейчас не используется */ case MOD_CH_ERROR: LoggerTraceStatic(LOGGER, LOG_SIGN, "Current mod ERROR") ChargerChanelSet(env,chanel,false); BatteryChanelSet(env,chanel,false); default: break; } } /// Переустановка таймера и флага для отключения зарядника и проверки на заряд if(env->processing.timer < SystemGetMs()){ LoggerTraceStatic(LOGGER, LOG_SIGN, "Timer update") env->processing.timer = SystemGetMs() + env->processing.check != false? STORAGE_CHARGE_TIME : STORAGE_VERIFICATION_TIME; env->processing.check = !env->processing.check; } }