Arduino_Modbus/rs_message.h

224 lines
9.7 KiB
C

/**
**************************************************************************
* @file rs_message.h
* @brief Заголовочный файл для модуля реализации протоколов по RS/UART.
**************************************************************************
* @defgroup RS_TOOLS
* @brief Всякое для работы по UART/RS
**************************************************************************
@details
**************************************************************************
Для настройки RS/UART под нужный протокол, необходимо:
- Определить структуру сообщения RS_MsgTypeDef и
дефайны RX_FIRST_PART_SIZE и MSG_SIZE_MAX.
- Подключить этот файл в раздел rs_message.h.
- Определить функции для обработки сообщения: RS_Parse_Message(),
RS_Collect_Message(), RS_Response(), RS_Define_Size_of_RX_Message()
**************************************************************************
@verbatim
Визуальное описание. Форматирование сохраняется как в коде.
@endverbatim
*************************************************************************/
#ifndef __RS_LIB_H_
#define __RS_LIB_H_
#include "modbus/modbus.h"
/////////////////////////////////////////////////////////////////////
////////////////////////////---DEFINES---////////////////////////////
#ifndef MSG_SIZE_MAX
#error "Define MSG_SIZE_MAX (Maximum size of message)"
#endif
#ifndef RX_FIRST_PART_SIZE
#error "Define RX_FIRST_PART_SIZE (Size of first part of message)"
#endif
#define RS_Clear_Buff(_buff_) for(int i=0;i<MSG_SIZE_MAX;i++) _buff_[i]=0
#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_)
#define RS_Clear_All(_hRS_) RS_Clear_Buff(_hRS_->pBufferPtr); RS_Reset_RX_Flags(_hRS_); RS_Reset_TX_Flags(_hRS_)
#define RS_Is_RX_Busy(_hRS_) (_hRS_->f.RX_Busy==1)
#define RS_Is_TX_Busy(_hRS_) (_hRS_->f.TX_Busy==1)
#ifndef RS_EnableReceive
#define RS_EnableReceive()
#endif
#ifndef RS_EnableTransmit
#define RS_EnableTransmit()
#endif
////////////////////////////---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;
/** @brief Enums for RS Modes */
typedef enum // RS_ModeTypeDef
{
SLAVE_ALWAYS_WAIT = 0x01, ///< Slave mode with infinity waiting
SLAVE_TIMEOUT_WAIT = 0x02, ///< Slave mode with waiting with timeout
// MASTER = 0x03, ///< Master mode
}RS_ModeTypeDef;
/** @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_RX_SizeTypeDef;
//-----------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 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 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
#ifdef RS_IN_RTOS
uint16_t taskDelay; ///< freertos buffer
#endif
uint32_t RS_Message_Size; ///< size of whole message, not only data
/* HANDLERS and SETTINGS */
uint8_t tx_pin; ///< Transmit pin
uint8_t rx_pin; ///< Receive pin
HUART_TypeDef *huart; ///< handler for used uart
RS_ModeTypeDef sRS_Mode; ///< setting: slave or master @ref RS_ModeTypeDef
uint16_t sRS_Timeout; ///< setting: timeout in ms
RS_RX_SizeTypeDef sRS_RX_Size_Mode; ///< setting: 1 - not const, 0 - const
/* FLAGS */
RS_FlagsTypeDef f; ///< These flags for controling receive/transmit
/* RS STATUS */
unsigned long lastByteTime;
unsigned long baudRate;
RS_StatusTypeDef RS_STATUS; ///< RS status
}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);
/* Define size of RX Message that need to be received */
RS_StatusTypeDef RS_Define_Size_of_RX_Message(RS_HandleTypeDef *hRS, uint32_t *rx_data_size);
//-------------------------GENERAL FUNCTIONS-------------------------
/*-----------------Should be called from main code-----------------*/
/* Задача обработки UART приёма (FreeRTOS) */
void RS_Task(void *pvParameters);
/* Основная функция обработки RS */
void RS_Process(RS_HandleTypeDef *hRS);
/* Initialize UART and handle RS stucture */
RS_StatusTypeDef RS_Init(RS_HandleTypeDef *hRS, HUART_TypeDef *SerialPort, uint32_t baudRate, uint8_t *pRS_BufferPtr);
/* Abort RS/UART */
RS_StatusTypeDef RS_Abort(RS_HandleTypeDef *hRS, RS_AbortTypeDef AbortMode);
/* Handle for starting transmit */
RS_StatusTypeDef RS_Handle_Transmit_Start(RS_HandleTypeDef *hRS, RS_MsgTypeDef *RS_msg);
///////////////////////////---FUNCTIONS---///////////////////////////
#if RS_DEBUG
#define RS_DEBUG_PRINT(msg) Serial.println(msg)
#define RS_DEBUG_PRINT_HEX(val) Serial.println(val, HEX)
#define RS_DEBUG_PRINT_DEC(val) Serial.println(val, DEC)
#define RS_DEBUG_PRINT2_HEX(msg,val) do { Serial.print(msg); Serial.println(val, HEX); } while(0)
#define RS_DEBUG_PRINT2_DEC(msg,val) do { Serial.print(msg); Serial.println(val, DEC); } while(0)
#else
#define RS_DEBUG_PRINT(msg) ((void)0)
#define RS_DEBUG_PRINT_HEX(val) ((void)0)
#define RS_DEBUG_PRINT_DEC(val) ((void)0)
#define RS_DEBUG_PRINT2_HEX(msg,val) ((void)0)
#define RS_DEBUG_PRINT2_DEC(msg,val) ((void)0)
#endif
#endif // __RS_LIB_H_