// // Created by cfif on 12.02.2026. // #include #include "LinSensorTasks.h" #include "CmsisRtosThreadUtils.h" #include "CanPorts.h" #include "fc7xxx_driver_lin.h" #include "Lins.h" #include "LoggerInterface.h" #include "memory.h" #define LOG_SIGN4 "Lin4" #define LOG_SIGN5 "Lin5" #define LOGGER env->logger const uint8_t DRS_SENSON_ADR_Stat[LIN5_SENSOR_COUNT] = {DRS_DL_Stat, DRS_DR_Stat, DRS_FPL_Stat, DRS_FPR_Stat, DRS_RLB_Stat, DRS_RRB_Stat, DRS_FCL_Stat, DRS_FCR_Stat}; static lin_event_id_t SEND_SENSOR_COM_x(tLinIO *linIo, uint8_t COM_ADR) { lin_event_id_t res = linIo->runCommand(linIo->env, COM_ADR, 30); // SystemDelayMs(40); return res; } static lin_event_id_t Set_CCU_Req(tLinIO *linIo, tLinData *linData, tCCU_Req *p_CCU_Req) { lin_event_id_t res; linData->direction = LIN_DIRECTION_SET; linData->g_aTxBufferLen = sizeof(tCCU_Req); linData->g_aRxBufferLen = 0; memcpy(linData->g_aTxBuffer, p_CCU_Req, sizeof(tCCU_Req)); uint8_t retry = 1; while (retry) { res = SEND_SENSOR_COM_x(linIo, CCU_Req); if (res == LIN_TX_COMPLETED) { break; } --retry; } return res; } static lin_event_id_t Get_AirQS_Stat(tLinIO *linIo, tLinData *linData, tAirQS_Stat *p_AirQS_Stat) { lin_event_id_t res; tAirQS_Stat *tAirQS_Stat_ = (tAirQS_Stat *) linData->g_aRxBuffer; uint8_t retry = 1; while (retry) { linData->direction = LIN_DIRECTION_GET; linData->g_aTxBufferLen = 0; linData->g_aRxBufferLen = sizeof(tAirQS_Stat); res = SEND_SENSOR_COM_x(linIo, AirQS_Stat); if (res == LIN_RX_COMPLETED) { memcpy(p_AirQS_Stat, tAirQS_Stat_, sizeof(tAirQS_Stat)); break; } --retry; } return res; } //начало----------------------------------------- LIN 4 ---------------------------------------------------------------- //начало----------------------------------------- LIN 4 ---------------------------------------------------------------- //начало----------------------------------------- LIN 4 ---------------------------------------------------------------- //начало----------------------------------------- LIN 4 --------------------------------------------------------------- static lin_event_id_t Lin4_Scheduler(tLin4TaskSensor *env) { lin_event_id_t ret = LIN_NO_EVENT; env->d_CCU_Req.CCU_AirQS_Req = 1; ret = Set_CCU_Req(env->linIo, env->linData, &env->d_CCU_Req); #if (LOG_LIN4_ACTUATOR == 1) if (ret == LIN_TX_COMPLETED) { LoggerFormatInfo(LOGGER, LOG_SIGN4, "OK Set_CCU_Req = %d", ret) } else { LoggerFormatInfo(LOGGER, LOG_SIGN4, "ERROR Set_CCU_Req = %d", ret) } #endif ret = Get_AirQS_Stat(env->linIo, env->linData, &env->d_AirQS_Stat); #if (LOG_LIN4_ACTUATOR == 1) if (ret == LIN_RX_COMPLETED) { LoggerFormatInfo(LOGGER, LOG_SIGN4, "AirQS_LinRespErr_Stat = %d AirQS_Sens_Stat = %d AirQS_Combined_Stat = %d AirQS_Err_Stat = %d AirQS_COLvl_Stat = %d AirQS_NOxLvl_Stat = %d AirQS_NH3Lvl_Stat = %d", env->d_AirQS_Stat.AirQS_LinRespErr_Stat, env->d_AirQS_Stat.AirQS_Sens_Stat, env->d_AirQS_Stat.AirQS_Combined_Stat, env->d_AirQS_Stat.AirQS_Err_Stat, env->d_AirQS_Stat.AirQS_COLvl_Stat, env->d_AirQS_Stat.AirQS_NOxLvl_Stat, env->d_AirQS_Stat.AirQS_NH3Lvl_Stat) } else { LoggerFormatInfo(LOGGER, LOG_SIGN4, "ERROR Get_AirQS_Stat = %d", ret) } #endif return LIN_NO_EVENT; } void Lin_4_Init(tLin4TaskSensor *env, tLinData *linData, tLinIO *linIO, tLoggerInterface *logger) { env->linIo = linIO; env->linData = linData; env->logger = logger; env->access = osMutexNew(NULL); InitThreadAtrStatic(&env->threadLin.attr, "Ln4", env->threadLin.controlBlock, env->threadLin.stack, osPriorityNormal); } static _Noreturn void Lin4_Thread(tLin4TaskSensor *env) { for (;;) { if (osMutexAcquire(env->access, 1000) == osOK) { lin_event_id_t res = Lin4_Scheduler(env); osMutexRelease(env->access); } SystemDelayMs(1000); } } void Lin4_StartThread(tLin4TaskSensor *env) { if (!env->threadLin.id) { env->threadLin.id = osThreadNew((osThreadFunc_t) (Lin4_Thread), (void *) (env), &env->threadLin.attr); } } //конец----------------------------------------- LIN 4 ---------------------------------------------------------------- //конец----------------------------------------- LIN 4 ---------------------------------------------------------------- //конец----------------------------------------- LIN 4 ---------------------------------------------------------------- //конец----------------------------------------- LIN 4 ---------------------------------------------------------------- //начало----------------------------------------- LIN 5 ---------------------------------------------------------------- //начало----------------------------------------- LIN 5 ---------------------------------------------------------------- //начало----------------------------------------- LIN 5 ---------------------------------------------------------------- //начало----------------------------------------- LIN 5 --------------------------------------------------------------- static lin_event_id_t Set_CCU_DRS_Req(tLinIO *linIo, tLinData *linData, tCCU_DRS_Req *p_CCU_DRS_Req) { lin_event_id_t res; linData->direction = LIN_DIRECTION_SET; linData->g_aTxBufferLen = sizeof(tCCU_DRS_Req); linData->g_aRxBufferLen = 0; memcpy(linData->g_aTxBuffer, p_CCU_DRS_Req, sizeof(tCCU_DRS_Req)); uint8_t retry = 1; while (retry) { res = SEND_SENSOR_COM_x(linIo, CCU_DRS_Req); if (res == LIN_TX_COMPLETED) { break; } --retry; } return res; } /* static lin_event_id_t Get_DRS_DL_Stat(tLinIO *linIo, tLinData *linData, tDRS_DL_Stat *p_tDRS_DL_Stat) { lin_event_id_t res; tDRS_DL_Stat *tDRS_DL_Stat_ = (tDRS_DL_Stat *) linData->g_aRxBuffer; uint8_t retry = 3; while (retry) { linData->direction = LIN_DIRECTION_GET; linData->g_aTxBufferLen = 0; linData->g_aRxBufferLen = sizeof(tDRS_DL_Stat); res = SEND_SENSOR_COM_x(linIo, DRS_DL_Stat); if (res == LIN_RX_COMPLETED) { memcpy(p_tDRS_DL_Stat, tDRS_DL_Stat_, sizeof(tDRS_DL_Stat)); break; } --retry; } return res; } */ static lin_event_id_t Get_DRS_Stat(tLinIO *linIo, tLinData *linData, tDRS_Stat *p_tDRS_Stat, uint8_t DRS_stat) { lin_event_id_t res; tDRS_Stat *tDRS_Stat_ = (tDRS_Stat *) linData->g_aRxBuffer; uint8_t retry = 3; while (retry) { linData->direction = LIN_DIRECTION_GET; linData->g_aTxBufferLen = 0; linData->g_aRxBufferLen = sizeof(tDRS_Stat); res = SEND_SENSOR_COM_x(linIo, DRS_stat); if (res == LIN_RX_COMPLETED) { memcpy(p_tDRS_Stat, tDRS_Stat_, sizeof(tDRS_Stat)); break; } --retry; } return res; } // Вспомогательная функция: устанавливает три бита для группы led_group // в соответствии со значением count (0, 1, 2, 3) static void set_led_group(tCCU_DRS_Req *req, uint8_t led_group, uint8_t count) { // Определяем, какой из трёх битов должен быть установлен uint8_t b1 = 0; uint8_t b2 = 0; uint8_t b3 = 0; if (count == 1) { b1 = 1; b2 = 0; b3 = 0; } if (count == 2) { b1 = 1; b2 = 1; b3 = 0; } if (count == 3) { b1 = 1; b2 = 1; b3 = 1; } switch (led_group) { case 0: req->CCU_DLLed1_Req = b1; req->CCU_DLLed2_Req = b2; req->CCU_DLLed3_Req = b3; break; case 1: req->CCU_DRLed1_Req = b1; req->CCU_DRLed2_Req = b2; req->CCU_DRLed3_Req = b3; break; case 2: req->CCU_FPLLed1_Req = b1; req->CCU_FPLLed2_Req = b2; req->CCU_FPLLed3_Req = b3; break; case 3: req->CCU_FPRLed1_Req = b1; req->CCU_FPRLed2_Req = b2; req->CCU_FPRLed3_Req = b3; break; case 4: req->CCU_RLBLed1_Req = b1; req->CCU_RLBLed2_Req = b2; req->CCU_RLBLed3_Req = b3; break; case 5: req->CCU_RRBLed1_Req = b1; req->CCU_RRBLed2_Req = b2; req->CCU_RRBLed3_Req = b3; break; case 6: req->CCU_FCLLed1_Req = b1; req->CCU_FCLLed2_Req = b2; req->CCU_FCLLed3_Req = b3; break; case 7: req->CCU_FCRLed1_Req = b1; req->CCU_FCRLed2_Req = b2; req->CCU_FCRLed3_Req = b3; break; default: // Недопустимый индекс – можно ничего не делать или добавить assert break; } } static lin_event_id_t Lin5_Scheduler(tLin5TaskSensor *env) { lin_event_id_t ret = LIN_NO_EVENT; for (uint8_t i = 0; i < LIN5_SENSOR_COUNT; ++i) { set_led_group(&env->d_CCU_DRS_Req, i, env->LED_COUNT[i]); } env->d_CCU_DRS_Req.BCM_SwIndIntens_Stat = 1; env->d_CCU_DRS_Req.BCM_IndFadingTime_Req = 2; // if (*((uint32_t *) &env->d_CCU_DRS_Req) != *((uint32_t *) &env->d_old_CCU_DRS_Req)) { // *((uint32_t *) &env->d_old_CCU_DRS_Req) = *((uint32_t *) &env->d_CCU_DRS_Req); ret = Set_CCU_DRS_Req(env->linIo, env->linData, &env->d_CCU_DRS_Req); #if (LOG_LIN5_SENSOR == 1) if (ret == LIN_TX_COMPLETED) { LoggerInfoStatic(LOGGER, LOG_SIGN5, "Sensor Set_CCU_DRS_Req - OK") } else { LoggerFormatInfo(LOGGER, LOG_SIGN5, "Sensor Set_CCU_DRS_Req (ERROR %d)", ret) } #endif // } for (uint8_t i = 0; i < LIN5_SENSOR_COUNT; ++i) { ret = Get_DRS_Stat(env->linIo, env->linData, &env->d_DRS_Stat[i], DRS_SENSON_ADR_Stat[i]); if (env->d_DRS_Stat[i].DRS_Btn_Stat) { ++env->LED_COUNT[i]; if (env->LED_COUNT[i] > 3) { env->LED_COUNT[i] = 0; } } #if (LOG_LIN5_SENSOR == 1) if (ret == LIN_RX_COMPLETED) { LoggerFormatInfo(LOGGER, LOG_SIGN5, "Sensor number %d: DRS_Btn_Stat = %d DRS_LinRespErr_Stat = %d DRS_Err_Stat = %d", i, env->d_DRS_Stat[i].DRS_Btn_Stat, env->d_DRS_Stat[i].DRS_LinRespErr_Stat, env->d_DRS_Stat[i].DRS_Err_Stat ) } else { LoggerFormatInfo(LOGGER, LOG_SIGN5, "Sensor number %d: ERROR Get_FPL_Stat = %d", i, ret) } #endif } return LIN_NO_EVENT; } void Lin_5_Init(tLin5TaskSensor *env, tLinData *linData, tLinIO *linIO, tLoggerInterface *logger) { env->linIo = linIO; env->linData = linData; env->logger = logger; env->access = osMutexNew(NULL); InitThreadAtrStatic(&env->threadLin.attr, "Ln5", env->threadLin.controlBlock, env->threadLin.stack, osPriorityNormal); } static _Noreturn void Lin5_Thread(tLin5TaskSensor *env) { for (;;) { if (osMutexAcquire(env->access, 1000) == osOK) { lin_event_id_t res = Lin5_Scheduler(env); osMutexRelease(env->access); } SystemDelayMs(50); } } void Lin5_StartThread(tLin5TaskSensor *env) { if (!env->threadLin.id) { env->threadLin.id = osThreadNew((osThreadFunc_t) (Lin5_Thread), (void *) (env), &env->threadLin.attr); } } //конец----------------------------------------- LIN 5 ---------------------------------------------------------------- //конец----------------------------------------- LIN 5 ---------------------------------------------------------------- //конец----------------------------------------- LIN 5 ---------------------------------------------------------------- //конец----------------------------------------- LIN 5 ----------------------------------------------------------------