HVAC_M7_LIN_TASKS/LinSensorTasks.c

467 lines
15 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//
// Created by cfif on 12.02.2026.
//
#include <SystemDelayInterface.h>
#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->linStateSensor.LED_COUNT[i]);
}
env->d_CCU_DRS_Req.BCM_SwIndIntens_Stat = 0;
env->d_CCU_DRS_Req.BCM_IndFadingTime_Req = 2;
ret = Set_CCU_DRS_Req(env->linIo, env->linData, &env->d_CCU_DRS_Req);
if (ret == LIN_TX_COMPLETED) {
#if (LOG_LIN5_SENSOR == 1)
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);
LoggerInfoStatic(LOGGER, LOG_SIGN5, "Sensor Set_CCU_DRS_Req - OK")
}
#endif
} else {
#if (LOG_LIN5_SENSOR == 1)
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);
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->linStateSensor.d_DRS_Stat[i], DRS_SENSON_ADR_Stat[i]);
if (env->linStateSensor.d_DRS_Stat[i].DRS_Btn_Stat) {
++env->linStateSensor.LED_COUNT[i];
if (env->linStateSensor.LED_COUNT[i] > 3) {
env->linStateSensor.LED_COUNT[i] = 0;
}
}
env->linStateSensor.LinRespErr_Stat[i] = env->linStateSensor.d_DRS_Stat[i].DRS_LinRespErr_Stat;
env->linStateSensor.Err_Stat[i] = env->linStateSensor.d_DRS_Stat[i].DRS_Err_Stat;
if (ret == LIN_RX_COMPLETED) {
env->linStateSensor.error_connect[i] = 0;
#if (LOG_LIN5_SENSOR == 1)
if ((*((uint8_t *) &env->linStateSensor.d_DRS_Stat[i]) !=
*((uint8_t *) &env->linStateSensor.d_old_DRS_Stat[i])) ||
(env->linStateSensor.LED_COUNT[i] != env->linStateSensor.LED_OLD_COUNT[i])) {
*((uint8_t *) &env->linStateSensor.d_old_DRS_Stat[i]) = *((uint8_t *) &env->linStateSensor.d_DRS_Stat[i]);
env->linStateSensor.LED_OLD_COUNT[i] = env->linStateSensor.LED_COUNT[i];
LoggerFormatInfo(LOGGER, LOG_SIGN5,
"Sensor number %d: COUNT = %d DRS_Btn_Stat = %d DRS_LinRespErr_Stat = %d DRS_Err_Stat = %d",
i,
env->linStateSensor.LED_COUNT[i],
env->linStateSensor.d_DRS_Stat[i].DRS_Btn_Stat,
env->linStateSensor.d_DRS_Stat[i].DRS_LinRespErr_Stat,
env->linStateSensor.d_DRS_Stat[i].DRS_Err_Stat
)
}
#endif
} else {
env->linStateSensor.error_connect[i] = 1;
#if (LOG_LIN5_SENSOR == 1)
if (env->linStateSensor.error_connect[i] != env->linStateSensor.error_old_connect[i]) {
env->linStateSensor.error_old_connect[i] = env->linStateSensor.error_connect[i];
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);
uint8_t isError = 0;
for (uint8_t i = 0; i < LIN5_SENSOR_COUNT; ++i) {
if (env->linStateSensor.error_connect[i] == 1)
++isError;
}
if (isError == LIN5_SENSOR_COUNT) {
env->error_connect = 1;
} else {
env->error_connect = 0;
}
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 ----------------------------------------------------------------