CAN_Request-Response_protocol/Core/Src/requester.c

620 lines
22 KiB
C
Raw 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.

#include "requester.h"
static union Byte byte[2048][8];
#define byte_modbusadr(x) byte[x/64][(x%64)/8]
#define _GET_MODBUS_BIT(x) byte[x/64][(x%64)/8].AllBit>>((x%64)%8)
#define _GET_MODBUS_ADR(SensorId, RequestedBytePosition, RequestedBitPosition) SensorId*64 + RequestedBytePosition*8 + RequestedBitPosition
uint16_t ModbusFilters[COUNT_OF_MODBUS_SECTIONS][2];
struct device CurrentDevice;
struct device Device_on_the_Network[32];
struct data Data;
struct controlflags ControlFlags;
struct received_request ReceivedRequest;
#define MAX_NUM_OF_DEVICES_PER_LINE 4
#define MAX_NUM_OF_REGISTERS_IN_DEVICE 255
//Регистр это слово (16 бит). uint16
uint16_t ModbusDemonstration[MAX_NUM_OF_DEVICES_PER_LINE][MAX_NUM_OF_REGISTERS_IN_DEVICE];
uint16_t ModbusAlternativeTable[MAX_NUM_OF_DEVICES_PER_LINE*MAX_NUM_OF_REGISTERS_IN_DEVICE];
_Bool IsLeapYear(uint8_t year)
{
year+=2000;
return (year%400==0)||((year%4==0)&&(year%100!=0));
}
/**
* @brief Инициализация переферии
* @details Инициализация HAL, CAN, TIM7, RTC.
* @note Фильтры CAN описаны в разделе REQUESTER_CAN_FILTERS().
*/
void REQUESTER_Init(void)
{
HAL_Init();
MX_CAN_Init();
HAL_CAN_Start(&hcan);
REQUESTER_CAN_FILTERS();
HAL_CAN_ActivateNotification(&hcan, CAN_IT_RX_FIFO0_MSG_PENDING);
ControlFlags.IsPulse = 1;
MX_TIM7_Init();
MX_RTC_Init();
#ifdef _DEMO
int Reg_AltModbusTable;
//Тестовые значения регистров. Для отладки/демонстрации
for(int x = 0; x < MAX_NUM_OF_DEVICES_PER_LINE; x++)
{
for(int y = 0; y < MAX_NUM_OF_REGISTERS_IN_DEVICE; y++)
{
ModbusDemonstration[x][y] = x<<8 | y;
Reg_AltModbusTable = x*MAX_NUM_OF_REGISTERS_IN_DEVICE+y;
ModbusAlternativeTable[Reg_AltModbusTable] = x<<8 | y;
}
}
#endif
}
int ProverkaDefinaResult;
int ProverkaDefinaItem = 0;
int ProverkaArbitors = 0;
/**
* @brief Функция с обработкой полученных запросов
* @details В бесконечном цикле функция ожидает выставление флага о полученном запросе.
* Обработка запроса аналоговых значений - REQUESTER_AnalogProcessing().
* Обработка широковещательных запросов - REQUESTER_BroadcastProcessing().
* Обработка запроса дискретных значений - REQUESTER_DiscreticProcessing().
* Обработка Modbus - REQUESTER_ModbusProcessing().
* @note
*/
void REQUESTER_MainWhile(void)
{
CAN_TxHeaderTypeDef TxHeader;
uint32_t TxMailBox = 0;
uint8_t data[8];
union ext_ID eID;
eID.Fields.DeviceID = 16;
eID.Fields.DataType = DATA_TYPE_ANALOG;
eID.Fields.SensorType = 0x1F;
eID.Fields.SensorID = 0;
eID.Fields.Route = ROUTE_SLAVE;
TxHeader.TransmitGlobalTime = DISABLE;
TxHeader.RTR = CAN_RTR_DATA;
int TxTest = 0;
HAL_TIM_Base_Start_IT(&htim7);
while(1)
{
if(ReceivedRequest.AnalogFlags.AllFlags)
{
REQUESTER_AnalogProcessing();
}
if(ReceivedRequest.BroadcastFlags.AllFlags)
{
REQUESTER_BroadcastProcessing();
}
if(ReceivedRequest.DiscreticFlags.AllFlags)
{
REQUESTER_DiscreticProcessing();
}
if(ReceivedRequest.ModbusFlags.AllFlags)
{
REQUESTER_ModbusProcessing();
}
while(HAL_CAN_GetTxMailboxesFreeLevel(&hcan) == 0);
TxHeader.ExtId = eID.BitAll;
if(HAL_CAN_AddTxMessage(&hcan, &TxHeader, data, &TxMailBox)!= HAL_OK)
{
ProverkaArbitors++;
}
eID.Fields.SensorID++;
if(eID.Fields.SensorID>100)
{
eID.Fields.SensorID = 0;
}
}
}
/**
* @brief Функция обработки аналоговых запросов.
* @details Функция, формирующая и отправляющая ответ на запросы. Типы запросов: Универсальный, Уставки, Напряжение, Ток, Температура
*/
void REQUESTER_AnalogProcessing()
{
CAN_TxHeaderTypeDef TxHeader;
uint32_t TxMailBox = 0;
uint8_t data[8];
if(ReceivedRequest.AnalogFlags.AnalogType.Request_Universal_Sens)
{
ReceivedRequest.AnalogFlags.AnalogType.Request_Universal_Sens = 0;
}
if(ReceivedRequest.AnalogFlags.AnalogType.Request_U_Sens)
{
//Запрос на данные датчика напряжения.
//В дальнейшем реализовать отправку настоящих данных.
//А пока - тестовое сообщение, нужное для отладки.
//Расширенный ID
TxHeader.IDE=CAN_ID_EXT;
//Ответ на запрос осуществляется по тому-же ID,
//с которым был отправлен запрос.
union ext_ID eID;
eID.BitAll = ReceivedRequest.RequestedExtID.BitAll;
eID.Fields.Route = ROUTE_SLAVE;
TxHeader.ExtId = eID.BitAll;
//Выставляется количество передаваемых байтов. (Макс. 8)
TxHeader.DLC = 6;
data[0] = 'U';
data[1] = ' ';
data[2] = 's';
data[3] = 'e';
data[4] = 'n';
data[5] = 's';
HAL_CAN_AddTxMessage(&hcan, &TxHeader, data, &TxMailBox);
ReceivedRequest.AnalogFlags.AnalogType.Request_U_Sens=0;
}
if(ReceivedRequest.AnalogFlags.AnalogType.Request_I_Sens)
{
TxHeader.IDE=CAN_ID_EXT;
union ext_ID eID;
eID.BitAll = ReceivedRequest.RequestedExtID.BitAll;
eID.Fields.Route = ROUTE_SLAVE;
TxHeader.ExtId = eID.BitAll;
TxHeader.DLC = 6;
data[0] = 'I';
data[1] = ' ';
data[2] = 's';
data[3] = 'e';
data[4] = 'n';
data[5] = 's';
HAL_CAN_AddTxMessage(&hcan, &TxHeader, data, &TxMailBox);
ReceivedRequest.AnalogFlags.AnalogType.Request_I_Sens=0;
}
if(ReceivedRequest.AnalogFlags.AnalogType.Request_T_Sens)
{
TxHeader.IDE=CAN_ID_EXT;
union ext_ID eID;
eID.BitAll = ReceivedRequest.RequestedExtID.BitAll;
eID.Fields.Route = ROUTE_SLAVE;
TxHeader.ExtId = eID.BitAll;
TxHeader.DLC = 6;
data[0] = 'T';
data[1] = ' ';
data[2] = 's';
data[3] = 'e';
data[4] = 'n';
data[5] = 's';
HAL_CAN_AddTxMessage(&hcan, &TxHeader, data, &TxMailBox);
ReceivedRequest.AnalogFlags.AnalogType.Request_T_Sens=0;
}
}
/**
* @brief Функция обработки широковещательных запросов.
* @details Функция, выполняющая команды, переданные в широковещательном формате с головного (master) устройства. Типы команд: Запрос статуса, запрос на включение или выключение, рестарт устройств, установка времени.
*/
void REQUESTER_BroadcastProcessing()
{
if(ReceivedRequest.BroadcastFlags.BroadcastType.Request_OnOff)
{
//Обработка запроса на вкл/выкл
ControlFlags.IsPulse = !ControlFlags.IsPulse;
ReceivedRequest.BroadcastFlags.BroadcastType.Request_OnOff = 0;
}
if(ReceivedRequest.BroadcastFlags.BroadcastType.Request_RTC_Setup)
{
//Обработка запроса на синхронизацию времени
//С головным устройством
if(ReceivedRequest.RequestedDLC > 7)
{
//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}};
if (ReceivedRequest.RxData[0]>23 ||
ReceivedRequest.RxData[1]>59 ||
ReceivedRequest.RxData[2]>59 ||
ReceivedRequest.RxData[3]>99 ||
ReceivedRequest.RxData[4]>12 ||
ReceivedRequest.RxData[5] > DaysCount_Normal[IsLeapYear(ReceivedRequest.RxData[3])][ReceivedRequest.RxData[4]] ||
ReceivedRequest.RxData[6]>6)
{
//ERROR
}
else
{
REQUESTER_RTC_SYNC(ReceivedRequest.RxData);
}
}
ReceivedRequest.BroadcastFlags.BroadcastType.Request_RTC_Setup = 0;
}
if(ReceivedRequest.BroadcastFlags.BroadcastType.Request_Status)
{
//Обработка запроса статуса устройства
RTC_TimeTypeDef sTime = {0};
RTC_DateTypeDef DateToUpdate = {0};
HAL_RTC_GetTime(&hrtc, &sTime, RTC_FORMAT_BIN);
CAN_TxHeaderTypeDef TxHeader;
uint32_t TxMailBox = 0;
uint8_t data[8];
TxHeader.IDE=CAN_ID_EXT;
union ext_ID eID;
eID.BitAll = ReceivedRequest.RequestedExtID.BitAll;
eID.Fields.Route = ROUTE_SLAVE;
TxHeader.ExtId = eID.BitAll;
TxHeader.DLC = 7;
data[0] = sTime.Hours;
data[1] = sTime.Minutes;
data[2] = sTime.Seconds;
HAL_RTC_GetDate(&hrtc, &DateToUpdate, RTC_FORMAT_BIN);
data[3] = DateToUpdate.Year;
data[4] = DateToUpdate.Month;
data[5] = DateToUpdate.Date;
data[6] = DateToUpdate.WeekDay;
HAL_CAN_AddTxMessage(&hcan, &TxHeader, data, &TxMailBox);
ReceivedRequest.AnalogFlags.AnalogType.Request_T_Sens=0;
ReceivedRequest.BroadcastFlags.BroadcastType.Request_Status = 0;
}
}
/**
* @brief Функция обработки дискретных запросов.
* @details Функция, формирующая и отправляющая ответ на запросы. Типы запросов: Аварии, Предупреждения, Управляющие сигналы, Флаги, Рестарт устройства, Изменение режима работы устройства, Запрос на устройство.
* @note Запрос на устройство. Головное (master) устройство запрашивает некоторое колличество параметров. В Data - 64 битовых адресса параметров, тип которых задаётся в Sensor ID. Имеется возможность запрашивать непоследовательные параметры.
*/
void REQUESTER_DiscreticProcessing()
{
if(ReceivedRequest.DiscreticFlags.DiscreticType.Request_Accident)
{
ReceivedRequest.DiscreticFlags.DiscreticType.Request_Accident = 0;
}
if(ReceivedRequest.DiscreticFlags.DiscreticType.Request_Control_Signals)
{
ReceivedRequest.DiscreticFlags.DiscreticType.Request_Control_Signals = 0;
}
if(ReceivedRequest.DiscreticFlags.DiscreticType.Request_Flags)
{
ReceivedRequest.DiscreticFlags.DiscreticType.Request_Flags = 0;
}
if(ReceivedRequest.DiscreticFlags.DiscreticType.Request_Warning)
{
ReceivedRequest.DiscreticFlags.DiscreticType.Request_Warning = 0;
}
if(ReceivedRequest.DiscreticFlags.DiscreticType.Request_Reset)
{
ReceivedRequest.DiscreticFlags.DiscreticType.Request_Reset = 0;
NVIC_SystemReset();
}
if(ReceivedRequest.DiscreticFlags.DiscreticType.Request_List_of_Parameters)
{
ReceivedRequest.DiscreticFlags.DiscreticType.Request_List_of_Parameters = 0;
for(int Current_byte = 0; Current_byte < 8; Current_byte++)
{
for(int Current_bit = 0; Current_bit < 8; Current_bit++)
{
if((ReceivedRequest.RxData[Current_byte]>>Current_bit)&0b1)
{
_GET_MODBUS_ADR(ReceivedRequest.RequestedExtID.Fields.SensorID, Current_byte, Current_bit);
}
}
}
}
}
/**
* @brief Функция обработки Modbus запросов.
* @details Функция, формирующая и отправляющая ответ на запросы.
*/
void REQUESTER_ModbusProcessing()
{
if((ReceivedRequest.SensorToModbus.Modbus.StrAdr>=0) && (ReceivedRequest.SensorToModbus.Modbus.StrAdr<=127))
{
//Обращение к существующему в устройстве модбас регистру
CAN_TxHeaderTypeDef TxHeader;
uint32_t TxMailBox = 0;
uint8_t data[8];
TxHeader.IDE = CAN_ID_EXT;
TxHeader.DLC = 8;
TxHeader.RTR = CAN_RTR_DATA;
int RequestFromDLC;
for(RequestFromDLC = ReceivedRequest.SensorToModbus.Modbus.StrAdr;
(RequestFromDLC<MAX_NUM_OF_REGISTERS_IN_DEVICE) &&
((RequestFromDLC-ReceivedRequest.SensorToModbus.Modbus.StrAdr)<ReceivedRequest.SensorToModbus.Modbus.Count);
// RequestFromDLC++
)
{
TxHeader.DLC = 0;
union ext_ID eID;
eID.BitAll = ReceivedRequest.RequestedExtID.BitAll;
eID.Fields.Route = ROUTE_SLAVE;
eID.Fields.SensorType = RequestFromDLC>>11;
eID.Fields.SensorID = RequestFromDLC;
TxHeader.ExtId = eID.BitAll;
for(int DataFor = 0; DataFor < 8; DataFor+=2)
{
data[DataFor] = HighByteOfWord(ModbusDemonstration[CURRENT_ID_DEVICE][RequestFromDLC]);
data[DataFor+1] = LowByteOfWord(ModbusDemonstration[CURRENT_ID_DEVICE][RequestFromDLC]);
RequestFromDLC++;
TxHeader.DLC +=2;
if(!((RequestFromDLC<MAX_NUM_OF_REGISTERS_IN_DEVICE) &&
((RequestFromDLC-ReceivedRequest.SensorToModbus.Modbus.StrAdr)<ReceivedRequest.SensorToModbus.Modbus.Count)))
{
break;
}
}
while(HAL_CAN_GetTxMailboxesFreeLevel(&hcan) == 0);
HAL_CAN_AddTxMessage(&hcan, &TxHeader, data, &TxMailBox);
}
union ext_ID_Modbus extID;
extID.Fields.DeviceID = CURRENT_ID_DEVICE;
extID.Fields.DataType = DATA_TYPE_ERROR;
extID.Fields.CountReg = NONEXISTENT_ELEMENT;
extID.Fields.Route = ROUTE_SLAVE;
TxHeader.DLC = 0;
for(;(RequestFromDLC-ReceivedRequest.SensorToModbus.Modbus.StrAdr)<ReceivedRequest.SensorToModbus.Modbus.Count; RequestFromDLC++)
{
extID.Fields.StrAdr = RequestFromDLC;
TxHeader.ExtId = extID.BitAll;
while(HAL_CAN_GetTxMailboxesFreeLevel(&hcan) == 0);
HAL_CAN_AddTxMessage(&hcan, &TxHeader, data, &TxMailBox);
}
ReceivedRequest.ModbusFlags.AllFlags = 0;
return;
}
ReceivedRequest.ModbusFlags.AllFlags = 0;
}
void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan)
{
CAN_RxHeaderTypeDef RxHeader;
uint8_t RCAN_Data[8];
HAL_CAN_GetRxMessage(hcan, CAN_RX_FIFO0, &RxHeader, RCAN_Data);
//Расширенный ID
if(RxHeader.IDE == CAN_ID_EXT)
{
union ext_ID ExtID_Of_RX_MSG;
ExtID_Of_RX_MSG.BitAll = RxHeader.ExtId;
//Полученное сообщение - широковещательное
if (ExtID_Of_RX_MSG.Fields.DeviceID == ID_MAIN_DEVICE)
{
if(ExtID_Of_RX_MSG.Fields.DataType == DATA_TYPE_BROADCAST)
{
switch(ExtID_Of_RX_MSG.Fields.SensorType)
{
case SENSOR_TYPE_STATUS:
ReceivedRequest.BroadcastFlags.BroadcastType.Request_Status = 1;
break;
case SENSOR_TYPE_ONOFF:
ReceivedRequest.BroadcastFlags.BroadcastType.Request_OnOff = 1;
break;
case SENSOR_TYPE_RTCSETUP:
ReceivedRequest.RequestedDLC = RxHeader.DLC;
ReceivedRequest.RxData[0] = RCAN_Data[0];
ReceivedRequest.RxData[1] = RCAN_Data[1];
ReceivedRequest.RxData[2] = RCAN_Data[2];
ReceivedRequest.RxData[3] = RCAN_Data[3];
ReceivedRequest.RxData[4] = RCAN_Data[4];
ReceivedRequest.RxData[5] = RCAN_Data[5];
ReceivedRequest.RxData[6] = RCAN_Data[6];
ReceivedRequest.BroadcastFlags.BroadcastType.Request_RTC_Setup = 1;
break;
default:
break;
}
return;
}
}
//Если ID запроса соответствует ID устройства
if(ExtID_Of_RX_MSG.Fields.DeviceID == (CURRENT_ID_DEVICE))
{
if(ExtID_Of_RX_MSG.Fields.DataType == DATA_TYPE_DISCRETE)
{
switch(ExtID_Of_RX_MSG.Fields.SensorType)
{
case SENSOR_TYPE_ACCIDENT:
break;
case SENSOR_TYPE_WARNING:
break;
case SENSOR_TYPE_CONTROL_SIGNALS:
break;
case SENSOR_TYPE_FLAGS:
break;
case SENSOR_TYPE_RESET:
ReceivedRequest.DiscreticFlags.DiscreticType.Request_Reset = 1;
break;
case SENSOR_TYPE_CHANGE_MODE:
ControlFlags.IsRtrMode = !ControlFlags.IsRtrMode;
break;
case SENSOR_TYPE_REQUEST_LIST_OF_PARAMETERS:
ReceivedRequest.DiscreticFlags.DiscreticType.Request_List_of_Parameters = 1;
break;
}
}
if(ExtID_Of_RX_MSG.Fields.DataType == DATA_TYPE_ANALOG)
{
//Является ли полученное сообщение - запросом
if(RxHeader.RTR)
{
ReceivedRequest.RequestedExtID.BitAll = ExtID_Of_RX_MSG.BitAll;
ReceivedRequest.RequestedDLC = RxHeader.DLC;
//Определяется запрашиваемая информация
switch(ExtID_Of_RX_MSG.Fields.SensorType)
{
case SENSOR_TYPE_UNIVERSAL:
{
ReceivedRequest.AnalogFlags.AnalogType.Request_Universal_Sens=1;
break;
}
case SENSOR_TYPE_U:
{
ReceivedRequest.AnalogFlags.AnalogType.Request_U_Sens=1;
break;
}
case SENSOR_TYPE_I:
{
ReceivedRequest.AnalogFlags.AnalogType.Request_I_Sens=1;
break;
}
case SENSOR_TYPE_T:
{
ReceivedRequest.AnalogFlags.AnalogType.Request_T_Sens=1;
break;
}
}
}
}
if(ExtID_Of_RX_MSG.Fields.DataType == DATA_TYPE_MODBUS_COIL)
{
ReceivedRequest.RequestedExtID.BitAll = ExtID_Of_RX_MSG.BitAll;
ReceivedRequest.SensorToModbus.Sensor = SensorToModbusRegister(ReceivedRequest.RequestedExtID.Fields.SensorType, ReceivedRequest.RequestedExtID.Fields.SensorID);
ReceivedRequest.ModbusFlags.ModbusType.Coil = 1;
}
if(ExtID_Of_RX_MSG.Fields.DataType == DATA_TYPE_MODBUS_DISCRETE)
{
ReceivedRequest.RequestedExtID.BitAll = ExtID_Of_RX_MSG.BitAll;
ReceivedRequest.SensorToModbus.Sensor = SensorToModbusRegister(ReceivedRequest.RequestedExtID.Fields.SensorType, ReceivedRequest.RequestedExtID.Fields.SensorID);
ReceivedRequest.ModbusFlags.ModbusType.Discrete = 1;
}
if(ExtID_Of_RX_MSG.Fields.DataType == DATA_TYPE_MODBUS_HOLDING)
{
ReceivedRequest.RequestedExtID.BitAll = ExtID_Of_RX_MSG.BitAll;
ReceivedRequest.SensorToModbus.Sensor = SensorToModbusRegister(ReceivedRequest.RequestedExtID.Fields.SensorType, ReceivedRequest.RequestedExtID.Fields.SensorID);
ReceivedRequest.ModbusFlags.ModbusType.Holding = 1;
}
if(ExtID_Of_RX_MSG.Fields.DataType == DATA_TYPE_MODBUS_INPUT)
{
ReceivedRequest.RequestedExtID.BitAll = ExtID_Of_RX_MSG.BitAll;
ReceivedRequest.SensorToModbus.Sensor = SensorToModbusRegister(ReceivedRequest.RequestedExtID.Fields.SensorType, ReceivedRequest.RequestedExtID.Fields.SensorID);
ReceivedRequest.ModbusFlags.ModbusType.Input = 1;
}
}
//Полученное сообщение - пульс устройств в сети
if (ExtID_Of_RX_MSG.Fields.DataType == DATA_TYPE_PULSE)
{
Device_on_the_Network[ExtID_Of_RX_MSG.Fields.DeviceID].Status = ONLINE;
Device_on_the_Network[ExtID_Of_RX_MSG.Fields.DeviceID].TimeFromLastPulse = 0;
}
}
}
void REQUESTER_Pulse_TIM_Handler()
{
if(ControlFlags.IsPulse)
{
static unsigned PulseStage = 0;
CAN_TxHeaderTypeDef TxHeader;
uint32_t TxMailBox = 0;
union ext_ID currentID;
currentID.BitAll = 0;
currentID.Fields.DeviceID = CURRENT_ID_DEVICE;
currentID.Fields.DataType = DATA_TYPE_PULSE;
currentID.Fields.Route = ROUTE_SLAVE;
TxHeader.ExtId = currentID.BitAll;
uint8_t data[8];
TxHeader.IDE = CAN_ID_EXT;
TxHeader.TransmitGlobalTime = DISABLE;
TxHeader.RTR = CAN_RTR_DATA;
TxHeader.DLC = 1;
if(PulseStage > 0xFF)
{
PulseStage = 0;
}
data[0] = PulseStage++;
HAL_CAN_AddTxMessage(&hcan, &TxHeader, data, &TxMailBox);
}
}
void REQUESTER_RTC_SYNC(uint8_t *data)
{
__HAL_RTC_WRITEPROTECTION_DISABLE(&hrtc);
RTC_TimeTypeDef sTime = {0};
RTC_DateTypeDef DateToUpdate = {0};
sTime.Hours = data[0];
sTime.Minutes = data[1];
sTime.Seconds = data[2];
if (HAL_RTC_SetTime(&hrtc, &sTime, RTC_FORMAT_BIN) != HAL_OK)
{
Error_Handler();
}
DateToUpdate.Year = data[3];
DateToUpdate.Month = data[4];
DateToUpdate.Date = data[5];
DateToUpdate.WeekDay = data[6];
if (HAL_RTC_SetDate(&hrtc, &DateToUpdate, RTC_FORMAT_BIN) != HAL_OK)
{
Error_Handler();
}
__HAL_RTC_WRITEPROTECTION_ENABLE(&hrtc);
}
void REQUESTER_CAN_FILTERS()
{
//MAIN DEVICE
CAN_FilterTypeDef canFilterConfig;
canFilterConfig.FilterBank = 0;
canFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;
canFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT;
/*Для ID устройства используются восемь младших битов.
Макс значение 0 устройство - 0x000, 1 - 0x002, 2 - 0x004, 3 - 0x006*/
canFilterConfig.FilterIdHigh = (uint16_t)(ID_MAIN_DEVICE>>13);
canFilterConfig.FilterIdLow = (uint16_t)(ID_MAIN_DEVICE<<5) | CAN_IDE_32;
/*Маска 1.1111.1110.<...>. Нули - любые символы. Единицы - точное соответствие фильтру выше.*/
canFilterConfig.FilterMaskIdHigh = (uint16_t)(CAN_DEVICE_ID_FILTER>>13);
canFilterConfig.FilterMaskIdLow = (uint16_t)(CAN_DEVICE_ID_FILTER<<3) | CAN_IDE_32;
canFilterConfig.FilterFIFOAssignment = CAN_RX_FIFO0;
canFilterConfig.FilterActivation = ENABLE;
canFilterConfig.SlaveStartFilterBank = 14;
if(HAL_CAN_ConfigFilter(&hcan, &canFilterConfig) != HAL_OK)
{
Error_Handler();
}
//CURRENT DEVICE
canFilterConfig.FilterBank = 1;
/*Для ID устройства используются восемь младших битов.
Макс значение 0 устройство - 0x000, 1 - 0x002, 2 - 0x004, 3 - 0x006*/
canFilterConfig.FilterIdHigh = (uint16_t)(CURRENT_ID_DEVICE>>13);
canFilterConfig.FilterIdLow = (uint16_t)(CURRENT_ID_DEVICE<<5) | CAN_IDE_32;
/*Маска 1.1111.1110.<...>. Нули - любые символы. Единицы - точное соответствие фильтру выше.*/
canFilterConfig.FilterMaskIdHigh = (uint16_t)(CAN_DEVICE_ID_FILTER>>13);
canFilterConfig.FilterMaskIdLow = (uint16_t)(CAN_DEVICE_ID_FILTER<<3) | CAN_IDE_32;
if(HAL_CAN_ConfigFilter(&hcan, &canFilterConfig) != HAL_OK)
{
Error_Handler();
}
//MODBUS
canFilterConfig.FilterBank = 2;
canFilterConfig.FilterIdHigh = (uint16_t)(0x03000000>>13);
canFilterConfig.FilterIdLow = (uint16_t)(0x03000000<<5) | CAN_IDE_32;
canFilterConfig.FilterMaskIdHigh = (uint16_t)(CAN_DATA_TYPE_FILTER>>13); // we're checking only high 13 bits, that contained "key"
canFilterConfig.FilterMaskIdLow = (uint16_t)(CAN_DATA_TYPE_FILTER<<3) | CAN_IDE_32; // 1<<2 - set IDE bit
if(HAL_CAN_ConfigFilter(&hcan, &canFilterConfig) != HAL_OK)
{
Error_Handler();
}
//PULSE
canFilterConfig.FilterBank = 3;
canFilterConfig.FilterIdHigh = (uint16_t)(HighIdFilter(DATA_TYPE_PULSE)>>13);
//canFilterConfig.FilterIdHigh = (uint16_t)(0x1F000000>>13);
canFilterConfig.FilterIdLow = (uint16_t)(HighIdFilter(DATA_TYPE_PULSE)<<5) | CAN_IDE_32;
canFilterConfig.FilterMaskIdHigh = (uint16_t)(CAN_DATA_TYPE_FILTER>>13); // we're checking only high 13 bits, that contained "key"
canFilterConfig.FilterMaskIdLow = (uint16_t)(CAN_DATA_TYPE_FILTER<<3) | CAN_IDE_32; // 1<<2 - set IDE bit
if(HAL_CAN_ConfigFilter(&hcan, &canFilterConfig) != HAL_OK)
{
Error_Handler();
}
}