Files
STM32_Modbus/Inc/rs_message.h
Razvalyaev dfadef7b43 pre-release 0.1
проверка
2025-11-03 19:52:33 +03:00

299 lines
13 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
******************************************************************************
* @file rs_message.h
* @brief Библиотека обмена сообщениями по RS-интерфейсу
******************************************************************************
@defgroup RS_TOOLS RS Tools
@brief Всякое для работы по UART/RS
@{
******************************************************************************
* @details
Универсальная библиотека для работы с последовательными протоколами (Modbus, Custom)
через UART в режиме прерываний с поддержкой таймаутов.
@section Основные возможности:
- Прием/передача в прерываниях
- Обработка IDLE линии для определения конца фрейма
- Таймауты приема через TIM
- Гибкая настройка размера сообщений
@section Использование:
1. Определить структуру сообщения и размеры буфера
2. Реализовать weak-функции обработки сообщений
3. Добавить вызовы RS_UART_Handler/RS_TIM_Handler в прерывания
4. Инициализировать через RS_Init() и запустить прием RS_Receive_IT()
@section Особенности:
- Буфер: RS_Buffer[MSG_SIZE_MAX] Общий для приема/передачи
- Состояния: отслеживается через флаги в RS_HandleTypeDef
- Таймауты: контролируют максимальное время ожидания фрейма
******************************************************************************/
#ifndef __RS_LIB_H_
#define __RS_LIB_H_
#include "modbus_core.h"
/////////////////////////////////////////////////////////////////////
////////////////////////////---DEFINES---////////////////////////////
/* Check that all defines required by RS are defined */
#ifndef MSG_SIZE_MAX
#error Define MSG_SIZE_MAX (Maximum size of message). This is necessary to create buffer for UART.
#endif
#ifndef RX_FIRST_PART_SIZE
#error Define RX_FIRST_PART_SIZE (Size of first part of message). This is necessary to receive the first part of the message, from which determine the size of the remaining part of the message.
#endif
/**
* @cond Заглушки и внутренний недокументированный стаф
*/
/* Clear message-uart buffer */
#define RS_Clear_Buff(_buff_) for(int i=0; i<MSG_SIZE_MAX;i++) _buff_[i] = NULL
/* Set/Reset flags */
#define RS_Set_Free(_hRS_) _hRS_->f.RS_Busy = 0
#define RS_Set_Busy(_hRS_) _hRS_->f.RS_Busy = 1
#define RS_Set_RX_Flags(_hRS_) _hRS_->f.RX_Busy = 1; _hRS_->f.RX_Done = 0; _hRS_->f.RX_Half = 0
#define RS_Set_RX_Active_Flags(_hRS_) _hRS_->f.RX_Ongoing = 1
#define RS_Set_TX_Flags(_hRS_) _hRS_->f.TX_Busy = 1; _hRS_->f.TX_Done = 0
#define RS_Reset_RX_Active_Flags(_hRS_) _hRS_->f.RX_Ongoing = 0
#define RS_Reset_RX_Flags(_hRS_) RS_Reset_RX_Active_Flags(_hRS_); _hRS_->f.RX_Busy = 0; _hRS_->f.RX_Done = 0; _hRS_->f.RX_Half = 0
#define RS_Reset_TX_Flags(_hRS_) _hRS_->f.TX_Busy = 0; _hRS_->f.TX_Done = 0
#define RS_Set_RX_End_Flag(_hRS_) _hRS_->f.RX_Done = 1;
#define RS_Set_TX_End_Flag(_hRS_) _hRS_->f.TX_Done = 1
#define RS_Set_RX_End(_hRS_) RS_Reset_RX_Flags(_hRS_); RS_Set_RX_End_Flag(_hRS_)
#define RS_Set_TX_End(_hRS_) RS_Reset_TX_Flags(_hRS_); RS_Set_TX_End_Flag(_hRS_)
/* Clear all RS stuff */
#define RS_Clear_All(_hRS_) RS_Clear_Buff(_hRS_->pBufferPtr); RS_Reset_RX_Flags(_hRS_); RS_Reset_TX_Flags(_hRS_);
//#define MB_Is_RX_Busy(_hRS_) ((_hRS_->huart->gState&HAL_USART_STATE_BUSY_RX) == HAL_USART_STATE_BUSY_RX)
//#define MB_Is_TX_Busy(_hRS_) ((_hRS_->huart->gState&HAL_USART_STATE_BUSY_RX) == HAL_USART_STATE_BUSY_TX)
#define RS_Is_RX_Busy(_hRS_) (_hRS_->f.RX_Busy == 1)
#define RS_Is_TX_Busy(_hRS_) (_hRS_->f.TX_Busy == 1)
// направление передачи rs485
#ifndef RS_EnableReceive
#define RS_EnableReceive()
#endif
#ifndef RS_EnableTransmit
#define RS_EnableTransmit()
#endif
#ifndef __MYLIBS_INCLUDE_H_
// дефайны из mylibs include
static int dummy;
#define TrackerTypeDef(num_user_vars) void *
#define num_of_usercnts(_user_) 0
#define assert_tracecnt(_cntstruct_, _uservarnumb_) 0
#define if_assert_usertracker(_cntstruct_, _uservarnumb_) if(0)
#define tern_assert_usertracker(_cntstruct_, _uservarnumb_) 0
#define TrackerGet_Ok(_cntstruct_) dummy
#define TrackerGet_Err(_cntstruct_) dummy
#define TrackerGet_Warn(_cntstruct_) dummy
#define TrackerGet_User(_cntstruct_, _uservarnumb_) dummy
#define TrackerCnt_Ok(_cntstruct_)
#define TrackerCnt_Err(_cntstruct_)
#define TrackerCnt_Warn(_cntstruct_)
#define TrackerCnt_User(_cntstruct_, _uservarnumb_)
#define TrackerWrite_User(_cntstruct_, _uservarnumb_, _val_)
#define TrackerClear_All(_cntstruct_)
#define TrackerClear_Ok(_cntstruct_)
#define TrackerClear_Err(_cntstruct_)
#define TrackerClear_Warn(_cntstruct_)
#define TrackerClear_User(_cntstruct_)
#define TrackerClear_UserAll(_cntstruct_)
#ifndef printf_rs_err
#define printf_rs_err(...)
#endif
#ifndef printf_rs
#define printf_rs(...)
#endif
#endif
#ifndef RS_USER_VARS_NUMB
#define RS_USER_VARS_NUMB 0
#endif
/** @endcond */
////////////////////////////---DEFINES---////////////////////////////
/////////////////////////////////////////////////////////////////////
///////////////////////---STRUCTURES & ENUMS---//////////////////////
//------------------ENUMERATIONS--------------------
/** @brief Enums for respond CMD about RS status */
typedef enum // RS_StatusTypeDef
{
/* IN-CODE STATUS (start from 0x01, and goes up)*/
/*0x01*/ RS_OK = 0x01,
/*0x02*/ RS_ERR,
/*0x03*/ RS_ABORTED,
/*0x04*/ RS_BUSY,
/*0x05*/ RS_SKIP,
/*0x06*/ RS_COLLECT_MSG_ERR,
/*0x07*/ RS_PARSE_MSG_ERR,
// reserved values
// /*0x00*/ RS_UNKNOWN_ERR = 0x00, ///< reserved for case, if no one error founded (nothing changed response from zero)
}RS_StatusTypeDef;
#define RS_MASTER_START 0x3
/** @brief Enums for RS Modes */
typedef enum // RS_ModeTypeDef
{
RS_SLAVE_ALWAYS_WAIT = 0x01, ///< Slave mode with infinity waiting
RS_SLAVE_TIMEOUT_WAIT = 0x02, ///< Slave mode with waiting with timeout
// RS_MASTER = 0x03, ///< Master mode
}RS_ModeTypeDef;
/** @brief Enums for RS UART Modes */
typedef enum // RS_ITModeTypeDef
{
BLCK_MODE = 0x00, ///< Blocking mode
IT_MODE = 0x01, ///< Interrupt mode
}RS_ITModeTypeDef;
/** @brief Enums for Abort modes */
typedef enum // RS_AbortTypeDef
{
ABORT_TX = 0x01, ///< Abort transmit
ABORT_RX = 0x02, ///< Abort receive
ABORT_RX_TX = 0x03, ///< Abort receive and transmit
ABORT_RS = 0x04, ///< Abort uart and reset RS structure
}RS_AbortTypeDef;
/** @brief Enums for RX Size modes */
typedef enum // RS_RXSizeTypeDef
{
RS_RX_Size_Const = 0x01, ///< size of receiving message is constant
RS_RX_Size_NotConst = 0x02, ///< size of receiving message isnt constant
}RS_RXSizeTypeDef;
//-----------STRUCTURE FOR HANDLE RS------------
/** @brief Struct for flags RS */
typedef struct
{
unsigned RX_Half:1; ///< flag: 0 - receiving msg before ByteCnt, 0 - receiving msg after ByteCnt
unsigned RS_Busy:1; ///< flag: 1 - RS is busy, 0 - RS isnt busy
unsigned RX_Ongoing:1; ///< flag: 1 - receiving data right now, 0 - waiting for receiving data
unsigned RX_Busy:1; ///< flag: 1 - receiving is active, 0 - receiving isnt active
unsigned TX_Busy:1; ///< flag: 1 - transmiting is active, 0 - transmiting isnt active
unsigned RX_Done:1; ///< flag: 1 - receiving is done, 0 - receiving isnt done
unsigned TX_Done:1; ///< flag: 1 - transmiting is done, 0 - transmiting isnt done
// setted by user
unsigned RX_Continue:1; ///< flag: 0 - continue receiving, 0 - start receiving from ind = 0
unsigned MessageHandled:1; ///< flag: 1 - RS command is handled, 0 - RS command isnt handled yet
unsigned EchoResponse:1; ///< flag: 1 - response with received msg, 0 - response with own msg
unsigned DeferredResponse:1; ///< flag: 1 - response not in interrupt, 0 - response in interrupt
unsigned DataUpdated:1; ///< flag: 1 - Received command to write colis/resg
unsigned ReInit_UART:1; ///< flag: 1 - need to reinitialize uart, 0 - nothing
}RS_FlagsTypeDef;
/**
* @brief Handle for RS communication.
* @note Prefixes: h - handle, s - settings, f - flag
*/
typedef struct // RS_HandleTypeDef
{
/* MESSAGE */
uint8_t ID; ///< ID of RS "channel"
RS_MsgTypeDef *pMessagePtr; ///< pointer to message struct
uint8_t *pBufferPtr; ///< pointer to message buffer
int32_t RS_Message_Size; ///< size of whole message, not only data
/* HANDLERS and SETTINGS */
UART_HandleTypeDef *huart; ///< handler for used uart
TIM_HandleTypeDef *htim; ///< handler for used tim
RS_ModeTypeDef sRS_Mode; ///< setting: slave or master @ref RS_ModeTypeDef
RS_ITModeTypeDef sRS_IT_Mode; ///< setting: 1 - IT mode, 0 - Blocking mode
uint16_t sRS_Timeout; ///< setting: timeout in ms
RS_RXSizeTypeDef sRS_RX_Size_Mode; ///< setting: 1 - not const, 0 - const
/* FLAGS */
RS_FlagsTypeDef f; ///< These flags for controling receive/transmit
/* RS STATUS */
uint32_t lastPacketTick;
RS_StatusTypeDef RS_STATUS; ///< RS status
TrackerTypeDef(RS_USER_VARS_NUMB) rs_err;
}RS_HandleTypeDef;
extern RS_HandleTypeDef hmodbus1;
///////////////////////---STRUCTURES & ENUMS---//////////////////////
/////////////////////////////////////////////////////////////////////
///////////////////////////---FUNCTIONS---///////////////////////////
//----------------FUNCTIONS FOR PROCESSING MESSAGE-------------------
/*--------------------Defined by users purposes--------------------*/
/* Respond accord to received message */
RS_StatusTypeDef RS_Response(RS_HandleTypeDef *hRS, RS_MsgTypeDef *RS_msg);
/* Collect message in buffer to transmit it */
RS_StatusTypeDef RS_Collect_Message(RS_HandleTypeDef *hRS, RS_MsgTypeDef *RS_msg, uint8_t *msg_uart_buff);
/* Parse message from buffer to process it */
RS_StatusTypeDef RS_Parse_Message(RS_HandleTypeDef *hRS, RS_MsgTypeDef *RS_msg, uint8_t *msg_uart_buff);
//-------------------------GENERAL FUNCTIONS-------------------------
/*-----------------Should be called from main code-----------------*/
/* Start receive IT */
RS_StatusTypeDef RS_Receive_IT(RS_HandleTypeDef *hRS, RS_MsgTypeDef *RS_msg);
/* Start transmit IT */
RS_StatusTypeDef RS_Transmit_IT(RS_HandleTypeDef *hRS, RS_MsgTypeDef *RS_msg);
/* Initialize UART and handle RS stucture */
RS_StatusTypeDef RS_Init(RS_HandleTypeDef *hRS, UART_HandleTypeDef *huart, TIM_HandleTypeDef *htim, uint8_t *pRS_BufferPtr);
/* ReInitialize UART and RS receive */
HAL_StatusTypeDef RS_ReInit_UART(RS_HandleTypeDef *hRS, UART_HandleTypeDef *suart);
/* Abort RS/UART */
RS_StatusTypeDef RS_Abort(RS_HandleTypeDef *hRS, RS_AbortTypeDef AbortMode);
//-------------------------GENERAL FUNCTIONS-------------------------
//-------------------------------------------------------------------
//--------------------CALLBACK/HANDLER FUNCTIONS---------------------
/* Handle for starting receive */
RS_StatusTypeDef RS_Handle_Receive_Start(RS_HandleTypeDef *hRS, RS_MsgTypeDef *RS_msg);
/* Handle for starting transmit */
RS_StatusTypeDef RS_Handle_Transmit_Start(RS_HandleTypeDef *hRS, RS_MsgTypeDef *RS_msg);
/* UART TX Callback: define behaviour after transmiting message */
RS_StatusTypeDef RS_UART_TxCpltCallback(RS_HandleTypeDef *hRS);
/* Handler for UART */
void RS_UART_Handler(RS_HandleTypeDef *hRS);
/* Handler for TIM */
void RS_TIM_Handler(RS_HandleTypeDef *hRS);
//--------------------CALLBACK/HANDLER FUNCTIONS---------------------
///////////////////////////---FUNCTIONS---///////////////////////////
/** RS_TOOLS
* @}
*/
#endif // __RS_LIB_H_