620 lines
22 KiB
C
620 lines
22 KiB
C
#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();
|
||
}
|
||
}
|