Обновление стиля библиотеки
This commit is contained in:
+232
-255
@@ -8,270 +8,245 @@
|
||||
#define ONLINE 1;
|
||||
#define OFFLINE 0;
|
||||
|
||||
// TIM defines
|
||||
#define TIM_PROTOCAN_Prescaler 64000
|
||||
|
||||
//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
|
||||
|
||||
//CAN Filter
|
||||
#define ID_MAIN_DEVICE 0x000
|
||||
|
||||
#define CURRENT_TYPE_DEVICE 0b001
|
||||
#define CURRENT_ID_DEVICE 0b0010
|
||||
|
||||
#define CAN_IDE_32 0b00000100 // Для 32-х битного масштаба
|
||||
|
||||
#define CAN_DATA_TYPE_FILTER 0x1F000000
|
||||
#define CAN_DEVICE_ID_FILTER 0x000000FF
|
||||
#define CAN_SENSOR_TYPE_FILTER 0x00F80000
|
||||
#define CAN_SENSOR_ID_FILTER 0x0007FF00
|
||||
|
||||
typedef union{
|
||||
struct bitfield{
|
||||
unsigned bit0:1;
|
||||
unsigned bit1:1;
|
||||
unsigned bit2:1;
|
||||
unsigned bit3:1;
|
||||
unsigned bit4:1;
|
||||
unsigned bit5:1;
|
||||
unsigned bit6:1;
|
||||
unsigned bit7:1;
|
||||
}Bitfield;
|
||||
char AllBit;
|
||||
}Byte;
|
||||
|
||||
_Bool IsLeapYear(uint8_t year);
|
||||
|
||||
#define COUNT_OF_MODBUS_SECTIONS 1
|
||||
#define MODBUS_SECTION_MASK 0
|
||||
#define MODBUS_SECTION_FILTER 1
|
||||
#define PROTOCAN_RX_BUFFER_SIZE 128
|
||||
|
||||
#define SensorToModbusRegister(SensorType, SensorID) SensorType << 11 | SensorID
|
||||
#define HighByteOfWord(WORD) (WORD>>8)&0xFF
|
||||
#define LowByteOfWord(WORD) WORD&0xFF
|
||||
|
||||
//Priority level
|
||||
#define PRIORITY_CRITICAL 0
|
||||
#define PRIORITY_STANDARD 1
|
||||
/**
|
||||
* @brief Статус инициализации протокола CAN.
|
||||
*
|
||||
* Это перечисление описывает возможные статусы после попытки инициализации.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
PROTOCAN_INIT_OK = 0x00U, /**< Инициализация прошла успешно. */
|
||||
PROTOCAN_INIT_HCAN_ERROR = 0x01U, /**< Ошибка при инициализации модуля CAN. */
|
||||
PROTOCAN_INIT_HRTC_ERROR = 0x02U, /**< Ошибка при инициализации модуля RTC. */
|
||||
PROTOCAN_INIT_TIM_ERROR = 0x04U /**< Ошибка при инициализации таймера. */
|
||||
} PROTOCAN_INIT_StatusTypeDef;
|
||||
|
||||
//Route mode
|
||||
#define ROUTE_MASTER 1
|
||||
#define ROUTE_SLAVE 0
|
||||
/**
|
||||
* @brief Статус выполнения операции протокола CAN.
|
||||
*
|
||||
* Это перечисление описывает возможные результаты выполнения функций протокола.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
PROTOCAN_OK = 0x00U, /**< Операция прошла успешно. */
|
||||
PROTOCAN_ERROR = 0x01U, /**< Обнаружена ошибка во время выполнения. */
|
||||
PROTOCAN_BUSY = 0x02U, /**< Канал занят, выполнение невозможно в данный момент. */
|
||||
PROTOCAN_TIMEOUT = 0x03U /**< Истек таймаут ожидания. */
|
||||
} PROTOCAN_StatusTypeDef;
|
||||
|
||||
//Data Types
|
||||
#define DATA_TYPE_BROADCAST 0b0000
|
||||
#define DATA_TYPE_DISCRETE 0b0001
|
||||
#define DATA_TYPE_ANALOG 0b0010
|
||||
#define DATA_TYPE_GENERAL_ADDRESS_SPACE 0b0011
|
||||
#define DATA_TYPE_MODBUS_COIL 0b0100
|
||||
#define DATA_TYPE_MODBUS_DISCRETE 0b0101
|
||||
#define DATA_TYPE_MODBUS_HOLDING 0b0110
|
||||
#define DATA_TYPE_MODBUS_INPUT 0b0111
|
||||
#define DATA_TYPE_ERROR 0b1000
|
||||
#define DATA_TYPE_PULSE 0b1111
|
||||
/**
|
||||
* @brief Уровень приоритета CAN-сообщения.
|
||||
*
|
||||
* Это перечисление определяет важность и приоритет обработки сообщения.
|
||||
*/
|
||||
typedef enum {
|
||||
PROTOCAN_PRIORITY_CRITICAL = 0, /**< Критический приоритет, рекомендуется обработка без задержек. */
|
||||
PROTOCAN_PRIORITY_STANDARD = 1 /**< Стандартный приоритет, менее важный. */
|
||||
} ProtoCanPriorityType;
|
||||
|
||||
//Sensor Types for DATA_TYPE_BROADCAST
|
||||
#define SENSOR_TYPE_BROADCAST_STATUS 0b000000000000
|
||||
#define SENSOR_TYPE_BROADCAST_ONOFF 0b000000000001
|
||||
#define SENSOR_TYPE_BROADCAST_RESTARTDEVICE 0b000000000010
|
||||
#define SENSOR_TYPE_BROADCAST_RTCSETUP 0b000000000011
|
||||
/**
|
||||
* @brief Маршрут CAN-сообщения.
|
||||
*
|
||||
* Это перечисление задает направление маршрута отправки сообщения.
|
||||
*/
|
||||
typedef enum {
|
||||
PROTOCAN_ROUTE_FROM_PM = 0, /**< Сообщение отправляется от управляющего модуля (PM). */
|
||||
PROTOCAN_ROUTE_FROM_DEVICE = 1 /**< Сообщение отправляется от устройства (Device). */
|
||||
} ProtoCanRouteType;
|
||||
|
||||
//Sensor Types for DATA_TYPE_DISCRETE
|
||||
#define SENSOR_TYPE_DISCRETE_ACCIDENT 0b0000
|
||||
#define SENSOR_TYPE_DISCRETE_WARNING 0b0001
|
||||
#define SENSOR_TYPE_DISCRETE_CONTROL_SIGNALS 0b0010
|
||||
#define SENSOR_TYPE_DISCRETE_FLAGS 0b0011
|
||||
#define SENSOR_TYPE_DISCRETE_RESET 0b0100
|
||||
#define SENSOR_TYPE_DISCRETE_CHANGE_MODE 0b0101
|
||||
#define SENSOR_TYPE_DISCRETE_REQUEST_LIST_OF_PARAMETERS 0b0110
|
||||
/**
|
||||
* @brief Типы сообщений CAN.
|
||||
*
|
||||
* Перечисление определяет различные типы сообщений, используемые в протоколе.
|
||||
*/
|
||||
typedef enum {
|
||||
PROTOCAN_MSGTYPE_BROADCAST = 0b0000, /**< Широковещательное сообщение. */
|
||||
PROTOCAN_MSGTYPE_DISCRETE = 0b0001, /**< Дискретное цифровое сообщение. */
|
||||
PROTOCAN_MSGTYPE_ANALOG = 0b0010, /**< Аналоговое сообщение. */
|
||||
PROTOCAN_MSGTYPE_GENERAL_ADDRESS_SPACE = 0b0011, /**< Сообщение общего адресного пространства. */
|
||||
PROTOCAN_MSGTYPE_MODBUS_COIL = 0b0100, /**< Сообщение Modbus - Coil. */
|
||||
PROTOCAN_MSGTYPE_MODBUS_DISCRETE = 0b0101, /**< Сообщение Modbus - Discrete. */
|
||||
PROTOCAN_MSGTYPE_MODBUS_HOLDING = 0b0110, /**< Сообщение Modbus - Holding. */
|
||||
PROTOCAN_MSGTYPE_MODBUS_INPUT = 0b0111, /**< Сообщение Modbus - Input. */
|
||||
PROTOCAN_MSGTYPE_ERROR = 0b1000, /**< Сообщение об ошибке. */
|
||||
PROTOCAN_MSGTYPE_PULSE = 0b1111, /**< Импульсное сообщение. */
|
||||
}ProtoCanMsgType;
|
||||
|
||||
//Sensor Types for DATA_TYPE_ANALOG
|
||||
#define SENSOR_TYPE_ANALOG_UNIVERSAL 0b0000
|
||||
#define SENSOR_TYPE_ANALOG_USTAVKI 0b0001
|
||||
#define SENSOR_TYPE_ANALOG_U 0b0010
|
||||
#define SENSOR_TYPE_ANALOG_I 0b0011
|
||||
#define SENSOR_TYPE_ANALOG_T 0b0100
|
||||
/**
|
||||
* @brief Типы широковещательных сообщений CAN.
|
||||
*
|
||||
* Перечисление задает различные типы широковещательных команд, используемых в протоколе.
|
||||
*/
|
||||
typedef enum {
|
||||
PROTOCAN_BROADCAST_STATUS = 0b000000000000, /**< Статус устройства. */
|
||||
PROTOCAN_BROADCAST_ONOFF = 0b000000000001, /**< Включение/выключение устройства. */
|
||||
PROTOCAN_BROADCAST_RESTARTDEVICE = 0b000000000010, /**< Перезагрузка устройства. */
|
||||
PROTOCAN_BROADCAST_RTCSETUP = 0b000000000011, /**< Настройка RTC (часы реального времени). */
|
||||
PROTOCAN_BROADCAST_END = 0b111111111111 /**< Конец диапазона широковещательных сообщений. */
|
||||
}ProtoCanBroadcastType;
|
||||
|
||||
//Error Code
|
||||
#define NONEXISTENT_ELEMENT 0x01
|
||||
/**
|
||||
* @brief Структура и представление широковещательного сообщения CAN.
|
||||
*
|
||||
* Объединение позволяет обращаться к данным сообщения либо как к отдельным полям, либо как к целому 16-битному значению.
|
||||
*/
|
||||
typedef union{
|
||||
struct msgBody_Broadcast{
|
||||
unsigned Body:4; /**< Поле для дополнительных данных или кода задачи (4 бита). */
|
||||
ProtoCanBroadcastType Type:12; /**< Тип широковещательного сообщения (12 бит). */
|
||||
} Fields; /**< Структура с разбивкой по полям. */
|
||||
unsigned Body; /**< Общее 16-битное представление сообщения. */
|
||||
} msgBodyBroadcastType;
|
||||
|
||||
#define HighIdFilter(x) x<<24
|
||||
/**
|
||||
* @brief Типы дискретных сообщений CAN.
|
||||
*
|
||||
* Перечисление задает различные виды дискретных команд или событий.
|
||||
*/
|
||||
typedef enum {
|
||||
PROTOCAN_DISCRETE_ACCIDENT = 0b0000, /**< Аварийное состояние. */
|
||||
PROTOCAN_DISCRETE_WARNING = 0b0001, /**< Предупредительный сигнал. */
|
||||
PROTOCAN_DISCRETE_CONTROL_SIGNALS = 0b0010, /**< Управляющие сигналы. */
|
||||
PROTOCAN_DISCRETE_FLAGS = 0b0011, /**< Флаги состояния. */
|
||||
PROTOCAN_DISCRETE_RESET = 0b0100, /**< Сброс устройства. */
|
||||
PROTOCAN_DISCRETE_CHANGE_MODE = 0b0101, /**< Смена режима работы. */
|
||||
PROTOCAN_DISCRETE_REQUEST_LIST_OF_PARAMETERS = 0b0110, /**< Запрос списка параметров. */
|
||||
PROTOCAN_DISCRETE_END = 0b1111 /**< Конец диапазона дискретных сообщений. */
|
||||
}ProtoCanDiscreteType;
|
||||
|
||||
/**
|
||||
* @brief Структура и представление дискретного сообщения CAN.
|
||||
*
|
||||
* Объединение позволяет обращаться к данным сообщения как к отдельным полям или как к целому 16-битному значению.
|
||||
*/
|
||||
typedef union{
|
||||
struct msgBody_Discrete{
|
||||
unsigned Body:12; /**< Поле данных или кода (12 бит). */
|
||||
ProtoCanDiscreteType Type:4; /**< Тип дискретного сообщения (4 бита). */
|
||||
} Fields; /**< Структура с разбивкой по полям. */
|
||||
unsigned Body; /**< Общее 16-битное представление сообщения. */
|
||||
} msgBodyDiscreteType;
|
||||
|
||||
/**
|
||||
* @brief Типы аналоговых сообщений CAN.
|
||||
*
|
||||
* Перечисление определяет различные типы аналоговых данных или команд.
|
||||
*/
|
||||
typedef enum {
|
||||
PROTOCAN_ANALOG_UNIVERSAL = 0b0000, /**< Универсальный тип. */
|
||||
PROTOCAN_ANALOG_SETTINGS = 0b0001, /**< Настройки. */
|
||||
PROTOCAN_ANALOG_U = 0b0010, /**< Напряжение (U). */
|
||||
PROTOCAN_ANALOG_I = 0b0011, /**< Ток (I). */
|
||||
PROTOCAN_ANALOG_T = 0b0100, /**< Температура (T). */
|
||||
PROTOCAN_ANALOG_END = 0b1111 /**< Конец диапазона типов. */
|
||||
}ProtoCanAnalogType;
|
||||
|
||||
/**
|
||||
* @brief Структура и представление аналогового сообщения CAN.
|
||||
*
|
||||
* Объединение позволяет обращаться к данным сообщения как к отдельным полям или как к целому 16-битному значению.
|
||||
*/
|
||||
typedef union{
|
||||
struct msgBody_Analog{
|
||||
unsigned SensorID:12; /**< Идентификатор датчика (12 бит). */
|
||||
ProtoCanAnalogType Type:4; /**< Тип аналоговых данных (4 бита). */
|
||||
} Fields; /**< Структура с разбивкой по полям. */
|
||||
unsigned Body; /**< Общее 16-битное представление сообщения. */
|
||||
}msgBodyAnalogType;
|
||||
|
||||
/**
|
||||
* @brief Структура и представление сообщения Modbus CAN.
|
||||
*
|
||||
* Объединение позволяет обращаться к данным как к отдельным полям или как к целому 16-битному значению.
|
||||
*/
|
||||
typedef union{
|
||||
struct msgBody_Modbus{
|
||||
unsigned RegCount:4; /**< Количество регистров (4 бита). */
|
||||
unsigned StrAdr:12; /**< Адрес строки или регистра (12 бит). */
|
||||
} Fields; /**< Поля структуры сообщения Modbus. */
|
||||
unsigned Body; /**< Общее 16-битное представление сообщения. */
|
||||
} msgBodyModbusType;
|
||||
|
||||
/**
|
||||
* @brief Структура и представление сообщения об ошибке CAN.
|
||||
*
|
||||
* Объединение позволяет обращаться к данным как к отдельным полям или как к целому 16-битному значению.
|
||||
*/
|
||||
typedef union{
|
||||
struct msgBody_Error{
|
||||
unsigned ErrorCode:8; /**< Код ошибки (8 бит). */
|
||||
unsigned Info:8; /**< Дополнительная информация (8 бит). */
|
||||
} Fields; /**< Поля ошибки. */
|
||||
unsigned Body; /**< Общее 16-битное представление сообщения об ошибке. */
|
||||
} msgBodyErrorType;
|
||||
|
||||
struct controlflags{
|
||||
unsigned IsPulse:1;
|
||||
unsigned IsRtrMode:1;
|
||||
};
|
||||
|
||||
//Device settings
|
||||
/**
|
||||
* @brief Поля идентификатора протокола CAN.
|
||||
*
|
||||
* Объединение позволяет обращаться к различным полям идентификатора, а также как к 29-битному целому числу.
|
||||
*/
|
||||
typedef union{
|
||||
struct msgBody_Broadcast{
|
||||
unsigned Page:4;
|
||||
unsigned BroadcastType:12;
|
||||
}Fields;
|
||||
unsigned Body:16;
|
||||
}msgBroadcastType;
|
||||
struct protoCanIdFields{
|
||||
unsigned MsgBody:16; /**< Поле сообщения (16 бит). */
|
||||
ProtoCanMsgType MsgType:4; /**< Тип сообщения (4 бита). */
|
||||
unsigned DeviceID:4; /**< Идентификатор устройства (4 бита). */
|
||||
unsigned DeviceType:3; /**< Тип устройства (3 бита). */
|
||||
ProtoCanRouteType Route:1; /**< Маршрут (1 бит). */
|
||||
ProtoCanPriorityType Priority:1; /**< Приоритет (1 бит). */
|
||||
} Fields; /**< Структура с разбивкой по полям. */
|
||||
unsigned int BitAll:29; /**< Общее представление 29-битного идентификатора. */
|
||||
} ProtoCanId_t;
|
||||
|
||||
typedef union{
|
||||
struct msgBody_Discrete{
|
||||
unsigned Body:12;
|
||||
unsigned Type:4;
|
||||
}Fields;
|
||||
unsigned Body:16;
|
||||
}msgDiscreteType;
|
||||
/**
|
||||
* @brief Структура для общего адресного пространства CAN.
|
||||
*
|
||||
* Используется для хранения данных о регистре и его содержимом.
|
||||
*/
|
||||
typedef struct{
|
||||
struct ProtoCanGeneralAddressSpaceData{
|
||||
uint16_t RegStartAdr; /**< Начальный адрес регистров. */
|
||||
uint16_t *Data; /**< Указатель на массив данных. */
|
||||
unsigned RegCount; /**< Количество регистров. */
|
||||
} GeneralAddressSpaceData;
|
||||
} ProtoCanData_t;
|
||||
|
||||
typedef union{
|
||||
struct msgBody_Analog{
|
||||
unsigned SensorID:12;
|
||||
unsigned SensorType:4;
|
||||
}Fields;
|
||||
unsigned Body:16;
|
||||
}msgAnalogType;
|
||||
|
||||
typedef union{
|
||||
struct msgBody_Modbus{
|
||||
unsigned RegCount:4;
|
||||
unsigned StrAdr:12;
|
||||
}Fields;
|
||||
unsigned Body:16;
|
||||
}msgModbusType;
|
||||
|
||||
typedef union{
|
||||
struct msgBody_Error{
|
||||
unsigned ErrorCode:8;
|
||||
unsigned Info:8;
|
||||
}Fields;
|
||||
unsigned Body:16;
|
||||
}msgErrorType;
|
||||
|
||||
typedef union{
|
||||
struct extID_Fields{
|
||||
unsigned MsgBody:16;
|
||||
unsigned MsgType:4;
|
||||
unsigned DeviceID:4;
|
||||
unsigned DeviceType:3;
|
||||
unsigned Route:1;
|
||||
unsigned Priority:1;
|
||||
}Fields;
|
||||
unsigned int BitAll:29;
|
||||
}extID;
|
||||
|
||||
struct device{
|
||||
unsigned Status:1;
|
||||
extID ExtID;
|
||||
unsigned TimeFromLastPulse;
|
||||
unsigned LastPulseStep;
|
||||
};
|
||||
|
||||
struct data{
|
||||
struct T_sens{
|
||||
char info[256];
|
||||
unsigned SensID;
|
||||
unsigned AvrgValue;
|
||||
unsigned LastTenValues[10];
|
||||
}TS;
|
||||
|
||||
struct U_sens{
|
||||
char info[256];
|
||||
unsigned SensID;
|
||||
unsigned AvrgValue;
|
||||
unsigned LastTenValues[10];
|
||||
}Uu, Uv, Uw;
|
||||
|
||||
struct I_sens{
|
||||
char info[256];
|
||||
unsigned SensID;
|
||||
unsigned AvrgValue;
|
||||
unsigned LastTenValues[10];
|
||||
}Iu, Iv, Iw;
|
||||
};
|
||||
|
||||
struct received_request{
|
||||
extID RequestedExtID;
|
||||
unsigned RequestedDLC;
|
||||
uint8_t RxData[8];
|
||||
|
||||
//DATA_TYPE_DISCRETIC
|
||||
union discreticflags{
|
||||
struct discretictype{
|
||||
unsigned Request_Accident:1;
|
||||
unsigned Request_Warning:1;
|
||||
unsigned Request_Control_Signals:1;
|
||||
unsigned Request_Flags:1;
|
||||
unsigned Request_Reset:1;
|
||||
unsigned Request_List_of_Parameters:1;
|
||||
}DiscreticType;
|
||||
unsigned AllFlags:5;
|
||||
}DiscreticFlags;
|
||||
|
||||
//DATA_TYPE_BROADCAST
|
||||
union broadcastflags{
|
||||
struct broadcasttype{
|
||||
unsigned Request_Status:1;
|
||||
unsigned Request_OnOff:1;
|
||||
unsigned Request_RTC_Setup:1;
|
||||
}BroadcastType;
|
||||
unsigned AllFlags:3;
|
||||
}BroadcastFlags;
|
||||
|
||||
//DATA_TYPE_ANALOG
|
||||
union analogflags{
|
||||
struct analogtype{
|
||||
unsigned Request_Universal_Sens:1;
|
||||
unsigned Request_U_Sens:1;
|
||||
unsigned Request_I_Sens:1;
|
||||
unsigned Request_T_Sens:1;
|
||||
}AnalogType;
|
||||
unsigned AllFlags:4;
|
||||
}AnalogFlags;
|
||||
|
||||
//DATA_TYPE_MODBUS
|
||||
union modbusflags{
|
||||
struct modbustype{
|
||||
unsigned Coil:1;
|
||||
unsigned Discrete:1;
|
||||
unsigned Holding:1;
|
||||
unsigned Input:1;
|
||||
}ModbusType;
|
||||
unsigned AllFlags:4;
|
||||
}ModbusFlags;
|
||||
|
||||
union sensor_To_Modbus{
|
||||
struct modbus{
|
||||
unsigned Count:8;
|
||||
unsigned StrAdr:8;
|
||||
}Modbus;
|
||||
unsigned Sensor:16;
|
||||
}SensorToModbus;
|
||||
|
||||
unsigned ModbusFlag:1;
|
||||
};
|
||||
|
||||
#define CAN_RX_BUFFER_SIZE 128
|
||||
/**
|
||||
* @brief Структура данных устройства CAN.
|
||||
*
|
||||
* Включает статус, идентификатор, таймер последнего импульса и шаг последнего импульса.
|
||||
*/
|
||||
typedef struct{
|
||||
unsigned Status:1; /**< Статус устройства (флаг). */
|
||||
ProtoCanId_t Id; /**< Идентификатор CAN. */
|
||||
unsigned TimeFromLastPulse; /**< Время с последнего импульса (мс). */
|
||||
unsigned LastPulseStep; /**< Шаг последнего импульса. */
|
||||
} ProtoCanDevice_t;
|
||||
|
||||
struct RXMsg{
|
||||
struct INFO{
|
||||
unsigned EXT:1;
|
||||
unsigned RTR:1;
|
||||
}info;
|
||||
extID eID;
|
||||
ProtoCanId_t eID;
|
||||
uint16_t DLC;
|
||||
uint8_t Data[8];
|
||||
};
|
||||
|
||||
typedef enum
|
||||
{
|
||||
PROTOCAN_OK = 0x00U,
|
||||
PROTOCAN_HCAN_ERROR = 0x01U,
|
||||
PROTOCAN_HRTC_ERROR = 0x02U,
|
||||
PROTOCAN_TIM_ERROR = 0x04U,
|
||||
} PROTOCAN_INIT_StatusTypeDef;
|
||||
|
||||
uint16_t AvailableCanRxMsg(void);
|
||||
|
||||
PROTOCAN_INIT_StatusTypeDef PROTOCAN_INIT(CAN_HandleTypeDef *tmp_hcan,
|
||||
@@ -280,39 +255,41 @@ PROTOCAN_INIT_StatusTypeDef PROTOCAN_INIT(CAN_HandleTypeDef *tmp_hcan,
|
||||
void PROTOCAN_DEINIT(uint8_t stage);
|
||||
void PROTOCAN_FILTERS(void);
|
||||
void PROTOCAN_LOOP(void);
|
||||
|
||||
void ProtoCanPulseCallback(TIM_HandleTypeDef *htim);
|
||||
void ProtoCanRxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan);
|
||||
|
||||
HAL_StatusTypeDef PROTOCAN_AnalogProcessing(struct RXMsg _rxMsg);
|
||||
HAL_StatusTypeDef ProtoCanMsgToAnalogUniversal(struct RXMsg _rxMsg);
|
||||
HAL_StatusTypeDef ProtoCanMsgToAnalogUSTAVKI(struct RXMsg _rxMsg);
|
||||
HAL_StatusTypeDef ProtoCanMsgToAnalogUSens(struct RXMsg _rxMsg);
|
||||
HAL_StatusTypeDef ProtoCanMsgToAnalogISens(struct RXMsg _rxMsg);
|
||||
HAL_StatusTypeDef ProtoCanMsgToAnalogTSens(struct RXMsg _rxMsg);
|
||||
PROTOCAN_StatusTypeDef PROTOCAN_BroadcastProcessing(struct RXMsg _rxMsg);
|
||||
PROTOCAN_StatusTypeDef ProtoCanMsgToBroadcastStatus(struct RXMsg _rxMsg);
|
||||
PROTOCAN_StatusTypeDef ProtoCanMsgToBroadcastOnOff(struct RXMsg _rxMsg);
|
||||
PROTOCAN_StatusTypeDef ProtoCanMsgToBroadcastRestart(struct RXMsg _rxMsg);
|
||||
PROTOCAN_StatusTypeDef ProtoCanMsgToBroadcastRtcSetup(struct RXMsg _rxMsg);
|
||||
|
||||
HAL_StatusTypeDef PROTOCAN_BroadcastProcessing(struct RXMsg _rxMsg);
|
||||
HAL_StatusTypeDef ProtoCanMsgToBroadcastStatus(struct RXMsg _rxMsg);
|
||||
void ProtoCanMsgToBroadcastOnOff(struct RXMsg _rxMsg);
|
||||
void ProtoCanMsgToBroadcastRestart(struct RXMsg _rxMsg);
|
||||
void ProtoCanMsgToBroadcastRtcSetup(struct RXMsg _rxMsg);
|
||||
PROTOCAN_StatusTypeDef PROTOCAN_DiscreticProcessing(struct RXMsg _rxMsg);
|
||||
PROTOCAN_StatusTypeDef ProtoCanMsgToDiscreteAccident(struct RXMsg _rxMsg);
|
||||
PROTOCAN_StatusTypeDef ProtoCanMsgToDiscreteWarning(struct RXMsg _rxMsg);
|
||||
PROTOCAN_StatusTypeDef ProtoCanMsgToDiscreteControlSignals(struct RXMsg _rxMsg);
|
||||
PROTOCAN_StatusTypeDef ProtoCanMsgToDiscreteFlags(struct RXMsg _rxMsg);
|
||||
PROTOCAN_StatusTypeDef ProtoCanMsgToDiscreteReset(struct RXMsg _rxMsg);
|
||||
PROTOCAN_StatusTypeDef ProtoCanMsgToDiscreteChangeMode(struct RXMsg _rxMsg);
|
||||
PROTOCAN_StatusTypeDef ProtoCanMsgToDiscreteRequestListOfParameters(struct RXMsg _rxMsg);
|
||||
|
||||
HAL_StatusTypeDef PROTOCAN_DiscreticProcessing(struct RXMsg _rxMsg);
|
||||
void ProtoCanMsgToDiscreteAccident(struct RXMsg _rxMsg);
|
||||
void ProtoCanMsgToDiscreteWarning(struct RXMsg _rxMsg);
|
||||
void ProtoCanMsgToDiscreteControlSignals(struct RXMsg _rxMsg);
|
||||
void ProtoCanMsgToDiscreteFlags(struct RXMsg _rxMsg);
|
||||
void ProtoCanMsgToDiscreteReset(struct RXMsg _rxMsg);
|
||||
void ProtoCanMsgToDiscreteChangeMode(struct RXMsg _rxMsg);
|
||||
void ProtoCanMsgToDiscreteRequestListOfParameters(struct RXMsg _rxMsg);
|
||||
PROTOCAN_StatusTypeDef PROTOCAN_AnalogProcessing(struct RXMsg _rxMsg);
|
||||
PROTOCAN_StatusTypeDef ProtoCanMsgToAnalogUniversal(struct RXMsg _rxMsg);
|
||||
PROTOCAN_StatusTypeDef ProtoCanMsgToAnalogSettings(struct RXMsg _rxMsg);
|
||||
PROTOCAN_StatusTypeDef ProtoCanMsgToAnalogUSens(struct RXMsg _rxMsg);
|
||||
PROTOCAN_StatusTypeDef ProtoCanMsgToAnalogISens(struct RXMsg _rxMsg);
|
||||
PROTOCAN_StatusTypeDef ProtoCanMsgToAnalogTSens(struct RXMsg _rxMsg);
|
||||
|
||||
void PROTOCAN_GeneralAddressSpace_Answer(struct RXMsg _rxMsg);
|
||||
HAL_StatusTypeDef CanRequestError(struct RXMsg _rxMsg);
|
||||
PROTOCAN_StatusTypeDef ProtoCanMsgToGeneralAddressSpace(struct RXMsg _rxMsg);
|
||||
|
||||
HAL_StatusTypeDef PROTOCAN_ModbusProcessing(struct RXMsg _rxMsg);
|
||||
HAL_StatusTypeDef ProtoCanMsgToModbusCoil(struct RXMsg _rxMsg);
|
||||
HAL_StatusTypeDef ProtoCanMsgToModbusDiscrete(struct RXMsg _rxMsg);
|
||||
HAL_StatusTypeDef ProtoCanMsgToModbusHolding(struct RXMsg _rxMsg);
|
||||
HAL_StatusTypeDef ProtoCanMsgToModbusInput(struct RXMsg _rxMsg);
|
||||
PROTOCAN_StatusTypeDef CanRequestError(struct RXMsg _rxMsg);
|
||||
|
||||
PROTOCAN_StatusTypeDef PROTOCAN_ModbusProcessing(struct RXMsg _rxMsg);
|
||||
PROTOCAN_StatusTypeDef ProtoCanMsgToModbusCoil(struct RXMsg _rxMsg);
|
||||
PROTOCAN_StatusTypeDef ProtoCanMsgToModbusDiscrete(struct RXMsg _rxMsg);
|
||||
PROTOCAN_StatusTypeDef ProtoCanMsgToModbusHolding(struct RXMsg _rxMsg);
|
||||
PROTOCAN_StatusTypeDef ProtoCanMsgToModbusInput(struct RXMsg _rxMsg);
|
||||
|
||||
void PROTOCAN_RTC_SYNC(uint8_t *data);
|
||||
|
||||
|
||||
+7
-1
@@ -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;
|
||||
|
||||
+1
-1
@@ -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();
|
||||
}
|
||||
|
||||
+354
-347
@@ -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);
|
||||
}
|
||||
|
||||
+2
-1
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user