From 3cae8b70080aa181400c6e84fd6369175658e31f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=92=D1=8F=D1=87=D0=B5=D1=81=D0=BB=D0=B0=D0=B2=20=D0=A8?= =?UTF-8?q?=D1=82=D0=B5=D0=B9=D0=B1=D0=B5=D0=B7=D0=B0=D0=BD=D0=B4=D1=82?= Date: Mon, 30 Mar 2026 14:15:42 +0300 Subject: [PATCH] ProtoCan --- Core/Inc/main.h | 2 +- Core/Inc/{requester.h => protocan.h} | 111 ++- Core/Inc/stm32f1xx_hal_conf.h | 2 +- Core/Src/main.c | 2 - Core/Src/protocan.c | 991 +++++++++++++++++++++++++++ Core/Src/requester.c | 841 ----------------------- F103C8T6.ioc | 2 +- MDK-ARM/F103C8T6.uvguix.Iurii | 145 ++-- MDK-ARM/F103C8T6.uvoptx | 170 ++++- MDK-ARM/F103C8T6.uvprojx | 37 +- 10 files changed, 1268 insertions(+), 1035 deletions(-) rename Core/Inc/{requester.h => protocan.h} (69%) create mode 100644 Core/Src/protocan.c delete mode 100644 Core/Src/requester.c diff --git a/Core/Inc/main.h b/Core/Inc/main.h index 1e23d5e..797fe49 100644 --- a/Core/Inc/main.h +++ b/Core/Inc/main.h @@ -31,7 +31,7 @@ extern "C" { /* Private includes ----------------------------------------------------------*/ /* USER CODE BEGIN Includes */ -#include "requester.h" +#include "protocan.h" #include "canerrorbox.h" /* USER CODE END Includes */ diff --git a/Core/Inc/requester.h b/Core/Inc/protocan.h similarity index 69% rename from Core/Inc/requester.h rename to Core/Inc/protocan.h index 081b571..a78bd52 100644 --- a/Core/Inc/requester.h +++ b/Core/Inc/protocan.h @@ -1,9 +1,7 @@ -#ifndef _requester -#define _requester +#ifndef _protocan +#define _protocan #include "main.h" #include "can.h" -#include "rtc.h" -#include "tim.h" #define _DEMO @@ -11,10 +9,7 @@ #define OFFLINE 0; // TIM defines -#define TIM_REQUESTER_Prescaler 64000 - -//CAN Settings -#define _HCAN hcan +#define TIM_PROTOCAN_Prescaler 64000 //CAN Speed #define CAN_SPEED_PRSC_1000KB 2 @@ -51,17 +46,6 @@ typedef union{ char AllBit; }Byte; -/** - * @brief HAL Status structures definition - */ -typedef enum -{ - CRR_OK = 0x00U, - CRR_ERROR = 0x01U, - CRR_BUSY = 0x02U, - CRR_TIMEOUT = 0x03U -} CRR_Status; - _Bool IsLeapYear(uint8_t year); #define COUNT_OF_MODBUS_SECTIONS 1 @@ -176,25 +160,6 @@ typedef union{ }Fields; unsigned int BitAll:29; }extID; - -// typedef union{ -// struct extID_Fields{ -// union{ -// msgBodyBroadcast Broadcast; -// msgBodyDiscrete Discrete; -// msgBodyAnalog Analog; -// msgBodyModbus Modbus; -// msgBodyError Error; -// unsigned Body:16; -// }Msg; -// 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; @@ -299,45 +264,51 @@ struct RXMsg{ uint8_t Data[8]; }; +typedef enum +{ + PROTOCAN_OK = 0x00U, + PROTOCAN_HCAN_ERROR = 0x01U, + PROTOCAN_HRTC_ERROR = 0x02U, +} PROTOCAN_INIT_StatusTypeDef; + uint16_t AvailableCanRxMsg(void); -void REQUESTER_Init(void); -void REQUESTER_MainWhile(void); -void Boot_SystemClock_Config(void); +PROTOCAN_INIT_StatusTypeDef PROTOCAN_INIT(CAN_HandleTypeDef *tmp_hcan, RTC_HandleTypeDef *tmp_hrtc); +void ProtoCanPulse_TIM_Handler(void); +void PROTOCAN_FILTERS(void); +void PROTOCAN_LOOP(void); -CRR_Status REQUESTER_AnalogProcessing(struct RXMsg _rxMsg); -HAL_StatusTypeDef CanRequestToAnalogUniversal(struct RXMsg _rxMsg); -HAL_StatusTypeDef CanRequestToAnalogUSTAVKI(struct RXMsg _rxMsg); -HAL_StatusTypeDef CanRequestToAnalogUSens(struct RXMsg _rxMsg); -HAL_StatusTypeDef CanRequestToAnalogISens(struct RXMsg _rxMsg); -HAL_StatusTypeDef CanRequestToAnalogTSens(struct RXMsg _rxMsg); +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); -CRR_Status REQUESTER_BroadcastProcessing(struct RXMsg _rxMsg); -HAL_StatusTypeDef CanRequestToBroadcastStatus(struct RXMsg _rxMsg); -void CanRequestToBroadcastOnOff(struct RXMsg _rxMsg); -void CanRequestToBroadcastRestart(struct RXMsg _rxMsg); -void CanRequestToBroadcastRtcSetup(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); -CRR_Status REQUESTER_DiscreticProcessing(struct RXMsg _rxMsg); -void CanRequestToDiscreteAccident(struct RXMsg _rxMsg); -void CanRequestToDiscreteWarning(struct RXMsg _rxMsg); -void CanRequestToDiscreteControlSignals(struct RXMsg _rxMsg); -void CanRequestToDiscreteFlags(struct RXMsg _rxMsg); -void CanRequestToDiscreteReset(struct RXMsg _rxMsg); -void CanRequestToDiscreteChangeMode(struct RXMsg _rxMsg); -void CanRequestToDiscreteRequestListOfParameters(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); -void REQUESTER_GeneralAddressSpace_Answer(struct RXMsg _rxMsg); +void PROTOCAN_GeneralAddressSpace_Answer(struct RXMsg _rxMsg); HAL_StatusTypeDef CanRequestError(struct RXMsg _rxMsg); -CRR_Status REQUESTER_ModbusProcessing(struct RXMsg _rxMsg); -HAL_StatusTypeDef CanRequestToModbusCoil(struct RXMsg _rxMsg); -HAL_StatusTypeDef CanRequestToModbusDiscrete(struct RXMsg _rxMsg); -HAL_StatusTypeDef CanRequestToModbusHolding(struct RXMsg _rxMsg); -HAL_StatusTypeDef CanRequestToModbusInput(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); + +void PROTOCAN_RTC_SYNC(uint8_t *data); -void REQUESTER_RTC_SYNC(uint8_t *data); -void REQUESTER_Pulse_TIM_Handler(void); -void Boot_SystemClock_Config(void); -void REQUESTER_CAN_FILTERS(void); #endif diff --git a/Core/Inc/stm32f1xx_hal_conf.h b/Core/Inc/stm32f1xx_hal_conf.h index bb795b8..793b63e 100644 --- a/Core/Inc/stm32f1xx_hal_conf.h +++ b/Core/Inc/stm32f1xx_hal_conf.h @@ -134,7 +134,7 @@ #define PREFETCH_ENABLE 1U #define USE_HAL_ADC_REGISTER_CALLBACKS 0U /* ADC register callback disabled */ -#define USE_HAL_CAN_REGISTER_CALLBACKS 0U /* CAN register callback disabled */ +#define USE_HAL_CAN_REGISTER_CALLBACKS 1U /* CAN register callback enabled */ #define USE_HAL_CEC_REGISTER_CALLBACKS 0U /* CEC register callback disabled */ #define USE_HAL_DAC_REGISTER_CALLBACKS 0U /* DAC register callback disabled */ #define USE_HAL_ETH_REGISTER_CALLBACKS 0U /* ETH register callback disabled */ diff --git a/Core/Src/main.c b/Core/Src/main.c index d0ca6c0..2b6b5c9 100644 --- a/Core/Src/main.c +++ b/Core/Src/main.c @@ -68,8 +68,6 @@ int main(void) { /* USER CODE BEGIN 1 */ SystemClock_Config(); - REQUESTER_Init(); - REQUESTER_MainWhile(); /* USER CODE END 1 */ /* MCU Configuration--------------------------------------------------------*/ diff --git a/Core/Src/protocan.c b/Core/Src/protocan.c new file mode 100644 index 0000000..1bc989e --- /dev/null +++ b/Core/Src/protocan.c @@ -0,0 +1,991 @@ +#include "protocan.h" + +struct device CurrentDevice; +struct device Device_on_the_Network[8][16]; +struct controlflags ControlFlags; + +CAN_HandleTypeDef *_HCAN = 0; +RTC_HandleTypeDef *_HRTC = 0; + +uint8_t CurrentStep = 1; +uint8_t LastStep = 0; +struct RXMsg rxMsg[CAN_RX_BUFFER_SIZE]; + +/** +* @brief Проверяет, является ли год високосным. +* В системе год хранится как смещение от 2000. Например, значение 24 соответствует 2024. +* Эта функция добавляет 2000 к значению и проверяет, високосный ли получившийся год. +* @param year Смещение от 2000, тип uint8_t (от 0 до 255). +* @return _Bool true, если год високосный; false — иначе. +*/ +_Bool IsLeapYear(uint8_t year) +{ + year+=2000; + return (year%400==0)||((year%4==0)&&(year%100!=0)); +} + +/** +* @brief Возвращает количество доступных сообщений в буфере приёма CAN. +* Используется кольцевой буфер. +* Возвращаемое значение — количество элементов между указателями LastStep и CurrentStep. +* @return uint16_t Количество доступных сообщений, ожидающих обработки, в буфере. +*/ +uint16_t AvailableCanRxMsg(void) +{ + return ((uint16_t)(CAN_RX_BUFFER_SIZE + (LastStep - CurrentStep + 1)))%CAN_RX_BUFFER_SIZE; +} + +/** +* @brief Инициализация переферии +* @details Инициализация указателей на HCAN, HRTC, установка фильтров CAN. +* @note Фильтры CAN описаны в разделе PROTOCAN_CAN_FILTERS(). +*/ +PROTOCAN_INIT_StatusTypeDef PROTOCAN_INIT(CAN_HandleTypeDef *tmp_hcan, RTC_HandleTypeDef *tmp_hrtc) +{ + //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); + //MX_TIM4_Init(); + //MX_RTC_Init(); + if(tmp_hcan) + _HCAN = tmp_hcan; + else + return PROTOCAN_HCAN_ERROR; + if(tmp_hrtc) + _HRTC = tmp_hrtc; + else + return PROTOCAN_HRTC_ERROR; + PROTOCAN_FILTERS(); + ControlFlags.IsPulse = 1; + return PROTOCAN_OK; +} + +/** +* @brief Функция с обработкой полученных запросов +* @details В бесконечном цикле функция ожидает приёма сообщения. После этого сообщение распределяется в зависимости от DataType. +* Обработка запроса аналоговых значений - PROTOCAN_AnalogProcessing(). +* Обработка широковещательных запросов - PROTOCAN_BroadcastProcessing(). +* Обработка запроса дискретных значений - PROTOCAN_DiscreticProcessing(). +* Обработка Modbus - PROTOCAN_ModbusProcessing(). +*/ +void PROTOCAN_LOOP(void) +{ + //HAL_TIM_Base_Start_IT(&htim4); + while(1) + { + if(AvailableCanRxMsg()) + { + if(rxMsg[CurrentStep].eID.Fields.MsgType == DATA_TYPE_ANALOG) + { + PROTOCAN_AnalogProcessing(rxMsg[CurrentStep]); + } + else if(rxMsg[CurrentStep].eID.Fields.MsgType == DATA_TYPE_BROADCAST) + { + PROTOCAN_BroadcastProcessing(rxMsg[CurrentStep]); + } + else if(rxMsg[CurrentStep].eID.Fields.MsgType == DATA_TYPE_DISCRETE) + { + PROTOCAN_DiscreticProcessing(rxMsg[CurrentStep]); + } + else if(rxMsg[CurrentStep].eID.Fields.MsgType == DATA_TYPE_GENERAL_ADDRESS_SPACE) + { + PROTOCAN_GeneralAddressSpace_Answer(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) + { + PROTOCAN_ModbusProcessing(rxMsg[CurrentStep]); + } + else if(rxMsg[CurrentStep].eID.Fields.MsgType == DATA_TYPE_ERROR) + { + CanRequestError(rxMsg[CurrentStep]); + } + CurrentStep = (uint16_t)(CurrentStep + 1) % CAN_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) +{ + msgBroadcastType msg; + msg.Body = _rxMsg.eID.Fields.MsgBody; + switch(msg.Fields.BroadcastType) + { + case SENSOR_TYPE_BROADCAST_STATUS: + { + //Обработка запроса статуса устройства + return ProtoCanMsgToBroadcastStatus(_rxMsg); + } + case SENSOR_TYPE_BROADCAST_ONOFF: + { + //Обработка запроса на вкл/выкл + ProtoCanMsgToBroadcastOnOff(_rxMsg); + break; + } + case SENSOR_TYPE_BROADCAST_RESTARTDEVICE: + { + ProtoCanMsgToBroadcastRestart(_rxMsg); + break; + } + case SENSOR_TYPE_BROADCAST_RTCSETUP: + { + //Обработка запроса на синхронизацию времени + //С головным устройством + ProtoCanMsgToBroadcastRtcSetup(_rxMsg); + break;; + } + default: + //RESERVE SENSOR TYPE. + return HAL_ERROR; + break; + } + return HAL_OK; +} + +/** +* @brief Формирует и отправляет широковещательное CAN-сообщение для ответа на запрос статуса. +* Устанавливает идентификатор, собирает текущие параметры времени и даты, и отправляет сообщение. +* @param _rxMsg Структура полученного по CAN запроса. +* @return HAL_StatusTypeDef Статус операции HAL, например HAL_OK при успехе. +*/ +__weak HAL_StatusTypeDef ProtoCanMsgToBroadcastStatus(struct RXMsg _rxMsg) +{ + CAN_TxHeaderTypeDef TxHeader; + uint32_t TxMailBox = 0; + uint8_t data[8]; + TxHeader.IDE = CAN_ID_EXT; + TxHeader.DLC = 7; + TxHeader.TransmitGlobalTime = DISABLE; + TxHeader.RTR = CAN_RTR_DATA; + extID tmp_eID; + tmp_eID.BitAll = _rxMsg.eID.BitAll; + tmp_eID.Fields.Route = ROUTE_SLAVE; + tmp_eID.Fields.DeviceType = CURRENT_TYPE_DEVICE; + tmp_eID.Fields.DeviceID = CURRENT_ID_DEVICE; + TxHeader.ExtId = tmp_eID.BitAll; + + RTC_TimeTypeDef sTime = {0}; + HAL_RTC_GetTime(_HRTC, &sTime, RTC_FORMAT_BIN); + data[0] = sTime.Hours; + data[1] = sTime.Minutes; + data[2] = sTime.Seconds; + + RTC_DateTypeDef DateToUpdate = {0}; + HAL_RTC_GetDate(_HRTC, &DateToUpdate, RTC_FORMAT_BIN); + data[3] = DateToUpdate.Year; + data[4] = DateToUpdate.Month; + data[5] = DateToUpdate.Date; + data[6] = DateToUpdate.WeekDay; + + return HAL_CAN_AddTxMessage(_HCAN, &TxHeader, data, &TxMailBox); +} + +/** +* @brief Виртуальная слабая функция для переключения режима пульсации ON/OFF. +* Меняет состояние флага IsPulse в структуре ControlFlags. +* В данном случае — просто инвертирует его логическое значение. +* @param _rxMsg Структура полученного CAN-сообщения (Пока не используется в функции). +*/ +__weak void ProtoCanMsgToBroadcastOnOff(struct RXMsg _rxMsg) +{ + ControlFlags.IsPulse = !ControlFlags.IsPulse; +} + +/** +* @brief __weak функция для обработки широковещательного сообщения перезапуска устройства. +* Проверяет длину сообщения, извлекает ID из данных и, если она совпадает с текущим устройством, +* вызывает системный перезапуск. +* @param _rxMsg Структура полученного CAN-сообщения с командой перезапуска. +*/ +__weak void ProtoCanMsgToBroadcastRestart(struct RXMsg _rxMsg) +{ + if(_rxMsg.DLC == 0) + { + return; + } + msgBroadcastType msg; + msg.Body = _rxMsg.eID.Fields.MsgBody; + if(msg.Fields.Page == (CURRENT_ID_DEVICE / (_rxMsg.DLC*8))) + { + uint64_t page = 0; + for(int i = 0; i < _rxMsg.DLC; i++) + { + page+=(_rxMsg.Data[i]<<(i*8)); + } + if((page>>CURRENT_ID_DEVICE)&0b1) + { + NVIC_SystemReset(); + } + } + return; +} + +/** +* @brief __weak функция для обработки запроса на синхронизацию RTC через широковещательное сообщение. +* Проверяет длину сообщения и корректность данных (время и дата). Если все проверки пройдены, +* вызывает функцию синхронизации RTC. +* @param _rxMsg Структура полученного CAN-сообщения с данными для установки времени и даты. +*/ +__weak void ProtoCanMsgToBroadcastRtcSetup(struct RXMsg _rxMsg) +{ + if(_rxMsg.DLC > 7) { + //ERROR + } else { + int DaysCount_Normal[2][12] = {{31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}, + {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}}; + if( _rxMsg.Data[0] > 23 || + _rxMsg.Data[1] > 59 || + _rxMsg.Data[2] > 59 || + _rxMsg.Data[3] > 99 || + _rxMsg.Data[4] > 12 || + _rxMsg.Data[5] > DaysCount_Normal[IsLeapYear(_rxMsg.Data[3])][_rxMsg.Data[4]] || + _rxMsg.Data[6] > 6) { + //ERROR + } else { + PROTOCAN_RTC_SYNC(_rxMsg.Data); + } + } +} + +/** +* @brief Функция обработки дискретных запросов. +* @param struct RXMsg _rxMsg - структура для полученного сообщения. +* @details Функция, формирующая и отправляющая ответ на запросы. Типы запросов: Аварии, Предупреждения, Управляющие сигналы, Флаги, Рестарт устройства, Изменение режима работы устройства, Запрос на устройство. +* @note Запрос на устройство. Головное (master) устройство запрашивает некоторое колличество параметров. В Data - 64 битовых адресса параметров, тип которых задаётся в Sensor ID. Имеется возможность запрашивать непоследовательные параметры. +* @return HAL_StatusTypeDef Статус выполнения команды CAN (успех или ошибка). +*/ +HAL_StatusTypeDef PROTOCAN_DiscreticProcessing(struct RXMsg _rxMsg) +{ + msgDiscreteType msg; + msg.Body = _rxMsg.eID.Fields.MsgBody; + switch(msg.Fields.Type){ + case SENSOR_TYPE_DISCRETE_ACCIDENT: + { + ProtoCanMsgToDiscreteAccident(_rxMsg); + break; + } + case SENSOR_TYPE_DISCRETE_WARNING: + { + ProtoCanMsgToDiscreteWarning(_rxMsg); + break; + } + case SENSOR_TYPE_DISCRETE_CONTROL_SIGNALS: + { + ProtoCanMsgToDiscreteControlSignals(_rxMsg); + break; + } + case SENSOR_TYPE_DISCRETE_FLAGS: + { + ProtoCanMsgToDiscreteFlags(_rxMsg); + break; + } + case SENSOR_TYPE_DISCRETE_RESET: + { + ProtoCanMsgToDiscreteReset(_rxMsg); + break; + } + case SENSOR_TYPE_DISCRETE_CHANGE_MODE: + { + ProtoCanMsgToDiscreteChangeMode(_rxMsg); + break; + } + case SENSOR_TYPE_DISCRETE_REQUEST_LIST_OF_PARAMETERS: + { + ProtoCanMsgToDiscreteRequestListOfParameters(_rxMsg); + break; + } + default: + //RESERVE SENSOR TYPE. + return HAL_ERROR; + break; + } + return HAL_OK; +} + +/** +* @brief Обработка запроса аварийных ситуаций. +* В текущей реализации — заглушка, ничего не выполняет. +* Можно реализовать отправку или обработку аварийных данных. +* @param _rxMsg Входящее сообщение с данными запроса. +*/ +__weak void ProtoCanMsgToDiscreteAccident(struct RXMsg _rxMsg) +{ + return; +} + +/** +* @brief Обработка запроса предупреждений. +* В текущей реализации — заглушка. +* Можно реализовать обработку или ответ на предупреждения. +* @param _rxMsg Входящее сообщение. +*/ +__weak void ProtoCanMsgToDiscreteWarning(struct RXMsg _rxMsg) +{ + return; +} + +/** +* @brief Обработка запроса управляющих сигналов. +* В текущей реализации — заглушка. +* Можно реализовать управление сигналами. +* @param _rxMsg Входящее сообщение. +*/ +__weak void ProtoCanMsgToDiscreteControlSignals(struct RXMsg _rxMsg) +{ + return; +} + +/** +* @brief Обработка запроса флагов. +* В текущей реализации — заглушка. +* Можно реализовать работу с флагами. +* @param _rxMsg Входящее сообщение. +*/ +__weak void ProtoCanMsgToDiscreteFlags(struct RXMsg _rxMsg) +{ + return; +} + +/** +* @brief Обработка рестарта системы по CAN-запросу. +* Выполняет программный рестарт системы. +* @param _rxMsg Входящее сообщение. +*/ +__weak void ProtoCanMsgToDiscreteReset(struct RXMsg _rxMsg) +{ + NVIC_SystemReset(); +} + +/** +* @brief Обработка запроса на изменение режима. +* В текущей реализации — заглушка. +* Можно реализовать изменение режима работы. +* @param _rxMsg Входящее сообщение. +*/ +__weak void ProtoCanMsgToDiscreteChangeMode(struct RXMsg _rxMsg) +{ + return; +} + +/** +* @brief Обработка запроса на получение списка параметров. +* В текущей реализации — заглушка. +* Можно реализовать отправку списка параметров. +* @param _rxMsg Входящее сообщение. +*/ +__weak void ProtoCanMsgToDiscreteRequestListOfParameters(struct RXMsg _rxMsg) +{ + return; +} + +/** +* @brief Обработка и ответ на запрос общего адресного пространства. +* Формирует и передает сообщение с данными о статусе "GAS-XXXX", где XXXX — значение из сообщения _rxMsg. +* @param _rxMsg Структура входящего сообщения, содержит идентификатор и тело сообщения. +*/ +void PROTOCAN_GeneralAddressSpace_Answer(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 = 8; + data[0] = 'G'; + data[1] = 'A'; + data[2] = 'S'; + data[3] = '-'; + for(int i = 0; i < 4; i++) { + unsigned sym = (_rxMsg.eID.Fields.MsgBody>>(12-(i*4)))&0xF; + if(sym >= 10) + data[4+i] = sym%10+'A'; + else + data[4+i] = sym+'0'; + } + HAL_CAN_AddTxMessage(_HCAN, &TxHeader, data, &TxMailBox); +} + +/** +* @brief Обработка запроса на основе типа Modbus. +* В зависимости от типа сообщения, вызывает соответствующую функцию +* для отправки Modbus-запроса по CAN-шине. +* @param _rxMsg Структура входящего сообщения RXMsg. +* @return HAL_StatusTypeDef Статус выполнения команды CAN (успех или ошибка). +*/ +HAL_StatusTypeDef PROTOCAN_ModbusProcessing(struct RXMsg _rxMsg) +{ + switch(_rxMsg.eID.Fields.MsgType) + { + case DATA_TYPE_MODBUS_COIL: + { + return ProtoCanMsgToModbusCoil(_rxMsg); + break; + } + case DATA_TYPE_MODBUS_DISCRETE: + { + return ProtoCanMsgToModbusDiscrete(_rxMsg); + break; + } + case DATA_TYPE_MODBUS_HOLDING: + { + return ProtoCanMsgToModbusHolding(_rxMsg); + break; + } + case DATA_TYPE_MODBUS_INPUT: + { + return ProtoCanMsgToModbusInput(_rxMsg); + break; + } + default: + //ERROR + return HAL_ERROR; + break; + } + return HAL_ERROR; +} + +/** +* @brief __weak Функция отправки ответа на запрос Coil Modbus по CAN. +* Формирует CAN ответ на запрос Coil Modbus и отправляет его. +* @param _rxMsg Структура входящего сообщения RXMsg. +* @return HAL_StatusTypeDef Статус выполнения команды CAN (успех или ошибка). +*/ +__weak HAL_StatusTypeDef ProtoCanMsgToModbusCoil(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 = 8; + msgModbusType msg; + msg.Body = _rxMsg.eID.Fields.MsgBody; + data[0] = 'M'; + data[1] = 'C'; + data[2] = ' '; + data[3] = 'S'; + data[4] = msg.Fields.StrAdr; + data[5] = ' '; + data[6] = 'C'; + data[7] = msg.Fields.RegCount; + return HAL_CAN_AddTxMessage(_HCAN, &TxHeader, data, &TxMailBox); +} + +/** +* @brief __weak Функция отправки ответа на запрос Discrete Modbus по CAN. +* Формирует CAN ответ на запрос Discrete Modbus и отправляет его. +* @param _rxMsg Структура входящего сообщения RXMsg. +* @return HAL_StatusTypeDef Статус выполнения команды CAN (успех или ошибка). +*/ +__weak HAL_StatusTypeDef ProtoCanMsgToModbusDiscrete(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 = 8; + msgModbusType msg; + msg.Body = _rxMsg.eID.Fields.MsgBody; + data[0] = 'M'; + data[1] = 'D'; + data[2] = ' '; + data[3] = 'S'; + data[4] = msg.Fields.StrAdr; + data[5] = ' '; + data[6] = 'C'; + data[7] = msg.Fields.RegCount; + return HAL_CAN_AddTxMessage(_HCAN, &TxHeader, data, &TxMailBox); +} + +/** +* @brief __weak Функция отправки ответа на запрос Holding Modbus по CAN. +* Формирует CAN ответ на запрос Holding Modbus и отправляет его. +* @param _rxMsg Структура входящего сообщения RXMsg. +* @return HAL_StatusTypeDef Статус выполнения команды CAN (успех или ошибка). +*/ +__weak HAL_StatusTypeDef ProtoCanMsgToModbusHolding(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 = 8; + msgModbusType msg; + msg.Body = _rxMsg.eID.Fields.MsgBody; + data[0] = 'M'; + data[1] = 'H'; + data[2] = ' '; + data[3] = 'S'; + data[4] = msg.Fields.StrAdr; + data[5] = ' '; + data[6] = 'C'; + data[7] = msg.Fields.RegCount; + return HAL_CAN_AddTxMessage(_HCAN, &TxHeader, data, &TxMailBox); +} + +/** +* @brief __weak Функция отправки ответа на запрос Input Modbus по CAN. +* Формирует CAN ответ на запрос Input Modbus и отправляет его. +* @param _rxMsg Структура входящего сообщения RXMsg. +* @return HAL_StatusTypeDef Статус выполнения команды CAN (успех или ошибка). +*/ +__weak HAL_StatusTypeDef ProtoCanMsgToModbusInput(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 = 8; + msgModbusType msg; + msg.Body = _rxMsg.eID.Fields.MsgBody; + data[0] = 'M'; + data[1] = 'I'; + data[2] = ' '; + data[3] = 'S'; + data[4] = msg.Fields.StrAdr; + data[5] = ' '; + data[6] = 'C'; + data[7] = msg.Fields.RegCount; + return HAL_CAN_AddTxMessage(_HCAN, &TxHeader, data, &TxMailBox); +} + +/** +* @brief __weak Функция отправки сообщения об ошибке. +* Посылает CAN сообщение с кодом ошибки. Используется, когда необходимо оповестить о неуспешной операции. +* @param _rxMsg Структура входящего сообщения RXMsg, данными которого формируется ответ-ошибка. +* @return HAL_StatusTypeDef Статус выполнения команды CAN. +*/ +__weak HAL_StatusTypeDef CanRequestError(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; + tmp_eID.Fields.MsgType = DATA_TYPE_ERROR; + msgErrorType 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); +} + +/** +* @brief Записывает полученное сообщение CAN в буфер rxMsg. +* Копирует параметры расширенного ID, типы, длину данных и сам данные в указанный элемент буфера. +* @param tmp_eID Расширенный ID сообщения. +* @param tmp_IDE Тип идентификатора (например, CAN_ID_EXT). +* @param tmp_RTR Тип запроса (например, CAN_RTR_DATA). +* @param tmp_DLC Длина данных в сообщении. +* @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) +{ + rxMsg[tmp_LastStep].eID.BitAll = tmp_eID.BitAll; + rxMsg[tmp_LastStep].info.EXT = tmp_IDE; + rxMsg[tmp_LastStep].info.RTR = tmp_RTR; + rxMsg[tmp_LastStep].DLC = tmp_DLC; + for(int i = 0; i < tmp_DLC; i++) + { + rxMsg[tmp_LastStep].Data[i] = tmp_DATA[i]; + } + LastStep = tmp_LastStep; +} + +/** +* @brief Обработка сообщений, ожидающих в FIFO, по прерыванию HAL_CAN_RxFifo0MsgPendingCallback. +* Читает все сообщения из FIFO, проверяет их тип, обновляет статус устройств сети или сохраняет сообщение в буфер. +* @param hcan Указатель на структуру управления CAN-Hardware. +*/ +void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan) +{ + //Обработка всех сообщений в FIFO + CAN_RxHeaderTypeDef RxHeader; + uint8_t RCAN_Data[8]; + while(HAL_CAN_GetRxMessage(hcan, CAN_RX_FIFO0, &RxHeader, RCAN_Data) == HAL_OK) + { + //Расширенный ID + if(RxHeader.IDE == CAN_ID_EXT) + { + if(!((CAN_RX_BUFFER_SIZE + LastStep - (CurrentStep-1))&CAN_RX_BUFFER_SIZE)) + { + //Буффер переполнен + return; + } + + uint16_t tmp_LastStep = (uint16_t)(LastStep + 1) % CAN_RX_BUFFER_SIZE; + + extID ExtID_Of_RX_MSG; + ExtID_Of_RX_MSG.BitAll = RxHeader.ExtId; + + //Полученное сообщение - пульс устройств в сети + if(ExtID_Of_RX_MSG.Fields.MsgType == DATA_TYPE_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; + return; + } + + TakeRxMsgToBuffer(ExtID_Of_RX_MSG, RxHeader.IDE, RxHeader.RTR, RxHeader.DLC, RCAN_Data, tmp_LastStep); + } + } +} + +/** +* @brief Функция отправки пульса устройства. +* @details Пульс устройства. Есть возможность отключить пульс по запросу. +*/ +void PROTOCAN_Pulse_TIM_Handler() +{ + if(ControlFlags.IsPulse) + { + static unsigned PulseStage = 0; + CAN_TxHeaderTypeDef TxHeader; + uint32_t TxMailBox = 0; + extID currentID; + currentID.BitAll = 0; + currentID.Fields.MsgBody = 0; + currentID.Fields.DeviceID = CURRENT_ID_DEVICE; + currentID.Fields.DeviceType = CURRENT_TYPE_DEVICE; + currentID.Fields.MsgType = DATA_TYPE_PULSE; + currentID.Fields.Route = ROUTE_SLAVE; + currentID.Fields.Priority = PRIORITY_STANDARD; + TxHeader.ExtId = currentID.BitAll; + uint8_t data[8]; + TxHeader.IDE = CAN_ID_EXT; + TxHeader.TransmitGlobalTime = DISABLE; + TxHeader.RTR = CAN_RTR_DATA; + TxHeader.DLC = 1; + PulseStage++; + unsigned int debugID; + debugID = currentID.BitAll; + if(PulseStage > 0xFF){ + PulseStage = 0; + } + data[0] = PulseStage; + HAL_CAN_AddTxMessage(_HCAN, &TxHeader, data, &TxMailBox); + } +} + +/** +* @brief Функция установки в RTC полученной даты/время из запроса. +* @param uint8_t *data - Байтовый массив, 7 элементов. [0] - Часы. [1] - Минуты. [2] - Секунды. [3] - Год. [4] - Месяц. [5] - Дата. [6] - День недели. +*/ +void PROTOCAN_RTC_SYNC(uint8_t *data) +{ + __HAL_RTC_WRITEPROTECTION_DISABLE(_HRTC); + RTC_TimeTypeDef sTime = {0}; + RTC_DateTypeDef DateToUpdate = {0}; + + sTime.Hours = data[0]; + sTime.Minutes = data[1]; + sTime.Seconds = data[2]; + + if(HAL_RTC_SetTime(_HRTC, &sTime, RTC_FORMAT_BIN) != HAL_OK) + { + Error_Handler(); + } + + DateToUpdate.Year = data[3]; + DateToUpdate.Month = data[4]; + DateToUpdate.Date = data[5]; + DateToUpdate.WeekDay = data[6]; + if(HAL_RTC_SetDate(_HRTC, &DateToUpdate, RTC_FORMAT_BIN) != HAL_OK) + { + Error_Handler(); + } + __HAL_RTC_WRITEPROTECTION_ENABLE(_HRTC); +} + +/** +* @brief Настройка CAN-Фильтра. +* На основе переданных ID и маски настраивает фильтр CAN для приема только определённых сообщений. +* @param filterBank Номер фильтра (обычно 0..27). +* @param idFilter 32-битный идентификатор, используемый для фильтрации. +* @param idMask 32-битная маска, определяющая биты, проверяемые фильтром. +*/ +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; + + // Разбиваем 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(); + } +} + +#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); + + // Второй фильтр: проверяем 16-19 биты, равны DATA_TYPE_BROADCASTE + PROTOCAN_CONFIG_FILTER(1, filter2_id, filter2_mask); + + // Третий фильтр: проверяем 16-19 биты, равны DATA_TYPE_PULSE + PROTOCAN_CONFIG_FILTER(2, filter3_id, filter3_mask); +} diff --git a/Core/Src/requester.c b/Core/Src/requester.c deleted file mode 100644 index 2e1fc3a..0000000 --- a/Core/Src/requester.c +++ /dev/null @@ -1,841 +0,0 @@ -#include "requester.h" - -struct device CurrentDevice; -struct device Device_on_the_Network[8][16]; -struct controlflags ControlFlags; - -uint8_t CurrentStep = 1; -uint8_t LastStep = 0; -struct RXMsg rxMsg[CAN_RX_BUFFER_SIZE]; - -_Bool IsLeapYear(uint8_t year) -{ - year+=2000; - return (year%400==0)||((year%4==0)&&(year%100!=0)); -} - -uint16_t AvailableCanRxMsg(void) -{ - return ((uint16_t)(CAN_RX_BUFFER_SIZE + (LastStep - CurrentStep + 1)))%CAN_RX_BUFFER_SIZE; -} - -/** - * @brief Инициализация переферии -* @details Инициализация HAL, CAN, TIM7, RTC. -* @note Фильтры CAN описаны в разделе REQUESTER_CAN_FILTERS(). -*/ -void REQUESTER_Init(void) -{ - HAL_Init(); - MX_CAN_Init(); - HAL_CAN_Start(&_HCAN); - REQUESTER_CAN_FILTERS(); - //HAL_CAN_ActivateNotification(&_HCAN, CAN_IT_RX_FIFO0_MSG_PENDING); - HAL_CAN_ActivateNotification(&hcan, CAN_IT_RX_FIFO0_MSG_PENDING | CAN_IT_ERROR | CAN_IT_BUSOFF | CAN_IT_LAST_ERROR_CODE); - ControlFlags.IsPulse = 1; - MX_TIM4_Init(); - MX_RTC_Init(); -} - -/** -* @brief Функция с обработкой полученных запросов -* @details В бесконечном цикле функция ожидает приёма сообщения. После этого сообщение распределяется в зависимости от DataType. -* Обработка запроса аналоговых значений - REQUESTER_AnalogProcessing(). -* Обработка широковещательных запросов - REQUESTER_BroadcastProcessing(). -* Обработка запроса дискретных значений - REQUESTER_DiscreticProcessing(). -* Обработка Modbus - REQUESTER_ModbusProcessing(). -*/ -void REQUESTER_MainWhile(void) -{ - HAL_TIM_Base_Start_IT(&htim4); - unsigned currentAttemptCount; - while(1) - { - if(AvailableCanRxMsg()) - { - currentAttemptCount = 0; - if(rxMsg[CurrentStep].eID.Fields.MsgType == DATA_TYPE_ANALOG) - { - REQUESTER_AnalogProcessing(rxMsg[CurrentStep]); - } - else if(rxMsg[CurrentStep].eID.Fields.MsgType == DATA_TYPE_BROADCAST) - { - REQUESTER_BroadcastProcessing(rxMsg[CurrentStep]); - } - else if(rxMsg[CurrentStep].eID.Fields.MsgType == DATA_TYPE_DISCRETE) - { - REQUESTER_DiscreticProcessing(rxMsg[CurrentStep]); - } - else if(rxMsg[CurrentStep].eID.Fields.MsgType == DATA_TYPE_GENERAL_ADDRESS_SPACE) - { - REQUESTER_GeneralAddressSpace_Answer(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) - { - REQUESTER_ModbusProcessing(rxMsg[CurrentStep]); - } - else if(rxMsg[CurrentStep].eID.Fields.MsgType == DATA_TYPE_ERROR) - { - CanRequestError(rxMsg[CurrentStep]); - } - CurrentStep = (uint16_t)(CurrentStep + 1) % CAN_RX_BUFFER_SIZE; - } - } -} - -/** -* @brief Функция обработки аналоговых запросов. -* @param struct RXMsg _rxMsg - структура для полученного сообщения. -* @details Функция, формирующая и отправляющая ответ на запросы. Типы запросов: Универсальный, Уставки, Напряжение, Ток, Температура. - -*/ -CRR_Status REQUESTER_AnalogProcessing(struct RXMsg _rxMsg) -{ - msgAnalogType msg; - msg.Body = _rxMsg.eID.Fields.MsgBody; - switch (msg.Fields.SensorType) - { - case SENSOR_TYPE_ANALOG_UNIVERSAL: - { - return (CRR_Status)CanRequestToAnalogUniversal(_rxMsg); - break; - } - case SENSOR_TYPE_ANALOG_USTAVKI: - { - return (CRR_Status)CanRequestToAnalogUSTAVKI(_rxMsg); - break; - } - case SENSOR_TYPE_ANALOG_U: - { - return (CRR_Status)CanRequestToAnalogUSens(_rxMsg); - break; - } - case SENSOR_TYPE_ANALOG_I: - { - return (CRR_Status)CanRequestToAnalogISens(_rxMsg); - break; - } - case SENSOR_TYPE_ANALOG_T: - { - return (CRR_Status)CanRequestToAnalogTSens(_rxMsg); - break; - } - default: - //RESERVE SENSOR TYPE - return CRR_ERROR; - break; - } - return CRR_ERROR; -} - -__weak HAL_StatusTypeDef CanRequestToAnalogUniversal(struct RXMsg _rxMsg) -{ - CAN_TxHeaderTypeDef TxHeader; - uint32_t TxMailBox = 0; - uint8_t data[8]; - TxHeader.IDE = CAN_ID_EXT; - TxHeader.TransmitGlobalTime = DISABLE; - TxHeader.RTR = CAN_RTR_DATA; - extID tmp_eID; - tmp_eID.BitAll = _rxMsg.eID.BitAll; - tmp_eID.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); -} - -__weak HAL_StatusTypeDef CanRequestToAnalogUSTAVKI(struct RXMsg _rxMsg) -{ - CAN_TxHeaderTypeDef TxHeader; - uint32_t TxMailBox = 0; - uint8_t data[8]; - TxHeader.IDE = CAN_ID_EXT; - TxHeader.TransmitGlobalTime = DISABLE; - TxHeader.RTR = CAN_RTR_DATA; - extID tmp_eID; - tmp_eID.BitAll = _rxMsg.eID.BitAll; - tmp_eID.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); -} - -__weak HAL_StatusTypeDef CanRequestToAnalogUSens(struct RXMsg _rxMsg) -{ - CAN_TxHeaderTypeDef TxHeader; - uint32_t TxMailBox = 0; - uint8_t data[8]; - TxHeader.IDE = CAN_ID_EXT; - TxHeader.TransmitGlobalTime = DISABLE; - TxHeader.RTR = CAN_RTR_DATA; - extID tmp_eID; - tmp_eID.BitAll = _rxMsg.eID.BitAll; - tmp_eID.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); -} - -__weak HAL_StatusTypeDef CanRequestToAnalogISens(struct RXMsg _rxMsg) -{ - CAN_TxHeaderTypeDef TxHeader; - uint32_t TxMailBox = 0; - uint8_t data[8]; - TxHeader.IDE = CAN_ID_EXT; - TxHeader.TransmitGlobalTime = DISABLE; - TxHeader.RTR = CAN_RTR_DATA; - extID tmp_eID; - tmp_eID.BitAll = _rxMsg.eID.BitAll; - tmp_eID.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); -} - -__weak HAL_StatusTypeDef CanRequestToAnalogTSens(struct RXMsg _rxMsg) -{ - CAN_TxHeaderTypeDef TxHeader; - uint32_t TxMailBox = 0; - uint8_t data[8]; - TxHeader.IDE = CAN_ID_EXT; - TxHeader.TransmitGlobalTime = DISABLE; - TxHeader.RTR = CAN_RTR_DATA; - extID tmp_eID; - tmp_eID.BitAll = _rxMsg.eID.BitAll; - tmp_eID.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) устройства. Типы команд: Запрос статуса, запрос на включение или выключение, рестарт устройств, установка времени. -*/ -CRR_Status REQUESTER_BroadcastProcessing(struct RXMsg _rxMsg) -{ - msgBroadcastType msg; - msg.Body = _rxMsg.eID.Fields.MsgBody; - switch(msg.Fields.BroadcastType) - { - case SENSOR_TYPE_BROADCAST_STATUS: - { - //Обработка запроса статуса устройства - if(CanRequestToBroadcastStatus(_rxMsg)!=HAL_OK) - { - return CRR_ERROR; - } - break; - } - case SENSOR_TYPE_BROADCAST_ONOFF: - { - //Обработка запроса на вкл/выкл - CanRequestToBroadcastOnOff(_rxMsg); - break; - } - case SENSOR_TYPE_BROADCAST_RESTARTDEVICE: - { - CanRequestToBroadcastRestart(_rxMsg); - break; - } - case SENSOR_TYPE_BROADCAST_RTCSETUP: - { - //Обработка запроса на синхронизацию времени - //С головным устройством - CanRequestToBroadcastRtcSetup(_rxMsg); - break;; - } - default: - //RESERVE SENSOR TYPE. - return CRR_ERROR; - break; - } - return CRR_OK; -} - -__weak HAL_StatusTypeDef CanRequestToBroadcastStatus(struct RXMsg _rxMsg) -{ - CAN_TxHeaderTypeDef TxHeader; - uint32_t TxMailBox = 0; - uint8_t data[8]; - TxHeader.IDE = CAN_ID_EXT; - TxHeader.DLC = 7; - TxHeader.TransmitGlobalTime = DISABLE; - TxHeader.RTR = CAN_RTR_DATA; - extID tmp_eID; - tmp_eID.BitAll = _rxMsg.eID.BitAll; - tmp_eID.Fields.Route = ROUTE_SLAVE; - tmp_eID.Fields.DeviceType = CURRENT_TYPE_DEVICE; - tmp_eID.Fields.DeviceID = CURRENT_ID_DEVICE; - TxHeader.ExtId = tmp_eID.BitAll; - - RTC_TimeTypeDef sTime = {0}; - HAL_RTC_GetTime(&hrtc, &sTime, RTC_FORMAT_BIN); - data[0] = sTime.Hours; - data[1] = sTime.Minutes; - data[2] = sTime.Seconds; - - RTC_DateTypeDef DateToUpdate = {0}; - HAL_RTC_GetDate(&hrtc, &DateToUpdate, RTC_FORMAT_BIN); - data[3] = DateToUpdate.Year; - data[4] = DateToUpdate.Month; - data[5] = DateToUpdate.Date; - data[6] = DateToUpdate.WeekDay; - - return HAL_CAN_AddTxMessage(&_HCAN, &TxHeader, data, &TxMailBox); -} - -__weak void CanRequestToBroadcastOnOff(struct RXMsg _rxMsg) -{ - ControlFlags.IsPulse = !ControlFlags.IsPulse; -} - -__weak void CanRequestToBroadcastRestart(struct RXMsg _rxMsg) -{ - if(_rxMsg.DLC == 0) - { - return; - } - msgBroadcastType msg; - msg.Body = _rxMsg.eID.Fields.MsgBody; - if(msg.Fields.Page == (CURRENT_ID_DEVICE / (_rxMsg.DLC*8))) - { - uint64_t page = 0; - for(int i = 0; i < _rxMsg.DLC; i++) - { - page+=(_rxMsg.Data[i]<<(i*8)); - } - if((page>>CURRENT_ID_DEVICE)&0b1) - { - NVIC_SystemReset(); - } - } - return; -} - -__weak void CanRequestToBroadcastRtcSetup(struct RXMsg _rxMsg) -{ - if(_rxMsg.DLC > 7) - { - //ERROR - } - else - { - int DaysCount_Normal[2][12] = {{31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}, - {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}}; - if(_rxMsg.Data[0]>23 || - _rxMsg.Data[1]>59 || - _rxMsg.Data[2]>59 || - _rxMsg.Data[3]>99 || - _rxMsg.Data[4]>12 || - _rxMsg.Data[5] > DaysCount_Normal[IsLeapYear(_rxMsg.Data[3])][_rxMsg.Data[4]] || - _rxMsg.Data[6]>6) - { - //ERROR - } - else - { - REQUESTER_RTC_SYNC(_rxMsg.Data); - } - } -} - -/** -* @brief Функция обработки дискретных запросов. -* @param struct RXMsg _rxMsg - структура для полученного сообщения. -* @details Функция, формирующая и отправляющая ответ на запросы. Типы запросов: Аварии, Предупреждения, Управляющие сигналы, Флаги, Рестарт устройства, Изменение режима работы устройства, Запрос на устройство. -* @note Запрос на устройство. Головное (master) устройство запрашивает некоторое колличество параметров. В Data - 64 битовых адресса параметров, тип которых задаётся в Sensor ID. Имеется возможность запрашивать непоследовательные параметры. -*/ -CRR_Status REQUESTER_DiscreticProcessing(struct RXMsg _rxMsg) -{ - msgDiscreteType msg; - msg.Body = _rxMsg.eID.Fields.MsgBody; - switch(msg.Fields.Type){ - case SENSOR_TYPE_DISCRETE_ACCIDENT: - { - CanRequestToDiscreteAccident(_rxMsg); - break; - } - case SENSOR_TYPE_DISCRETE_WARNING: - { - CanRequestToDiscreteWarning(_rxMsg); - break; - } - case SENSOR_TYPE_DISCRETE_CONTROL_SIGNALS: - { - CanRequestToDiscreteControlSignals(_rxMsg); - break; - } - case SENSOR_TYPE_DISCRETE_FLAGS: - { - CanRequestToDiscreteFlags(_rxMsg); - break; - } - case SENSOR_TYPE_DISCRETE_RESET: - { - CanRequestToDiscreteReset(_rxMsg); - break; - } - case SENSOR_TYPE_DISCRETE_CHANGE_MODE: - { - CanRequestToDiscreteChangeMode(_rxMsg); - break; - } - case SENSOR_TYPE_DISCRETE_REQUEST_LIST_OF_PARAMETERS: - { - CanRequestToDiscreteRequestListOfParameters(_rxMsg); - break; - } - default: - //RESERVE SENSOR TYPE. - return CRR_ERROR; - break; - } - return CRR_OK; -} - -__weak void CanRequestToDiscreteAccident(struct RXMsg _rxMsg) -{ - return; -} - -__weak void CanRequestToDiscreteWarning(struct RXMsg _rxMsg) -{ - return; -} - -__weak void CanRequestToDiscreteControlSignals(struct RXMsg _rxMsg) -{ - return; -} - -__weak void CanRequestToDiscreteFlags(struct RXMsg _rxMsg) -{ - return; -} - -__weak void CanRequestToDiscreteReset(struct RXMsg _rxMsg) -{ - NVIC_SystemReset(); -} - -__weak void CanRequestToDiscreteChangeMode(struct RXMsg _rxMsg) -{ - return; -} -__weak void CanRequestToDiscreteRequestListOfParameters(struct RXMsg _rxMsg) -{ - return; -} - - -void REQUESTER_GeneralAddressSpace_Answer(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 = 8; - data[0] = 'G'; - data[1] = 'A'; - data[2] = 'S'; - data[3] = '-'; - for(int i = 0; i < 4; i++) { - unsigned sym = (_rxMsg.eID.Fields.MsgBody>>(12-(i*4)))&0xF; - if(sym >= 10) - data[4+i] = sym%10+'A'; - else - data[4+i] = sym+'0'; - } - HAL_CAN_AddTxMessage(&_HCAN, &TxHeader, data, &TxMailBox); -} - -/** -* @brief Функция обработки Modbus запросов. -* @param struct RXMsg _rxMsg - структура для полученного сообщения. -* @details Функция, формирующая и отправляющая ответ на запросы. -*/ -CRR_Status REQUESTER_ModbusProcessing(struct RXMsg _rxMsg) -{ - switch(_rxMsg.eID.Fields.MsgType) - { - case DATA_TYPE_MODBUS_COIL: - { - return (CRR_Status)CanRequestToModbusCoil(_rxMsg); - break; - } - case DATA_TYPE_MODBUS_DISCRETE: - { - return (CRR_Status)CanRequestToModbusDiscrete(_rxMsg); - break; - } - case DATA_TYPE_MODBUS_HOLDING: - { - return (CRR_Status)CanRequestToModbusHolding(_rxMsg); - break; - } - case DATA_TYPE_MODBUS_INPUT: - { - return (CRR_Status)CanRequestToModbusInput(_rxMsg); - break; - } - default: - //ERROR - return CRR_ERROR; - break; - } - return CRR_ERROR; -} - -__weak HAL_StatusTypeDef CanRequestToModbusCoil(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 = 8; - msgModbusType msg; - msg.Body = _rxMsg.eID.Fields.MsgBody; - data[0] = 'M'; - data[1] = 'C'; - data[2] = ' '; - data[3] = 'S'; - data[4] = msg.Fields.StrAdr; - data[5] = ' '; - data[6] = 'C'; - data[7] = msg.Fields.RegCount; - return HAL_CAN_AddTxMessage(&_HCAN, &TxHeader, data, &TxMailBox); -} -__weak HAL_StatusTypeDef CanRequestToModbusDiscrete(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 = 8; - msgModbusType msg; - msg.Body = _rxMsg.eID.Fields.MsgBody; - data[0] = 'M'; - data[1] = 'D'; - data[2] = ' '; - data[3] = 'S'; - data[4] = msg.Fields.StrAdr; - data[5] = ' '; - data[6] = 'C'; - data[7] = msg.Fields.RegCount; - return HAL_CAN_AddTxMessage(&_HCAN, &TxHeader, data, &TxMailBox); -} -__weak HAL_StatusTypeDef CanRequestToModbusHolding(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 = 8; - msgModbusType msg; - msg.Body = _rxMsg.eID.Fields.MsgBody; - data[0] = 'M'; - data[1] = 'H'; - data[2] = ' '; - data[3] = 'S'; - data[4] = msg.Fields.StrAdr; - data[5] = ' '; - data[6] = 'C'; - data[7] = msg.Fields.RegCount; - return HAL_CAN_AddTxMessage(&_HCAN, &TxHeader, data, &TxMailBox); -} -__weak HAL_StatusTypeDef CanRequestToModbusInput(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 = 8; - msgModbusType msg; - msg.Body = _rxMsg.eID.Fields.MsgBody; - data[0] = 'M'; - data[1] = 'I'; - data[2] = ' '; - data[3] = 'S'; - data[4] = msg.Fields.StrAdr; - data[5] = ' '; - data[6] = 'C'; - data[7] = msg.Fields.RegCount; - return HAL_CAN_AddTxMessage(&_HCAN, &TxHeader, data, &TxMailBox); -} - -__weak HAL_StatusTypeDef CanRequestError(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; - tmp_eID.Fields.MsgType = DATA_TYPE_ERROR; - msgErrorType 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); -} - - -/** -* @brief -* @param extID tmp_eID -* @param uint32_t tmp_IDE -* @param uint32_t tmp_RTR -* @param uint32_t tmp_DLC -* @param uint8_t *tmp_DATA -* @param uint16_t tmp_LastStep -* @details -*/ -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) -{ - rxMsg[tmp_LastStep].eID.BitAll = tmp_eID.BitAll; - rxMsg[tmp_LastStep].info.EXT = tmp_IDE; - rxMsg[tmp_LastStep].info.RTR = tmp_RTR; - rxMsg[tmp_LastStep].DLC = tmp_DLC; - for(int i = 0; i < tmp_DLC; i++) - { - rxMsg[tmp_LastStep].Data[i] = tmp_DATA[i]; - } - LastStep = tmp_LastStep; -} - -/** -* @brief Callback-Функция обработки приёма. -* @details Функция, сигнализирующая через флаги в бесконечный цикл REQUESTER_MainWhile о приёме запроса. -*/ -void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan) -{ - // Обработка всех сообщений в FIFO - CAN_RxHeaderTypeDef RxHeader; - uint8_t RCAN_Data[8]; - while(HAL_CAN_GetRxMessage(hcan, CAN_RX_FIFO0, &RxHeader, RCAN_Data) == HAL_OK) - { - //Расширенный ID - if(RxHeader.IDE == CAN_ID_EXT) - { - if(!((CAN_RX_BUFFER_SIZE + LastStep - (CurrentStep-1))&CAN_RX_BUFFER_SIZE)) - { - //Буффер переполнен - return; - } - - uint16_t tmp_LastStep = (uint16_t)(LastStep + 1) % CAN_RX_BUFFER_SIZE; - - extID ExtID_Of_RX_MSG; - ExtID_Of_RX_MSG.BitAll = RxHeader.ExtId; - - //Полученное сообщение - пульс устройств в сети - if(ExtID_Of_RX_MSG.Fields.MsgType == DATA_TYPE_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; - return; - } - - TakeRxMsgToBuffer(ExtID_Of_RX_MSG, RxHeader.IDE, RxHeader.RTR, RxHeader.DLC, RCAN_Data, tmp_LastStep); - } - } -} - -/** -* @brief Функция отправки пульса устройства. -* @details Пульс устройства. Есть возможность отключить пульс по запросу. -*/ -void REQUESTER_Pulse_TIM_Handler() -{ - if(ControlFlags.IsPulse) - { - static unsigned PulseStage = 0; - CAN_TxHeaderTypeDef TxHeader; - uint32_t TxMailBox = 0; - extID currentID; - currentID.BitAll = 0; - currentID.Fields.MsgBody = 0; - currentID.Fields.DeviceID = CURRENT_ID_DEVICE; - currentID.Fields.DeviceType = CURRENT_TYPE_DEVICE; - currentID.Fields.MsgType = DATA_TYPE_PULSE; - currentID.Fields.Route = ROUTE_SLAVE; - currentID.Fields.Priority = PRIORITY_STANDARD; - TxHeader.ExtId = currentID.BitAll; - uint8_t data[8]; - TxHeader.IDE = CAN_ID_EXT; - TxHeader.TransmitGlobalTime = DISABLE; - TxHeader.RTR = CAN_RTR_DATA; - TxHeader.DLC = 1; - PulseStage++; - unsigned int debugID; - debugID = currentID.BitAll; - if(PulseStage > 0xFF){ - PulseStage = 0; - } - data[0] = PulseStage; - HAL_CAN_AddTxMessage(&_HCAN, &TxHeader, data, &TxMailBox); - } -} - -/** -* @brief Функция установки в RTC полученной даты/время из запроса. -* @param uint8_t *data - Байтовый массив, 7 элементов. [0] - Часы. [1] - Минуты. [2] - Секунды. [3] - Год. [4] - Месяц. [5] - Дата. [6] - День недели. -*/ -void REQUESTER_RTC_SYNC(uint8_t *data) -{ - __HAL_RTC_WRITEPROTECTION_DISABLE(&hrtc); - RTC_TimeTypeDef sTime = {0}; - RTC_DateTypeDef DateToUpdate = {0}; - - sTime.Hours = data[0]; - sTime.Minutes = data[1]; - sTime.Seconds = data[2]; - - if(HAL_RTC_SetTime(&hrtc, &sTime, RTC_FORMAT_BIN) != HAL_OK) - { - Error_Handler(); - } - - DateToUpdate.Year = data[3]; - DateToUpdate.Month = data[4]; - DateToUpdate.Date = data[5]; - DateToUpdate.WeekDay = data[6]; - if(HAL_RTC_SetDate(&hrtc, &DateToUpdate, RTC_FORMAT_BIN) != HAL_OK) - { - Error_Handler(); - } - __HAL_RTC_WRITEPROTECTION_ENABLE(&hrtc); -} - -/** -* @brief Функция настройки фильтров CAN. -* @details Настройка фильтров. Фильр для приёма сообщений с главного устройства. Фильтр для приёма на текущее устройство. Фильтр для приёма пульса других устройств в сети. -*/ - -void CONFIG_CAN_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; - - // Разбиваем 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(); - } -} - -#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; - -void REQUESTER_CAN_FILTERS() -{ - // Первый фильтр: проверяем 20-27 биты, где 27-й всегда 1 - CONFIG_CAN_FILTER(0, filter1_id, filter1_mask); - - // Второй фильтр: проверяем 16-19 биты, равны DATA_TYPE_BROADCASTE - CONFIG_CAN_FILTER(1, filter2_id, filter2_mask); - - // Третий фильтр: проверяем 16-19 биты, равны DATA_TYPE_PULSE - CONFIG_CAN_FILTER(2, filter3_id, filter3_mask); - - //CONFIG_CAN_FILTER(3, 0, 0); -} diff --git a/F103C8T6.ioc b/F103C8T6.ioc index e153ad0..1e5f01a 100644 --- a/F103C8T6.ioc +++ b/F103C8T6.ioc @@ -86,7 +86,7 @@ ProjectManager.ProjectBuild=false ProjectManager.ProjectFileName=F103C8T6.ioc ProjectManager.ProjectName=F103C8T6 ProjectManager.ProjectStructure= -ProjectManager.RegisterCallBack= +ProjectManager.RegisterCallBack=CAN ProjectManager.StackSize=0x400 ProjectManager.TargetToolchain=MDK-ARM V5.32 ProjectManager.ToolChainLocation= diff --git a/MDK-ARM/F103C8T6.uvguix.Iurii b/MDK-ARM/F103C8T6.uvguix.Iurii index d46d72e..8e377f9 100644 --- a/MDK-ARM/F103C8T6.uvguix.Iurii +++ b/MDK-ARM/F103C8T6.uvguix.Iurii @@ -6,7 +6,7 @@
### uVision Project, (C) Keil Software
- D:\Work\MCU\F103C8T6\Core\Src + D:\Work\MCU\F103C8T6\Core\Inc @@ -123,8 +123,8 @@ 0 - 1741 - 01000000040000000100000001000000010000000100000000000000020000000000000001000000010000000000000028000000280000000100000013000000110000000100000024443A5C576F726B5C4D43555C46313033433854365C436F72655C5372635C6D61696E2E6300000000066D61696E2E6300000000C5D4F200FFFFFFFF24443A5C576F726B5C4D43555C46313033433854365C436F72655C496E635C6D61696E2E6800000000066D61696E2E6800000000FFDC7800FFFFFFFF29443A5C576F726B5C4D43555C46313033433854365C436F72655C5372635C7265717565737465722E63000000000B7265717565737465722E6300000000BECEA100FFFFFFFF2C443A5C576F726B5C4D43555C46313033433854365C436F72655C5372635C73746D3332663178785F69742E63000000000E73746D3332663178785F69742E6300000000F0A0A100FFFFFFFF31443A5C576F726B5C4D43555C46313033433854365C436F72655C5372635C73746D3332663178785F68616C5F6D73702E63000000001373746D3332663178785F68616C5F6D73702E6300000000BCA8E100FFFFFFFF49443A5C576F726B5C4D43555C46313033433854365C447269766572735C53544D3332463178785F48414C5F4472697665725C5372635C73746D3332663178785F68616C5F63616E2E63000000001373746D3332663178785F68616C5F63616E2E63000000009CC1B600FFFFFFFF23443A5C576F726B5C4D43555C46313033433854365C436F72655C5372635C74696D2E63000000000574696D2E6300000000F7B88600FFFFFFFF23443A5C576F726B5C4D43555C46313033433854365C436F72655C5372635C7274632E6300000000057274632E6300000000D9ADC200FFFFFFFF45443A5C576F726B5C4D43555C46313033433854365C447269766572735C53544D3332463178785F48414C5F4472697665725C5372635C73746D3332663178785F68616C2E63000000000F73746D3332663178785F68616C2E6300000000A5C2D700FFFFFFFF23443A5C576F726B5C4D43555C46313033433854365C436F72655C5372635C63616E2E63000000000563616E2E6300000000B3A6BE00FFFFFFFF29443A5C576F726B5C4D43555C46313033433854365C436F72655C496E635C7265717565737465722E68000000000B7265717565737465722E6800000000EAD6A300FFFFFFFF32443A5C576F726B5C4D43555C46313033433854365C4D444B2D41524D5C737461727475705F73746D33326631303378622E730000000015737461727475705F73746D33326631303378622E7300000000F6FA7D00FFFFFFFF35443A5C576F726B5C4D43555C46313033433854365C447269766572735C434D5349535C496E636C7564655C636F72655F636D332E68000000000A636F72655F636D332E6800000000B5E99D00FFFFFFFF49443A5C576F726B5C4D43555C46313033433854365C447269766572735C53544D3332463178785F48414C5F4472697665725C5372635C73746D3332663178785F68616C5F74696D2E63000000001373746D3332663178785F68616C5F74696D2E63000000005FC3CF00FFFFFFFF4C443A5C576F726B5C4D43555C46313033433854365C447269766572735C53544D3332463178785F48414C5F4472697665725C5372635C73746D3332663178785F68616C5F74696D5F65782E63000000001673746D3332663178785F68616C5F74696D5F65782E6300000000C1838300FFFFFFFF49443A5C576F726B5C4D43555C46313033433854365C447269766572735C53544D3332463178785F48414C5F4472697665725C496E635C73746D3332663178785F68616C5F63616E2E68000000001373746D3332663178785F68616C5F63616E2E6800000000CACAD500FFFFFFFF4C443A5C576F726B5C4D43555C46313033433854365C447269766572735C434D5349535C4465766963655C53545C53544D3332463178785C496E636C7564655C73746D33326631303378622E68000000000D73746D33326631303378622E6800000000C5D4F200FFFFFFFF2B443A5C576F726B5C4D43555C46313033433854365C436F72655C5372635C63616E6572726F72626F782E63000000000D63616E6572726F72626F782E6300000000FFDC7800FFFFFFFF2B443A5C576F726B5C4D43555C46313033433854365C436F72655C496E635C63616E6572726F72626F782E68000000000D63616E6572726F72626F782E6800000000BECEA100FFFFFFFF0100000010000000C5D4F200FFDC7800BECEA100F0A0A100BCA8E1009CC1B600F7B88600D9ADC200A5C2D700B3A6BE00EAD6A300F6FA7D00B5E99D005FC3CF00C1838300CACAD500010000000000000002000000F4000000650000008007000069030000 + 1848 + 01000000040000000100000001000000010000000100000000000000020000000000000001000000010000000000000028000000280000000100000014000000020000000100000024443A5C576F726B5C4D43555C46313033433854365C436F72655C5372635C6D61696E2E6300000000066D61696E2E6300000000C5D4F200FFFFFFFF24443A5C576F726B5C4D43555C46313033433854365C436F72655C496E635C6D61696E2E6800000000066D61696E2E6800000000FFDC7800FFFFFFFF28443A5C576F726B5C4D43555C46313033433854365C436F72655C5372635C70726F746F63616E2E63000000000B70726F746F63616E2E632A00000000BECEA100FFFFFFFF2C443A5C576F726B5C4D43555C46313033433854365C436F72655C5372635C73746D3332663178785F69742E63000000000E73746D3332663178785F69742E6300000000F0A0A100FFFFFFFF31443A5C576F726B5C4D43555C46313033433854365C436F72655C5372635C73746D3332663178785F68616C5F6D73702E63000000001373746D3332663178785F68616C5F6D73702E6300000000BCA8E100FFFFFFFF49443A5C576F726B5C4D43555C46313033433854365C447269766572735C53544D3332463178785F48414C5F4472697665725C5372635C73746D3332663178785F68616C5F63616E2E63000000001373746D3332663178785F68616C5F63616E2E63000000009CC1B600FFFFFFFF23443A5C576F726B5C4D43555C46313033433854365C436F72655C5372635C74696D2E63000000000574696D2E6300000000F7B88600FFFFFFFF23443A5C576F726B5C4D43555C46313033433854365C436F72655C5372635C7274632E6300000000057274632E6300000000D9ADC200FFFFFFFF45443A5C576F726B5C4D43555C46313033433854365C447269766572735C53544D3332463178785F48414C5F4472697665725C5372635C73746D3332663178785F68616C2E63000000000F73746D3332663178785F68616C2E6300000000A5C2D700FFFFFFFF23443A5C576F726B5C4D43555C46313033433854365C436F72655C5372635C63616E2E63000000000563616E2E6300000000B3A6BE00FFFFFFFF28443A5C576F726B5C4D43555C46313033433854365C436F72655C496E635C70726F746F63616E2E68000000000A70726F746F63616E2E6800000000EAD6A300FFFFFFFF32443A5C576F726B5C4D43555C46313033433854365C4D444B2D41524D5C737461727475705F73746D33326631303378622E730000000015737461727475705F73746D33326631303378622E7300000000F6FA7D00FFFFFFFF35443A5C576F726B5C4D43555C46313033433854365C447269766572735C434D5349535C496E636C7564655C636F72655F636D332E68000000000A636F72655F636D332E6800000000B5E99D00FFFFFFFF49443A5C576F726B5C4D43555C46313033433854365C447269766572735C53544D3332463178785F48414C5F4472697665725C5372635C73746D3332663178785F68616C5F74696D2E63000000001373746D3332663178785F68616C5F74696D2E63000000005FC3CF00FFFFFFFF4C443A5C576F726B5C4D43555C46313033433854365C447269766572735C53544D3332463178785F48414C5F4472697665725C5372635C73746D3332663178785F68616C5F74696D5F65782E63000000001673746D3332663178785F68616C5F74696D5F65782E6300000000C1838300FFFFFFFF49443A5C576F726B5C4D43555C46313033433854365C447269766572735C53544D3332463178785F48414C5F4472697665725C496E635C73746D3332663178785F68616C5F63616E2E68000000001373746D3332663178785F68616C5F63616E2E6800000000CACAD500FFFFFFFF4C443A5C576F726B5C4D43555C46313033433854365C447269766572735C434D5349535C4465766963655C53545C53544D3332463178785C496E636C7564655C73746D33326631303378622E68000000000D73746D33326631303378622E6800000000C5D4F200FFFFFFFF2B443A5C576F726B5C4D43555C46313033433854365C436F72655C5372635C63616E6572726F72626F782E63000000000D63616E6572726F72626F782E6300000000FFDC7800FFFFFFFF2B443A5C576F726B5C4D43555C46313033433854365C436F72655C496E635C63616E6572726F72626F782E68000000000D63616E6572726F72626F782E6800000000BECEA100FFFFFFFF49443A5C576F726B5C4D43555C46313033433854365C447269766572735C53544D3332463178785F48414C5F4472697665725C496E635C73746D3332663178785F68616C5F6465662E68000000001373746D3332663178785F68616C5F6465662E6800000000F0A0A100FFFFFFFF0100000010000000C5D4F200FFDC7800BECEA100F0A0A100BCA8E1009CC1B600F7B88600D9ADC200A5C2D700B3A6BE00EAD6A300F6FA7D00B5E99D005FC3CF00C1838300CACAD500010000000000000002000000F40000006500000080070000FD030000 @@ -134,7 +134,7 @@ -1 -1 0 - 0 + 1 0 0 32767 @@ -143,11 +143,11 @@ 0 16 - F40000004F00000090050000DF000000 + 000000005703000080070000E7030000 16 - F40000006500000090050000F5000000 + 01000000700300008107000000040000 @@ -163,7 +163,7 @@ 0 16 - 0300000066000000ED0000003A030000 + 0300000066000000ED000000CE030000 16 @@ -183,7 +183,7 @@ 0 16 - 0300000066000000ED0000003A030000 + 0300000066000000ED000000CE030000 16 @@ -463,7 +463,7 @@ 0 16 - 0300000066000000ED0000003A030000 + 0300000066000000ED000000CE030000 16 @@ -483,7 +483,7 @@ 0 16 - 0300000066000000ED0000003A030000 + 0300000066000000ED000000CE030000 16 @@ -493,8 +493,8 @@ 197 197 - 1 - 0 + 0 + 1 0 0 32767 @@ -507,7 +507,7 @@ 16 - E9000000FF000000B10300008F010000 + 01000000700300008107000000040000 @@ -534,12 +534,12 @@ 199 199 0 - 0 + 1 0 0 32767 0 - 4096 + 32768 0 16 @@ -547,7 +547,7 @@ 16 - E9000000FF000000B10300008F010000 + 01000000700300008107000000040000 @@ -1163,7 +1163,7 @@ 0 16 - 0300000066000000ED0000003A030000 + 0300000066000000ED000000CE030000 16 @@ -1174,12 +1174,12 @@ 38007 38007 0 - 0 + 1 0 0 32767 0 - 4096 + 32768 0 16 @@ -1187,19 +1187,19 @@ 16 - E9000000FF000000B10300008F010000 + 01000000700300008107000000040000 436 436 0 - 0 + 1 0 0 32767 0 - 4096 + 32768 0 16 @@ -1207,7 +1207,7 @@ 16 - E9000000FF0000000502000041030000 + 01000000700300008107000000040000 @@ -1254,12 +1254,12 @@ 463 463 0 - 0 + 1 0 0 32767 0 - 4096 + 32768 0 16 @@ -1267,19 +1267,19 @@ 16 - E9000000FF0000000502000041030000 + 01000000700300008107000000040000 466 466 0 - 0 + 1 0 0 32767 0 - 4096 + 32768 0 16 @@ -1287,7 +1287,7 @@ 16 - E9000000FF0000000502000041030000 + 01000000700300008107000000040000 @@ -1811,15 +1811,15 @@ - 3312 - 000000000B000000000000000020000000000000FFFFFFFFFFFFFFFFF4000000DF00000090050000E3000000000000000100000004000000010000000000000000000000FFFFFFFF08000000CB00000057010000CC000000F08B00005A01000079070000D601000045890000FFFF02000B004354616262656450616E650020000000000000F40000006500000090050000F5000000F40000004F00000090050000DF0000000000000040280046080000000B446973617373656D626C7900000000CB00000001000000FFFFFFFFFFFFFFFF14506572666F726D616E636520416E616C797A6572000000005701000001000000FFFFFFFFFFFFFFFF14506572666F726D616E636520416E616C797A657200000000CC00000001000000FFFFFFFFFFFFFFFF0E4C6F67696320416E616C797A657200000000F08B000001000000FFFFFFFFFFFFFFFF0D436F646520436F766572616765000000005A01000001000000FFFFFFFFFFFFFFFF11496E737472756374696F6E205472616365000000007907000001000000FFFFFFFFFFFFFFFF0F53797374656D20416E616C797A657200000000D601000001000000FFFFFFFFFFFFFFFF104576656E742053746174697374696373000000004589000001000000FFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000000000000000000000001000000FFFFFFFFCB00000001000000FFFFFFFFCB000000000000000040000000000000FFFFFFFFFFFFFFFF9C0400004F000000A00400002B020000000000000200000004000000010000000000000000000000FFFFFFFF2B000000E2050000CA0900002D8C00002E8C00002F8C0000308C0000318C0000328C0000338C0000348C0000358C0000368C0000378C0000388C0000398C00003A8C00003B8C00003C8C00003D8C00003E8C00003F8C0000408C0000418C000050C3000051C3000052C3000053C3000054C3000055C3000056C3000057C3000058C3000059C300005AC300005BC300005CC300005DC300005EC300005FC3000060C3000061C3000062C3000063C3000001800040000000000000A0040000650000009005000041020000A00400004F000000900500002B02000000000000404100462B0000000753796D626F6C7300000000E205000001000000FFFFFFFFFFFFFFFF0A5472616365204461746100000000CA09000001000000FFFFFFFFFFFFFFFF00000000002D8C000001000000FFFFFFFFFFFFFFFF00000000002E8C000001000000FFFFFFFFFFFFFFFF00000000002F8C000001000000FFFFFFFFFFFFFFFF0000000000308C000001000000FFFFFFFFFFFFFFFF0000000000318C000001000000FFFFFFFFFFFFFFFF0000000000328C000001000000FFFFFFFFFFFFFFFF0000000000338C000001000000FFFFFFFFFFFFFFFF0000000000348C000001000000FFFFFFFFFFFFFFFF0000000000358C000001000000FFFFFFFFFFFFFFFF0000000000368C000001000000FFFFFFFFFFFFFFFF0000000000378C000001000000FFFFFFFFFFFFFFFF0000000000388C000001000000FFFFFFFFFFFFFFFF0000000000398C000001000000FFFFFFFFFFFFFFFF00000000003A8C000001000000FFFFFFFFFFFFFFFF00000000003B8C000001000000FFFFFFFFFFFFFFFF00000000003C8C000001000000FFFFFFFFFFFFFFFF00000000003D8C000001000000FFFFFFFFFFFFFFFF00000000003E8C000001000000FFFFFFFFFFFFFFFF00000000003F8C000001000000FFFFFFFFFFFFFFFF0000000000408C000001000000FFFFFFFFFFFFFFFF0000000000418C000001000000FFFFFFFFFFFFFFFF000000000050C3000001000000FFFFFFFFFFFFFFFF000000000051C3000001000000FFFFFFFFFFFFFFFF000000000052C3000001000000FFFFFFFFFFFFFFFF000000000053C3000001000000FFFFFFFFFFFFFFFF000000000054C3000001000000FFFFFFFFFFFFFFFF000000000055C3000001000000FFFFFFFFFFFFFFFF000000000056C3000001000000FFFFFFFFFFFFFFFF000000000057C3000001000000FFFFFFFFFFFFFFFF000000000058C3000001000000FFFFFFFFFFFFFFFF000000000059C3000001000000FFFFFFFFFFFFFFFF00000000005AC3000001000000FFFFFFFFFFFFFFFF00000000005BC3000001000000FFFFFFFFFFFFFFFF00000000005CC3000001000000FFFFFFFFFFFFFFFF00000000005DC3000001000000FFFFFFFFFFFFFFFF00000000005EC3000001000000FFFFFFFFFFFFFFFF00000000005FC3000001000000FFFFFFFFFFFFFFFF000000000060C3000001000000FFFFFFFFFFFFFFFF000000000061C3000001000000FFFFFFFFFFFFFFFF000000000062C3000001000000FFFFFFFFFFFFFFFF000000000063C3000001000000FFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000000000000000000000001000000FFFFFFFFE205000001000000FFFFFFFFE2050000000000000010000001000000FFFFFFFFFFFFFFFFF00000004F000000F400000053030000010000000200001004000000010000000000000000000000FFFFFFFF05000000ED0300006D000000C3000000C400000073940000018000100000010000000000000065000000F000000069030000000000004F000000F0000000530300000000000040410056050000000750726F6A65637401000000ED03000001000000FFFFFFFFFFFFFFFF05426F6F6B73010000006D00000001000000FFFFFFFFFFFFFFFF0946756E6374696F6E7301000000C300000001000000FFFFFFFFFFFFFFFF0954656D706C6174657301000000C400000001000000FFFFFFFFFFFFFFFF09526567697374657273000000007394000001000000FFFFFFFFFFFFFFFF00000000000000000000000000000000000000000000000001000000FFFFFFFFED03000001000000FFFFFFFFED030000000000000080000000000000FFFFFFFFFFFFFFFF0000000017020000900500001B02000000000000010000000400000001000000000000000000000000000000000000000000000001000000C6000000FFFFFFFF0F0000008F070000930700009407000095070000960700009007000091070000B5010000B801000038030000B9050000BA050000BB050000BC050000CB09000001800080000000000000000000003102000090050000D5020000000000001B02000090050000BF02000000000000404100460F0000001343616C6C20537461636B202B204C6F63616C73000000008F07000001000000FFFFFFFFFFFFFFFF0755415254202331000000009307000001000000FFFFFFFFFFFFFFFF0755415254202332000000009407000001000000FFFFFFFFFFFFFFFF0755415254202333000000009507000001000000FFFFFFFFFFFFFFFF15446562756720287072696E74662920566965776572000000009607000001000000FFFFFFFFFFFFFFFF0757617463682031000000009007000001000000FFFFFFFFFFFFFFFF0757617463682032000000009107000001000000FFFFFFFFFFFFFFFF10547261636520457863657074696F6E7300000000B501000001000000FFFFFFFFFFFFFFFF0E4576656E7420436F756E7465727300000000B801000001000000FFFFFFFFFFFFFFFF09554C494E4B706C7573000000003803000001000000FFFFFFFFFFFFFFFF084D656D6F7279203100000000B905000001000000FFFFFFFFFFFFFFFF084D656D6F7279203200000000BA05000001000000FFFFFFFFFFFFFFFF084D656D6F7279203300000000BB05000001000000FFFFFFFFFFFFFFFF084D656D6F7279203400000000BC05000001000000FFFFFFFFFFFFFFFF105472616365204E617669676174696F6E00000000CB09000001000000FFFFFFFFFFFFFFFFFFFFFFFF0000000001000000000000000000000001000000FFFFFFFFC80200001B020000CC020000BF02000000000000020000000400000000000000000000000000000000000000000000000000000002000000C6000000FFFFFFFF8F07000001000000FFFFFFFF8F07000001000000C6000000000000000080000001000000FFFFFFFFFFFFFFFF00000000530300008007000057030000010000000100001004000000010000000000000000000000FFFFFFFF06000000C5000000C7000000B4010000D2010000CF0100007794000001800080000001000000000000006D03000080070000FD030000000000005703000080070000E70300000000000040820056060000000C4275696C64204F757470757401000000C500000001000000FFFFFFFFFFFFFFFF0D46696E6420496E2046696C657300000000C700000001000000FFFFFFFFFFFFFFFF0A4572726F72204C69737400000000B401000001000000FFFFFFFFFFFFFFFF0E536F757263652042726F7773657200000000D201000001000000FFFFFFFFFFFFFFFF0E416C6C205265666572656E63657300000000CF01000001000000FFFFFFFFFFFFFFFF0742726F77736572000000007794000001000000FFFFFFFFFFFFFFFF00000000000000000000000000000000000000000000000001000000FFFFFFFFC500000001000000FFFFFFFFC5000000000000000000000000000000 + 3300 + 0000000009000000000000000020000000000000FFFFFFFFFFFFFFFFF4000000DF00000090050000E3000000000000000100000004000000010000000000000000000000FFFFFFFF08000000CB00000057010000CC000000F08B00005A01000079070000D601000045890000FFFF02000B004354616262656450616E650020000000000000F40000006500000090050000F5000000F40000004F00000090050000DF0000000000000040280046080000000B446973617373656D626C7900000000CB00000001000000FFFFFFFFFFFFFFFF14506572666F726D616E636520416E616C797A6572000000005701000001000000FFFFFFFFFFFFFFFF14506572666F726D616E636520416E616C797A657200000000CC00000001000000FFFFFFFFFFFFFFFF0E4C6F67696320416E616C797A657200000000F08B000001000000FFFFFFFFFFFFFFFF0D436F646520436F766572616765000000005A01000001000000FFFFFFFFFFFFFFFF11496E737472756374696F6E205472616365000000007907000001000000FFFFFFFFFFFFFFFF0F53797374656D20416E616C797A657200000000D601000001000000FFFFFFFFFFFFFFFF104576656E742053746174697374696373000000004589000001000000FFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000000000000000000000001000000FFFFFFFFCB00000001000000FFFFFFFFCB000000000000000040000000000000FFFFFFFFFFFFFFFF9C0400004F000000A00400002B020000000000000200000004000000010000000000000000000000FFFFFFFF2B000000E2050000CA0900002D8C00002E8C00002F8C0000308C0000318C0000328C0000338C0000348C0000358C0000368C0000378C0000388C0000398C00003A8C00003B8C00003C8C00003D8C00003E8C00003F8C0000408C0000418C000050C3000051C3000052C3000053C3000054C3000055C3000056C3000057C3000058C3000059C300005AC300005BC300005CC300005DC300005EC300005FC3000060C3000061C3000062C3000063C3000001800040000000000000A0040000650000009005000041020000A00400004F000000900500002B02000000000000404100462B0000000753796D626F6C7300000000E205000001000000FFFFFFFFFFFFFFFF0A5472616365204461746100000000CA09000001000000FFFFFFFFFFFFFFFF00000000002D8C000001000000FFFFFFFFFFFFFFFF00000000002E8C000001000000FFFFFFFFFFFFFFFF00000000002F8C000001000000FFFFFFFFFFFFFFFF0000000000308C000001000000FFFFFFFFFFFFFFFF0000000000318C000001000000FFFFFFFFFFFFFFFF0000000000328C000001000000FFFFFFFFFFFFFFFF0000000000338C000001000000FFFFFFFFFFFFFFFF0000000000348C000001000000FFFFFFFFFFFFFFFF0000000000358C000001000000FFFFFFFFFFFFFFFF0000000000368C000001000000FFFFFFFFFFFFFFFF0000000000378C000001000000FFFFFFFFFFFFFFFF0000000000388C000001000000FFFFFFFFFFFFFFFF0000000000398C000001000000FFFFFFFFFFFFFFFF00000000003A8C000001000000FFFFFFFFFFFFFFFF00000000003B8C000001000000FFFFFFFFFFFFFFFF00000000003C8C000001000000FFFFFFFFFFFFFFFF00000000003D8C000001000000FFFFFFFFFFFFFFFF00000000003E8C000001000000FFFFFFFFFFFFFFFF00000000003F8C000001000000FFFFFFFFFFFFFFFF0000000000408C000001000000FFFFFFFFFFFFFFFF0000000000418C000001000000FFFFFFFFFFFFFFFF000000000050C3000001000000FFFFFFFFFFFFFFFF000000000051C3000001000000FFFFFFFFFFFFFFFF000000000052C3000001000000FFFFFFFFFFFFFFFF000000000053C3000001000000FFFFFFFFFFFFFFFF000000000054C3000001000000FFFFFFFFFFFFFFFF000000000055C3000001000000FFFFFFFFFFFFFFFF000000000056C3000001000000FFFFFFFFFFFFFFFF000000000057C3000001000000FFFFFFFFFFFFFFFF000000000058C3000001000000FFFFFFFFFFFFFFFF000000000059C3000001000000FFFFFFFFFFFFFFFF00000000005AC3000001000000FFFFFFFFFFFFFFFF00000000005BC3000001000000FFFFFFFFFFFFFFFF00000000005CC3000001000000FFFFFFFFFFFFFFFF00000000005DC3000001000000FFFFFFFFFFFFFFFF00000000005EC3000001000000FFFFFFFFFFFFFFFF00000000005FC3000001000000FFFFFFFFFFFFFFFF000000000060C3000001000000FFFFFFFFFFFFFFFF000000000061C3000001000000FFFFFFFFFFFFFFFF000000000062C3000001000000FFFFFFFFFFFFFFFF000000000063C3000001000000FFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000000000000000000000001000000FFFFFFFFE205000001000000FFFFFFFFE2050000000000000010000001000000FFFFFFFFFFFFFFFFF00000004F000000F4000000E7030000010000000200001004000000010000000000000000000000FFFFFFFF05000000ED0300006D000000C3000000C400000073940000018000100000010000000000000065000000F0000000FD030000000000004F000000F0000000E70300000000000040410056050000000750726F6A65637401000000ED03000001000000FFFFFFFFFFFFFFFF05426F6F6B73010000006D00000001000000FFFFFFFFFFFFFFFF0946756E6374696F6E7301000000C300000001000000FFFFFFFFFFFFFFFF0954656D706C6174657301000000C400000001000000FFFFFFFFFFFFFFFF09526567697374657273000000007394000001000000FFFFFFFFFFFFFFFF00000000000000000000000000000000000000000000000001000000FFFFFFFFED03000001000000FFFFFFFFED030000000000000080000000000000FFFFFFFFFFFFFFFF0000000017020000900500001B02000000000000010000000400000001000000000000000000000000000000000000000000000001000000C6000000FFFFFFFF0F0000008F070000930700009407000095070000960700009007000091070000B5010000B801000038030000B9050000BA050000BB050000BC050000CB09000001800080000000000000000000003102000090050000D5020000000000001B02000090050000BF02000000000000404100460F0000001343616C6C20537461636B202B204C6F63616C73000000008F07000001000000FFFFFFFFFFFFFFFF0755415254202331000000009307000001000000FFFFFFFFFFFFFFFF0755415254202332000000009407000001000000FFFFFFFFFFFFFFFF0755415254202333000000009507000001000000FFFFFFFFFFFFFFFF15446562756720287072696E74662920566965776572000000009607000001000000FFFFFFFFFFFFFFFF0757617463682031000000009007000001000000FFFFFFFFFFFFFFFF0757617463682032000000009107000001000000FFFFFFFFFFFFFFFF10547261636520457863657074696F6E7300000000B501000001000000FFFFFFFFFFFFFFFF0E4576656E7420436F756E7465727300000000B801000001000000FFFFFFFFFFFFFFFF09554C494E4B706C7573000000003803000001000000FFFFFFFFFFFFFFFF084D656D6F7279203100000000B905000001000000FFFFFFFFFFFFFFFF084D656D6F7279203200000000BA05000001000000FFFFFFFFFFFFFFFF084D656D6F7279203300000000BB05000001000000FFFFFFFFFFFFFFFF084D656D6F7279203400000000BC05000001000000FFFFFFFFFFFFFFFF105472616365204E617669676174696F6E00000000CB09000001000000FFFFFFFFFFFFFFFFFFFFFFFF0000000001000000000000000000000001000000FFFFFFFFC80200001B020000CC020000BF02000000000000020000000400000000000000000000000000000000000000000000000000000002000000C6000000FFFFFFFF8F07000001000000FFFFFFFF8F07000001000000C600000001000000FFFF02001200434D756C746950616E654672616D65576E64000100840100000070030000810700000004000000000000000000000200000000000000FFFFFFFF06000000C5000000C7000000B4010000D2010000CF010000779400000180008000000000000001000000700300008107000000040000000000005703000080070000E70300000000000040820046060000000C4275696C64204F757470757401000000C500000001000000FFFFFFFFFFFFFFFF0D46696E6420496E2046696C657300000000C700000001000000FFFFFFFFFFFFFFFF0A4572726F72204C69737400000000B401000001000000FFFFFFFFFFFFFFFF0E536F757263652042726F7773657200000000D201000001000000FFFFFFFFFFFFFFFF0E416C6C205265666572656E63657300000000CF01000001000000FFFFFFFFFFFFFFFF0742726F77736572000000007794000001000000FFFFFFFFFFFFFFFF00000000000000000000000000000000000000000000000001000000FFFFFFFFC50000000000000000000000 59392 File - 2648 - 00200000010000002800FFFF01001100434D4643546F6F6C426172427574746F6E00E100000000000000000000000000000000000000000000000100000001000000018001E100000000000001000000000000000000000000000000000100000001000000018003E1000000000000020000000000000000000000000000000001000000010000000180CD7F0000000000000300000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF000000000000000000000000000100000001000000018023E100000000040004000000000000000000000000000000000100000001000000018022E100000000040005000000000000000000000000000000000100000001000000018025E10000000000000600000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF00000000000000000000000000010000000100000001802BE10000000000000700000000000000000000000000000000010000000100000001802CE10000000004000800000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF00000000000000000000000000010000000100000001807A8A0000000000000900000000000000000000000000000000010000000100000001807B8A0000000004000A00000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180D3B00000000000000B000000000000000000000000000000000100000001000000018015B10000000004000C0000000000000000000000000000000001000000010000000180F4B00000000004000D000000000000000000000000000000000100000001000000018036B10000000004000E00000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180FF88000000000400460000000000000000000000000000000001000000010000000180FE880000000004004500000000000000000000000000000000010000000100000001800B810000000004001300000000000000000000000000000000010000000100000001800C810000000004001400000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180F0880000020000000F000000000000000000000000000000000100000001000000FFFF0100120043555646696E64436F6D626F427574746F6EE803000000000000000000000000000000000000000000000001000000010000009600000002002050000000000469662028960000000000000006000C43616E4572726F7273426F781823696E636C756465202263616E6572726F72626F782E682204696620280269660E43414E5F4572726F725F436F64651548414C5F43414E5F4572726F7243616C6C6261636B000000000000000000000000000000000000000000000000018024E10000000000001100000000000000000000000000000000010000000100000001800A810000000000001200000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF000000000000000000000000000100000001000000FFFF01001500434D4643546F6F6C4261724D656E75427574746F6E2280000002000000150000002153746172742F53746F70202644656275672053657373696F6E094374726C2B46350000000000000000000000000100000001000000000000000000000001000000020021802280000000000000150000002153746172742F53746F70202644656275672053657373696F6E094374726C2B4635000000000000000000000000010000000100000000000000000000000100000000002180E0010000000000007500000021456E65726779204D6561737572656D656E742026776974686F75742044656275670000000000000000000000000100000001000000000000000000000001000000000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180C488000000000000160000000000000000000000000000000001000000010000000180C988000000000400180000000000000000000000000000000001000000010000000180C788000000000000190000000000000000000000000000000001000000010000002180C8880000000000001700000027264B696C6C20416C6C20427265616B706F696E747320696E2043757272656E7420546172676574000000000000000000000000010000000100000000000000000000000100000003002180C8880000000000001700000027264B696C6C20416C6C20427265616B706F696E747320696E2043757272656E7420546172676574000000000000000000000000010000000100000000000000000000000100000000002180E50100000000000078000000264B696C6C20416C6C20427265616B706F696E747320696E204163746976652050726F6A656374000000000000000000000000010000000100000000000000000000000100000000002180E601000000000000790000002F4B696C6C20416C6C20427265616B706F696E747320696E204D756C74692D50726F6A65637420576F726B73706163650000000000000000000000000100000001000000000000000000000001000000000001800000000001000000FFFFFFFF00000000000000000000000000010000000100000021804C010000020001001A0000000F2650726F6A6563742057696E646F77000000000000000000000000010000000100000000000000000000000100000008002180DD880000000000001A0000000750726F6A656374000000000000000000000000010000000100000000000000000000000100000000002180DC8B0000000000003A00000005426F6F6B73000000000000000000000000010000000100000000000000000000000100000000002180E18B0000000000003B0000000946756E6374696F6E73000000000000000000000000010000000100000000000000000000000100000000002180E28B000000000000400000000954656D706C6174657300000000000000000000000001000000010000000000000000000000010000000000218018890000000000003D0000000E536F757263652042726F777365720000000000000000000000000100000001000000000000000000000001000000000021800000000000000400FFFFFFFF00000000000000000001000000000000000100000000000000000000000100000000002180D988000000000000390000000C4275696C64204F7574707574000000000000000000000000010000000100000000000000000000000100000000002180E38B000000000000410000000B46696E64204F75747075740000000000000000000000000100000001000000000000000000000001000000000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180FB7F0000000000001B000000000000000000000000000000000100000001000000000000000446696C65C6030000 + 2958 + 00200000010000002800FFFF01001100434D4643546F6F6C426172427574746F6E00E100000000000000000000000000000000000000000000000100000001000000018001E100000000000001000000000000000000000000000000000100000001000000018003E1000000000000020000000000000000000000000000000001000000010000000180CD7F0000000002000300000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF000000000000000000000000000100000001000000018023E100000000040004000000000000000000000000000000000100000001000000018022E100000000040005000000000000000000000000000000000100000001000000018025E10000000000000600000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF00000000000000000000000000010000000100000001802BE10000000000000700000000000000000000000000000000010000000100000001802CE10000000004000800000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF00000000000000000000000000010000000100000001807A8A0000000000000900000000000000000000000000000000010000000100000001807B8A0000000004000A00000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180D3B00000000000000B000000000000000000000000000000000100000001000000018015B10000000004000C0000000000000000000000000000000001000000010000000180F4B00000000004000D000000000000000000000000000000000100000001000000018036B10000000004000E00000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180FF88000000000400460000000000000000000000000000000001000000010000000180FE880000000004004500000000000000000000000000000000010000000100000001800B810000000004001300000000000000000000000000000000010000000100000001800C810000000004001400000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180F0880000020000000F000000000000000000000000000000000100000001000000FFFF0100120043555646696E64436F6D626F427574746F6EE80300000000000000000000000000000000000000000000000100000001000000960000000200205000000000055F4843414E960000000000000014001150524F544F43414E5F5254435F53594E43000C43616E52657175657374546F09524551554553544552055F4843414E2148414C5F43414E5F52784669666F304D736750656E64696E6743616C6C6261636B0863616C6C6261636B0C43414E5F52585F4649464F300C43414E5F49545F4552524F520E43414E5F496E74657272757074731A48414C5F43414E5F526567697374657243616C6C6261636B28290852656769737465721757616B65557046726F6D52784D736743616C6C6261636B0E43414E5F4572726F725F436F64651548414C5F43414E5F4572726F7243616C6C6261636B037278662248414C5F43414E5F52784669666F3046756C6C43616C6C6261636B286863616E293B1F48414C5F43414E5F57616B65557046726F6D52784D736743616C6C6261636B11417661696C61626C6543616E52784D73671143414E5F43555252454E545F53504545440000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018024E10000000000001100000000000000000000000000000000010000000100000001800A810000000000001200000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF000000000000000000000000000100000001000000FFFF01001500434D4643546F6F6C4261724D656E75427574746F6E2280000002000000150000002153746172742F53746F70202644656275672053657373696F6E094374726C2B46350000000000000000000000000100000001000000000000000000000001000000020021802280000000000000150000002153746172742F53746F70202644656275672053657373696F6E094374726C2B4635000000000000000000000000010000000100000000000000000000000100000000002180E0010000000000007500000021456E65726779204D6561737572656D656E742026776974686F75742044656275670000000000000000000000000100000001000000000000000000000001000000000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180C488000000000000160000000000000000000000000000000001000000010000000180C988000000000400180000000000000000000000000000000001000000010000000180C788000000000000190000000000000000000000000000000001000000010000002180C8880000000000001700000027264B696C6C20416C6C20427265616B706F696E747320696E2043757272656E7420546172676574000000000000000000000000010000000100000000000000000000000100000003002180C8880000000000001700000027264B696C6C20416C6C20427265616B706F696E747320696E2043757272656E7420546172676574000000000000000000000000010000000100000000000000000000000100000000002180E50100000000000078000000264B696C6C20416C6C20427265616B706F696E747320696E204163746976652050726F6A656374000000000000000000000000010000000100000000000000000000000100000000002180E601000000000000790000002F4B696C6C20416C6C20427265616B706F696E747320696E204D756C74692D50726F6A65637420576F726B73706163650000000000000000000000000100000001000000000000000000000001000000000001800000000001000000FFFFFFFF00000000000000000000000000010000000100000021804C010000020001001A0000000F2650726F6A6563742057696E646F77000000000000000000000000010000000100000000000000000000000100000008002180DD880000000000001A0000000750726F6A656374000000000000000000000000010000000100000000000000000000000100000000002180DC8B0000000000003A00000005426F6F6B73000000000000000000000000010000000100000000000000000000000100000000002180E18B0000000000003B0000000946756E6374696F6E73000000000000000000000000010000000100000000000000000000000100000000002180E28B000000000000400000000954656D706C6174657300000000000000000000000001000000010000000000000000000000010000000000218018890000000000003D0000000E536F757263652042726F777365720000000000000000000000000100000001000000000000000000000001000000000021800000000000000400FFFFFFFF00000000000000000001000000000000000100000000000000000000000100000000002180D988000000000000390000000C4275696C64204F7574707574000000000000000000000000010000000100000000000000000000000100000000002180E38B000000000000410000000B46696E64204F75747075740000000000000000000000000100000001000000000000000000000001000000000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180FB7F0000000000001B000000000000000000000000000000000100000001000000000000000446696C65C6030000 1423 @@ -1851,7 +1851,7 @@ Debug 2373 - 00200000000000001900FFFF01001100434D4643546F6F6C426172427574746F6ECC880000000000002500000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF000000000000000000000000000100000001000000018017800000000000002600000000000000000000000000000000010000000100000001801D800000000000002700000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF00000000000000000000000000010000000100000001801A800000000000002800000000000000000000000000000000010000000100000001801B80000000000000290000000000000000000000000000000001000000010000000180E57F0000000000002A00000000000000000000000000000000010000000100000001801C800000000000002B00000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF000000000000000000000000000100000001000000018000890000000000002C00000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180E48B0000000000002D0000000000000000000000000000000001000000010000000180F07F0000000000002E0000000000000000000000000000000001000000010000000180E8880000000000003700000000000000000000000000000000010000000100000001803B010000000000002F0000000000000000000000000000000001000000010000000180BB8A00000000000030000000000000000000000000000000000100000001000000FFFF01001500434D4643546F6F6C4261724D656E75427574746F6E0E01000000000000310000000D57617463682057696E646F7773000000000000000000000000010000000100000000000000000000000100000003001380D88B00000000000031000000085761746368202631000000000000000000000000010000000100000000000000000000000100000000001380D98B00000000000031000000085761746368202632000000000000000000000000010000000100000000000000000000000100000000001380CE01000000000000FFFFFFFF0C576174636820416E63686F720000000000000000010000000000000001000000000000000000000001000000000013800F01000000000000320000000E4D656D6F72792057696E646F7773000000000000000000000000010000000100000000000000000000000100000004001380D28B00000000000032000000094D656D6F7279202631000000000000000000000000010000000100000000000000000000000100000000001380D38B00000000000032000000094D656D6F7279202632000000000000000000000000010000000100000000000000000000000100000000001380D48B00000000000032000000094D656D6F7279202633000000000000000000000000010000000100000000000000000000000100000000001380D58B00000000000032000000094D656D6F72792026340000000000000000000000000100000001000000000000000000000001000000000013801001000000000000330000000E53657269616C2057696E646F77730000000000000000000000000100000001000000000000000000000001000000040013809307000000000000330000000855415254202326310000000000000000000000000100000001000000000000000000000001000000000013809407000000000000330000000855415254202326320000000000000000000000000100000001000000000000000000000001000000000013809507000000000000330000000855415254202326330000000000000000000000000100000001000000000000000000000001000000000013809607000000000000330000001626446562756720287072696E746629205669657765720000000000000000000000000100000001000000000000000000000001000000000013803C010000000000007200000010416E616C797369732057696E646F7773000000000000000000000000010000000100000000000000000000000100000004001380658A000000000000340000000F264C6F67696320416E616C797A6572000000000000000000000000010000000100000000000000000000000100000000001380DC7F0000000000003E0000001526506572666F726D616E636520416E616C797A6572000000000000000000000000010000000100000000000000000000000100000000001380E788000000000000380000000E26436F646520436F766572616765000000000000000000000000010000000100000000000000000000000100000000001380CD01000000000000FFFFFFFF0F416E616C7973697320416E63686F7200000000000000000100000000000000010000000000000000000000010000000000138053010000000000003F0000000D54726163652057696E646F77730000000000000000000000000100000001000000000000000000000001000000010013805401000000000000FFFFFFFF115472616365204D656E7520416E63686F720000000000000000010000000000000001000000000000000000000001000000000013802901000000000000350000001553797374656D205669657765722057696E646F77730000000000000000000000000100000001000000000000000000000001000000010013804B01000000000000FFFFFFFF1453797374656D2056696577657220416E63686F720000000000000000010000000000000001000000000000000000000001000000000001800000000001000000FFFFFFFF00000000000000000000000000010000000100000013800189000000000000360000000F26546F6F6C626F782057696E646F7700000000000000000000000001000000010000000000000000000000010000000300138044C5000000000000FFFFFFFF0E5570646174652057696E646F77730000000000000000010000000000000001000000000000000000000001000000000013800000000000000400FFFFFFFF000000000000000000010000000000000001000000000000000000000001000000000013805B01000000000000FFFFFFFF12546F6F6C626F78204D656E75416E63686F72000000000000000001000000000000000100000000000000000000000100000000000000000005446562756764020000 + 00200000000000001900FFFF01001100434D4643546F6F6C426172427574746F6ECC880000000000002500000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF000000000000000000000000000100000001000000018017800000000000002600000000000000000000000000000000010000000100000001801D800000000000002700000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF00000000000000000000000000010000000100000001801A800000000000002800000000000000000000000000000000010000000100000001801B80000000000000290000000000000000000000000000000001000000010000000180E57F0000000000002A00000000000000000000000000000000010000000100000001801C800000000000002B00000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF000000000000000000000000000100000001000000018000890000000000002C00000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180E48B0000000000002D0000000000000000000000000000000001000000010000000180F07F0000000000002E0000000000000000000000000000000001000000010000000180E8880000000000003700000000000000000000000000000000010000000100000001803B010000000000002F0000000000000000000000000000000001000000010000000180BB8A00000000000030000000000000000000000000000000000100000001000000FFFF01001500434D4643546F6F6C4261724D656E75427574746F6E0E01000000000000310000000D57617463682057696E646F7773000000000000000000000000010000000100000000000000000000000100000003001380D88B00000000000031000000085761746368202631000000000000000000000000010000000100000000000000000000000100000000001380D98B00000000000031000000085761746368202632000000000000000000000000010000000100000000000000000000000100000000001380CE01000000000000FFFFFFFF0C576174636820416E63686F720100000000000000010000000000000001000000000000000000000001000000000013800F01000000000000320000000E4D656D6F72792057696E646F7773000000000000000000000000010000000100000000000000000000000100000004001380D28B00000000000032000000094D656D6F7279202631000000000000000000000000010000000100000000000000000000000100000000001380D38B00000000000032000000094D656D6F7279202632000000000000000000000000010000000100000000000000000000000100000000001380D48B00000000000032000000094D656D6F7279202633000000000000000000000000010000000100000000000000000000000100000000001380D58B00000000000032000000094D656D6F72792026340000000000000000000000000100000001000000000000000000000001000000000013801001000000000000330000000E53657269616C2057696E646F77730000000000000000000000000100000001000000000000000000000001000000040013809307000000000000330000000855415254202326310000000000000000000000000100000001000000000000000000000001000000000013809407000000000000330000000855415254202326320000000000000000000000000100000001000000000000000000000001000000000013809507000000000000330000000855415254202326330000000000000000000000000100000001000000000000000000000001000000000013809607000000000000330000001626446562756720287072696E746629205669657765720000000000000000000000000100000001000000000000000000000001000000000013803C010000000000007200000010416E616C797369732057696E646F7773000000000000000000000000010000000100000000000000000000000100000004001380658A000000000000340000000F264C6F67696320416E616C797A6572000000000000000000000000010000000100000000000000000000000100000000001380DC7F0000000000003E0000001526506572666F726D616E636520416E616C797A6572000000000000000000000000010000000100000000000000000000000100000000001380E788000000000000380000000E26436F646520436F766572616765000000000000000000000000010000000100000000000000000000000100000000001380CD01000000000000FFFFFFFF0F416E616C7973697320416E63686F7201000000000000000100000000000000010000000000000000000000010000000000138053010000000000003F0000000D54726163652057696E646F77730000000000000000000000000100000001000000000000000000000001000000010013805401000000000000FFFFFFFF115472616365204D656E7520416E63686F720100000000000000010000000000000001000000000000000000000001000000000013802901000000000000350000001553797374656D205669657765722057696E646F77730000000000000000000000000100000001000000000000000000000001000000010013804B01000000000000FFFFFFFF1453797374656D2056696577657220416E63686F720100000000000000010000000000000001000000000000000000000001000000000001800000000001000000FFFFFFFF00000000000000000000000000010000000100000013800189000000000000360000000F26546F6F6C626F782057696E646F7700000000000000000000000001000000010000000000000000000000010000000300138044C5000000000000FFFFFFFF0E5570646174652057696E646F77730100000000000000010000000000000001000000000000000000000001000000000013800000000000000400FFFFFFFF000000000000000000010000000000000001000000000000000000000001000000000013805B01000000000000FFFFFFFF12546F6F6C626F78204D656E75416E63686F72010000000000000001000000000000000100000000000000000000000100000000000000000005446562756764020000 898 @@ -3616,39 +3616,39 @@ 0 100 - 17 + 2 ../Core/Src/main.c - 9 + 23 63 - 93 + 70 1 0 ..\Core\Inc\main.h - 24 - 25 - 35 + 30 + 18 + 33 1 0 - ..\Core\Src\requester.c - 4 - 705 - 729 + ..\Core\Src\protocan.c + 18 + 76 + 43 1 0 ../Core/Src/stm32f1xx_it.c - 1 - 200 - 214 + 4 + 222 + 260 1 0 @@ -3664,18 +3664,18 @@ ../Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_can.c - 33 - 2264 - 2312 + 69 + 239 + 291 1 1709 0 ../Core/Src/tim.c - 20 - 10 - 30 + 27 + 59 + 81 1 0 @@ -3700,18 +3700,18 @@ ../Core/Src/can.c - 12 - 51 - 52 + 20 + 9 + 40 1 0 - ..\Core\Inc\requester.h - 16 - 184 - 122 + ..\Core\Inc\protocan.h + 11 + 262 + 281 1 0 @@ -3754,9 +3754,9 @@ ..\Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_can.h - 45 - 275 - 297 + 0 + 510 + 541 1 0 @@ -3764,17 +3764,17 @@ ..\Drivers\CMSIS\Device\ST\STM32F1xx\Include\stm32f103xb.h 8 - 629 - 684 + 653 + 659 1 0 ..\Core\Src\canerrorbox.c - 30 - 136 - 191 + 26 + 157 + 176 1 0 @@ -3788,6 +3788,15 @@ 0 + + ..\Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_def.h + 19 + 1 + 31 + 1 + + 0 + diff --git a/MDK-ARM/F103C8T6.uvoptx b/MDK-ARM/F103C8T6.uvoptx index b5c3647..601f947 100644 --- a/MDK-ARM/F103C8T6.uvoptx +++ b/MDK-ARM/F103C8T6.uvoptx @@ -161,7 +161,7 @@ 0 0 1 - ..\Core\Src\requester.c + D:\Work\MCU\F103C8T6\Core\Src\requester.c \\F103C8T6\../Core/Src/requester.c\55 @@ -177,10 +177,106 @@ 0 0 1 - ..\Core\Src\requester.c + D:\Work\MCU\F103C8T6\Core\Src\requester.c \\F103C8T6\../Core/Src/requester.c\690 + + 2 + 0 + 56 + 1 +
0
+ 0 + 0 + 0 + 0 + 0 + 0 + D:\Work\MCU\F103C8T6\Core\Src\requester.c + + +
+ + 3 + 0 + 691 + 1 +
0
+ 0 + 0 + 0 + 0 + 0 + 0 + D:\Work\MCU\F103C8T6\Core\Src\requester.c + + +
+ + 4 + 0 + 63 + 1 +
0
+ 0 + 0 + 0 + 0 + 0 + 0 + ..\Core\Src\protocan.c + + +
+ + 5 + 0 + 64 + 1 +
0
+ 0 + 0 + 0 + 0 + 0 + 0 + ..\Core\Src\protocan.c + + +
+ + 6 + 0 + 695 + 1 +
0
+ 0 + 0 + 0 + 0 + 0 + 0 + ..\Core\Src\protocan.c + + +
+ + 7 + 0 + 696 + 1 +
0
+ 0 + 0 + 0 + 0 + 0 + 0 + ..\Core\Src\protocan.c + + +
@@ -321,7 +417,31 @@ 2 2 1 - 1 + 0 + 0 + 0 + ..\Core\Src\canerrorbox.c + canerrorbox.c + 0 + 0 + + + 2 + 3 + 5 + 0 + 0 + 0 + ..\Core\Inc\canerrorbox.h + canerrorbox.h + 0 + 0 + + + 2 + 4 + 1 + 0 0 0 ../Core/Src/main.c @@ -331,7 +451,7 @@ 2 - 3 + 5 1 0 0 @@ -343,7 +463,7 @@ 2 - 4 + 6 1 0 0 @@ -355,7 +475,7 @@ 2 - 5 + 7 1 0 0 @@ -367,7 +487,7 @@ 2 - 6 + 8 1 0 0 @@ -379,7 +499,7 @@ 2 - 7 + 9 1 0 0 @@ -391,7 +511,7 @@ 2 - 8 + 10 1 0 0 @@ -401,30 +521,6 @@ 0 0 - - 2 - 9 - 5 - 0 - 0 - 0 - ..\Core\Inc\requester.h - requester.h - 0 - 0 - - - 2 - 10 - 1 - 0 - 0 - 0 - ..\Core\Src\requester.c - requester.c - 0 - 0 - 2 11 @@ -432,8 +528,8 @@ 0 0 0 - ..\Core\Src\canerrorbox.c - canerrorbox.c + ..\Core\Src\protocan.c + protocan.c 0 0 @@ -444,8 +540,8 @@ 0 0 0 - ..\Core\Inc\canerrorbox.h - canerrorbox.h + ..\Core\Inc\protocan.h + protocan.h 0 0 diff --git a/MDK-ARM/F103C8T6.uvprojx b/MDK-ARM/F103C8T6.uvprojx index 8252efc..23bc3e0 100644 --- a/MDK-ARM/F103C8T6.uvprojx +++ b/MDK-ARM/F103C8T6.uvprojx @@ -395,6 +395,16 @@ Application/User/Core + + canerrorbox.c + 1 + ..\Core\Src\canerrorbox.c + + + canerrorbox.h + 5 + ..\Core\Inc\canerrorbox.h + main.c 1 @@ -635,24 +645,14 @@ ../Core/Src/stm32f1xx_hal_msp.c - requester.h - 5 - ..\Core\Inc\requester.h - - - requester.c + protocan.c 1 - ..\Core\Src\requester.c + ..\Core\Src\protocan.c - canerrorbox.c - 1 - ..\Core\Src\canerrorbox.c - - - canerrorbox.h + protocan.h 5 - ..\Core\Inc\canerrorbox.h + ..\Core\Inc\protocan.h @@ -924,4 +924,13 @@ + + + + F103C8T6 + 1 + + + +