#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; uint8_t CurrentStep = 0; uint8_t LastStep = 0; struct RXMsg rxMsg[CAN_RX_BUFFER_SIZE]; #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)); } uint16_t AvailableCanRxMsg(void) { return ((uint16_t)(CAN_RX_BUFFER_SIZE + LastStep - CurrentStep))%CAN_RX_BUFFER_SIZE; } /** * @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]; extID eID; eID.BitAll = 0; eID.StandardFields.DeviceID = 2; eID.StandardFields.DataType = DATA_TYPE_ANALOG; eID.StandardFields.SensorType = 0x1F; eID.StandardFields.SensorID = 0; eID.StandardFields.Route = ROUTE_SLAVE; TxHeader.IDE = CAN_ID_EXT; TxHeader.TransmitGlobalTime = DISABLE; TxHeader.RTR = CAN_RTR_DATA; TxHeader.ExtId = eID.BitAll; int TxTest = 0; HAL_TIM_Base_Start_IT(&htim7); while(1) { if(AvailableCanRxMsg()) { if(rxMsg[CurrentStep].eID.StandardFields.DataType == DATA_TYPE_ANALOG) { REQUESTER_AnalogProcessing(rxMsg[CurrentStep]); } else if(rxMsg[CurrentStep].eID.StandardFields.DataType == DATA_TYPE_BROADCAST) { REQUESTER_BroadcastProcessing(rxMsg[CurrentStep]); } else if(rxMsg[CurrentStep].eID.StandardFields.DataType == DATA_TYPE_DISCRETE) { REQUESTER_DiscreticProcessing(rxMsg[CurrentStep]); } else if(rxMsg[CurrentStep].eID.StandardFields.DataType == DATA_TYPE_MODBUS_COIL || rxMsg[CurrentStep].eID.StandardFields.DataType == DATA_TYPE_MODBUS_DISCRETE || rxMsg[CurrentStep].eID.StandardFields.DataType == DATA_TYPE_MODBUS_HOLDING || rxMsg[CurrentStep].eID.StandardFields.DataType == DATA_TYPE_MODBUS_INPUT) { REQUESTER_ModbusProcessing(rxMsg[CurrentStep]); } CurrentStep = (uint16_t)(CurrentStep + 1) % CAN_RX_BUFFER_SIZE; } /* while(HAL_CAN_GetTxMailboxesFreeLevel(&hcan) == 0); if(HAL_CAN_AddTxMessage(&hcan, &TxHeader, data, &TxMailBox)!= HAL_OK) { ProverkaArbitors++; } */ // eID.Fields.SensorID++; // if(eID.Fields.SensorID>10) //{ // eID.Fields.SensorID = 0; // } } } /** * @brief Функция обработки аналоговых запросов. * @details Функция, формирующая и отправляющая ответ на запросы. Типы запросов: Универсальный, Уставки, Напряжение, Ток, Температура */ void REQUESTER_AnalogProcessing(struct RXMsg _rxMsg) { switch (_rxMsg.eID.StandardFields.SensorType) { case SENSOR_TYPE_ANALOG_UNIVERSAL: { CanRequestToAnalogUniversal(_rxMsg); break; } case SENSOR_TYPE_ANALOG_USTAVKI: { CanRequestToAnalogUSTAVKI(_rxMsg); break; } case SENSOR_TYPE_ANALOG_U: { CanRequestToAnalogUSens(_rxMsg); break; } case SENSOR_TYPE_ANALOG_I: { CanRequestToAnalogISens(_rxMsg); break; } case SENSOR_TYPE_ANALOG_T: { CanRequestToAnalogTSens(_rxMsg); break; } default: //RESERVE SENSOR TYPE break; } } __weak HAL_StatusTypeDef CanRequestToAnalogUniversal(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.StandardFields.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); } __weak HAL_StatusTypeDef CanRequestToAnalogUSTAVKI(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.StandardFields.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); } __weak HAL_StatusTypeDef CanRequestToAnalogUSens(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.StandardFields.Route = ROUTE_SLAVE; TxHeader.ExtId = tmp_eID.BitAll; TxHeader.DLC = 6; data[0] = 'U'; data[1] = ' '; data[2] = 's'; data[3] = 'e'; data[4] = 'n'; data[5] = 's'; return HAL_CAN_AddTxMessage(&_HCAN, &TxHeader, data, &TxMailBox); } __weak HAL_StatusTypeDef CanRequestToAnalogISens(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.StandardFields.Route = ROUTE_SLAVE; TxHeader.ExtId = tmp_eID.BitAll; TxHeader.DLC = 6; data[0] = 'I'; data[1] = ' '; data[2] = 's'; data[3] = 'e'; data[4] = 'n'; data[5] = 's'; return HAL_CAN_AddTxMessage(&_HCAN, &TxHeader, data, &TxMailBox); } __weak HAL_StatusTypeDef CanRequestToAnalogTSens(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.StandardFields.Route = ROUTE_SLAVE; TxHeader.ExtId = tmp_eID.BitAll; TxHeader.DLC = 6; data[0] = 'T'; data[1] = ' '; data[2] = 's'; data[3] = 'e'; data[4] = 'n'; data[5] = 's'; return HAL_CAN_AddTxMessage(&_HCAN, &TxHeader, data, &TxMailBox); } /** * @brief Функция обработки широковещательных запросов. * @details Функция, выполняющая команды, переданные в широковещательном формате с головного (master) устройства. Типы команд: Запрос статуса, запрос на включение или выключение, рестарт устройств, установка времени. */ void REQUESTER_BroadcastProcessing(struct RXMsg _rxMsg) { switch(_rxMsg.eID.StandardFields.SensorType) { case SENSOR_TYPE_BROADCAST_STATUS: { //Обработка запроса статуса устройства CanRequestToBroadcastStatus(_rxMsg); break; } case SENSOR_TYPE_BROADCAST_ONOFF: { //Обработка запроса на вкл/выкл CanRequestToBroadcastOnOff(_rxMsg); break; } case SENSOR_TYPE_BROADCAST_RESTARTDEVICE: { CanRequestToBroadcastRestart(_rxMsg); break; } case SENSOR_TYPE_BROADCAST_RTCSETUP: { //Обработка запроса на синхронизацию времени //С головным устройством CanRequestToBroadcastRtcSetup(_rxMsg); break;; } default: //RESERVE SENSOR TYPE. break; } } __weak HAL_StatusTypeDef CanRequestToBroadcastStatus(struct RXMsg _rxMsg) { CAN_TxHeaderTypeDef TxHeader; uint32_t TxMailBox = 0; uint8_t data[8]; TxHeader.IDE = CAN_ID_EXT; TxHeader.DLC = 7; TxHeader.TransmitGlobalTime = DISABLE; TxHeader.RTR = CAN_RTR_DATA; extID tmp_eID; tmp_eID.BitAll = _rxMsg.eID.BitAll; tmp_eID.StandardFields.Route = ROUTE_SLAVE; tmp_eID.StandardFields.DeviceID = CURRENT_ID_DEVICE; TxHeader.ExtId = tmp_eID.BitAll; RTC_TimeTypeDef sTime = {0}; HAL_RTC_GetTime(&hrtc, &sTime, RTC_FORMAT_BIN); data[0] = sTime.Hours; data[1] = sTime.Minutes; data[2] = sTime.Seconds; RTC_DateTypeDef DateToUpdate = {0}; HAL_RTC_GetDate(&hrtc, &DateToUpdate, RTC_FORMAT_BIN); data[3] = DateToUpdate.Year; data[4] = DateToUpdate.Month; data[5] = DateToUpdate.Date; data[6] = DateToUpdate.WeekDay; return HAL_CAN_AddTxMessage(&_HCAN, &TxHeader, data, &TxMailBox); } __weak void CanRequestToBroadcastOnOff(struct RXMsg _rxMsg) { ControlFlags.IsPulse = !ControlFlags.IsPulse; } __weak void CanRequestToBroadcastRestart(struct RXMsg _rxMsg) { if(_rxMsg.DLC == 0) { return; } if(_rxMsg.eID.StandardFields.SensorID == (CURRENT_ID_DEVICE / (_rxMsg.DLC*8))) { uint64_t page = 0; for(int i = 0; i < _rxMsg.DLC; i++) { page+=(_rxMsg.Data[i]<<(i*8)); } if((page>>CURRENT_ID_DEVICE)&0b1) { NVIC_SystemReset(); } } return; } __weak void CanRequestToBroadcastRtcSetup(struct RXMsg _rxMsg) { if(_rxMsg.DLC > 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 (_rxMsg.Data[0]>23 || _rxMsg.Data[1]>59 || _rxMsg.Data[2]>59 || _rxMsg.Data[3]>99 || _rxMsg.Data[4]>12 || _rxMsg.Data[5] > DaysCount_Normal[IsLeapYear(_rxMsg.Data[3])][_rxMsg.Data[4]] || _rxMsg.Data[6]>6) { //ERROR } else { REQUESTER_RTC_SYNC(_rxMsg.Data); } } } /** * @brief Функция обработки дискретных запросов. * @details Функция, формирующая и отправляющая ответ на запросы. Типы запросов: Аварии, Предупреждения, Управляющие сигналы, Флаги, Рестарт устройства, Изменение режима работы устройства, Запрос на устройство. * @note Запрос на устройство. Головное (master) устройство запрашивает некоторое колличество параметров. В Data - 64 битовых адресса параметров, тип которых задаётся в Sensor ID. Имеется возможность запрашивать непоследовательные параметры. */ void REQUESTER_DiscreticProcessing(struct RXMsg _rxMsg) { switch(_rxMsg.eID.StandardFields.SensorType){ case SENSOR_TYPE_DISCRETE_ACCIDENT: { CanRequestToDiscreteAccident(_rxMsg); break; } case SENSOR_TYPE_DISCRETE_WARNING: { CanRequestToDiscreteWarning(_rxMsg); break; } case SENSOR_TYPE_DISCRETE_CONTROL_SIGNALS: { CanRequestToDiscreteControlSignals(_rxMsg); break; } case SENSOR_TYPE_DISCRETE_FLAGS: { CanRequestToDiscreteFlags(_rxMsg); break; } case SENSOR_TYPE_DISCRETE_RESET: { CanRequestToDiscreteReset(_rxMsg); break; } case SENSOR_TYPE_DISCRETE_CHANGE_MODE: { CanRequestToDiscreteChangeMode(_rxMsg); break; } case SENSOR_TYPE_DISCRETE_REQUEST_LIST_OF_PARAMETERS: { CanRequestToDiscreteRequestListOfParameters(_rxMsg); break; } default: //RESERVE SENSOR TYPE. break; } } __weak void CanRequestToDiscreteAccident(struct RXMsg _rxMsg) { return; } __weak void CanRequestToDiscreteWarning(struct RXMsg _rxMsg) { return; } __weak void CanRequestToDiscreteControlSignals(struct RXMsg _rxMsg) { return; } __weak void CanRequestToDiscreteFlags(struct RXMsg _rxMsg) { return; } __weak void CanRequestToDiscreteReset(struct RXMsg _rxMsg) { NVIC_SystemReset(); } __weak void CanRequestToDiscreteChangeMode(struct RXMsg _rxMsg) { return; } __weak void CanRequestToDiscreteRequestListOfParameters(struct RXMsg _rxMsg) { return; } /** * @brief Функция обработки Modbus запросов. * @details Функция, формирующая и отправляющая ответ на запросы. */ void REQUESTER_ModbusProcessing(struct RXMsg _rxMsg) { switch(_rxMsg.eID.ModbusFields.DataType) { case DATA_TYPE_MODBUS_COIL: { CanRequestToModbusCoil(_rxMsg); break; } case DATA_TYPE_MODBUS_DISCRETE: { CanRequestToModbusDiscrete(_rxMsg); break; } case DATA_TYPE_MODBUS_HOLDING: { CanRequestToModbusHolding(_rxMsg); break; } case DATA_TYPE_MODBUS_INPUT: { CanRequestToModbusInput(_rxMsg); break; } default: //ERROR break; } } __weak void CanRequestToModbusCoil(struct RXMsg _rxMsg) { return; } __weak void CanRequestToModbusDiscrete(struct RXMsg _rxMsg) { return; } __weak void CanRequestToModbusHolding(struct RXMsg _rxMsg) { return; } __weak void CanRequestToModbusInput(struct RXMsg _rxMsg) { return; } /* СТАРЫЙ УЖАСНЫЙ МОДБАС 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>11; eID.StandardFields.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 0xFF) { PulseStage = 0; } data[0] = PulseStage++; HAL_CAN_AddTxMessage(&_HCAN, &TxHeader, data, &TxMailBox); } } /** * @brief Функция установки в RTC полученной даты/время из запроса. * @param Байтовый массив, 7 элементов. [0] - Часы. [1] - Минуты. [2] - Секунды. [3] - Год. [4] - Месяц. [5] - Дата. [6] - День недели. */ 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); } /** * @brief Функция настройки фильтров CAN. * @details Настройка фильтров. Фильр для приёма сообщений с главного устройства. Фильтр для приёма на текущее устройство. Фильтр для приёма пульса других устройств в сети. */ 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(); } //DEBUG FILTER "ALL IDE WELCOME" canFilterConfig.FilterBank = 4; canFilterConfig.FilterIdHigh = (uint16_t)(HighIdFilter(0)>>13); canFilterConfig.FilterIdLow = (uint16_t)(HighIdFilter(0)<<5) | CAN_IDE_32; canFilterConfig.FilterMaskIdHigh = (uint16_t)(0>>13); // we're checking only high 13 bits, that contained "key" canFilterConfig.FilterMaskIdLow = (uint16_t)(0<<3) | CAN_IDE_32; // 1<<2 - set IDE bit if(HAL_CAN_ConfigFilter(&_HCAN, &canFilterConfig) != HAL_OK) { Error_Handler(); } }