Обновление стиля библиотеки

This commit is contained in:
2026-06-01 15:19:18 +03:00
parent 88af7cdfce
commit 757d608ad4
17 changed files with 3335 additions and 3537 deletions

View File

@@ -21,7 +21,13 @@
#include "can.h"
/* USER CODE BEGIN 0 */
//CAN Speed
#define CAN_SPEED_PRSC_1000KB 2
#define CAN_SPEED_PRSC_500KB 4
#define CAN_SPEED_PRSC_250KB 8
#define CAN_SPEED_PRSC_125KB 16
#define CAN_SPEED_PRSC_50KB 40
#define CAN_CURRENT_SPEED CAN_SPEED_PRSC_250KB
/* USER CODE END 0 */
CAN_HandleTypeDef hcan;

View File

@@ -92,9 +92,9 @@ int main(void)
MX_RTC_Init();
MX_TIM4_Init();
/* USER CODE BEGIN 2 */
HAL_CAN_Start(&hcan);
if(PROTOCAN_INIT(&hcan, &hrtc, &htim4) == PROTOCAN_OK)
{
HAL_CAN_Start(&hcan);
HAL_CAN_ActivateNotification(&hcan, CAN_IT_RX_FIFO0_MSG_PENDING | CAN_IT_ERROR | CAN_IT_BUSOFF | CAN_IT_LAST_ERROR_CODE);
PROTOCAN_LOOP();
}

View File

@@ -1,7 +1,7 @@
#include "protocan.h"
struct device CurrentDevice;
struct device Device_on_the_Network[8][16];
ProtoCanDevice_t CurrentDevice;
ProtoCanDevice_t Device_on_the_Network[8][16];
struct controlflags ControlFlags;
CAN_HandleTypeDef *_HCAN = 0;
@@ -10,7 +10,7 @@ TIM_HandleTypeDef *_HTIM = 0;
uint8_t CurrentStep = 1;
uint8_t LastStep = 0;
struct RXMsg rxMsg[CAN_RX_BUFFER_SIZE];
struct RXMsg rxMsg[PROTOCAN_RX_BUFFER_SIZE];
/**
* @brief Проверяет, является ли год високосным.
@@ -33,7 +33,7 @@ _Bool IsLeapYear(uint8_t year)
*/
uint16_t AvailableCanRxMsg(void)
{
return ((uint16_t)(CAN_RX_BUFFER_SIZE + (LastStep - CurrentStep + 1)))%CAN_RX_BUFFER_SIZE;
return ((uint16_t)(PROTOCAN_RX_BUFFER_SIZE + (LastStep - CurrentStep + 1)))%PROTOCAN_RX_BUFFER_SIZE;
}
void PROTOCAN_DEINIT(uint8_t stage)
@@ -66,19 +66,19 @@ PROTOCAN_INIT_StatusTypeDef PROTOCAN_INIT(CAN_HandleTypeDef *tmp_hcan, RTC_Handl
HAL_StatusTypeDef CAN_RC_RESULT = HAL_CAN_RegisterCallback(_HCAN, HAL_CAN_RX_FIFO0_MSG_PENDING_CB_ID, ProtoCanRxFifo0MsgPendingCallback);
if(CAN_RC_RESULT != HAL_OK) {
PROTOCAN_DEINIT(initStage);
return PROTOCAN_HRTC_ERROR;
return PROTOCAN_INIT_HRTC_ERROR;
}
#endif
} else {
PROTOCAN_DEINIT(initStage);
return PROTOCAN_HCAN_ERROR;
return PROTOCAN_INIT_HCAN_ERROR;
}
initStage++;
if(tmp_hrtc) {
_HRTC = tmp_hrtc;
} else {
PROTOCAN_DEINIT(initStage);
return PROTOCAN_HRTC_ERROR;
return PROTOCAN_INIT_HRTC_ERROR;
}
initStage++;
if(tmp_tim) {
@@ -87,17 +87,17 @@ PROTOCAN_INIT_StatusTypeDef PROTOCAN_INIT(CAN_HandleTypeDef *tmp_hcan, RTC_Handl
HAL_StatusTypeDef TIM_RC_RESULT = HAL_TIM_RegisterCallback(_HTIM, HAL_TIM_PERIOD_ELAPSED_CB_ID, ProtoCanPulseCallback);
if(TIM_RC_RESULT != HAL_OK) {
PROTOCAN_DEINIT(initStage);
return PROTOCAN_HRTC_ERROR;
return PROTOCAN_INIT_HRTC_ERROR;
}
#endif
} else {
PROTOCAN_DEINIT(initStage);
return PROTOCAN_TIM_ERROR;
return PROTOCAN_INIT_TIM_ERROR;
}
initStage++;
PROTOCAN_FILTERS();
ControlFlags.IsPulse = 1;
return PROTOCAN_OK;
return PROTOCAN_INIT_OK;
}
/**
@@ -111,264 +111,71 @@ PROTOCAN_INIT_StatusTypeDef PROTOCAN_INIT(CAN_HandleTypeDef *tmp_hcan, RTC_Handl
*/
void PROTOCAN_LOOP(void)
{
//HAL_TIM_Base_Start_IT(&htim4);
while(1)
{
if(AvailableCanRxMsg())
{
if(rxMsg[CurrentStep].eID.Fields.MsgType == DATA_TYPE_ANALOG)
if(rxMsg[CurrentStep].eID.Fields.MsgType == PROTOCAN_MSGTYPE_ANALOG)
{
PROTOCAN_AnalogProcessing(rxMsg[CurrentStep]);
}
else if(rxMsg[CurrentStep].eID.Fields.MsgType == DATA_TYPE_BROADCAST)
else if(rxMsg[CurrentStep].eID.Fields.MsgType == PROTOCAN_MSGTYPE_BROADCAST)
{
PROTOCAN_BroadcastProcessing(rxMsg[CurrentStep]);
}
else if(rxMsg[CurrentStep].eID.Fields.MsgType == DATA_TYPE_DISCRETE)
else if(rxMsg[CurrentStep].eID.Fields.MsgType == PROTOCAN_MSGTYPE_DISCRETE)
{
PROTOCAN_DiscreticProcessing(rxMsg[CurrentStep]);
}
else if(rxMsg[CurrentStep].eID.Fields.MsgType == DATA_TYPE_GENERAL_ADDRESS_SPACE)
else if(rxMsg[CurrentStep].eID.Fields.MsgType == PROTOCAN_MSGTYPE_GENERAL_ADDRESS_SPACE)
{
PROTOCAN_GeneralAddressSpace_Answer(rxMsg[CurrentStep]);
ProtoCanMsgToGeneralAddressSpace(rxMsg[CurrentStep]);
}
else if(rxMsg[CurrentStep].eID.Fields.MsgType == DATA_TYPE_MODBUS_COIL ||
rxMsg[CurrentStep].eID.Fields.MsgType == DATA_TYPE_MODBUS_DISCRETE ||
rxMsg[CurrentStep].eID.Fields.MsgType == DATA_TYPE_MODBUS_HOLDING ||
rxMsg[CurrentStep].eID.Fields.MsgType == DATA_TYPE_MODBUS_INPUT)
else if(rxMsg[CurrentStep].eID.Fields.MsgType == PROTOCAN_MSGTYPE_MODBUS_COIL ||
rxMsg[CurrentStep].eID.Fields.MsgType == PROTOCAN_MSGTYPE_MODBUS_DISCRETE ||
rxMsg[CurrentStep].eID.Fields.MsgType == PROTOCAN_MSGTYPE_MODBUS_HOLDING ||
rxMsg[CurrentStep].eID.Fields.MsgType == PROTOCAN_MSGTYPE_MODBUS_INPUT)
{
PROTOCAN_ModbusProcessing(rxMsg[CurrentStep]);
}
else if(rxMsg[CurrentStep].eID.Fields.MsgType == DATA_TYPE_ERROR)
else if(rxMsg[CurrentStep].eID.Fields.MsgType == PROTOCAN_MSGTYPE_ERROR)
{
CanRequestError(rxMsg[CurrentStep]);
}
CurrentStep = (uint16_t)(CurrentStep + 1) % CAN_RX_BUFFER_SIZE;
CurrentStep = (uint16_t)(CurrentStep + 1) % PROTOCAN_RX_BUFFER_SIZE;
}
}
}
/**
* @brief Функция обработки аналоговых запросов.
* @param struct RXMsg _rxMsg - структура для полученного сообщения.
* @details Функция, сортирующая запросы по типам и вызывающая соответствующие функции. Типы запросов: Универсальный, Уставки, Напряжение, Ток, Температура.
* @return HAL_StatusTypeDef Статус выполнения команды CAN (успех или ошибка).
*/
HAL_StatusTypeDef PROTOCAN_AnalogProcessing(struct RXMsg _rxMsg)
{
msgAnalogType msg;
msg.Body = _rxMsg.eID.Fields.MsgBody;
switch (msg.Fields.SensorType)
{
case SENSOR_TYPE_ANALOG_UNIVERSAL:
{
return ProtoCanMsgToAnalogUniversal(_rxMsg);
break;
}
case SENSOR_TYPE_ANALOG_USTAVKI:
{
return ProtoCanMsgToAnalogUSTAVKI(_rxMsg);
break;
}
case SENSOR_TYPE_ANALOG_U:
{
return ProtoCanMsgToAnalogUSens(_rxMsg);
break;
}
case SENSOR_TYPE_ANALOG_I:
{
return ProtoCanMsgToAnalogISens(_rxMsg);
break;
}
case SENSOR_TYPE_ANALOG_T:
{
return ProtoCanMsgToAnalogTSens(_rxMsg);
break;
}
default:
//RESERVE SENSOR TYPE
return HAL_ERROR;
break;
}
return HAL_ERROR;
}
/**
* @brief Функция ответа на запрос данных со всех датчиков.
* Создает сообщение с определенными данными и отправляет его через CAN-шину.
* @param _rxMsg Структура входящего сообщения, используется для формирования ID.
* @return HAL_StatusTypeDef Статус выполнения операции HAL, например HAL_OK.
*/
__weak HAL_StatusTypeDef ProtoCanMsgToAnalogUniversal(struct RXMsg _rxMsg)
{
CAN_TxHeaderTypeDef TxHeader;
uint32_t TxMailBox = 0;
uint8_t data[8];
TxHeader.IDE = CAN_ID_EXT;
TxHeader.TransmitGlobalTime = DISABLE;
TxHeader.RTR = CAN_RTR_DATA;
extID tmp_eID;
tmp_eID.BitAll = _rxMsg.eID.BitAll;
tmp_eID.Fields.Route = ROUTE_SLAVE;
TxHeader.ExtId = tmp_eID.BitAll;
TxHeader.DLC = 6;
data[0] = 'U';
data[1] = 'N';
data[2] = 'I';
data[3] = 'V';
data[4] = 'E';
data[5] = 'R';
return HAL_CAN_AddTxMessage(_HCAN, &TxHeader, data, &TxMailBox);
}
/**
* @brief Функция ответа на запрос уставок по CAN.
* Создает сообщение с определенными данными и отправляет его через CAN-шину.
* @param _rxMsg Структура входящего сообщения, используется только для формирования ID.
* @return HAL_StatusTypeDef Статус выполнения операции HAL, например HAL_OK.
*/
__weak HAL_StatusTypeDef ProtoCanMsgToAnalogUSTAVKI(struct RXMsg _rxMsg)
{
CAN_TxHeaderTypeDef TxHeader;
uint32_t TxMailBox = 0;
uint8_t data[8];
TxHeader.IDE = CAN_ID_EXT;
TxHeader.TransmitGlobalTime = DISABLE;
TxHeader.RTR = CAN_RTR_DATA;
extID tmp_eID;
tmp_eID.BitAll = _rxMsg.eID.BitAll;
tmp_eID.Fields.Route = ROUTE_SLAVE;
TxHeader.ExtId = tmp_eID.BitAll;
TxHeader.DLC = 7;
data[0] = 'U';
data[1] = 'S';
data[2] = 'T';
data[3] = 'A';
data[4] = 'V';
data[5] = 'K';
data[6] = 'I';
return HAL_CAN_AddTxMessage(_HCAN, &TxHeader, data, &TxMailBox);
}
/**
* @brief Функция ответа на запрос данных с датчиков напряжения.
* Создает сообщение с указанными параметрами и отправляет его через CAN-шину.
* @param _rxMsg Структура входящего сообщения, используемая для формирования идентификатора и данных.
* @return HAL_StatusTypeDef Статус выполнения операции HAL, например HAL_OK при успешной отправке.
*/
__weak HAL_StatusTypeDef ProtoCanMsgToAnalogUSens(struct RXMsg _rxMsg)
{
CAN_TxHeaderTypeDef TxHeader;
uint32_t TxMailBox = 0;
uint8_t data[8];
TxHeader.IDE = CAN_ID_EXT;
TxHeader.TransmitGlobalTime = DISABLE;
TxHeader.RTR = CAN_RTR_DATA;
extID tmp_eID;
tmp_eID.BitAll = _rxMsg.eID.BitAll;
tmp_eID.Fields.Route = ROUTE_SLAVE;
TxHeader.ExtId = tmp_eID.BitAll;
TxHeader.DLC = 6;
msgAnalogType msg;
msg.Body = _rxMsg.eID.Fields.MsgBody;
data[0] = 'U';
data[1] = 'S';
data[2] = 47 + msg.Fields.SensorID / 1000;
data[3] = 47 + msg.Fields.SensorID / 100 % 10;
data[4] = 47 + msg.Fields.SensorID / 10 % 10;
data[5] = 47 + msg.Fields.SensorID % 10;
return HAL_CAN_AddTxMessage(_HCAN, &TxHeader, data, &TxMailBox);
}
/**
* @brief Функция ответа на запрос данных с датчиков тока.
* Создает сообщение с определенными параметрами и отправляет его через CAN-шину.
* @param _rxMsg Структура входящего сообщения, используется для формирования идентификатора и данных.
* @return HAL_StatusTypeDef Статус операции HAL, например HAL_OK при успешной отправке.
*/
__weak HAL_StatusTypeDef ProtoCanMsgToAnalogISens(struct RXMsg _rxMsg)
{
CAN_TxHeaderTypeDef TxHeader;
uint32_t TxMailBox = 0;
uint8_t data[8];
TxHeader.IDE = CAN_ID_EXT;
TxHeader.TransmitGlobalTime = DISABLE;
TxHeader.RTR = CAN_RTR_DATA;
extID tmp_eID;
tmp_eID.BitAll = _rxMsg.eID.BitAll;
tmp_eID.Fields.Route = ROUTE_SLAVE;
TxHeader.ExtId = tmp_eID.BitAll;
TxHeader.DLC = 6;
msgAnalogType msg;
msg.Body = _rxMsg.eID.Fields.MsgBody;
data[0] = 'I';
data[1] = 'S';
data[2] = 47 + msg.Fields.SensorID / 1000;
data[3] = 47 + msg.Fields.SensorID / 100 % 10;
data[4] = 47 + msg.Fields.SensorID / 10 % 10;
data[5] = 47 + msg.Fields.SensorID % 10;
return HAL_CAN_AddTxMessage(_HCAN, &TxHeader, data, &TxMailBox);
}
/**
* @brief Функция ответа на запрос данных с датчиков температуры.
* Создает сообщение с определенным заголовком, формирует данные по ID сенсора и отправляет его через CAN.
* @param _rxMsg Структура полученного сообщения, которая используется для формирования идентификатора.
* @return HAL_StatusTypeDef Статус выполнения функции HAL, например HAL_OK при успехе.
*/
__weak HAL_StatusTypeDef ProtoCanMsgToAnalogTSens(struct RXMsg _rxMsg)
{
CAN_TxHeaderTypeDef TxHeader;
uint32_t TxMailBox = 0;
uint8_t data[8];
TxHeader.IDE = CAN_ID_EXT;
TxHeader.TransmitGlobalTime = DISABLE;
TxHeader.RTR = CAN_RTR_DATA;
extID tmp_eID;
tmp_eID.BitAll = _rxMsg.eID.BitAll;
tmp_eID.Fields.Route = ROUTE_SLAVE;
TxHeader.ExtId = tmp_eID.BitAll;
TxHeader.DLC = 6;
msgAnalogType msg;
msg.Body = _rxMsg.eID.Fields.MsgBody;
data[0] = 'T';
data[1] = 'S';
data[2] = 47 + msg.Fields.SensorID / 1000;
data[3] = 47 + msg.Fields.SensorID / 100 % 10;
data[4] = 47 + msg.Fields.SensorID / 10 % 10;
data[5] = 47 + msg.Fields.SensorID % 10;
return HAL_CAN_AddTxMessage(_HCAN, &TxHeader, data, &TxMailBox);
}
/**
* @brief Функция обработки широковещательных запросов.
* @param struct RXMsg _rxMsg - структура для полученного сообщения.
* @details Функция, выполняющая команды, переданные в широковещательном формате с головного (master) устройства. Типы команд: Запрос статуса, запрос на включение или выключение, рестарт устройств, установка времени.
* @return HAL_StatusTypeDef Статус выполнения команды CAN (успех или ошибка).
*/
HAL_StatusTypeDef PROTOCAN_BroadcastProcessing(struct RXMsg _rxMsg)
PROTOCAN_StatusTypeDef PROTOCAN_BroadcastProcessing(struct RXMsg _rxMsg)
{
msgBroadcastType msg;
msgBodyBroadcastType msg;
msg.Body = _rxMsg.eID.Fields.MsgBody;
switch(msg.Fields.BroadcastType)
switch(msg.Fields.Type)
{
case SENSOR_TYPE_BROADCAST_STATUS:
case PROTOCAN_BROADCAST_STATUS:
{
//Обработка запроса статуса устройства
return ProtoCanMsgToBroadcastStatus(_rxMsg);
}
case SENSOR_TYPE_BROADCAST_ONOFF:
case PROTOCAN_BROADCAST_ONOFF:
{
//Обработка запроса на вкл/выкл
ProtoCanMsgToBroadcastOnOff(_rxMsg);
break;
}
case SENSOR_TYPE_BROADCAST_RESTARTDEVICE:
case PROTOCAN_BROADCAST_RESTARTDEVICE:
{
ProtoCanMsgToBroadcastRestart(_rxMsg);
break;
}
case SENSOR_TYPE_BROADCAST_RTCSETUP:
case PROTOCAN_BROADCAST_RTCSETUP:
{
//Обработка запроса на синхронизацию времени
//С головным устройством
@@ -377,10 +184,10 @@ HAL_StatusTypeDef PROTOCAN_BroadcastProcessing(struct RXMsg _rxMsg)
}
default:
//RESERVE SENSOR TYPE.
return HAL_ERROR;
return PROTOCAN_ERROR;
break;
}
return HAL_OK;
return PROTOCAN_OK;
}
/**
@@ -389,7 +196,7 @@ HAL_StatusTypeDef PROTOCAN_BroadcastProcessing(struct RXMsg _rxMsg)
* @param _rxMsg Структура полученного по CAN запроса.
* @return HAL_StatusTypeDef Статус операции HAL, например HAL_OK при успехе.
*/
__weak HAL_StatusTypeDef ProtoCanMsgToBroadcastStatus(struct RXMsg _rxMsg)
__weak PROTOCAN_StatusTypeDef ProtoCanMsgToBroadcastStatus(struct RXMsg _rxMsg)
{
CAN_TxHeaderTypeDef TxHeader;
uint32_t TxMailBox = 0;
@@ -398,9 +205,9 @@ __weak HAL_StatusTypeDef ProtoCanMsgToBroadcastStatus(struct RXMsg _rxMsg)
TxHeader.DLC = 7;
TxHeader.TransmitGlobalTime = DISABLE;
TxHeader.RTR = CAN_RTR_DATA;
extID tmp_eID;
ProtoCanId_t tmp_eID;
tmp_eID.BitAll = _rxMsg.eID.BitAll;
tmp_eID.Fields.Route = ROUTE_SLAVE;
tmp_eID.Fields.Route = PROTOCAN_ROUTE_FROM_DEVICE;
tmp_eID.Fields.DeviceType = CURRENT_TYPE_DEVICE;
tmp_eID.Fields.DeviceID = CURRENT_ID_DEVICE;
TxHeader.ExtId = tmp_eID.BitAll;
@@ -418,7 +225,7 @@ __weak HAL_StatusTypeDef ProtoCanMsgToBroadcastStatus(struct RXMsg _rxMsg)
data[5] = DateToUpdate.Date;
data[6] = DateToUpdate.WeekDay;
return HAL_CAN_AddTxMessage(_HCAN, &TxHeader, data, &TxMailBox);
return (PROTOCAN_StatusTypeDef)HAL_CAN_AddTxMessage(_HCAN, &TxHeader, data, &TxMailBox);
}
/**
@@ -427,9 +234,10 @@ __weak HAL_StatusTypeDef ProtoCanMsgToBroadcastStatus(struct RXMsg _rxMsg)
* В данном случае — просто инвертирует его логическое значение.
* @param _rxMsg Структура полученного CAN-сообщения (Пока не используется в функции).
*/
__weak void ProtoCanMsgToBroadcastOnOff(struct RXMsg _rxMsg)
__weak PROTOCAN_StatusTypeDef ProtoCanMsgToBroadcastOnOff(struct RXMsg _rxMsg)
{
ControlFlags.IsPulse = !ControlFlags.IsPulse;
return PROTOCAN_OK;
}
/**
@@ -438,15 +246,15 @@ __weak void ProtoCanMsgToBroadcastOnOff(struct RXMsg _rxMsg)
* вызывает системный перезапуск.
* @param _rxMsg Структура полученного CAN-сообщения с командой перезапуска.
*/
__weak void ProtoCanMsgToBroadcastRestart(struct RXMsg _rxMsg)
__weak PROTOCAN_StatusTypeDef ProtoCanMsgToBroadcastRestart(struct RXMsg _rxMsg)
{
if(_rxMsg.DLC == 0)
{
return;
return PROTOCAN_ERROR;
}
msgBroadcastType msg;
msgBodyBroadcastType msg;
msg.Body = _rxMsg.eID.Fields.MsgBody;
if(msg.Fields.Page == (CURRENT_ID_DEVICE / (_rxMsg.DLC*8)))
if(msg.Fields.Body == (CURRENT_ID_DEVICE / (_rxMsg.DLC*8)))
{
uint64_t page = 0;
for(int i = 0; i < _rxMsg.DLC; i++)
@@ -458,7 +266,7 @@ __weak void ProtoCanMsgToBroadcastRestart(struct RXMsg _rxMsg)
NVIC_SystemReset();
}
}
return;
return PROTOCAN_OK;
}
/**
@@ -467,10 +275,10 @@ __weak void ProtoCanMsgToBroadcastRestart(struct RXMsg _rxMsg)
* вызывает функцию синхронизации RTC.
* @param _rxMsg Структура полученного CAN-сообщения с данными для установки времени и даты.
*/
__weak void ProtoCanMsgToBroadcastRtcSetup(struct RXMsg _rxMsg)
__weak PROTOCAN_StatusTypeDef ProtoCanMsgToBroadcastRtcSetup(struct RXMsg _rxMsg)
{
if(_rxMsg.DLC > 7) {
//ERROR
return PROTOCAN_ERROR;
} else {
int DaysCount_Normal[2][12] = {{31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
{31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}};
@@ -481,11 +289,13 @@ __weak void ProtoCanMsgToBroadcastRtcSetup(struct RXMsg _rxMsg)
_rxMsg.Data[4] > 12 ||
_rxMsg.Data[5] > DaysCount_Normal[IsLeapYear(_rxMsg.Data[3])][_rxMsg.Data[4]] ||
_rxMsg.Data[6] > 6) {
return PROTOCAN_ERROR;
//ERROR
} else {
PROTOCAN_RTC_SYNC(_rxMsg.Data);
}
}
return PROTOCAN_OK;
}
/**
@@ -495,52 +305,52 @@ __weak void ProtoCanMsgToBroadcastRtcSetup(struct RXMsg _rxMsg)
* @note Запрос на устройство. Головное (master) устройство запрашивает некоторое колличество параметров. В Data - 64 битовых адресса параметров, тип которых задаётся в Sensor ID. Имеется возможность запрашивать непоследовательные параметры.
* @return HAL_StatusTypeDef Статус выполнения команды CAN (успех или ошибка).
*/
HAL_StatusTypeDef PROTOCAN_DiscreticProcessing(struct RXMsg _rxMsg)
PROTOCAN_StatusTypeDef PROTOCAN_DiscreticProcessing(struct RXMsg _rxMsg)
{
msgDiscreteType msg;
msgBodyDiscreteType msg;
msg.Body = _rxMsg.eID.Fields.MsgBody;
switch(msg.Fields.Type){
case SENSOR_TYPE_DISCRETE_ACCIDENT:
case PROTOCAN_DISCRETE_ACCIDENT:
{
ProtoCanMsgToDiscreteAccident(_rxMsg);
break;
}
case SENSOR_TYPE_DISCRETE_WARNING:
case PROTOCAN_DISCRETE_WARNING:
{
ProtoCanMsgToDiscreteWarning(_rxMsg);
break;
}
case SENSOR_TYPE_DISCRETE_CONTROL_SIGNALS:
case PROTOCAN_DISCRETE_CONTROL_SIGNALS:
{
ProtoCanMsgToDiscreteControlSignals(_rxMsg);
break;
}
case SENSOR_TYPE_DISCRETE_FLAGS:
case PROTOCAN_DISCRETE_FLAGS:
{
ProtoCanMsgToDiscreteFlags(_rxMsg);
break;
}
case SENSOR_TYPE_DISCRETE_RESET:
case PROTOCAN_DISCRETE_RESET:
{
ProtoCanMsgToDiscreteReset(_rxMsg);
break;
}
case SENSOR_TYPE_DISCRETE_CHANGE_MODE:
case PROTOCAN_DISCRETE_CHANGE_MODE:
{
ProtoCanMsgToDiscreteChangeMode(_rxMsg);
break;
}
case SENSOR_TYPE_DISCRETE_REQUEST_LIST_OF_PARAMETERS:
case PROTOCAN_DISCRETE_REQUEST_LIST_OF_PARAMETERS:
{
ProtoCanMsgToDiscreteRequestListOfParameters(_rxMsg);
break;
}
default:
//RESERVE SENSOR TYPE.
return HAL_ERROR;
return PROTOCAN_ERROR;
break;
}
return HAL_OK;
return PROTOCAN_OK;
}
/**
@@ -549,9 +359,9 @@ HAL_StatusTypeDef PROTOCAN_DiscreticProcessing(struct RXMsg _rxMsg)
* Можно реализовать отправку или обработку аварийных данных.
* @param _rxMsg Входящее сообщение с данными запроса.
*/
__weak void ProtoCanMsgToDiscreteAccident(struct RXMsg _rxMsg)
__weak PROTOCAN_StatusTypeDef ProtoCanMsgToDiscreteAccident(struct RXMsg _rxMsg)
{
return;
return PROTOCAN_OK;
}
/**
@@ -560,9 +370,9 @@ __weak void ProtoCanMsgToDiscreteAccident(struct RXMsg _rxMsg)
* Можно реализовать обработку или ответ на предупреждения.
* @param _rxMsg Входящее сообщение.
*/
__weak void ProtoCanMsgToDiscreteWarning(struct RXMsg _rxMsg)
__weak PROTOCAN_StatusTypeDef ProtoCanMsgToDiscreteWarning(struct RXMsg _rxMsg)
{
return;
return PROTOCAN_OK;
}
/**
@@ -571,9 +381,9 @@ __weak void ProtoCanMsgToDiscreteWarning(struct RXMsg _rxMsg)
* Можно реализовать управление сигналами.
* @param _rxMsg Входящее сообщение.
*/
__weak void ProtoCanMsgToDiscreteControlSignals(struct RXMsg _rxMsg)
__weak PROTOCAN_StatusTypeDef ProtoCanMsgToDiscreteControlSignals(struct RXMsg _rxMsg)
{
return;
return PROTOCAN_OK;
}
/**
@@ -582,9 +392,9 @@ __weak void ProtoCanMsgToDiscreteControlSignals(struct RXMsg _rxMsg)
* Можно реализовать работу с флагами.
* @param _rxMsg Входящее сообщение.
*/
__weak void ProtoCanMsgToDiscreteFlags(struct RXMsg _rxMsg)
__weak PROTOCAN_StatusTypeDef ProtoCanMsgToDiscreteFlags(struct RXMsg _rxMsg)
{
return;
return PROTOCAN_OK;
}
/**
@@ -592,9 +402,10 @@ __weak void ProtoCanMsgToDiscreteFlags(struct RXMsg _rxMsg)
* Выполняет программный рестарт системы.
* @param _rxMsg Входящее сообщение.
*/
__weak void ProtoCanMsgToDiscreteReset(struct RXMsg _rxMsg)
__weak PROTOCAN_StatusTypeDef ProtoCanMsgToDiscreteReset(struct RXMsg _rxMsg)
{
NVIC_SystemReset();
return PROTOCAN_ERROR;
}
/**
@@ -603,9 +414,9 @@ __weak void ProtoCanMsgToDiscreteReset(struct RXMsg _rxMsg)
* Можно реализовать изменение режима работы.
* @param _rxMsg Входящее сообщение.
*/
__weak void ProtoCanMsgToDiscreteChangeMode(struct RXMsg _rxMsg)
__weak PROTOCAN_StatusTypeDef ProtoCanMsgToDiscreteChangeMode(struct RXMsg _rxMsg)
{
return;
return PROTOCAN_OK;
}
/**
@@ -614,17 +425,63 @@ __weak void ProtoCanMsgToDiscreteChangeMode(struct RXMsg _rxMsg)
* Можно реализовать отправку списка параметров.
* @param _rxMsg Входящее сообщение.
*/
__weak void ProtoCanMsgToDiscreteRequestListOfParameters(struct RXMsg _rxMsg)
__weak PROTOCAN_StatusTypeDef ProtoCanMsgToDiscreteRequestListOfParameters(struct RXMsg _rxMsg)
{
return;
return PROTOCAN_OK;
}
/**
* @brief Обработка и ответ на запрос общего адресного пространства.
* Формирует и передает сообщение с данными о статусе "GAS-XXXX", где XXXX — значение из сообщения _rxMsg.
* @param _rxMsg Структура входящего сообщения, содержит идентификатор и тело сообщения.
* @brief Функция обработки аналоговых запросов.
* @param struct RXMsg _rxMsg - структура для полученного сообщения.
* @details Функция, сортирующая запросы по типам и вызывающая соответствующие функции. Типы запросов: Универсальный, Уставки, Напряжение, Ток, Температура.
* @return HAL_StatusTypeDef Статус выполнения команды CAN (успех или ошибка).
*/
void PROTOCAN_GeneralAddressSpace_Answer(struct RXMsg _rxMsg)
PROTOCAN_StatusTypeDef PROTOCAN_AnalogProcessing(struct RXMsg _rxMsg)
{
msgBodyAnalogType msg;
msg.Body = _rxMsg.eID.Fields.MsgBody;
switch (msg.Fields.Type)
{
case PROTOCAN_ANALOG_UNIVERSAL:
{
return ProtoCanMsgToAnalogUniversal(_rxMsg);
break;
}
case PROTOCAN_ANALOG_SETTINGS:
{
return ProtoCanMsgToAnalogSettings(_rxMsg);
break;
}
case PROTOCAN_ANALOG_U:
{
return ProtoCanMsgToAnalogUSens(_rxMsg);
break;
}
case PROTOCAN_ANALOG_I:
{
return ProtoCanMsgToAnalogISens(_rxMsg);
break;
}
case PROTOCAN_ANALOG_T:
{
return ProtoCanMsgToAnalogTSens(_rxMsg);
break;
}
default:
//RESERVE SENSOR TYPE
return PROTOCAN_ERROR;
break;
}
return PROTOCAN_ERROR;
}
/**
* @brief Функция ответа на запрос данных со всех датчиков.
* Создает сообщение с определенными данными и отправляет его через CAN-шину.
* @param _rxMsg Структура входящего сообщения, используется для формирования ID.
* @return HAL_StatusTypeDef Статус выполнения операции HAL, например HAL_OK.
*/
__weak PROTOCAN_StatusTypeDef ProtoCanMsgToAnalogUniversal(struct RXMsg _rxMsg)
{
CAN_TxHeaderTypeDef TxHeader;
uint32_t TxMailBox = 0;
@@ -632,9 +489,155 @@ void PROTOCAN_GeneralAddressSpace_Answer(struct RXMsg _rxMsg)
TxHeader.IDE = CAN_ID_EXT;
TxHeader.TransmitGlobalTime = DISABLE;
TxHeader.RTR = CAN_RTR_DATA;
extID tmp_eID;
ProtoCanId_t tmp_eID;
tmp_eID.BitAll = _rxMsg.eID.BitAll;
tmp_eID.Fields.Route = ROUTE_SLAVE;
tmp_eID.Fields.Route = PROTOCAN_ROUTE_FROM_DEVICE;
TxHeader.ExtId = tmp_eID.BitAll;
TxHeader.DLC = 6;
data[0] = 'U';
data[1] = 'N';
data[2] = 'I';
data[3] = 'V';
data[4] = 'E';
data[5] = 'R';
return (PROTOCAN_StatusTypeDef)HAL_CAN_AddTxMessage(_HCAN, &TxHeader, data, &TxMailBox);
}
/**
* @brief Функция ответа на запрос уставок по CAN.
* Создает сообщение с определенными данными и отправляет его через CAN-шину.
* @param _rxMsg Структура входящего сообщения, используется только для формирования ID.
* @return HAL_StatusTypeDef Статус выполнения операции HAL, например HAL_OK.
*/
__weak PROTOCAN_StatusTypeDef ProtoCanMsgToAnalogSettings(struct RXMsg _rxMsg)
{
CAN_TxHeaderTypeDef TxHeader;
uint32_t TxMailBox = 0;
uint8_t data[8];
TxHeader.IDE = CAN_ID_EXT;
TxHeader.TransmitGlobalTime = DISABLE;
TxHeader.RTR = CAN_RTR_DATA;
ProtoCanId_t tmp_eID;
tmp_eID.BitAll = _rxMsg.eID.BitAll;
tmp_eID.Fields.Route = PROTOCAN_ROUTE_FROM_DEVICE;
TxHeader.ExtId = tmp_eID.BitAll;
TxHeader.DLC = 7;
data[0] = 'U';
data[1] = 'S';
data[2] = 'T';
data[3] = 'A';
data[4] = 'V';
data[5] = 'K';
data[6] = 'I';
return (PROTOCAN_StatusTypeDef)HAL_CAN_AddTxMessage(_HCAN, &TxHeader, data, &TxMailBox);
}
/**
* @brief Функция ответа на запрос данных с датчиков напряжения.
* Создает сообщение с указанными параметрами и отправляет его через CAN-шину.
* @param _rxMsg Структура входящего сообщения, используемая для формирования идентификатора и данных.
* @return HAL_StatusTypeDef Статус выполнения операции HAL, например HAL_OK при успешной отправке.
*/
__weak PROTOCAN_StatusTypeDef ProtoCanMsgToAnalogUSens(struct RXMsg _rxMsg)
{
CAN_TxHeaderTypeDef TxHeader;
uint32_t TxMailBox = 0;
uint8_t data[8];
TxHeader.IDE = CAN_ID_EXT;
TxHeader.TransmitGlobalTime = DISABLE;
TxHeader.RTR = CAN_RTR_DATA;
ProtoCanId_t tmp_eID;
tmp_eID.BitAll = _rxMsg.eID.BitAll;
tmp_eID.Fields.Route = PROTOCAN_ROUTE_FROM_DEVICE;
TxHeader.ExtId = tmp_eID.BitAll;
TxHeader.DLC = 6;
msgBodyAnalogType msg;
msg.Body = _rxMsg.eID.Fields.MsgBody;
data[0] = 'U';
data[1] = 'S';
data[2] = 47 + msg.Fields.SensorID / 1000;
data[3] = 47 + msg.Fields.SensorID / 100 % 10;
data[4] = 47 + msg.Fields.SensorID / 10 % 10;
data[5] = 47 + msg.Fields.SensorID % 10;
return (PROTOCAN_StatusTypeDef)HAL_CAN_AddTxMessage(_HCAN, &TxHeader, data, &TxMailBox);
}
/**
* @brief Функция ответа на запрос данных с датчиков тока.
* Создает сообщение с определенными параметрами и отправляет его через CAN-шину.
* @param _rxMsg Структура входящего сообщения, используется для формирования идентификатора и данных.
* @return HAL_StatusTypeDef Статус операции HAL, например HAL_OK при успешной отправке.
*/
__weak PROTOCAN_StatusTypeDef ProtoCanMsgToAnalogISens(struct RXMsg _rxMsg)
{
CAN_TxHeaderTypeDef TxHeader;
uint32_t TxMailBox = 0;
uint8_t data[8];
TxHeader.IDE = CAN_ID_EXT;
TxHeader.TransmitGlobalTime = DISABLE;
TxHeader.RTR = CAN_RTR_DATA;
ProtoCanId_t tmp_eID;
tmp_eID.BitAll = _rxMsg.eID.BitAll;
tmp_eID.Fields.Route = PROTOCAN_ROUTE_FROM_DEVICE;
TxHeader.ExtId = tmp_eID.BitAll;
TxHeader.DLC = 6;
msgBodyAnalogType msg;
msg.Body = _rxMsg.eID.Fields.MsgBody;
data[0] = 'I';
data[1] = 'S';
data[2] = 47 + msg.Fields.SensorID / 1000;
data[3] = 47 + msg.Fields.SensorID / 100 % 10;
data[4] = 47 + msg.Fields.SensorID / 10 % 10;
data[5] = 47 + msg.Fields.SensorID % 10;
return (PROTOCAN_StatusTypeDef)HAL_CAN_AddTxMessage(_HCAN, &TxHeader, data, &TxMailBox);
}
/**
* @brief Функция ответа на запрос данных с датчиков температуры.
* Создает сообщение с определенным заголовком, формирует данные по ID сенсора и отправляет его через CAN.
* @param _rxMsg Структура полученного сообщения, которая используется для формирования идентификатора.
* @return HAL_StatusTypeDef Статус выполнения функции HAL, например HAL_OK при успехе.
*/
__weak PROTOCAN_StatusTypeDef ProtoCanMsgToAnalogTSens(struct RXMsg _rxMsg)
{
CAN_TxHeaderTypeDef TxHeader;
uint32_t TxMailBox = 0;
uint8_t data[8];
TxHeader.IDE = CAN_ID_EXT;
TxHeader.TransmitGlobalTime = DISABLE;
TxHeader.RTR = CAN_RTR_DATA;
ProtoCanId_t tmp_eID;
tmp_eID.BitAll = _rxMsg.eID.BitAll;
tmp_eID.Fields.Route = PROTOCAN_ROUTE_FROM_DEVICE;
TxHeader.ExtId = tmp_eID.BitAll;
TxHeader.DLC = 6;
msgBodyAnalogType msg;
msg.Body = _rxMsg.eID.Fields.MsgBody;
data[0] = 'T';
data[1] = 'S';
data[2] = 47 + msg.Fields.SensorID / 1000;
data[3] = 47 + msg.Fields.SensorID / 100 % 10;
data[4] = 47 + msg.Fields.SensorID / 10 % 10;
data[5] = 47 + msg.Fields.SensorID % 10;
return (PROTOCAN_StatusTypeDef)HAL_CAN_AddTxMessage(_HCAN, &TxHeader, data, &TxMailBox);
}
/**
* @brief Обработка и ответ на запрос общего адресного пространства.
* Формирует и передает сообщение с данными о статусе "GAS-XXXX", где XXXX — значение из сообщения _rxMsg.
* @param _rxMsg Структура входящего сообщения, содержит идентификатор и тело сообщения.
*/
__weak PROTOCAN_StatusTypeDef ProtoCanMsgToGeneralAddressSpace(struct RXMsg _rxMsg)
{
CAN_TxHeaderTypeDef TxHeader;
uint32_t TxMailBox = 0;
uint8_t data[8];
TxHeader.IDE = CAN_ID_EXT;
TxHeader.TransmitGlobalTime = DISABLE;
TxHeader.RTR = CAN_RTR_DATA;
ProtoCanId_t tmp_eID;
tmp_eID.BitAll = _rxMsg.eID.BitAll;
tmp_eID.Fields.Route = PROTOCAN_ROUTE_FROM_DEVICE;
TxHeader.ExtId = tmp_eID.BitAll;
TxHeader.DLC = 8;
data[0] = 'G';
@@ -653,7 +656,9 @@ void PROTOCAN_GeneralAddressSpace_Answer(struct RXMsg _rxMsg)
data[4+i] = sym+'0';
}
}
HAL_CAN_AddTxMessage(_HCAN, &TxHeader, data, &TxMailBox);
return (PROTOCAN_StatusTypeDef)HAL_CAN_AddTxMessage(_HCAN, &TxHeader, data, &TxMailBox);
}
}
/**
@@ -663,36 +668,36 @@ void PROTOCAN_GeneralAddressSpace_Answer(struct RXMsg _rxMsg)
* @param _rxMsg Структура входящего сообщения RXMsg.
* @return HAL_StatusTypeDef Статус выполнения команды CAN (успех или ошибка).
*/
HAL_StatusTypeDef PROTOCAN_ModbusProcessing(struct RXMsg _rxMsg)
PROTOCAN_StatusTypeDef PROTOCAN_ModbusProcessing(struct RXMsg _rxMsg)
{
switch(_rxMsg.eID.Fields.MsgType)
{
case DATA_TYPE_MODBUS_COIL:
case PROTOCAN_MSGTYPE_MODBUS_COIL:
{
return ProtoCanMsgToModbusCoil(_rxMsg);
break;
}
case DATA_TYPE_MODBUS_DISCRETE:
case PROTOCAN_MSGTYPE_MODBUS_DISCRETE:
{
return ProtoCanMsgToModbusDiscrete(_rxMsg);
break;
}
case DATA_TYPE_MODBUS_HOLDING:
case PROTOCAN_MSGTYPE_MODBUS_HOLDING:
{
return ProtoCanMsgToModbusHolding(_rxMsg);
break;
}
case DATA_TYPE_MODBUS_INPUT:
case PROTOCAN_MSGTYPE_MODBUS_INPUT:
{
return ProtoCanMsgToModbusInput(_rxMsg);
break;
}
default:
//ERROR
return HAL_ERROR;
return PROTOCAN_ERROR;
break;
}
return HAL_ERROR;
return PROTOCAN_ERROR;
}
/**
@@ -701,7 +706,7 @@ HAL_StatusTypeDef PROTOCAN_ModbusProcessing(struct RXMsg _rxMsg)
* @param _rxMsg Структура входящего сообщения RXMsg.
* @return HAL_StatusTypeDef Статус выполнения команды CAN (успех или ошибка).
*/
__weak HAL_StatusTypeDef ProtoCanMsgToModbusCoil(struct RXMsg _rxMsg)
__weak PROTOCAN_StatusTypeDef ProtoCanMsgToModbusCoil(struct RXMsg _rxMsg)
{
CAN_TxHeaderTypeDef TxHeader;
uint32_t TxMailBox = 0;
@@ -709,12 +714,12 @@ __weak HAL_StatusTypeDef ProtoCanMsgToModbusCoil(struct RXMsg _rxMsg)
TxHeader.IDE = CAN_ID_EXT;
TxHeader.TransmitGlobalTime = DISABLE;
TxHeader.RTR = CAN_RTR_DATA;
extID tmp_eID;
ProtoCanId_t tmp_eID;
tmp_eID.BitAll = _rxMsg.eID.BitAll;
tmp_eID.Fields.Route = ROUTE_SLAVE;
tmp_eID.Fields.Route = PROTOCAN_ROUTE_FROM_DEVICE;
TxHeader.ExtId = tmp_eID.BitAll;
TxHeader.DLC = 8;
msgModbusType msg;
msgBodyModbusType msg;
msg.Body = _rxMsg.eID.Fields.MsgBody;
data[0] = 'M';
data[1] = 'C';
@@ -724,7 +729,7 @@ __weak HAL_StatusTypeDef ProtoCanMsgToModbusCoil(struct RXMsg _rxMsg)
data[5] = ' ';
data[6] = 'C';
data[7] = msg.Fields.RegCount;
return HAL_CAN_AddTxMessage(_HCAN, &TxHeader, data, &TxMailBox);
return (PROTOCAN_StatusTypeDef)HAL_CAN_AddTxMessage(_HCAN, &TxHeader, data, &TxMailBox);
}
/**
@@ -733,7 +738,7 @@ __weak HAL_StatusTypeDef ProtoCanMsgToModbusCoil(struct RXMsg _rxMsg)
* @param _rxMsg Структура входящего сообщения RXMsg.
* @return HAL_StatusTypeDef Статус выполнения команды CAN (успех или ошибка).
*/
__weak HAL_StatusTypeDef ProtoCanMsgToModbusDiscrete(struct RXMsg _rxMsg)
__weak PROTOCAN_StatusTypeDef ProtoCanMsgToModbusDiscrete(struct RXMsg _rxMsg)
{
CAN_TxHeaderTypeDef TxHeader;
uint32_t TxMailBox = 0;
@@ -741,12 +746,12 @@ __weak HAL_StatusTypeDef ProtoCanMsgToModbusDiscrete(struct RXMsg _rxMsg)
TxHeader.IDE = CAN_ID_EXT;
TxHeader.TransmitGlobalTime = DISABLE;
TxHeader.RTR = CAN_RTR_DATA;
extID tmp_eID;
ProtoCanId_t tmp_eID;
tmp_eID.BitAll = _rxMsg.eID.BitAll;
tmp_eID.Fields.Route = ROUTE_SLAVE;
tmp_eID.Fields.Route = PROTOCAN_ROUTE_FROM_DEVICE;
TxHeader.ExtId = tmp_eID.BitAll;
TxHeader.DLC = 8;
msgModbusType msg;
msgBodyModbusType msg;
msg.Body = _rxMsg.eID.Fields.MsgBody;
data[0] = 'M';
data[1] = 'D';
@@ -756,7 +761,7 @@ __weak HAL_StatusTypeDef ProtoCanMsgToModbusDiscrete(struct RXMsg _rxMsg)
data[5] = ' ';
data[6] = 'C';
data[7] = msg.Fields.RegCount;
return HAL_CAN_AddTxMessage(_HCAN, &TxHeader, data, &TxMailBox);
return (PROTOCAN_StatusTypeDef)HAL_CAN_AddTxMessage(_HCAN, &TxHeader, data, &TxMailBox);
}
/**
@@ -765,7 +770,7 @@ __weak HAL_StatusTypeDef ProtoCanMsgToModbusDiscrete(struct RXMsg _rxMsg)
* @param _rxMsg Структура входящего сообщения RXMsg.
* @return HAL_StatusTypeDef Статус выполнения команды CAN (успех или ошибка).
*/
__weak HAL_StatusTypeDef ProtoCanMsgToModbusHolding(struct RXMsg _rxMsg)
__weak PROTOCAN_StatusTypeDef ProtoCanMsgToModbusHolding(struct RXMsg _rxMsg)
{
CAN_TxHeaderTypeDef TxHeader;
uint32_t TxMailBox = 0;
@@ -773,12 +778,12 @@ __weak HAL_StatusTypeDef ProtoCanMsgToModbusHolding(struct RXMsg _rxMsg)
TxHeader.IDE = CAN_ID_EXT;
TxHeader.TransmitGlobalTime = DISABLE;
TxHeader.RTR = CAN_RTR_DATA;
extID tmp_eID;
ProtoCanId_t tmp_eID;
tmp_eID.BitAll = _rxMsg.eID.BitAll;
tmp_eID.Fields.Route = ROUTE_SLAVE;
tmp_eID.Fields.Route = PROTOCAN_ROUTE_FROM_DEVICE;
TxHeader.ExtId = tmp_eID.BitAll;
TxHeader.DLC = 8;
msgModbusType msg;
msgBodyModbusType msg;
msg.Body = _rxMsg.eID.Fields.MsgBody;
data[0] = 'M';
data[1] = 'H';
@@ -788,7 +793,7 @@ __weak HAL_StatusTypeDef ProtoCanMsgToModbusHolding(struct RXMsg _rxMsg)
data[5] = ' ';
data[6] = 'C';
data[7] = msg.Fields.RegCount;
return HAL_CAN_AddTxMessage(_HCAN, &TxHeader, data, &TxMailBox);
return (PROTOCAN_StatusTypeDef)HAL_CAN_AddTxMessage(_HCAN, &TxHeader, data, &TxMailBox);
}
/**
@@ -797,7 +802,7 @@ __weak HAL_StatusTypeDef ProtoCanMsgToModbusHolding(struct RXMsg _rxMsg)
* @param _rxMsg Структура входящего сообщения RXMsg.
* @return HAL_StatusTypeDef Статус выполнения команды CAN (успех или ошибка).
*/
__weak HAL_StatusTypeDef ProtoCanMsgToModbusInput(struct RXMsg _rxMsg)
__weak PROTOCAN_StatusTypeDef ProtoCanMsgToModbusInput(struct RXMsg _rxMsg)
{
CAN_TxHeaderTypeDef TxHeader;
uint32_t TxMailBox = 0;
@@ -805,12 +810,12 @@ __weak HAL_StatusTypeDef ProtoCanMsgToModbusInput(struct RXMsg _rxMsg)
TxHeader.IDE = CAN_ID_EXT;
TxHeader.TransmitGlobalTime = DISABLE;
TxHeader.RTR = CAN_RTR_DATA;
extID tmp_eID;
ProtoCanId_t tmp_eID;
tmp_eID.BitAll = _rxMsg.eID.BitAll;
tmp_eID.Fields.Route = ROUTE_SLAVE;
tmp_eID.Fields.Route = PROTOCAN_ROUTE_FROM_DEVICE;
TxHeader.ExtId = tmp_eID.BitAll;
TxHeader.DLC = 8;
msgModbusType msg;
msgBodyModbusType msg;
msg.Body = _rxMsg.eID.Fields.MsgBody;
data[0] = 'M';
data[1] = 'I';
@@ -820,7 +825,7 @@ __weak HAL_StatusTypeDef ProtoCanMsgToModbusInput(struct RXMsg _rxMsg)
data[5] = ' ';
data[6] = 'C';
data[7] = msg.Fields.RegCount;
return HAL_CAN_AddTxMessage(_HCAN, &TxHeader, data, &TxMailBox);
return (PROTOCAN_StatusTypeDef)HAL_CAN_AddTxMessage(_HCAN, &TxHeader, data, &TxMailBox);
}
/**
@@ -829,7 +834,7 @@ __weak HAL_StatusTypeDef ProtoCanMsgToModbusInput(struct RXMsg _rxMsg)
* @param _rxMsg Структура входящего сообщения RXMsg, данными которого формируется ответ-ошибка.
* @return HAL_StatusTypeDef Статус выполнения команды CAN.
*/
__weak HAL_StatusTypeDef CanRequestError(struct RXMsg _rxMsg)
__weak PROTOCAN_StatusTypeDef CanRequestError(struct RXMsg _rxMsg)
{
CAN_TxHeaderTypeDef TxHeader;
uint32_t TxMailBox = 0;
@@ -837,17 +842,17 @@ __weak HAL_StatusTypeDef CanRequestError(struct RXMsg _rxMsg)
TxHeader.IDE = CAN_ID_EXT;
TxHeader.TransmitGlobalTime = DISABLE;
TxHeader.RTR = CAN_RTR_DATA;
extID tmp_eID;
ProtoCanId_t tmp_eID;
tmp_eID.BitAll = _rxMsg.eID.BitAll;
tmp_eID.Fields.Route = ROUTE_SLAVE;
tmp_eID.Fields.MsgType = DATA_TYPE_ERROR;
msgErrorType msg;
tmp_eID.Fields.Route = PROTOCAN_ROUTE_FROM_DEVICE;
tmp_eID.Fields.MsgType = PROTOCAN_MSGTYPE_ERROR;
msgBodyErrorType msg;
msg.Fields.ErrorCode = 0xFF;
msg.Fields.Info = 0;
tmp_eID.Fields.MsgBody = msg.Body;
TxHeader.ExtId = tmp_eID.BitAll;
TxHeader.DLC = 0;
return HAL_CAN_AddTxMessage(_HCAN, &TxHeader, data, &TxMailBox);
return (PROTOCAN_StatusTypeDef)HAL_CAN_AddTxMessage(_HCAN, &TxHeader, data, &TxMailBox);
}
/**
@@ -860,7 +865,7 @@ __weak HAL_StatusTypeDef CanRequestError(struct RXMsg _rxMsg)
* @param tmp_DATA Указатель на массив данных, полученных из CAN.
* @param tmp_LastStep Индекс позиции в буфере, куда записывать сообщение.
*/
void TakeRxMsgToBuffer(extID tmp_eID, uint32_t tmp_IDE, uint32_t tmp_RTR, uint32_t tmp_DLC, uint8_t *tmp_DATA, uint16_t tmp_LastStep)
void TakeRxMsgToBuffer(ProtoCanId_t tmp_eID, uint32_t tmp_IDE, uint32_t tmp_RTR, uint32_t tmp_DLC, uint8_t *tmp_DATA, uint16_t tmp_LastStep)
{
rxMsg[tmp_LastStep].eID.BitAll = tmp_eID.BitAll;
rxMsg[tmp_LastStep].info.EXT = tmp_IDE;
@@ -888,19 +893,19 @@ void ProtoCanRxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan)
//Расширенный ID
if(RxHeader.IDE == CAN_ID_EXT)
{
if(!((CAN_RX_BUFFER_SIZE + LastStep - (CurrentStep-1))&CAN_RX_BUFFER_SIZE))
if(!((PROTOCAN_RX_BUFFER_SIZE + LastStep - (CurrentStep-1))&PROTOCAN_RX_BUFFER_SIZE))
{
//Буффер переполнен
return;
}
uint16_t tmp_LastStep = (uint16_t)(LastStep + 1) % CAN_RX_BUFFER_SIZE;
uint16_t tmp_LastStep = (uint16_t)(LastStep + 1) % PROTOCAN_RX_BUFFER_SIZE;
extID ExtID_Of_RX_MSG;
ProtoCanId_t ExtID_Of_RX_MSG;
ExtID_Of_RX_MSG.BitAll = RxHeader.ExtId;
//Полученное сообщение - пульс устройств в сети
if(ExtID_Of_RX_MSG.Fields.MsgType == DATA_TYPE_PULSE)
if(ExtID_Of_RX_MSG.Fields.MsgType == PROTOCAN_MSGTYPE_PULSE)
{
Device_on_the_Network[ExtID_Of_RX_MSG.Fields.DeviceType][ExtID_Of_RX_MSG.Fields.DeviceID].Status = ONLINE;
Device_on_the_Network[ExtID_Of_RX_MSG.Fields.DeviceType][ExtID_Of_RX_MSG.Fields.DeviceID].TimeFromLastPulse = 0;
@@ -923,14 +928,14 @@ void ProtoCanPulseCallback(TIM_HandleTypeDef *htim)
static unsigned PulseStage = 0;
CAN_TxHeaderTypeDef TxHeader;
uint32_t TxMailBox = 0;
extID currentID;
ProtoCanId_t currentID;
currentID.BitAll = 0;
currentID.Fields.MsgBody = 0;
currentID.Fields.DeviceID = CURRENT_ID_DEVICE;
currentID.Fields.Priority = PROTOCAN_PRIORITY_STANDARD;
currentID.Fields.Route = PROTOCAN_ROUTE_FROM_DEVICE;
currentID.Fields.DeviceType = CURRENT_TYPE_DEVICE;
currentID.Fields.MsgType = DATA_TYPE_PULSE;
currentID.Fields.Route = ROUTE_SLAVE;
currentID.Fields.Priority = PRIORITY_STANDARD;
currentID.Fields.DeviceID = CURRENT_ID_DEVICE;
currentID.Fields.MsgType = PROTOCAN_MSGTYPE_PULSE;
currentID.Fields.MsgBody = 0;
TxHeader.ExtId = currentID.BitAll;
uint8_t data[8];
TxHeader.IDE = CAN_ID_EXT;
@@ -988,52 +993,54 @@ void PROTOCAN_RTC_SYNC(uint8_t *data)
*/
void PROTOCAN_CONFIG_FILTER(uint8_t filterBank, uint32_t idFilter, uint32_t idMask)
{
CAN_FilterTypeDef canFilterConfig;
canFilterConfig.FilterBank = filterBank;
canFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;
canFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT;
canFilterConfig.FilterFIFOAssignment = CAN_RX_FIFO0;
canFilterConfig.FilterActivation = ENABLE;
canFilterConfig.SlaveStartFilterBank = 14;
CAN_FilterTypeDef canFilterConfig;
canFilterConfig.FilterBank = filterBank;
canFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;
canFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT;
canFilterConfig.FilterFIFOAssignment = CAN_RX_FIFO0;
canFilterConfig.FilterActivation = ENABLE;
canFilterConfig.SlaveStartFilterBank = 14;
// Разбиваем 32-битный ID и маску для фильтрации на High и Low 16 бит
canFilterConfig.FilterIdHigh = (uint16_t)(((idFilter) >> 13)); // верхние 16 бит
canFilterConfig.FilterIdLow = (uint16_t)((((idFilter) << 3)) | CAN_IDE_32); // низкие 16 бит,
canFilterConfig.FilterMaskIdHigh = (uint16_t)(((idMask) >> 13));
canFilterConfig.FilterMaskIdLow = (uint16_t)((((idMask) << 3)) | CAN_IDE_32);
#define CAN_IDE_32 0b00000100 // Для 32-х битного масштаба
// Разбиваем 32-битный ID и маску для фильтрации на High и Low 16 бит
canFilterConfig.FilterIdHigh = (uint16_t)(((idFilter) >> 13)); // верхние 16 бит
canFilterConfig.FilterIdLow = (uint16_t)((((idFilter) << 3)) | CAN_IDE_32); // низкие 16 бит,
canFilterConfig.FilterMaskIdHigh = (uint16_t)(((idMask) >> 13));
canFilterConfig.FilterMaskIdLow = (uint16_t)((((idMask) << 3)) | CAN_IDE_32);
if(HAL_CAN_ConfigFilter(_HCAN, &canFilterConfig) != HAL_OK)
{
Error_Handler();
}
if(HAL_CAN_ConfigFilter(_HCAN, &canFilterConfig) != HAL_OK)
{
Error_Handler();
}
}
#define BIT27 (1UL << 27)
#define BITS_20_23_MASK (0xFUL << 20) // 4 бита (20..23)
#define BITS_24_26_MASK (0x7UL << 24) // 3 бита (24..26)
uint32_t filter1_id = BIT27 | (CURRENT_TYPE_DEVICE << 24) | (CURRENT_ID_DEVICE << 20);
uint32_t filter1_mask = BIT27 | BITS_24_26_MASK | BITS_20_23_MASK; // все проверяемые биты
#define BITS_16_19_MASK (0xFUL << 16)
uint32_t filter2_id = DATA_TYPE_BROADCAST << 16;
uint32_t filter2_mask = BITS_16_19_MASK;
uint32_t filter3_id = DATA_TYPE_PULSE << 16;
uint32_t filter3_mask = BITS_16_19_MASK;
/**
* @brief Конфигурирует три фильтра CAN для различных типов сообщений.
*/
void PROTOCAN_FILTERS()
{
// Первый фильтр: проверяем 20-27 биты, где 27-й всегда 1
PROTOCAN_CONFIG_FILTER(0, filter1_id, filter1_mask);
#define BIT27 (1UL << 27)
#define BITS_20_23_MASK (0xFUL << 20) // 4 бита (20..23)
#define BITS_24_26_MASK (0x7UL << 24) // 3 бита (24..26)
uint32_t filter1_id = BIT27 | (CURRENT_TYPE_DEVICE << 24) | (CURRENT_ID_DEVICE << 20);
uint32_t filter1_mask = BIT27 | BITS_24_26_MASK | BITS_20_23_MASK; // все проверяемые биты
// Второй фильтр: проверяем 16-19 биты, равны DATA_TYPE_BROADCASTE
PROTOCAN_CONFIG_FILTER(1, filter2_id, filter2_mask);
#define BITS_16_19_MASK (0xFUL << 16)
// Третий фильтр: проверяем 16-19 биты, равны DATA_TYPE_PULSE
PROTOCAN_CONFIG_FILTER(2, filter3_id, filter3_mask);
uint32_t filter2_id = PROTOCAN_MSGTYPE_BROADCAST << 16;
uint32_t filter2_mask = BITS_16_19_MASK;
uint32_t filter3_id = PROTOCAN_MSGTYPE_PULSE << 16;
uint32_t filter3_mask = BITS_16_19_MASK;
// Первый фильтр: проверяем 20-27 биты, где 27-й всегда 1
PROTOCAN_CONFIG_FILTER(0, filter1_id, filter1_mask);
// Второй фильтр: проверяем 16-19 биты, равны PROTOCAN_MSGTYPE_BROADCASTE
PROTOCAN_CONFIG_FILTER(1, filter2_id, filter2_mask);
// Третий фильтр: проверяем 16-19 биты, равны PROTOCAN_MSGTYPE_PULSE
PROTOCAN_CONFIG_FILTER(2, filter3_id, filter3_mask);
}

View File

@@ -21,7 +21,8 @@
#include "tim.h"
/* USER CODE BEGIN 0 */
// TIM defines
#define TIM_PROTOCAN_Prescaler 64000
/* USER CODE END 0 */
TIM_HandleTypeDef htim4;