forked from espressif/esp-modbus
freemodbus: fix long buffer failure
check master read write functions with array of registers) fix master serial processing code and modbus controller to work with register array modbus_master: add reading and writing of test value array (58 registers) to check failure is gone remove parameter temporary buffer from modbus controller to allow more than 24 byte writes driver: fix issue with TOUT feature driver: fix uart_rx_timeout issue driver: fix issue with rxfifo_tout_int_raw not triggered when received fifo_len = 120 byte and all bytes read out of fifo as result of rxfifo_full_int_raw driver: add function uart_internal_set_always_rx_timeout() to always handle tout interrupt examples: call uart_internal_set_always_rx_timeout() to handle tout interrupt correctly examples: update examples to use tout feature driver: reflect changes of uart_set_always_rx_timeout() function, change uart.c driver: change conditions to trigger workaround for tout feature in uart.c driver: change uart_set_always_rx_timeout() freemodbus: fix tabs, remove commented code driver: remove uart_ll_is_rx_idle() * Original commit: espressif/esp-idf@3abdd2207d
This commit is contained in:
@@ -382,8 +382,6 @@ xMBASCIITransmitFSM( void )
|
|||||||
eSndState = STATE_TX_IDLE;
|
eSndState = STATE_TX_IDLE;
|
||||||
xMBPortEventPost( EV_FRAME_TRANSMIT );
|
xMBPortEventPost( EV_FRAME_TRANSMIT );
|
||||||
xNeedPoll = FALSE;
|
xNeedPoll = FALSE;
|
||||||
|
|
||||||
eSndState = STATE_TX_IDLE;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* We should not get a transmitter event if the transmitter is in
|
/* We should not get a transmitter event if the transmitter is in
|
||||||
|
@@ -31,6 +31,8 @@
|
|||||||
#ifndef _MB_FRAME_H
|
#ifndef _MB_FRAME_H
|
||||||
#define _MB_FRAME_H
|
#define _MB_FRAME_H
|
||||||
|
|
||||||
|
#include "port.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
PR_BEGIN_EXTERN_C
|
PR_BEGIN_EXTERN_C
|
||||||
#endif
|
#endif
|
||||||
@@ -61,12 +63,12 @@ PR_BEGIN_EXTERN_C
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/* ----------------------- Defines ------------------------------------------*/
|
/* ----------------------- Defines ------------------------------------------*/
|
||||||
#define MB_PDU_SIZE_MAX 253 /*!< Maximum size of a PDU. */
|
#define MB_PDU_SIZE_MAX ( 253 ) /*!< Maximum size of a PDU. */
|
||||||
#define MB_PDU_SIZE_MIN 1 /*!< Function Code */
|
#define MB_PDU_SIZE_MIN 1 /*!< Function Code */
|
||||||
#define MB_PDU_FUNC_OFF 0 /*!< Offset of function code in PDU. */
|
#define MB_PDU_FUNC_OFF 0 /*!< Offset of function code in PDU. */
|
||||||
#define MB_PDU_DATA_OFF 1 /*!< Offset for response data in PDU. */
|
#define MB_PDU_DATA_OFF 1 /*!< Offset for response data in PDU. */
|
||||||
|
|
||||||
#define MB_SER_PDU_SIZE_MAX 256 /*!< Maximum size of a Modbus frame. */
|
#define MB_SER_PDU_SIZE_MAX ( MB_SERIAL_BUF_SIZE ) /*!< Maximum size of a Modbus frame. */
|
||||||
#define MB_SER_PDU_SIZE_LRC 1 /*!< Size of LRC field in PDU. */
|
#define MB_SER_PDU_SIZE_LRC 1 /*!< Size of LRC field in PDU. */
|
||||||
#define MB_SER_PDU_ADDR_OFF 0 /*!< Offset of slave address in Ser-PDU. */
|
#define MB_SER_PDU_ADDR_OFF 0 /*!< Offset of slave address in Ser-PDU. */
|
||||||
#define MB_SER_PDU_PDU_OFF 1 /*!< Offset of Modbus-PDU in Ser-PDU. */
|
#define MB_SER_PDU_PDU_OFF 1 /*!< Offset of Modbus-PDU in Ser-PDU. */
|
||||||
|
@@ -81,6 +81,7 @@ typedef enum {
|
|||||||
EV_ERROR_RESPOND_TIMEOUT, /*!< Slave respond timeout. */
|
EV_ERROR_RESPOND_TIMEOUT, /*!< Slave respond timeout. */
|
||||||
EV_ERROR_RECEIVE_DATA, /*!< Receive frame data erroe. */
|
EV_ERROR_RECEIVE_DATA, /*!< Receive frame data erroe. */
|
||||||
EV_ERROR_EXECUTE_FUNCTION, /*!< Execute function error. */
|
EV_ERROR_EXECUTE_FUNCTION, /*!< Execute function error. */
|
||||||
|
EV_ERROR_OK, /*!< Data processed. */
|
||||||
} eMBMasterErrorEventType;
|
} eMBMasterErrorEventType;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@@ -62,7 +62,7 @@
|
|||||||
static UCHAR ucMBAddress;
|
static UCHAR ucMBAddress;
|
||||||
static eMBMode eMBCurrentMode;
|
static eMBMode eMBCurrentMode;
|
||||||
|
|
||||||
volatile UCHAR ucMbSlaveBuf[MB_SER_PDU_SIZE_MAX];
|
volatile UCHAR ucMbSlaveBuf[MB_SERIAL_BUF_SIZE];
|
||||||
|
|
||||||
static enum
|
static enum
|
||||||
{
|
{
|
||||||
|
@@ -69,8 +69,8 @@ static volatile USHORT usMasterSendPDULength;
|
|||||||
|
|
||||||
/*------------------------ Shared variables ---------------------------------*/
|
/*------------------------ Shared variables ---------------------------------*/
|
||||||
|
|
||||||
volatile UCHAR ucMasterSndBuf[MB_PDU_SIZE_MAX];
|
volatile UCHAR ucMasterSndBuf[MB_SERIAL_BUF_SIZE];
|
||||||
volatile UCHAR ucMasterRcvBuf[MB_SER_PDU_SIZE_MAX];
|
volatile UCHAR ucMasterRcvBuf[MB_SERIAL_BUF_SIZE];
|
||||||
volatile eMBMasterTimerMode eMasterCurTimerMode;
|
volatile eMBMasterTimerMode eMasterCurTimerMode;
|
||||||
volatile BOOL xFrameIsBroadcast = FALSE;
|
volatile BOOL xFrameIsBroadcast = FALSE;
|
||||||
|
|
||||||
@@ -359,8 +359,8 @@ eMBMasterPoll( void )
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
vMBMasterCBRequestSuccess( );
|
vMBMasterSetErrorType(EV_ERROR_OK);
|
||||||
vMBMasterRunResRelease( );
|
( void ) xMBMasterPortEventPost( EV_MASTER_ERROR_PROCESS );
|
||||||
}
|
}
|
||||||
MB_PORT_CLEAR_EVENT( eEvent, EV_MASTER_EXECUTE );
|
MB_PORT_CLEAR_EVENT( eEvent, EV_MASTER_EXECUTE );
|
||||||
} else if ( MB_PORT_CHECK_EVENT( eEvent, EV_MASTER_FRAME_TRANSMIT ) ) {
|
} else if ( MB_PORT_CHECK_EVENT( eEvent, EV_MASTER_FRAME_TRANSMIT ) ) {
|
||||||
@@ -395,6 +395,9 @@ eMBMasterPoll( void )
|
|||||||
vMBMasterErrorCBExecuteFunction( ucMBMasterGetDestAddress( ),
|
vMBMasterErrorCBExecuteFunction( ucMBMasterGetDestAddress( ),
|
||||||
ucMBFrame, usMBMasterGetPDUSndLength( ) );
|
ucMBFrame, usMBMasterGetPDUSndLength( ) );
|
||||||
break;
|
break;
|
||||||
|
case EV_ERROR_OK:
|
||||||
|
vMBMasterCBRequestSuccess( );
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
ESP_LOGE( MB_PORT_TAG, "%s: incorrect error type = %d.", __func__, errorType);
|
ESP_LOGE( MB_PORT_TAG, "%s: incorrect error type = %d.", __func__, errorType);
|
||||||
break;
|
break;
|
||||||
|
@@ -265,8 +265,10 @@ xMBRTUReceiveFSM( void )
|
|||||||
case STATE_RX_RCV:
|
case STATE_RX_RCV:
|
||||||
if( usRcvBufferPos < MB_SER_PDU_SIZE_MAX )
|
if( usRcvBufferPos < MB_SER_PDU_SIZE_MAX )
|
||||||
{
|
{
|
||||||
|
if ( xStatus ) {
|
||||||
ucRTUBuf[usRcvBufferPos++] = ucByte;
|
ucRTUBuf[usRcvBufferPos++] = ucByte;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
eRcvState = STATE_RX_ERROR;
|
eRcvState = STATE_RX_ERROR;
|
||||||
|
@@ -281,8 +281,10 @@ xMBMasterRTUReceiveFSM( void )
|
|||||||
case STATE_M_RX_RCV:
|
case STATE_M_RX_RCV:
|
||||||
if( usMasterRcvBufferPos < MB_SER_PDU_SIZE_MAX )
|
if( usMasterRcvBufferPos < MB_SER_PDU_SIZE_MAX )
|
||||||
{
|
{
|
||||||
|
if ( xStatus ) {
|
||||||
ucMasterRTURcvBuf[usMasterRcvBufferPos++] = ucByte;
|
ucMasterRTURcvBuf[usMasterRcvBufferPos++] = ucByte;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
eRcvState = STATE_M_RX_ERROR;
|
eRcvState = STATE_M_RX_ERROR;
|
||||||
|
@@ -19,6 +19,7 @@
|
|||||||
#include "freertos/FreeRTOS.h"
|
#include "freertos/FreeRTOS.h"
|
||||||
#include "freertos/xtensa_api.h"
|
#include "freertos/xtensa_api.h"
|
||||||
#include "esp_log.h" // for ESP_LOGE macro
|
#include "esp_log.h" // for ESP_LOGE macro
|
||||||
|
#include "sdkconfig.h"
|
||||||
|
|
||||||
#define INLINE inline
|
#define INLINE inline
|
||||||
#define PR_BEGIN_EXTERN_C extern "C" {
|
#define PR_BEGIN_EXTERN_C extern "C" {
|
||||||
@@ -26,10 +27,22 @@
|
|||||||
|
|
||||||
#define MB_PORT_TAG "MB_PORT_COMMON"
|
#define MB_PORT_TAG "MB_PORT_COMMON"
|
||||||
|
|
||||||
|
#define MB_BAUD_RATE_DEFAULT (115200)
|
||||||
|
#define MB_QUEUE_LENGTH (CONFIG_FMB_QUEUE_LENGTH)
|
||||||
|
|
||||||
|
#define MB_SERIAL_TASK_PRIO (CONFIG_FMB_SERIAL_TASK_PRIO)
|
||||||
|
#define MB_SERIAL_TASK_STACK_SIZE (CONFIG_FMB_SERIAL_TASK_STACK_SIZE)
|
||||||
|
#define MB_SERIAL_TOUT (3) // 3.5*8 = 28 ticks, TOUT=3 -> ~24..33 ticks
|
||||||
|
|
||||||
|
// Set buffer size for transmission
|
||||||
|
#define MB_SERIAL_BUF_SIZE (CONFIG_FMB_SERIAL_BUF_SIZE)
|
||||||
|
|
||||||
// common definitions for serial port implementations
|
// common definitions for serial port implementations
|
||||||
#define MB_SERIAL_TX_TOUT_MS (100)
|
#define MB_SERIAL_TX_TOUT_MS (100)
|
||||||
#define MB_SERIAL_TX_TOUT_TICKS pdMS_TO_TICKS(MB_SERIAL_TX_TOUT_MS) // timeout for transmission
|
#define MB_SERIAL_TX_TOUT_TICKS pdMS_TO_TICKS(MB_SERIAL_TX_TOUT_MS) // timeout for transmission
|
||||||
#define MB_SERIAL_RX_TOUT_TICKS pdMS_TO_TICKS(1) // timeout for rx from buffer
|
#define MB_SERIAL_RX_TOUT_MS (1)
|
||||||
|
#define MB_SERIAL_RX_TOUT_TICKS pdMS_TO_TICKS(MB_SERIAL_RX_TOUT_MS) // timeout for receive
|
||||||
|
|
||||||
#define MB_SERIAL_RESP_LEN_MIN (4)
|
#define MB_SERIAL_RESP_LEN_MIN (4)
|
||||||
|
|
||||||
#define MB_PORT_CHECK(a, ret_val, str, ...) \
|
#define MB_PORT_CHECK(a, ret_val, str, ...) \
|
||||||
|
@@ -217,7 +217,7 @@ void vMBMasterErrorCBExecuteFunction(UCHAR ucDestAddress, const UCHAR* pucPDUDat
|
|||||||
{
|
{
|
||||||
BOOL ret = xMBMasterPortEventPost(EV_MASTER_ERROR_EXECUTE_FUNCTION);
|
BOOL ret = xMBMasterPortEventPost(EV_MASTER_ERROR_EXECUTE_FUNCTION);
|
||||||
MB_PORT_CHECK((ret == TRUE), ; , "%s: Post event 'EV_MASTER_ERROR_EXECUTE_FUNCTION' failed!", __func__);
|
MB_PORT_CHECK((ret == TRUE), ; , "%s: Post event 'EV_MASTER_ERROR_EXECUTE_FUNCTION' failed!", __func__);
|
||||||
ESP_LOGD(MB_PORT_TAG,"%s:Callback execute data timeout failure.", __func__);
|
ESP_LOGD(MB_PORT_TAG,"%s:Callback execute data handler failure.", __func__);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -252,7 +252,7 @@ eMBMasterReqErrCode eMBMasterWaitRequestFinish( void ) {
|
|||||||
MB_EVENT_REQ_MASK, // The bits within the event group to wait for.
|
MB_EVENT_REQ_MASK, // The bits within the event group to wait for.
|
||||||
pdTRUE, // Masked bits should be cleared before returning.
|
pdTRUE, // Masked bits should be cleared before returning.
|
||||||
pdFALSE, // Don't wait for both bits, either bit will do.
|
pdFALSE, // Don't wait for both bits, either bit will do.
|
||||||
portMAX_DELAY ); // Wait forever for either bit to be set.
|
1000 ); // Wait forever for either bit to be set. //portMAX_DELAY
|
||||||
xRecvedEvent = (eMBMasterEventType)(uxBits);
|
xRecvedEvent = (eMBMasterEventType)(uxBits);
|
||||||
if (xRecvedEvent) {
|
if (xRecvedEvent) {
|
||||||
ESP_LOGD(MB_PORT_TAG,"%s: returned event = 0x%x", __func__, xRecvedEvent);
|
ESP_LOGD(MB_PORT_TAG,"%s: returned event = 0x%x", __func__, xRecvedEvent);
|
||||||
|
@@ -55,25 +55,6 @@
|
|||||||
#include "sdkconfig.h" // for KConfig options
|
#include "sdkconfig.h" // for KConfig options
|
||||||
#include "port_serial_slave.h"
|
#include "port_serial_slave.h"
|
||||||
|
|
||||||
// Definitions of UART default pin numbers
|
|
||||||
#define MB_UART_RXD (CONFIG_MB_UART_RXD)
|
|
||||||
#define MB_UART_TXD (CONFIG_MB_UART_TXD)
|
|
||||||
#define MB_UART_RTS (CONFIG_MB_UART_RTS)
|
|
||||||
|
|
||||||
#define MB_BAUD_RATE_DEFAULT (115200)
|
|
||||||
#define MB_QUEUE_LENGTH (CONFIG_FMB_QUEUE_LENGTH)
|
|
||||||
|
|
||||||
#define MB_SERIAL_TASK_PRIO (CONFIG_FMB_SERIAL_TASK_PRIO)
|
|
||||||
#define MB_SERIAL_TASK_STACK_SIZE (CONFIG_FMB_SERIAL_TASK_STACK_SIZE)
|
|
||||||
#define MB_SERIAL_TOUT (3) // 3.5*8 = 28 ticks, TOUT=3 -> ~24..33 ticks
|
|
||||||
|
|
||||||
#define MB_SERIAL_TX_TOUT_MS (100)
|
|
||||||
#define MB_SERIAL_TX_TOUT_TICKS pdMS_TO_TICKS(MB_SERIAL_TX_TOUT_MS) // timeout for transmission
|
|
||||||
// Set buffer size for transmission
|
|
||||||
#define MB_SERIAL_BUF_SIZE (CONFIG_FMB_SERIAL_BUF_SIZE)
|
|
||||||
|
|
||||||
// Note: This code uses mixed coding standard from legacy IDF code and used freemodbus stack
|
|
||||||
|
|
||||||
// A queue to handle UART event.
|
// A queue to handle UART event.
|
||||||
static QueueHandle_t xMbUartQueue;
|
static QueueHandle_t xMbUartQueue;
|
||||||
static TaskHandle_t xMbTaskHandle;
|
static TaskHandle_t xMbTaskHandle;
|
||||||
@@ -103,28 +84,26 @@ void vMBPortSerialEnable(BOOL bRxEnable, BOOL bTxEnable)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void vMBPortSerialRxPoll(size_t xEventSize)
|
static USHORT usMBPortSerialRxPoll(size_t xEventSize)
|
||||||
{
|
{
|
||||||
BOOL xReadStatus = TRUE;
|
BOOL xReadStatus = TRUE;
|
||||||
USHORT usCnt = 0;
|
USHORT usCnt = 0;
|
||||||
|
|
||||||
if (bRxStateEnabled) {
|
if (bRxStateEnabled) {
|
||||||
if (xEventSize > MB_SERIAL_RESP_LEN_MIN) {
|
|
||||||
xEventSize = (xEventSize > MB_SERIAL_BUF_SIZE) ? MB_SERIAL_BUF_SIZE : xEventSize;
|
|
||||||
// Get received packet into Rx buffer
|
// Get received packet into Rx buffer
|
||||||
for(usCnt = 0; xReadStatus && (usCnt < xEventSize); usCnt++ ) {
|
while(xReadStatus && (usCnt++ <= MB_SERIAL_BUF_SIZE)) {
|
||||||
// Call the Modbus stack callback function and let it fill the buffers.
|
// Call the Modbus stack callback function and let it fill the buffers.
|
||||||
xReadStatus = pxMBFrameCBByteReceived(); // callback to execute receive FSM state machine
|
xReadStatus = pxMBFrameCBByteReceived(); // callback to execute receive FSM
|
||||||
}
|
}
|
||||||
uart_flush_input(ucUartNumber);
|
uart_flush_input(ucUartNumber);
|
||||||
// Send event EV_FRAME_RECEIVED to allow stack process packet
|
// Send event EV_FRAME_RECEIVED to allow stack process packet
|
||||||
#ifndef MB_TIMER_PORT_ENABLED
|
#if !CONFIG_FMB_TIMER_PORT_ENABLED
|
||||||
// Let the stack know that T3.5 time is expired and data is received
|
// Let the stack know that T3.5 time is expired and data is received
|
||||||
(void)pxMBPortCBTimerExpired(); // calls callback xMBRTUTimerT35Expired();
|
(void)pxMBPortCBTimerExpired(); // calls callback xMBRTUTimerT35Expired();
|
||||||
#endif
|
#endif
|
||||||
ESP_LOGD(TAG, "RX: %d bytes\n", usCnt);
|
ESP_LOGD(TAG, "RX: %d bytes\n", usCnt);
|
||||||
}
|
}
|
||||||
}
|
return usCnt;
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL xMBPortSerialTxPoll(void)
|
BOOL xMBPortSerialTxPoll(void)
|
||||||
@@ -136,7 +115,7 @@ BOOL xMBPortSerialTxPoll(void)
|
|||||||
// Continue while all response bytes put in buffer or out of buffer
|
// Continue while all response bytes put in buffer or out of buffer
|
||||||
while((bNeedPoll) && (usCount++ < MB_SERIAL_BUF_SIZE)) {
|
while((bNeedPoll) && (usCount++ < MB_SERIAL_BUF_SIZE)) {
|
||||||
// Calls the modbus stack callback function to let it fill the UART transmit buffer.
|
// Calls the modbus stack callback function to let it fill the UART transmit buffer.
|
||||||
bNeedPoll = pxMBFrameCBTransmitterEmpty( ); // callback to transmit FSM state machine
|
bNeedPoll = pxMBFrameCBTransmitterEmpty( ); // callback to transmit FSM
|
||||||
}
|
}
|
||||||
ESP_LOGD(TAG, "MB_TX_buffer send: (%d) bytes\n", (uint16_t)usCount);
|
ESP_LOGD(TAG, "MB_TX_buffer send: (%d) bytes\n", (uint16_t)usCount);
|
||||||
// Waits while UART sending the packet
|
// Waits while UART sending the packet
|
||||||
@@ -151,15 +130,21 @@ BOOL xMBPortSerialTxPoll(void)
|
|||||||
static void vUartTask(void *pvParameters)
|
static void vUartTask(void *pvParameters)
|
||||||
{
|
{
|
||||||
uart_event_t xEvent;
|
uart_event_t xEvent;
|
||||||
|
USHORT usResult = 0;
|
||||||
for(;;) {
|
for(;;) {
|
||||||
if (xQueueReceive(xMbUartQueue, (void*)&xEvent, portMAX_DELAY) == pdTRUE) {
|
if (xQueueReceive(xMbUartQueue, (void*)&xEvent, portMAX_DELAY) == pdTRUE) {
|
||||||
ESP_LOGD(TAG, "MB_uart[%d] event:", ucUartNumber);
|
ESP_LOGD(TAG, "MB_uart[%d] event:", ucUartNumber);
|
||||||
switch(xEvent.type) {
|
switch(xEvent.type) {
|
||||||
//Event of UART receving data
|
//Event of UART receving data
|
||||||
case UART_DATA:
|
case UART_DATA:
|
||||||
ESP_LOGD(TAG,"Receive data, len: %d", xEvent.size);
|
ESP_LOGD(TAG,"Data event, length: %d", xEvent.size);
|
||||||
|
// This flag set in the event means that no more
|
||||||
|
// data received during configured timeout and UART TOUT feature is triggered
|
||||||
|
if (xEvent.timeout_flag) {
|
||||||
// Read received data and send it to modbus stack
|
// Read received data and send it to modbus stack
|
||||||
vMBPortSerialRxPoll(xEvent.size);
|
usResult = usMBPortSerialRxPoll(xEvent.size);
|
||||||
|
ESP_LOGD(TAG,"Timeout occured, processed: %d bytes", usResult);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
//Event of HW FIFO overflow detected
|
//Event of HW FIFO overflow detected
|
||||||
case UART_FIFO_OVF:
|
case UART_FIFO_OVF:
|
||||||
@@ -249,12 +234,16 @@ BOOL xMBPortSerialInit(UCHAR ucPORT, ULONG ulBaudRate,
|
|||||||
MB_QUEUE_LENGTH, &xMbUartQueue, MB_PORT_SERIAL_ISR_FLAG);
|
MB_QUEUE_LENGTH, &xMbUartQueue, MB_PORT_SERIAL_ISR_FLAG);
|
||||||
MB_PORT_CHECK((xErr == ESP_OK), FALSE,
|
MB_PORT_CHECK((xErr == ESP_OK), FALSE,
|
||||||
"mb serial driver failure, uart_driver_install() returned (0x%x).", xErr);
|
"mb serial driver failure, uart_driver_install() returned (0x%x).", xErr);
|
||||||
#ifndef MB_TIMER_PORT_ENABLED
|
#if !CONFIG_FMB_TIMER_PORT_ENABLED
|
||||||
// Set timeout for TOUT interrupt (T3.5 modbus time)
|
// Set timeout for TOUT interrupt (T3.5 modbus time)
|
||||||
xErr = uart_set_rx_timeout(ucUartNumber, MB_SERIAL_TOUT);
|
xErr = uart_set_rx_timeout(ucUartNumber, MB_SERIAL_TOUT);
|
||||||
MB_PORT_CHECK((xErr == ESP_OK), FALSE,
|
MB_PORT_CHECK((xErr == ESP_OK), FALSE,
|
||||||
"mb serial set rx timeout failure, uart_set_rx_timeout() returned (0x%x).", xErr);
|
"mb serial set rx timeout failure, uart_set_rx_timeout() returned (0x%x).", xErr);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// Set always timeout flag to trigger timeout interrupt even after rx fifo full
|
||||||
|
uart_set_always_rx_timeout(ucUartNumber, true);
|
||||||
|
|
||||||
// Create a task to handle UART events
|
// Create a task to handle UART events
|
||||||
BaseType_t xStatus = xTaskCreate(vUartTask, "uart_queue_task", MB_SERIAL_TASK_STACK_SIZE,
|
BaseType_t xStatus = xTaskCreate(vUartTask, "uart_queue_task", MB_SERIAL_TASK_STACK_SIZE,
|
||||||
NULL, MB_SERIAL_TASK_PRIO, &xMbTaskHandle);
|
NULL, MB_SERIAL_TASK_PRIO, &xMbTaskHandle);
|
||||||
|
@@ -51,18 +51,6 @@
|
|||||||
#include "sdkconfig.h"
|
#include "sdkconfig.h"
|
||||||
#include "port_serial_master.h"
|
#include "port_serial_master.h"
|
||||||
|
|
||||||
/* ----------------------- Defines ------------------------------------------*/
|
|
||||||
|
|
||||||
#define MB_BAUD_RATE_DEFAULT (115200)
|
|
||||||
#define MB_QUEUE_LENGTH (CONFIG_FMB_QUEUE_LENGTH)
|
|
||||||
|
|
||||||
#define MB_SERIAL_TASK_PRIO (CONFIG_FMB_SERIAL_TASK_PRIO)
|
|
||||||
#define MB_SERIAL_TASK_STACK_SIZE (CONFIG_FMB_SERIAL_TASK_STACK_SIZE)
|
|
||||||
#define MB_SERIAL_TOUT (3) // 3.5*8 = 28 ticks, TOUT=3 -> ~24..33 ticks
|
|
||||||
|
|
||||||
// Set buffer size for transmission
|
|
||||||
#define MB_SERIAL_BUF_SIZE (CONFIG_FMB_SERIAL_BUF_SIZE)
|
|
||||||
|
|
||||||
/* ----------------------- Static variables ---------------------------------*/
|
/* ----------------------- Static variables ---------------------------------*/
|
||||||
static const CHAR *TAG = "MB_MASTER_SERIAL";
|
static const CHAR *TAG = "MB_MASTER_SERIAL";
|
||||||
|
|
||||||
@@ -76,9 +64,6 @@ static UCHAR ucUartNumber = UART_NUM_MAX - 1;
|
|||||||
static BOOL bRxStateEnabled = FALSE; // Receiver enabled flag
|
static BOOL bRxStateEnabled = FALSE; // Receiver enabled flag
|
||||||
static BOOL bTxStateEnabled = FALSE; // Transmitter enabled flag
|
static BOOL bTxStateEnabled = FALSE; // Transmitter enabled flag
|
||||||
|
|
||||||
static UCHAR ucBuffer[MB_SERIAL_BUF_SIZE]; // Temporary buffer to transfer received data to modbus stack
|
|
||||||
static USHORT uiRxBufferPos = 0; // position in the receiver buffer
|
|
||||||
|
|
||||||
void vMBMasterPortSerialEnable(BOOL bRxEnable, BOOL bTxEnable)
|
void vMBMasterPortSerialEnable(BOOL bRxEnable, BOOL bTxEnable)
|
||||||
{
|
{
|
||||||
// This function can be called from xMBRTUTransmitFSM() of different task
|
// This function can be called from xMBRTUTransmitFSM() of different task
|
||||||
@@ -96,28 +81,23 @@ void vMBMasterPortSerialEnable(BOOL bRxEnable, BOOL bTxEnable)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void vMBMasterPortSerialRxPoll(size_t xEventSize)
|
static USHORT usMBMasterPortSerialRxPoll(size_t xEventSize)
|
||||||
{
|
{
|
||||||
BOOL xReadStatus = TRUE;
|
BOOL xReadStatus = TRUE;
|
||||||
USHORT usCnt = 0;
|
USHORT usCnt = 0;
|
||||||
|
|
||||||
if (bRxStateEnabled) {
|
if (bRxStateEnabled) {
|
||||||
if (xEventSize > MB_SERIAL_RESP_LEN_MIN) {
|
while(xReadStatus && (usCnt++ <= MB_SERIAL_BUF_SIZE)) {
|
||||||
xEventSize = (xEventSize > MB_SERIAL_BUF_SIZE) ? MB_SERIAL_BUF_SIZE : xEventSize;
|
|
||||||
// Get received packet into Rx buffer
|
|
||||||
USHORT usLength = uart_read_bytes(ucUartNumber, &ucBuffer[0], xEventSize, portMAX_DELAY);
|
|
||||||
uiRxBufferPos = 0;
|
|
||||||
for(usCnt = 0; xReadStatus && (usCnt < usLength); usCnt++ ) {
|
|
||||||
// Call the Modbus stack callback function and let it fill the stack buffers.
|
// Call the Modbus stack callback function and let it fill the stack buffers.
|
||||||
xReadStatus = pxMBMasterFrameCBByteReceived(); // callback to receive FSM state machine
|
xReadStatus = pxMBMasterFrameCBByteReceived(); // callback to receive FSM
|
||||||
}
|
}
|
||||||
// The buffer is transferred into Modbus stack and is not needed here any more
|
// The buffer is transferred into Modbus stack and is not needed here any more
|
||||||
uart_flush_input(ucUartNumber);
|
uart_flush_input(ucUartNumber);
|
||||||
ESP_LOGD(TAG, "Received data: %d(bytes in buffer)\n", (uint32_t)usCnt);
|
ESP_LOGD(TAG, "Received data: %d(bytes in buffer)\n", (uint32_t)usCnt);
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
ESP_LOGE(TAG, "%s: bRxState disabled but junk data (%d bytes) received. ", __func__, xEventSize);
|
ESP_LOGE(TAG, "%s: bRxState disabled but junk data (%d bytes) received. ", __func__, xEventSize);
|
||||||
}
|
}
|
||||||
|
return usCnt;
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL xMBMasterPortSerialTxPoll(void)
|
BOOL xMBMasterPortSerialTxPoll(void)
|
||||||
@@ -127,9 +107,9 @@ BOOL xMBMasterPortSerialTxPoll(void)
|
|||||||
|
|
||||||
if( bTxStateEnabled ) {
|
if( bTxStateEnabled ) {
|
||||||
// Continue while all response bytes put in buffer or out of buffer
|
// Continue while all response bytes put in buffer or out of buffer
|
||||||
while((bNeedPoll) && (usCount++ < MB_SERIAL_BUF_SIZE)) {
|
while(bNeedPoll && (usCount++ < MB_SERIAL_BUF_SIZE)) {
|
||||||
// Calls the modbus stack callback function to let it fill the UART transmit buffer.
|
// Calls the modbus stack callback function to let it fill the UART transmit buffer.
|
||||||
bNeedPoll = pxMBMasterFrameCBTransmitterEmpty( ); // callback to transmit FSM state machine
|
bNeedPoll = pxMBMasterFrameCBTransmitterEmpty( ); // callback to transmit FSM
|
||||||
}
|
}
|
||||||
ESP_LOGD(TAG, "MB_TX_buffer sent: (%d) bytes.", (uint16_t)(usCount - 1));
|
ESP_LOGD(TAG, "MB_TX_buffer sent: (%d) bytes.", (uint16_t)(usCount - 1));
|
||||||
// Waits while UART sending the packet
|
// Waits while UART sending the packet
|
||||||
@@ -145,15 +125,21 @@ BOOL xMBMasterPortSerialTxPoll(void)
|
|||||||
static void vUartTask(void* pvParameters)
|
static void vUartTask(void* pvParameters)
|
||||||
{
|
{
|
||||||
uart_event_t xEvent;
|
uart_event_t xEvent;
|
||||||
|
USHORT usResult = 0;
|
||||||
for(;;) {
|
for(;;) {
|
||||||
if (xQueueReceive(xMbUartQueue, (void*)&xEvent, portMAX_DELAY) == pdTRUE) {
|
if (xQueueReceive(xMbUartQueue, (void*)&xEvent, portMAX_DELAY) == pdTRUE) {
|
||||||
ESP_LOGD(TAG, "MB_uart[%d] event:", ucUartNumber);
|
ESP_LOGD(TAG, "MB_uart[%d] event:", ucUartNumber);
|
||||||
switch(xEvent.type) {
|
switch(xEvent.type) {
|
||||||
//Event of UART receiving data
|
//Event of UART receiving data
|
||||||
case UART_DATA:
|
case UART_DATA:
|
||||||
ESP_LOGD(TAG,"Receive data, len: %d.", xEvent.size);
|
ESP_LOGD(TAG,"Data event, len: %d.", xEvent.size);
|
||||||
|
// This flag set in the event means that no more
|
||||||
|
// data received during configured timeout and UART TOUT feature is triggered
|
||||||
|
if (xEvent.timeout_flag) {
|
||||||
// Read received data and send it to modbus stack
|
// Read received data and send it to modbus stack
|
||||||
vMBMasterPortSerialRxPoll(xEvent.size);
|
usResult = usMBMasterPortSerialRxPoll(xEvent.size);
|
||||||
|
ESP_LOGD(TAG,"Timeout occured, processed: %d bytes", usResult);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
//Event of HW FIFO overflow detected
|
//Event of HW FIFO overflow detected
|
||||||
case UART_FIFO_OVF:
|
case UART_FIFO_OVF:
|
||||||
@@ -247,6 +233,10 @@ BOOL xMBMasterPortSerialInit( UCHAR ucPORT, ULONG ulBaudRate, UCHAR ucDataBits,
|
|||||||
xErr = uart_set_rx_timeout(ucUartNumber, MB_SERIAL_TOUT);
|
xErr = uart_set_rx_timeout(ucUartNumber, MB_SERIAL_TOUT);
|
||||||
MB_PORT_CHECK((xErr == ESP_OK), FALSE,
|
MB_PORT_CHECK((xErr == ESP_OK), FALSE,
|
||||||
"mb serial set rx timeout failure, uart_set_rx_timeout() returned (0x%x).", xErr);
|
"mb serial set rx timeout failure, uart_set_rx_timeout() returned (0x%x).", xErr);
|
||||||
|
|
||||||
|
// Set always timeout flag to trigger timeout interrupt even after rx fifo full
|
||||||
|
uart_set_always_rx_timeout(ucUartNumber, true);
|
||||||
|
|
||||||
// Create a task to handle UART events
|
// Create a task to handle UART events
|
||||||
BaseType_t xStatus = xTaskCreate(vUartTask, "uart_queue_task", MB_SERIAL_TASK_STACK_SIZE,
|
BaseType_t xStatus = xTaskCreate(vUartTask, "uart_queue_task", MB_SERIAL_TASK_STACK_SIZE,
|
||||||
NULL, MB_SERIAL_TASK_PRIO, &xMbTaskHandle);
|
NULL, MB_SERIAL_TASK_PRIO, &xMbTaskHandle);
|
||||||
@@ -259,7 +249,6 @@ BOOL xMBMasterPortSerialInit( UCHAR ucPORT, ULONG ulBaudRate, UCHAR ucDataBits,
|
|||||||
} else {
|
} else {
|
||||||
vTaskSuspend(xMbTaskHandle); // Suspend serial task while stack is not started
|
vTaskSuspend(xMbTaskHandle); // Suspend serial task while stack is not started
|
||||||
}
|
}
|
||||||
uiRxBufferPos = 0;
|
|
||||||
ESP_LOGD(MB_PORT_TAG,"%s Init serial.", __func__);
|
ESP_LOGD(MB_PORT_TAG,"%s Init serial.", __func__);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
@@ -282,9 +271,6 @@ BOOL xMBMasterPortSerialPutByte(CHAR ucByte)
|
|||||||
BOOL xMBMasterPortSerialGetByte(CHAR* pucByte)
|
BOOL xMBMasterPortSerialGetByte(CHAR* pucByte)
|
||||||
{
|
{
|
||||||
assert(pucByte != NULL);
|
assert(pucByte != NULL);
|
||||||
MB_PORT_CHECK((uiRxBufferPos < MB_SERIAL_BUF_SIZE),
|
USHORT usLength = uart_read_bytes(ucUartNumber, (uint8_t*)pucByte, 1, MB_SERIAL_RX_TOUT_TICKS);
|
||||||
FALSE, "mb stack serial get byte failure.");
|
return (usLength == 1);
|
||||||
*pucByte = ucBuffer[uiRxBufferPos];
|
|
||||||
uiRxBufferPos++;
|
|
||||||
return TRUE;
|
|
||||||
}
|
}
|
||||||
|
@@ -52,7 +52,7 @@
|
|||||||
#include "port_serial_slave.h"
|
#include "port_serial_slave.h"
|
||||||
#include "sdkconfig.h"
|
#include "sdkconfig.h"
|
||||||
|
|
||||||
#ifdef CONFIG_FMB_TIMER_PORT_ENABLED
|
#if CONFIG_FMB_TIMER_PORT_ENABLED
|
||||||
|
|
||||||
#define MB_US50_FREQ (20000) // 20kHz 1/20000 = 50mks
|
#define MB_US50_FREQ (20000) // 20kHz 1/20000 = 50mks
|
||||||
#define MB_DISCR_TIME_US (50) // 50uS = one discreet for timer
|
#define MB_DISCR_TIME_US (50) // 50uS = one discreet for timer
|
||||||
@@ -92,7 +92,7 @@ static void IRAM_ATTR vTimerGroupIsr(void *param)
|
|||||||
|
|
||||||
BOOL xMBPortTimersInit(USHORT usTim1Timerout50us)
|
BOOL xMBPortTimersInit(USHORT usTim1Timerout50us)
|
||||||
{
|
{
|
||||||
#ifdef CONFIG_FMB_TIMER_PORT_ENABLED
|
#if CONFIG_FMB_TIMER_PORT_ENABLED
|
||||||
MB_PORT_CHECK((usTim1Timerout50us > 0), FALSE,
|
MB_PORT_CHECK((usTim1Timerout50us > 0), FALSE,
|
||||||
"Modbus timeout discreet is incorrect.");
|
"Modbus timeout discreet is incorrect.");
|
||||||
esp_err_t xErr;
|
esp_err_t xErr;
|
||||||
@@ -133,7 +133,7 @@ BOOL xMBPortTimersInit(USHORT usTim1Timerout50us)
|
|||||||
|
|
||||||
void vMBPortTimersEnable(void)
|
void vMBPortTimersEnable(void)
|
||||||
{
|
{
|
||||||
#ifdef CONFIG_FMB_TIMER_PORT_ENABLED
|
#if CONFIG_FMB_TIMER_PORT_ENABLED
|
||||||
ESP_ERROR_CHECK(timer_pause(usTimerGroupIndex, usTimerIndex));
|
ESP_ERROR_CHECK(timer_pause(usTimerGroupIndex, usTimerIndex));
|
||||||
ESP_ERROR_CHECK(timer_set_counter_value(usTimerGroupIndex, usTimerIndex, 0ULL));
|
ESP_ERROR_CHECK(timer_set_counter_value(usTimerGroupIndex, usTimerIndex, 0ULL));
|
||||||
ESP_ERROR_CHECK(timer_enable_intr(usTimerGroupIndex, usTimerIndex));
|
ESP_ERROR_CHECK(timer_enable_intr(usTimerGroupIndex, usTimerIndex));
|
||||||
@@ -144,7 +144,7 @@ void vMBPortTimersEnable(void)
|
|||||||
void MB_PORT_ISR_ATTR
|
void MB_PORT_ISR_ATTR
|
||||||
vMBPortTimersDisable(void)
|
vMBPortTimersDisable(void)
|
||||||
{
|
{
|
||||||
#ifdef CONFIG_FMB_TIMER_PORT_ENABLED
|
#if CONFIG_FMB_TIMER_PORT_ENABLED
|
||||||
if( (BOOL)xPortInIsrContext() ) {
|
if( (BOOL)xPortInIsrContext() ) {
|
||||||
timer_group_set_counter_enable_in_isr(usTimerGroupIndex, usTimerIndex, TIMER_PAUSE);
|
timer_group_set_counter_enable_in_isr(usTimerGroupIndex, usTimerIndex, TIMER_PAUSE);
|
||||||
} else {
|
} else {
|
||||||
|
@@ -36,7 +36,7 @@
|
|||||||
extern BOOL xMBMasterPortSerialTxPoll(void);
|
extern BOOL xMBMasterPortSerialTxPoll(void);
|
||||||
|
|
||||||
/*-----------------------Master mode use these variables----------------------*/
|
/*-----------------------Master mode use these variables----------------------*/
|
||||||
#define MB_RESPONSE_TICS pdMS_TO_TICKS(CONFIG_FMB_MASTER_TIMEOUT_MS_RESPOND)
|
#define MB_RESPONSE_TICS pdMS_TO_TICKS(CONFIG_FMB_MASTER_TIMEOUT_MS_RESPOND + 10)
|
||||||
|
|
||||||
|
|
||||||
static mb_master_interface_t* mbm_interface_ptr = NULL; //&default_interface_inst;
|
static mb_master_interface_t* mbm_interface_ptr = NULL; //&default_interface_inst;
|
||||||
@@ -333,41 +333,6 @@ static uint8_t mbc_serial_master_get_command(mb_param_type_t param_type, mb_para
|
|||||||
return command;
|
return command;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Helper function to set parameter buffer according to its type
|
|
||||||
static esp_err_t mbc_serial_master_set_param_data(void* dest, void* src, mb_descr_type_t param_type, size_t param_size)
|
|
||||||
{
|
|
||||||
esp_err_t err = ESP_OK;
|
|
||||||
MB_MASTER_CHECK((dest != NULL),
|
|
||||||
ESP_ERR_INVALID_ARG, "incorrect parameter pointer.");
|
|
||||||
MB_MASTER_CHECK((src != NULL),
|
|
||||||
ESP_ERR_INVALID_ARG, "incorrect parameter pointer.");
|
|
||||||
// Transfer parameter data into value of characteristic
|
|
||||||
switch(param_type)
|
|
||||||
{
|
|
||||||
case PARAM_TYPE_U8:
|
|
||||||
*((uint8_t*)dest) = *((uint8_t*)src);
|
|
||||||
break;
|
|
||||||
case PARAM_TYPE_U16:
|
|
||||||
*((uint16_t*)dest) = *((uint16_t*)src);
|
|
||||||
break;
|
|
||||||
case PARAM_TYPE_U32:
|
|
||||||
*((uint32_t*)dest) = *((uint32_t*)src);
|
|
||||||
break;
|
|
||||||
case PARAM_TYPE_FLOAT:
|
|
||||||
*((float*)dest) = *(float*)src;
|
|
||||||
break;
|
|
||||||
case PARAM_TYPE_ASCII:
|
|
||||||
memcpy((void*)dest, (void*)src, (size_t)param_size);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
ESP_LOGE(MB_MASTER_TAG, "%s: Incorrect param type (%u).",
|
|
||||||
__FUNCTION__, (uint16_t)param_type);
|
|
||||||
err = ESP_ERR_NOT_SUPPORTED;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Helper to search parameter by name in the parameter description table
|
// Helper to search parameter by name in the parameter description table
|
||||||
// and fills Modbus request fields accordingly
|
// and fills Modbus request fields accordingly
|
||||||
static esp_err_t mbc_serial_master_set_request(char* name, mb_param_mode_t mode,
|
static esp_err_t mbc_serial_master_set_request(char* name, mb_param_mode_t mode,
|
||||||
@@ -418,7 +383,7 @@ static esp_err_t mbc_serial_master_set_request(char* name, mb_param_mode_t mode,
|
|||||||
|
|
||||||
// Get parameter data for corresponding characteristic
|
// Get parameter data for corresponding characteristic
|
||||||
static esp_err_t mbc_serial_master_get_parameter(uint16_t cid, char* name,
|
static esp_err_t mbc_serial_master_get_parameter(uint16_t cid, char* name,
|
||||||
uint8_t* value, uint8_t *type)
|
uint8_t* value_ptr, uint8_t *type)
|
||||||
{
|
{
|
||||||
MB_MASTER_CHECK((name != NULL),
|
MB_MASTER_CHECK((name != NULL),
|
||||||
ESP_ERR_INVALID_ARG, "mb incorrect descriptor.");
|
ESP_ERR_INVALID_ARG, "mb incorrect descriptor.");
|
||||||
@@ -427,19 +392,12 @@ static esp_err_t mbc_serial_master_get_parameter(uint16_t cid, char* name,
|
|||||||
esp_err_t error = ESP_ERR_INVALID_RESPONSE;
|
esp_err_t error = ESP_ERR_INVALID_RESPONSE;
|
||||||
mb_param_request_t request ;
|
mb_param_request_t request ;
|
||||||
mb_parameter_descriptor_t reg_info = { 0 };
|
mb_parameter_descriptor_t reg_info = { 0 };
|
||||||
uint8_t param_buffer[PARAM_MAX_SIZE] = { 0 };
|
|
||||||
|
|
||||||
error = mbc_serial_master_set_request(name, MB_PARAM_READ, &request, ®_info);
|
error = mbc_serial_master_set_request(name, MB_PARAM_READ, &request, ®_info);
|
||||||
if ((error == ESP_OK) && (cid == reg_info.cid)) {
|
if ((error == ESP_OK) && (cid == reg_info.cid)) {
|
||||||
error = mbc_serial_master_send_request(&request, ¶m_buffer[0]);
|
// Send request to read characteristic data
|
||||||
|
error = mbc_serial_master_send_request(&request, value_ptr);
|
||||||
if (error == ESP_OK) {
|
if (error == ESP_OK) {
|
||||||
// If data pointer is NULL then we don't need to set value
|
|
||||||
// (it is still in the cache of cid)
|
|
||||||
if (value != NULL) {
|
|
||||||
error = mbc_serial_master_set_param_data((void*)value, (void*)¶m_buffer[0],
|
|
||||||
reg_info.param_type, reg_info.param_size);
|
|
||||||
MB_MASTER_CHECK((error == ESP_OK), ESP_ERR_INVALID_STATE, "fail to set parameter data.");
|
|
||||||
}
|
|
||||||
ESP_LOGD(MB_MASTER_TAG, "%s: Good response for get cid(%u) = %s",
|
ESP_LOGD(MB_MASTER_TAG, "%s: Good response for get cid(%u) = %s",
|
||||||
__FUNCTION__, (int)reg_info.cid, (char*)esp_err_to_name(error));
|
__FUNCTION__, (int)reg_info.cid, (char*)esp_err_to_name(error));
|
||||||
} else {
|
} else {
|
||||||
@@ -457,28 +415,22 @@ static esp_err_t mbc_serial_master_get_parameter(uint16_t cid, char* name,
|
|||||||
|
|
||||||
// Set parameter value for characteristic selected by name and cid
|
// Set parameter value for characteristic selected by name and cid
|
||||||
static esp_err_t mbc_serial_master_set_parameter(uint16_t cid, char* name,
|
static esp_err_t mbc_serial_master_set_parameter(uint16_t cid, char* name,
|
||||||
uint8_t* value, uint8_t *type)
|
uint8_t* value_ptr, uint8_t *type)
|
||||||
{
|
{
|
||||||
MB_MASTER_CHECK((name != NULL),
|
MB_MASTER_CHECK((name != NULL),
|
||||||
ESP_ERR_INVALID_ARG, "mb incorrect descriptor.");
|
ESP_ERR_INVALID_ARG, "mb incorrect descriptor.");
|
||||||
MB_MASTER_CHECK((value != NULL),
|
MB_MASTER_CHECK((value_ptr != NULL),
|
||||||
ESP_ERR_INVALID_ARG, "value pointer is incorrect.");
|
ESP_ERR_INVALID_ARG, "value pointer is incorrect.");
|
||||||
MB_MASTER_CHECK((type != NULL),
|
MB_MASTER_CHECK((type != NULL),
|
||||||
ESP_ERR_INVALID_ARG, "type pointer is incorrect.");
|
ESP_ERR_INVALID_ARG, "type pointer is incorrect.");
|
||||||
esp_err_t error = ESP_ERR_INVALID_RESPONSE;
|
esp_err_t error = ESP_ERR_INVALID_RESPONSE;
|
||||||
mb_param_request_t request ;
|
mb_param_request_t request ;
|
||||||
mb_parameter_descriptor_t reg_info = { 0 };
|
mb_parameter_descriptor_t reg_info = { 0 };
|
||||||
uint8_t param_buffer[PARAM_MAX_SIZE] = { 0 };
|
|
||||||
|
|
||||||
error = mbc_serial_master_set_request(name, MB_PARAM_WRITE, &request, ®_info);
|
error = mbc_serial_master_set_request(name, MB_PARAM_WRITE, &request, ®_info);
|
||||||
if ((error == ESP_OK) && (cid == reg_info.cid)) {
|
if ((error == ESP_OK) && (cid == reg_info.cid)) {
|
||||||
// Transfer value of characteristic into parameter buffer
|
|
||||||
error = mbc_serial_master_set_param_data((void*)¶m_buffer[0], (void*)value,
|
|
||||||
reg_info.param_type, reg_info.param_size);
|
|
||||||
MB_MASTER_CHECK((error == ESP_OK),
|
|
||||||
ESP_ERR_INVALID_STATE, "failure to set parameter data.");
|
|
||||||
// Send request to write characteristic data
|
// Send request to write characteristic data
|
||||||
error = mbc_serial_master_send_request(&request, ¶m_buffer[0]);
|
error = mbc_serial_master_send_request(&request, value_ptr);
|
||||||
if (error == ESP_OK) {
|
if (error == ESP_OK) {
|
||||||
ESP_LOGD(MB_MASTER_TAG, "%s: Good response for set cid(%u) = %s",
|
ESP_LOGD(MB_MASTER_TAG, "%s: Good response for set cid(%u) = %s",
|
||||||
__FUNCTION__, (int)reg_info.cid, (char*)esp_err_to_name(error));
|
__FUNCTION__, (int)reg_info.cid, (char*)esp_err_to_name(error));
|
||||||
|
@@ -41,7 +41,7 @@ expect_dict_master_err = {"READ_PAR_ERR": (u'263', u'ESP_ERR_TIMEOUT'),
|
|||||||
# The dictionary for regular expression patterns to check in listing
|
# The dictionary for regular expression patterns to check in listing
|
||||||
pattern_dict_master_ok = {"START": (r'.*I \([0-9]+\) MASTER_TEST: Start modbus test...'),
|
pattern_dict_master_ok = {"START": (r'.*I \([0-9]+\) MASTER_TEST: Start modbus test...'),
|
||||||
"READ_PAR_OK": (r'.*I\s\([0-9]+\) MASTER_TEST: Characteristic #[0-9]+ [a-zA-Z0-9_]+'
|
"READ_PAR_OK": (r'.*I\s\([0-9]+\) MASTER_TEST: Characteristic #[0-9]+ [a-zA-Z0-9_]+'
|
||||||
r'\s\([a-zA-Z\%\/]+\) value = [a-zA-Z0-9\.]+ \(0x[a-zA-Z0-9]+\) read successful.'),
|
r'\s\([a-zA-Z\%\/]+\) value = [a-zA-Z0-9\.\s]*\(0x[a-zA-Z0-9]+\) read successful.'),
|
||||||
"ALARM_MSG": (r'.*I \([0-9]*\) MASTER_TEST: Alarm triggered by cid #([0-9]+).')}
|
"ALARM_MSG": (r'.*I \([0-9]*\) MASTER_TEST: Alarm triggered by cid #([0-9]+).')}
|
||||||
|
|
||||||
pattern_dict_master_err = {"READ_PAR_ERR_TOUT": (r'.*E \([0-9]+\) MASTER_TEST: Characteristic #[0-9]+'
|
pattern_dict_master_err = {"READ_PAR_ERR_TOUT": (r'.*E \([0-9]+\) MASTER_TEST: Characteristic #[0-9]+'
|
||||||
|
@@ -49,6 +49,7 @@ typedef struct
|
|||||||
float holding_data1;
|
float holding_data1;
|
||||||
float holding_data2;
|
float holding_data2;
|
||||||
float holding_data3;
|
float holding_data3;
|
||||||
|
uint16_t test_regs[150];
|
||||||
} holding_reg_params_t;
|
} holding_reg_params_t;
|
||||||
#pragma pack(pop)
|
#pragma pack(pop)
|
||||||
|
|
||||||
|
@@ -70,6 +70,7 @@ enum {
|
|||||||
CID_HOLD_DATA_1,
|
CID_HOLD_DATA_1,
|
||||||
CID_INP_DATA_2,
|
CID_INP_DATA_2,
|
||||||
CID_HOLD_DATA_2,
|
CID_HOLD_DATA_2,
|
||||||
|
CID_HOLD_TEST_REG,
|
||||||
CID_RELAY_P1,
|
CID_RELAY_P1,
|
||||||
CID_RELAY_P2,
|
CID_RELAY_P2,
|
||||||
CID_COUNT
|
CID_COUNT
|
||||||
@@ -98,6 +99,8 @@ const mb_parameter_descriptor_t device_parameters[] = {
|
|||||||
INPUT_OFFSET(input_data2), PARAM_TYPE_FLOAT, 4, OPTS( -40, 100, 1 ), PAR_PERMS_READ_WRITE_TRIGGER },
|
INPUT_OFFSET(input_data2), PARAM_TYPE_FLOAT, 4, OPTS( -40, 100, 1 ), PAR_PERMS_READ_WRITE_TRIGGER },
|
||||||
{ CID_HOLD_DATA_2, STR("Humidity_3"), STR("%rH"), MB_DEVICE_ADDR1, MB_PARAM_HOLDING, 4, 2,
|
{ CID_HOLD_DATA_2, STR("Humidity_3"), STR("%rH"), MB_DEVICE_ADDR1, MB_PARAM_HOLDING, 4, 2,
|
||||||
HOLD_OFFSET(holding_data2), PARAM_TYPE_FLOAT, 4, OPTS( 0, 100, 1 ), PAR_PERMS_READ_WRITE_TRIGGER },
|
HOLD_OFFSET(holding_data2), PARAM_TYPE_FLOAT, 4, OPTS( 0, 100, 1 ), PAR_PERMS_READ_WRITE_TRIGGER },
|
||||||
|
{ CID_HOLD_TEST_REG, STR("Test_regs"), STR("__"), MB_DEVICE_ADDR1, MB_PARAM_HOLDING, 10, 58,
|
||||||
|
HOLD_OFFSET(test_regs), PARAM_TYPE_ASCII, 116, OPTS( 0, 100, 1 ), PAR_PERMS_READ_WRITE_TRIGGER },
|
||||||
{ CID_RELAY_P1, STR("RelayP1"), STR("on/off"), MB_DEVICE_ADDR1, MB_PARAM_COIL, 0, 8,
|
{ CID_RELAY_P1, STR("RelayP1"), STR("on/off"), MB_DEVICE_ADDR1, MB_PARAM_COIL, 0, 8,
|
||||||
COIL_OFFSET(coils_port0), PARAM_TYPE_U16, 2, OPTS( BIT1, 0, 0 ), PAR_PERMS_READ_WRITE_TRIGGER },
|
COIL_OFFSET(coils_port0), PARAM_TYPE_U16, 2, OPTS( BIT1, 0, 0 ), PAR_PERMS_READ_WRITE_TRIGGER },
|
||||||
{ CID_RELAY_P2, STR("RelayP2"), STR("on/off"), MB_DEVICE_ADDR1, MB_PARAM_COIL, 8, 8,
|
{ CID_RELAY_P2, STR("RelayP2"), STR("on/off"), MB_DEVICE_ADDR1, MB_PARAM_COIL, 8, 8,
|
||||||
@@ -160,6 +163,45 @@ static void master_operation_func(void *arg)
|
|||||||
void* temp_data_ptr = master_get_param_data(param_descriptor);
|
void* temp_data_ptr = master_get_param_data(param_descriptor);
|
||||||
assert(temp_data_ptr);
|
assert(temp_data_ptr);
|
||||||
uint8_t type = 0;
|
uint8_t type = 0;
|
||||||
|
if ((param_descriptor->param_type == PARAM_TYPE_ASCII) &&
|
||||||
|
(param_descriptor->cid == CID_HOLD_TEST_REG)) {
|
||||||
|
// Check for long array of registers of type PARAM_TYPE_ASCII
|
||||||
|
err = mbc_master_get_parameter(cid, (char*)param_descriptor->param_key,
|
||||||
|
(uint8_t*)temp_data_ptr, &type);
|
||||||
|
if (err == ESP_OK) {
|
||||||
|
ESP_LOGI(MASTER_TAG, "Characteristic #%d %s (%s) value = (0x%08x) read successful.",
|
||||||
|
param_descriptor->cid,
|
||||||
|
(char*)param_descriptor->param_key,
|
||||||
|
(char*)param_descriptor->param_units,
|
||||||
|
*(uint32_t*)temp_data_ptr);
|
||||||
|
// Initialize data of test array and write to slave
|
||||||
|
if (*(uint32_t*)temp_data_ptr != 0xAAAAAAAA) {
|
||||||
|
memset((void*)temp_data_ptr, 0xAA, param_descriptor->param_size);
|
||||||
|
*(uint32_t*)temp_data_ptr = 0xAAAAAAAA;
|
||||||
|
err = mbc_master_set_parameter(cid, (char*)param_descriptor->param_key,
|
||||||
|
(uint8_t*)temp_data_ptr, &type);
|
||||||
|
if (err == ESP_OK) {
|
||||||
|
ESP_LOGI(MASTER_TAG, "Characteristic #%d %s (%s) value = (0x%08x), write successful.",
|
||||||
|
param_descriptor->cid,
|
||||||
|
(char*)param_descriptor->param_key,
|
||||||
|
(char*)param_descriptor->param_units,
|
||||||
|
*(uint32_t*)temp_data_ptr);
|
||||||
|
} else {
|
||||||
|
ESP_LOGE(MASTER_TAG, "Characteristic #%d (%s) write fail, err = 0x%x (%s).",
|
||||||
|
param_descriptor->cid,
|
||||||
|
(char*)param_descriptor->param_key,
|
||||||
|
(int)err,
|
||||||
|
(char*)esp_err_to_name(err));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ESP_LOGE(MASTER_TAG, "Characteristic #%d (%s) read fail, err = 0x%x (%s).",
|
||||||
|
param_descriptor->cid,
|
||||||
|
(char*)param_descriptor->param_key,
|
||||||
|
(int)err,
|
||||||
|
(char*)esp_err_to_name(err));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
err = mbc_master_get_parameter(cid, (char*)param_descriptor->param_key,
|
err = mbc_master_get_parameter(cid, (char*)param_descriptor->param_key,
|
||||||
(uint8_t*)&value, &type);
|
(uint8_t*)&value, &type);
|
||||||
if (err == ESP_OK) {
|
if (err == ESP_OK) {
|
||||||
@@ -192,12 +234,13 @@ static void master_operation_func(void *arg)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ESP_LOGE(MASTER_TAG, "Characteristic #%d (%s) read fail, err = %d (%s).",
|
ESP_LOGE(MASTER_TAG, "Characteristic #%d (%s) read fail, err = 0x%x (%s).",
|
||||||
param_descriptor->cid,
|
param_descriptor->cid,
|
||||||
(char*)param_descriptor->param_key,
|
(char*)param_descriptor->param_key,
|
||||||
(int)err,
|
(int)err,
|
||||||
(char*)esp_err_to_name(err));
|
(char*)esp_err_to_name(err));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
vTaskDelay(POLL_TIMEOUT_TICS); // timeout between polls
|
vTaskDelay(POLL_TIMEOUT_TICS); // timeout between polls
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -257,6 +300,7 @@ static esp_err_t master_init(void)
|
|||||||
err = uart_set_mode(MB_PORT_NUM, UART_MODE_RS485_HALF_DUPLEX);
|
err = uart_set_mode(MB_PORT_NUM, UART_MODE_RS485_HALF_DUPLEX);
|
||||||
MASTER_CHECK((err == ESP_OK), ESP_ERR_INVALID_STATE,
|
MASTER_CHECK((err == ESP_OK), ESP_ERR_INVALID_STATE,
|
||||||
"mb serial set mode failure, uart_set_mode() returned (0x%x).", (uint32_t)err);
|
"mb serial set mode failure, uart_set_mode() returned (0x%x).", (uint32_t)err);
|
||||||
|
|
||||||
vTaskDelay(5);
|
vTaskDelay(5);
|
||||||
err = mbc_master_set_descriptor(&device_parameters[0], num_device_parameters);
|
err = mbc_master_set_descriptor(&device_parameters[0], num_device_parameters);
|
||||||
MASTER_CHECK((err == ESP_OK), ESP_ERR_INVALID_STATE,
|
MASTER_CHECK((err == ESP_OK), ESP_ERR_INVALID_STATE,
|
||||||
|
Reference in New Issue
Block a user