init commit

This commit is contained in:
2026-08-20 17:24:34 +03:00
commit 3cf85a278e
2 changed files with 1837 additions and 0 deletions

320
Inc/protocan.h Normal file
View File

@@ -0,0 +1,320 @@
#ifndef _protocan
#define _protocan
#include "main.h"
#include "can.h"
#define _DEMO
#define ONLINE 1;
#define OFFLINE 0;
#define ID_MAIN_DEVICE 0x000
#define CURRENT_TYPE_DEVICE 0b001
#define CURRENT_ID_DEVICE 0b0010
#define PROTOCAN_RX_BUFFER_SIZE 128
#define SensorToModbusRegister(SensorType, SensorID) SensorType << 11 | SensorID
#define HighByteOfWord(WORD) (WORD>>8)&0xFF
#define LowByteOfWord(WORD) WORD&0xFF
/**
* @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;
/**
* @brief Статус выполнения операции протокола CAN.
*
* Это перечисление описывает возможные результаты выполнения функций протокола.
*/
typedef enum
{
PROTOCAN_OK = 0x00U, /**< Операция прошла успешно. */
PROTOCAN_ERROR = 0x01U, /**< Обнаружена ошибка во время выполнения. */
PROTOCAN_BUSY = 0x02U, /**< Канал занят, выполнение невозможно в данный момент. */
PROTOCAN_TIMEOUT = 0x03U /**< Истек таймаут ожидания. */
} PROTOCAN_StatusTypeDef;
/**
* @brief Уровень приоритета CAN-сообщения.
*
* Это перечисление определяет важность и приоритет обработки сообщения.
*/
typedef enum {
PROTOCAN_PRIORITY_CRITICAL = 0, /**< Критический приоритет, рекомендуется обработка без задержек. */
PROTOCAN_PRIORITY_STANDARD = 1 /**< Стандартный приоритет, менее важный. */
} ProtoCanPriorityType;
/**
* @brief Маршрут CAN-сообщения.
*
* Это перечисление задает направление маршрута отправки сообщения.
*/
typedef enum {
PROTOCAN_ROUTE_FROM_PM = 0, /**< Сообщение отправляется от управляющего модуля (PM). */
PROTOCAN_ROUTE_FROM_DEVICE = 1 /**< Сообщение отправляется от устройства (Device). */
} ProtoCanRouteType;
/**
* @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;
/**
* @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;
/**
* @brief Структура и представление широковещательного сообщения CAN.
*
* Объединение позволяет обращаться к данным сообщения либо как к отдельным полям, либо как к целому 16-битному значению.
*/
typedef union{
struct msgBody_Broadcast{
unsigned Body:4; /**< Поле для дополнительных данных или кода задачи (4 бита). */
ProtoCanBroadcastType Type:12; /**< Тип широковещательного сообщения (12 бит). */
} Fields; /**< Структура с разбивкой по полям. */
unsigned Body; /**< Общее 16-битное представление сообщения. */
} msgBodyBroadcastType;
/**
* @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;
};
/**
* @brief Поля идентификатора протокола CAN.
*
* Объединение позволяет обращаться к различным полям идентификатора, а также как к 29-битному целому числу.
*/
typedef union{
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;
/**
* @brief Структура для общего адресного пространства CAN.
*
* Используется для хранения данных о регистре и его содержимом.
*/
typedef struct{
struct ProtoCanCoreData{
uint16_t Type;
uint16_t Body;
uint8_t *Data;
unsigned DataCount;
} CoreData;
struct ProtoCanGeneralAddressSpaceData{
uint16_t RegStartAdr; /**< Начальный адрес регистров. */
uint16_t *Data; /**< Указатель на массив данных. */
unsigned RegCount; /**< Количество регистров. */
} GeneralAddressSpaceData;
struct ProtoCanModbusData{
uint16_t StrAdr;
uint16_t *Data;
unsigned RegCount:4;
} ModbusData;
struct ProtoCanErrorData{
uint16_t Info;
uint16_t Code;
} ErrorData;
} ProtoCanData_t;
/**
* @brief Структура данных устройства CAN.
*
* Включает статус, идентификатор, таймер последнего импульса и шаг последнего импульса.
*/
typedef struct{
unsigned Status:1; /**< Статус устройства (флаг). */
ProtoCanId_t Id; /**< Идентификатор CAN. */
unsigned TimeFromLastPulse; /**< Время с последнего импульса (мс). */
unsigned LastPulseStep; /**< Шаг последнего импульса. */
} ProtoCanDevice_t;
/**
* @brief Структура для хранения сообщения RXCAN.
*/
struct RXMsg {
/**
* @brief Структура, содержащая флаги информации.
*/
struct INFO {
unsigned EXT : 1; /**< Бит расширенного идентификатора (EXT). */
unsigned RTR : 1; /**< Бит запроса на передачу (RTR). */
} info; /**< Информационные флаги сообщения. */
ProtoCanId_t eID; /**< Идентификатор CAN-сообщения. */
uint16_t DLC; /**< Длина данных (Data Length Code). */
uint8_t Data[8]; /**< Массив данных (до 8 байт). */
};
uint16_t AvailableCanRxMsg(void);
PROTOCAN_INIT_StatusTypeDef PROTOCAN_INIT(CAN_HandleTypeDef *tmp_hcan,
RTC_HandleTypeDef *tmp_hrtc,
TIM_HandleTypeDef *tmp_tim);
void PROTOCAN_DEINIT(uint8_t stage);
void PROTOCAN_FILTERS(void);
void PROTOCAN_LoopProcessRxMsgs(void);
PROTOCAN_StatusTypeDef PROTOCAN_ProcessAllRxMsgs(void);
PROTOCAN_StatusTypeDef PROTOCAN_ProcessSingleRxMsg(void);
PROTOCAN_StatusTypeDef PROTOCAN_SEND(ProtoCanId_t id, ProtoCanData_t data);
void ProtoCanPulseCallback(TIM_HandleTypeDef *htim);
void ProtoCanRxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan);
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);
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);
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);
PROTOCAN_StatusTypeDef ProtoCanMsgToGeneralAddressSpace(struct RXMsg _rxMsg);
PROTOCAN_StatusTypeDef PROTOCAN_RequestError(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);
#endif