forked from espressif/esp-modbus
serial master, slave fix parity check
This commit is contained in:
@ -159,6 +159,17 @@ typedef struct {
|
|||||||
BOOL xTimerState;
|
BOOL xTimerState;
|
||||||
} xTimerContext_t;
|
} xTimerContext_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
QueueHandle_t xMbUartQueue; /*!< A queue to handle UART event. */
|
||||||
|
TaskHandle_t xMbTaskHandle; /*!< Serial task handle */
|
||||||
|
UCHAR ucUartNumber; /*!< The UART hardware port number */
|
||||||
|
BOOL bRxStateEnabled; /*!< Receiver enabled flag */
|
||||||
|
BOOL bTxStateEnabled; /*!< Transmitter enabled flag */
|
||||||
|
SemaphoreHandle_t xRxSemaHandle; /*!< Rx blocking semaphore handle */
|
||||||
|
ULONG ulParityErrors; /*!< Parity errors counter */
|
||||||
|
ULONG ulFrameErrors; /*!< Frame errors counter */
|
||||||
|
} MBMSerialContext_t;
|
||||||
|
|
||||||
void vMBPortEnterCritical(void);
|
void vMBPortEnterCritical(void);
|
||||||
void vMBPortExitCritical(void);
|
void vMBPortExitCritical(void);
|
||||||
|
|
||||||
|
@ -292,12 +292,12 @@ eMBMasterReqErrCode eMBMasterWaitRequestFinish( void ) {
|
|||||||
xEventGroupSetBits( xEventGroupMasterConfirmHdl, (xRecvedEvent & MB_EVENT_REQ_MASK) );
|
xEventGroupSetBits( xEventGroupMasterConfirmHdl, (xRecvedEvent & MB_EVENT_REQ_MASK) );
|
||||||
if (MB_PORT_CHECK_EVENT(xRecvedEvent, EV_MASTER_PROCESS_SUCCESS)) {
|
if (MB_PORT_CHECK_EVENT(xRecvedEvent, EV_MASTER_PROCESS_SUCCESS)) {
|
||||||
eErrStatus = MB_MRE_NO_ERR;
|
eErrStatus = MB_MRE_NO_ERR;
|
||||||
} else if (MB_PORT_CHECK_EVENT(xRecvedEvent, EV_MASTER_ERROR_RESPOND_TIMEOUT)) {
|
|
||||||
eErrStatus = MB_MRE_TIMEDOUT;
|
|
||||||
} else if (MB_PORT_CHECK_EVENT(xRecvedEvent, EV_MASTER_ERROR_RECEIVE_DATA)) {
|
} else if (MB_PORT_CHECK_EVENT(xRecvedEvent, EV_MASTER_ERROR_RECEIVE_DATA)) {
|
||||||
eErrStatus = MB_MRE_REV_DATA;
|
eErrStatus = MB_MRE_REV_DATA;
|
||||||
} else if (MB_PORT_CHECK_EVENT(xRecvedEvent, EV_MASTER_ERROR_EXECUTE_FUNCTION)) {
|
} else if (MB_PORT_CHECK_EVENT(xRecvedEvent, EV_MASTER_ERROR_EXECUTE_FUNCTION)) {
|
||||||
eErrStatus = MB_MRE_EXE_FUN;
|
eErrStatus = MB_MRE_EXE_FUN;
|
||||||
|
} else if (MB_PORT_CHECK_EVENT(xRecvedEvent, EV_MASTER_ERROR_RESPOND_TIMEOUT)) {
|
||||||
|
eErrStatus = MB_MRE_TIMEDOUT;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ESP_LOGE(MB_PORT_TAG,"%s: Incorrect event or timeout xRecvedEvent = 0x%x", __func__, uxBits);
|
ESP_LOGE(MB_PORT_TAG,"%s: Incorrect event or timeout xRecvedEvent = 0x%x", __func__, uxBits);
|
||||||
|
@ -50,33 +50,34 @@
|
|||||||
#include "port_serial_slave.h"
|
#include "port_serial_slave.h"
|
||||||
|
|
||||||
// Note: This code uses mixed coding standard from legacy IDF code and used freemodbus stack
|
// Note: This code uses mixed coding standard from legacy IDF code and used freemodbus stack
|
||||||
|
|
||||||
// A queue to handle UART event.
|
|
||||||
static QueueHandle_t xMbUartQueue;
|
|
||||||
static TaskHandle_t xMbTaskHandle;
|
|
||||||
static const CHAR *TAG = "MB_SERIAL";
|
static const CHAR *TAG = "MB_SERIAL";
|
||||||
|
|
||||||
// The UART hardware port number
|
// Serial communication context structure
|
||||||
static UCHAR ucUartNumber = UART_NUM_MAX - 1;
|
static MBMSerialContext_t xMBSCtx = {
|
||||||
|
.xMbUartQueue = NULL,
|
||||||
static BOOL bRxStateEnabled = FALSE; // Receiver enabled flag
|
.xMbTaskHandle = NULL,
|
||||||
static BOOL bTxStateEnabled = FALSE; // Transmitter enabled flag
|
.ucUartNumber = UART_NUM_MAX - 1,
|
||||||
|
.xRxSemaHandle = NULL,
|
||||||
|
.bTxStateEnabled = FALSE,
|
||||||
|
.bRxStateEnabled = FALSE,
|
||||||
|
.ulParityErrors = 0
|
||||||
|
};
|
||||||
|
|
||||||
void vMBPortSerialEnable(BOOL bRxEnable, BOOL bTxEnable)
|
void vMBPortSerialEnable(BOOL bRxEnable, BOOL bTxEnable)
|
||||||
{
|
{
|
||||||
// This function can be called from xMBRTUTransmitFSM() of different task
|
// This function can be called from xMBRTUTransmitFSM() of different task
|
||||||
if (bTxEnable) {
|
if (bTxEnable) {
|
||||||
bTxStateEnabled = TRUE;
|
xMBSCtx.bTxStateEnabled = TRUE;
|
||||||
} else {
|
} else {
|
||||||
bTxStateEnabled = FALSE;
|
xMBSCtx.bTxStateEnabled = FALSE;
|
||||||
}
|
}
|
||||||
if (bRxEnable) {
|
if (bRxEnable) {
|
||||||
//uart_enable_rx_intr(ucUartNumber);
|
//uart_enable_rx_intr(ucUartNumber);
|
||||||
bRxStateEnabled = TRUE;
|
xMBSCtx.bRxStateEnabled = TRUE;
|
||||||
vTaskResume(xMbTaskHandle); // Resume receiver task
|
vTaskResume(xMBSCtx.xMbTaskHandle); // Resume receiver task
|
||||||
} else {
|
} else {
|
||||||
vTaskSuspend(xMbTaskHandle); // Block receiver task
|
vTaskSuspend(xMBSCtx.xMbTaskHandle); // Block receiver task
|
||||||
bRxStateEnabled = FALSE;
|
xMBSCtx.bRxStateEnabled = FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -85,13 +86,13 @@ static USHORT usMBPortSerialRxPoll(size_t xEventSize)
|
|||||||
BOOL xReadStatus = TRUE;
|
BOOL xReadStatus = TRUE;
|
||||||
USHORT usCnt = 0;
|
USHORT usCnt = 0;
|
||||||
|
|
||||||
if (bRxStateEnabled) {
|
if (xMBSCtx.bRxStateEnabled) {
|
||||||
// Get received packet into Rx buffer
|
// Get received packet into Rx buffer
|
||||||
while(xReadStatus && (usCnt++ <= xEventSize)) {
|
while(xReadStatus && (usCnt++ <= xEventSize)) {
|
||||||
// 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
|
xReadStatus = pxMBFrameCBByteReceived(); // callback to execute receive FSM
|
||||||
}
|
}
|
||||||
uart_flush_input(ucUartNumber);
|
uart_flush_input(xMBSCtx.ucUartNumber);
|
||||||
// Send event EV_FRAME_RECEIVED to allow stack process packet
|
// Send event EV_FRAME_RECEIVED to allow stack process packet
|
||||||
#if !CONFIG_FMB_TIMER_PORT_ENABLED
|
#if !CONFIG_FMB_TIMER_PORT_ENABLED
|
||||||
pxMBPortCBTimerExpired();
|
pxMBPortCBTimerExpired();
|
||||||
@ -106,7 +107,7 @@ BOOL xMBPortSerialTxPoll(void)
|
|||||||
USHORT usCount = 0;
|
USHORT usCount = 0;
|
||||||
BOOL bNeedPoll = TRUE;
|
BOOL bNeedPoll = TRUE;
|
||||||
|
|
||||||
if( bTxStateEnabled ) {
|
if(xMBSCtx.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.
|
||||||
@ -114,7 +115,7 @@ BOOL xMBPortSerialTxPoll(void)
|
|||||||
}
|
}
|
||||||
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
|
||||||
esp_err_t xTxStatus = uart_wait_tx_done(ucUartNumber, MB_SERIAL_TX_TOUT_TICKS);
|
esp_err_t xTxStatus = uart_wait_tx_done(xMBSCtx.ucUartNumber, MB_SERIAL_TX_TOUT_TICKS);
|
||||||
vMBPortSerialEnable(TRUE, FALSE);
|
vMBPortSerialEnable(TRUE, FALSE);
|
||||||
MB_PORT_CHECK((xTxStatus == ESP_OK), FALSE, "mb serial sent buffer failure.");
|
MB_PORT_CHECK((xTxStatus == ESP_OK), FALSE, "mb serial sent buffer failure.");
|
||||||
return TRUE;
|
return TRUE;
|
||||||
@ -127,8 +128,8 @@ static void vUartTask(void *pvParameters)
|
|||||||
uart_event_t xEvent;
|
uart_event_t xEvent;
|
||||||
USHORT usResult = 0;
|
USHORT usResult = 0;
|
||||||
for(;;) {
|
for(;;) {
|
||||||
if (xMBPortSerialWaitEvent(xMbUartQueue, (void*)&xEvent, portMAX_DELAY)) {
|
if (xMBPortSerialWaitEvent(xMBSCtx.xMbUartQueue, (void*)&xEvent, portMAX_DELAY)) {
|
||||||
ESP_LOGD(TAG, "MB_uart[%d] event:", ucUartNumber);
|
ESP_LOGD(TAG, "MB_uart[%d] event:", xMBSCtx.ucUartNumber);
|
||||||
switch(xEvent.type) {
|
switch(xEvent.type) {
|
||||||
//Event of UART receving data
|
//Event of UART receving data
|
||||||
case UART_DATA:
|
case UART_DATA:
|
||||||
@ -137,7 +138,7 @@ static void vUartTask(void *pvParameters)
|
|||||||
// data received during configured timeout and UART TOUT feature is triggered
|
// data received during configured timeout and UART TOUT feature is triggered
|
||||||
if (xEvent.timeout_flag) {
|
if (xEvent.timeout_flag) {
|
||||||
// Get buffered data length
|
// Get buffered data length
|
||||||
ESP_ERROR_CHECK(uart_get_buffered_data_len(ucUartNumber, &xEvent.size));
|
ESP_ERROR_CHECK(uart_get_buffered_data_len(xMBSCtx.ucUartNumber, &xEvent.size));
|
||||||
// Read received data and send it to modbus stack
|
// Read received data and send it to modbus stack
|
||||||
usResult = usMBPortSerialRxPoll(xEvent.size);
|
usResult = usMBPortSerialRxPoll(xEvent.size);
|
||||||
ESP_LOGD(TAG,"Timeout occured, processed: %d bytes", usResult);
|
ESP_LOGD(TAG,"Timeout occured, processed: %d bytes", usResult);
|
||||||
@ -146,13 +147,13 @@ static void vUartTask(void *pvParameters)
|
|||||||
//Event of HW FIFO overflow detected
|
//Event of HW FIFO overflow detected
|
||||||
case UART_FIFO_OVF:
|
case UART_FIFO_OVF:
|
||||||
ESP_LOGD(TAG, "hw fifo overflow\n");
|
ESP_LOGD(TAG, "hw fifo overflow\n");
|
||||||
xQueueReset(xMbUartQueue);
|
xQueueReset(xMBSCtx.xMbUartQueue);
|
||||||
break;
|
break;
|
||||||
//Event of UART ring buffer full
|
//Event of UART ring buffer full
|
||||||
case UART_BUFFER_FULL:
|
case UART_BUFFER_FULL:
|
||||||
ESP_LOGD(TAG, "ring buffer full\n");
|
ESP_LOGD(TAG, "ring buffer full\n");
|
||||||
xQueueReset(xMbUartQueue);
|
xQueueReset(xMBSCtx.xMbUartQueue);
|
||||||
uart_flush_input(ucUartNumber);
|
uart_flush_input(xMBSCtx.ucUartNumber);
|
||||||
break;
|
break;
|
||||||
//Event of UART RX break detected
|
//Event of UART RX break detected
|
||||||
case UART_BREAK:
|
case UART_BREAK:
|
||||||
@ -160,7 +161,10 @@ static void vUartTask(void *pvParameters)
|
|||||||
break;
|
break;
|
||||||
//Event of UART parity check error
|
//Event of UART parity check error
|
||||||
case UART_PARITY_ERR:
|
case UART_PARITY_ERR:
|
||||||
ESP_LOGD(TAG, "uart parity error\n");
|
ESP_LOGD(TAG, "uart parity error, count: %lu.", xMBSCtx.ulParityErrors);
|
||||||
|
xMBSCtx.ulParityErrors++;
|
||||||
|
xQueueReset(xMBSCtx.xMbUartQueue);
|
||||||
|
uart_flush_input(xMBSCtx.ucUartNumber);
|
||||||
break;
|
break;
|
||||||
//Event of UART frame error
|
//Event of UART frame error
|
||||||
case UART_FRAME_ERR:
|
case UART_FRAME_ERR:
|
||||||
@ -180,7 +184,8 @@ BOOL xMBPortSerialInit(UCHAR ucPORT, ULONG ulBaudRate,
|
|||||||
{
|
{
|
||||||
esp_err_t xErr = ESP_OK;
|
esp_err_t xErr = ESP_OK;
|
||||||
// Set communication port number
|
// Set communication port number
|
||||||
ucUartNumber = ucPORT;
|
xMBSCtx.ucUartNumber = ucPORT;
|
||||||
|
xMBSCtx.ulParityErrors = 0;
|
||||||
// Configure serial communication parameters
|
// Configure serial communication parameters
|
||||||
UCHAR ucParity = UART_PARITY_DISABLE;
|
UCHAR ucParity = UART_PARITY_DISABLE;
|
||||||
UCHAR ucData = UART_DATA_8_BITS;
|
UCHAR ucData = UART_DATA_8_BITS;
|
||||||
@ -229,53 +234,53 @@ BOOL xMBPortSerialInit(UCHAR ucPORT, ULONG ulBaudRate,
|
|||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
// Set UART config
|
// Set UART config
|
||||||
xErr = uart_param_config(ucUartNumber, &xUartConfig);
|
xErr = uart_param_config(xMBSCtx.ucUartNumber, &xUartConfig);
|
||||||
MB_PORT_CHECK((xErr == ESP_OK),
|
MB_PORT_CHECK((xErr == ESP_OK),
|
||||||
FALSE, "mb config failure, uart_param_config() returned (0x%x).", xErr);
|
FALSE, "mb config failure, uart_param_config() returned (0x%x).", xErr);
|
||||||
// Install UART driver, and get the queue.
|
// Install UART driver, and get the queue.
|
||||||
xErr = uart_driver_install(ucUartNumber, MB_SERIAL_BUF_SIZE, MB_SERIAL_BUF_SIZE,
|
xErr = uart_driver_install(xMBSCtx.ucUartNumber, MB_SERIAL_BUF_SIZE, MB_SERIAL_BUF_SIZE,
|
||||||
MB_QUEUE_LENGTH, &xMbUartQueue, MB_PORT_SERIAL_ISR_FLAG);
|
MB_QUEUE_LENGTH, &xMBSCtx.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);
|
||||||
#if !CONFIG_FMB_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(xMBSCtx.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
|
// Set always timeout flag to trigger timeout interrupt even after rx fifo full
|
||||||
uart_set_always_rx_timeout(ucUartNumber, true);
|
uart_set_always_rx_timeout(xMBSCtx.ucUartNumber, true);
|
||||||
|
|
||||||
// Create a task to handle UART events
|
// Create a task to handle UART events
|
||||||
BaseType_t xStatus = xTaskCreatePinnedToCore(vUartTask, "uart_queue_task",
|
BaseType_t xStatus = xTaskCreatePinnedToCore(vUartTask, "uart_queue_task",
|
||||||
MB_SERIAL_TASK_STACK_SIZE,
|
MB_SERIAL_TASK_STACK_SIZE,
|
||||||
NULL, MB_SERIAL_TASK_PRIO,
|
NULL, MB_SERIAL_TASK_PRIO,
|
||||||
&xMbTaskHandle, MB_PORT_TASK_AFFINITY);
|
&xMBSCtx.xMbTaskHandle, MB_PORT_TASK_AFFINITY);
|
||||||
if (xStatus != pdPASS) {
|
if (xStatus != pdPASS) {
|
||||||
vTaskDelete(xMbTaskHandle);
|
vTaskDelete(xMBSCtx.xMbTaskHandle);
|
||||||
// Force exit from function with failure
|
// Force exit from function with failure
|
||||||
MB_PORT_CHECK(FALSE, FALSE,
|
MB_PORT_CHECK(FALSE, FALSE,
|
||||||
"mb stack serial task creation error. xTaskCreate() returned (0x%x).",
|
"mb stack serial task creation error. xTaskCreate() returned (0x%x).",
|
||||||
xStatus);
|
xStatus);
|
||||||
} else {
|
} else {
|
||||||
vTaskSuspend(xMbTaskHandle); // Suspend serial task while stack is not started
|
vTaskSuspend(xMBSCtx.xMbTaskHandle); // Suspend serial task while stack is not started
|
||||||
}
|
}
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void vMBPortSerialClose(void)
|
void vMBPortSerialClose(void)
|
||||||
{
|
{
|
||||||
(void)vTaskSuspend(xMbTaskHandle);
|
(void)vTaskSuspend(xMBSCtx.xMbTaskHandle);
|
||||||
(void)vTaskDelete(xMbTaskHandle);
|
(void)vTaskDelete(xMBSCtx.xMbTaskHandle);
|
||||||
ESP_ERROR_CHECK(uart_driver_delete(ucUartNumber));
|
ESP_ERROR_CHECK(uart_driver_delete(xMBSCtx.ucUartNumber));
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL xMBPortSerialPutByte(CHAR ucByte)
|
BOOL xMBPortSerialPutByte(CHAR ucByte)
|
||||||
{
|
{
|
||||||
// Send one byte to UART transmission buffer
|
// Send one byte to UART transmission buffer
|
||||||
// This function is called by Modbus stack
|
// This function is called by Modbus stack
|
||||||
UCHAR ucLength = uart_write_bytes(ucUartNumber, &ucByte, 1);
|
UCHAR ucLength = uart_write_bytes(xMBSCtx.ucUartNumber, &ucByte, 1);
|
||||||
return (ucLength == 1);
|
return (ucLength == 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -283,6 +288,6 @@ BOOL xMBPortSerialPutByte(CHAR ucByte)
|
|||||||
BOOL xMBPortSerialGetByte(CHAR* pucByte)
|
BOOL xMBPortSerialGetByte(CHAR* pucByte)
|
||||||
{
|
{
|
||||||
assert(pucByte != NULL);
|
assert(pucByte != NULL);
|
||||||
USHORT usLength = uart_read_bytes(ucUartNumber, (uint8_t*)pucByte, 1, MB_SERIAL_RX_TOUT_TICKS);
|
USHORT usLength = uart_read_bytes(xMBSCtx.ucUartNumber, (uint8_t*)pucByte, 1, MB_SERIAL_RX_TOUT_TICKS);
|
||||||
return (usLength == 1);
|
return (usLength == 1);
|
||||||
}
|
}
|
||||||
|
@ -59,38 +59,40 @@
|
|||||||
/* ----------------------- Static variables ---------------------------------*/
|
/* ----------------------- Static variables ---------------------------------*/
|
||||||
static const CHAR *TAG = "MB_MASTER_SERIAL";
|
static const CHAR *TAG = "MB_MASTER_SERIAL";
|
||||||
|
|
||||||
// A queue to handle UART event.
|
// Serial communication context structure
|
||||||
static QueueHandle_t xMbUartQueue;
|
static MBMSerialContext_t xMBMCtx = {
|
||||||
static TaskHandle_t xMbTaskHandle;
|
.xMbUartQueue = NULL,
|
||||||
|
.xMbTaskHandle = NULL,
|
||||||
// The UART hardware port number
|
.ucUartNumber = UART_NUM_MAX - 1,
|
||||||
static UCHAR ucUartNumber = UART_NUM_MAX - 1;
|
.xRxSemaHandle = NULL,
|
||||||
|
.bTxStateEnabled = FALSE,
|
||||||
static BOOL bRxStateEnabled = FALSE; // Receiver enabled flag
|
.bRxStateEnabled = FALSE,
|
||||||
static BOOL bTxStateEnabled = FALSE; // Transmitter enabled flag
|
.ulParityErrors = 0, // Debug counters, can overrun
|
||||||
|
.ulFrameErrors = 0
|
||||||
static SemaphoreHandle_t xMasterSemaRxHandle; // Rx blocking semaphore handle
|
};
|
||||||
|
|
||||||
static BOOL xMBMasterPortRxSemaInit( void )
|
static BOOL xMBMasterPortRxSemaInit( void )
|
||||||
{
|
{
|
||||||
xMasterSemaRxHandle = xSemaphoreCreateBinary();
|
xMBMCtx.xRxSemaHandle = xSemaphoreCreateBinary();
|
||||||
MB_PORT_CHECK((xMasterSemaRxHandle != NULL), FALSE , "%s: RX semaphore create failure.", __func__);
|
MB_PORT_CHECK((xMBMCtx.xRxSemaHandle != NULL), FALSE , "%s: RX semaphore create failure.", __func__);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void vMBMasterPortRxSemaClose( void )
|
static void vMBMasterPortRxSemaClose( void )
|
||||||
{
|
{
|
||||||
if (xMasterSemaRxHandle) {
|
if (xMBMCtx.xRxSemaHandle) {
|
||||||
vSemaphoreDelete(xMasterSemaRxHandle);
|
vSemaphoreDelete(xMBMCtx.xRxSemaHandle);
|
||||||
xMasterSemaRxHandle = NULL;
|
xMBMCtx.xRxSemaHandle = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static BOOL xMBMasterPortRxSemaTake( LONG lTimeOut )
|
static BOOL xMBMasterPortRxSemaTake( LONG lTimeOut )
|
||||||
{
|
{
|
||||||
BaseType_t xStatus = pdTRUE;
|
BaseType_t xStatus = pdTRUE;
|
||||||
xStatus = xSemaphoreTake(xMasterSemaRxHandle, lTimeOut );
|
xStatus = xSemaphoreTake(xMBMCtx.xRxSemaHandle, lTimeOut );
|
||||||
MB_PORT_CHECK((xStatus == pdTRUE), FALSE , "%s: RX semaphore take failure.", __func__);
|
if (xStatus != pdTRUE) {
|
||||||
|
ESP_LOGD(TAG, "%s: RX semaphore take failure.", __func__);
|
||||||
|
}
|
||||||
ESP_LOGV(MB_PORT_TAG,"%s:Take RX semaphore (%lu ticks).", __func__, lTimeOut);
|
ESP_LOGV(MB_PORT_TAG,"%s:Take RX semaphore (%lu ticks).", __func__, lTimeOut);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
@ -98,7 +100,7 @@ static BOOL xMBMasterPortRxSemaTake( LONG lTimeOut )
|
|||||||
static void vMBMasterRxSemaRelease( void )
|
static void vMBMasterRxSemaRelease( void )
|
||||||
{
|
{
|
||||||
BaseType_t xStatus = pdFALSE;
|
BaseType_t xStatus = pdFALSE;
|
||||||
xStatus = xSemaphoreGive(xMasterSemaRxHandle);
|
xStatus = xSemaphoreGive(xMBMCtx.xRxSemaHandle);
|
||||||
if (xStatus != pdTRUE) {
|
if (xStatus != pdTRUE) {
|
||||||
ESP_LOGD(MB_PORT_TAG,"%s:RX semaphore is free.", __func__);
|
ESP_LOGD(MB_PORT_TAG,"%s:RX semaphore is free.", __func__);
|
||||||
}
|
}
|
||||||
@ -107,7 +109,7 @@ static void vMBMasterRxSemaRelease( void )
|
|||||||
static BOOL vMBMasterRxSemaIsBusy( void )
|
static BOOL vMBMasterRxSemaIsBusy( void )
|
||||||
{
|
{
|
||||||
BaseType_t xStatus = pdFALSE;
|
BaseType_t xStatus = pdFALSE;
|
||||||
xStatus = (uxSemaphoreGetCount(xMasterSemaRxHandle) == 0) ? TRUE : FALSE;
|
xStatus = (uxSemaphoreGetCount(xMBMCtx.xRxSemaHandle) == 0) ? TRUE : FALSE;
|
||||||
return xStatus;
|
return xStatus;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -116,11 +118,11 @@ void vMBMasterRxFlush( void )
|
|||||||
size_t xSize = 1;
|
size_t xSize = 1;
|
||||||
esp_err_t xErr = ESP_OK;
|
esp_err_t xErr = ESP_OK;
|
||||||
for (int xCount = 0; (xCount < MB_SERIAL_RX_FLUSH_RETRY) && xSize; xCount++) {
|
for (int xCount = 0; (xCount < MB_SERIAL_RX_FLUSH_RETRY) && xSize; xCount++) {
|
||||||
xErr = uart_get_buffered_data_len(ucUartNumber, &xSize);
|
xErr = uart_get_buffered_data_len(xMBMCtx.ucUartNumber, &xSize);
|
||||||
MB_PORT_CHECK((xErr == ESP_OK), ; , "mb flush serial fail, error = 0x%x.", xErr);
|
MB_PORT_CHECK((xErr == ESP_OK), ; , "mb flush serial fail, error = 0x%x.", xErr);
|
||||||
BaseType_t xStatus = xQueueReset(xMbUartQueue);
|
BaseType_t xStatus = xQueueReset(xMBMCtx.xMbUartQueue);
|
||||||
if (xStatus) {
|
if (xStatus) {
|
||||||
xErr = uart_flush_input(ucUartNumber);
|
xErr = uart_flush_input(xMBMCtx.ucUartNumber);
|
||||||
MB_PORT_CHECK((xErr == ESP_OK), ; , "mb flush serial fail, error = 0x%x.", xErr);
|
MB_PORT_CHECK((xErr == ESP_OK), ; , "mb flush serial fail, error = 0x%x.", xErr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -131,17 +133,17 @@ 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
|
||||||
if (bTxEnable) {
|
if (bTxEnable) {
|
||||||
vMBMasterRxFlush();
|
vMBMasterRxFlush();
|
||||||
bTxStateEnabled = TRUE;
|
xMBMCtx.bTxStateEnabled = TRUE;
|
||||||
} else {
|
} else {
|
||||||
bTxStateEnabled = FALSE;
|
xMBMCtx.bTxStateEnabled = FALSE;
|
||||||
}
|
}
|
||||||
if (bRxEnable) {
|
if (bRxEnable) {
|
||||||
bRxStateEnabled = TRUE;
|
xMBMCtx.bRxStateEnabled = TRUE;
|
||||||
vMBMasterRxSemaRelease();
|
vMBMasterRxSemaRelease();
|
||||||
vTaskResume(xMbTaskHandle); // Resume receiver task
|
vTaskResume(xMBMCtx.xMbTaskHandle); // Resume receiver task
|
||||||
} else {
|
} else {
|
||||||
vTaskSuspend(xMbTaskHandle); // Block receiver task
|
vTaskSuspend(xMBMCtx.xMbTaskHandle); // Block receiver task
|
||||||
bRxStateEnabled = FALSE;
|
xMBMCtx.bRxStateEnabled = FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -157,7 +159,7 @@ static USHORT usMBMasterPortSerialRxPoll(size_t xEventSize)
|
|||||||
xStatus = pxMBMasterFrameCBByteReceived(); // callback to receive FSM
|
xStatus = 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(xMBMCtx.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);
|
||||||
#if !CONFIG_FMB_TIMER_PORT_ENABLED
|
#if !CONFIG_FMB_TIMER_PORT_ENABLED
|
||||||
vMBMasterSetCurTimerMode(MB_TMODE_T35);
|
vMBMasterSetCurTimerMode(MB_TMODE_T35);
|
||||||
@ -178,7 +180,7 @@ BOOL xMBMasterPortSerialTxPoll(void)
|
|||||||
USHORT usCount = 0;
|
USHORT usCount = 0;
|
||||||
BOOL bNeedPoll = TRUE;
|
BOOL bNeedPoll = TRUE;
|
||||||
|
|
||||||
if( bTxStateEnabled ) {
|
if(xMBMCtx.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.
|
||||||
@ -186,7 +188,7 @@ BOOL xMBMasterPortSerialTxPoll(void)
|
|||||||
}
|
}
|
||||||
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
|
||||||
esp_err_t xTxStatus = uart_wait_tx_done(ucUartNumber, MB_SERIAL_TX_TOUT_TICKS);
|
esp_err_t xTxStatus = uart_wait_tx_done(xMBMCtx.ucUartNumber, MB_SERIAL_TX_TOUT_TICKS);
|
||||||
vMBMasterPortSerialEnable(TRUE, FALSE);
|
vMBMasterPortSerialEnable(TRUE, FALSE);
|
||||||
MB_PORT_CHECK((xTxStatus == ESP_OK), FALSE, "mb serial sent buffer failure.");
|
MB_PORT_CHECK((xTxStatus == ESP_OK), FALSE, "mb serial sent buffer failure.");
|
||||||
return TRUE;
|
return TRUE;
|
||||||
@ -200,8 +202,8 @@ static void vUartTask(void* pvParameters)
|
|||||||
uart_event_t xEvent;
|
uart_event_t xEvent;
|
||||||
USHORT usResult = 0;
|
USHORT usResult = 0;
|
||||||
for(;;) {
|
for(;;) {
|
||||||
if (xMBPortSerialWaitEvent(xMbUartQueue, (void*)&xEvent, portMAX_DELAY)) {
|
if (xMBPortSerialWaitEvent(xMBMCtx.xMbUartQueue, (void*)&xEvent, portMAX_DELAY)) {
|
||||||
ESP_LOGD(TAG, "MB_uart[%d] event:", ucUartNumber);
|
ESP_LOGD(TAG, "MB_uart[%d] event:", xMBMCtx.ucUartNumber);
|
||||||
switch(xEvent.type) {
|
switch(xEvent.type) {
|
||||||
//Event of UART receiving data
|
//Event of UART receiving data
|
||||||
case UART_DATA:
|
case UART_DATA:
|
||||||
@ -213,10 +215,12 @@ static void vUartTask(void* pvParameters)
|
|||||||
// Do not wait completion of processing and just discard received data as incorrect
|
// Do not wait completion of processing and just discard received data as incorrect
|
||||||
if (vMBMasterRxSemaIsBusy()) {
|
if (vMBMasterRxSemaIsBusy()) {
|
||||||
vMBMasterRxFlush();
|
vMBMasterRxFlush();
|
||||||
|
vMBMasterSetErrorType(EV_ERROR_RECEIVE_DATA);
|
||||||
|
xMBMasterPortEventPost(EV_MASTER_ERROR_PROCESS);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// Get buffered data length
|
// Get buffered data length
|
||||||
ESP_ERROR_CHECK(uart_get_buffered_data_len(ucUartNumber, &xEvent.size));
|
ESP_ERROR_CHECK(uart_get_buffered_data_len(xMBMCtx.ucUartNumber, &xEvent.size));
|
||||||
// Read received data and send it to modbus stack
|
// Read received data and send it to modbus stack
|
||||||
usResult = usMBMasterPortSerialRxPoll(xEvent.size);
|
usResult = usMBMasterPortSerialRxPoll(xEvent.size);
|
||||||
ESP_LOGD(TAG,"Timeout occured, processed: %d bytes", usResult);
|
ESP_LOGD(TAG,"Timeout occured, processed: %d bytes", usResult);
|
||||||
@ -225,13 +229,13 @@ static void vUartTask(void* pvParameters)
|
|||||||
//Event of HW FIFO overflow detected
|
//Event of HW FIFO overflow detected
|
||||||
case UART_FIFO_OVF:
|
case UART_FIFO_OVF:
|
||||||
ESP_LOGD(TAG, "hw fifo overflow.");
|
ESP_LOGD(TAG, "hw fifo overflow.");
|
||||||
xQueueReset(xMbUartQueue);
|
xQueueReset(xMBMCtx.xMbUartQueue);
|
||||||
break;
|
break;
|
||||||
//Event of UART ring buffer full
|
//Event of UART ring buffer full
|
||||||
case UART_BUFFER_FULL:
|
case UART_BUFFER_FULL:
|
||||||
ESP_LOGD(TAG, "ring buffer full.");
|
ESP_LOGD(TAG, "ring buffer full.");
|
||||||
xQueueReset(xMbUartQueue);
|
xQueueReset(xMBMCtx.xMbUartQueue);
|
||||||
uart_flush_input(ucUartNumber);
|
uart_flush_input(xMBMCtx.ucUartNumber);
|
||||||
break;
|
break;
|
||||||
//Event of UART RX break detected
|
//Event of UART RX break detected
|
||||||
case UART_BREAK:
|
case UART_BREAK:
|
||||||
@ -239,11 +243,15 @@ static void vUartTask(void* pvParameters)
|
|||||||
break;
|
break;
|
||||||
//Event of UART parity check error
|
//Event of UART parity check error
|
||||||
case UART_PARITY_ERR:
|
case UART_PARITY_ERR:
|
||||||
ESP_LOGD(TAG, "uart parity error.");
|
ESP_LOGD(TAG, "uart parity error, count: %lu.", xMBMCtx.ulParityErrors);
|
||||||
|
xMBMasterPortRxSemaTake(0);
|
||||||
|
xMBMCtx.ulParityErrors++;
|
||||||
break;
|
break;
|
||||||
//Event of UART frame error
|
//Event of UART frame error
|
||||||
case UART_FRAME_ERR:
|
case UART_FRAME_ERR:
|
||||||
ESP_LOGD(TAG, "uart frame error.");
|
ESP_LOGD(TAG, "uart frame error, count: %lu.", xMBMCtx.ulFrameErrors);
|
||||||
|
xMBMasterPortRxSemaTake(0);
|
||||||
|
xMBMCtx.ulFrameErrors++;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
ESP_LOGD(TAG, "uart event type: %d.", xEvent.type);
|
ESP_LOGD(TAG, "uart event type: %d.", xEvent.type);
|
||||||
@ -259,7 +267,9 @@ BOOL xMBMasterPortSerialInit( UCHAR ucPORT, ULONG ulBaudRate, UCHAR ucDataBits,
|
|||||||
{
|
{
|
||||||
esp_err_t xErr = ESP_OK;
|
esp_err_t xErr = ESP_OK;
|
||||||
// Set communication port number
|
// Set communication port number
|
||||||
ucUartNumber = ucPORT;
|
xMBMCtx.ucUartNumber = ucPORT;
|
||||||
|
xMBMCtx.ulParityErrors = 0;
|
||||||
|
xMBMCtx.ulFrameErrors = 0;
|
||||||
// Configure serial communication parameters
|
// Configure serial communication parameters
|
||||||
UCHAR ucParity = UART_PARITY_DISABLE;
|
UCHAR ucParity = UART_PARITY_DISABLE;
|
||||||
UCHAR ucData = UART_DATA_8_BITS;
|
UCHAR ucData = UART_DATA_8_BITS;
|
||||||
@ -308,36 +318,35 @@ BOOL xMBMasterPortSerialInit( UCHAR ucPORT, ULONG ulBaudRate, UCHAR ucDataBits,
|
|||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
// Set UART config
|
// Set UART config
|
||||||
xErr = uart_param_config(ucUartNumber, &xUartConfig);
|
xErr = uart_param_config(xMBMCtx.ucUartNumber, &xUartConfig);
|
||||||
MB_PORT_CHECK((xErr == ESP_OK),
|
MB_PORT_CHECK((xErr == ESP_OK),
|
||||||
FALSE, "mb config failure, uart_param_config() returned (0x%x).", xErr);
|
FALSE, "mb config failure, uart_param_config() returned (0x%x).", xErr);
|
||||||
// Install UART driver, and get the queue.
|
// Install UART driver, and get the queue.
|
||||||
xErr = uart_driver_install(ucUartNumber, MB_SERIAL_BUF_SIZE, MB_SERIAL_BUF_SIZE,
|
xErr = uart_driver_install(xMBMCtx.ucUartNumber, MB_SERIAL_BUF_SIZE, MB_SERIAL_BUF_SIZE,
|
||||||
MB_QUEUE_LENGTH, &xMbUartQueue, MB_PORT_SERIAL_ISR_FLAG);
|
MB_QUEUE_LENGTH, &xMBMCtx.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);
|
||||||
// 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(xMBMCtx.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
|
// Set always timeout flag to trigger timeout interrupt even after rx fifo full
|
||||||
uart_set_always_rx_timeout(ucUartNumber, true);
|
uart_set_always_rx_timeout(xMBMCtx.ucUartNumber, true);
|
||||||
MB_PORT_CHECK((xMBMasterPortRxSemaInit()), FALSE,
|
MB_PORT_CHECK((xMBMasterPortRxSemaInit()), FALSE,
|
||||||
"mb serial RX semaphore create fail.");
|
"mb serial RX semaphore create fail.");
|
||||||
// Create a task to handle UART events
|
// Create a task to handle UART events
|
||||||
BaseType_t xStatus = xTaskCreatePinnedToCore(vUartTask, "uart_queue_task",
|
BaseType_t xStatus = xTaskCreatePinnedToCore(vUartTask, "uart_queue_task",
|
||||||
MB_SERIAL_TASK_STACK_SIZE,
|
MB_SERIAL_TASK_STACK_SIZE,
|
||||||
NULL, MB_SERIAL_TASK_PRIO,
|
NULL, MB_SERIAL_TASK_PRIO,
|
||||||
&xMbTaskHandle, MB_PORT_TASK_AFFINITY);
|
&xMBMCtx.xMbTaskHandle, MB_PORT_TASK_AFFINITY);
|
||||||
if (xStatus != pdPASS) {
|
if (xStatus != pdPASS) {
|
||||||
vTaskDelete(xMbTaskHandle);
|
vTaskDelete(xMBMCtx.xMbTaskHandle);
|
||||||
// Force exit from function with failure
|
// Force exit from function with failure
|
||||||
MB_PORT_CHECK(FALSE, FALSE,
|
MB_PORT_CHECK(FALSE, FALSE,
|
||||||
"mb stack serial task creation error. xTaskCreate() returned (0x%x).",
|
"mb stack serial task creation error. xTaskCreate() returned (0x%x).",
|
||||||
xStatus);
|
xStatus);
|
||||||
} else {
|
} else {
|
||||||
vTaskSuspend(xMbTaskHandle); // Suspend serial task while stack is not started
|
vTaskSuspend(xMBMCtx.xMbTaskHandle); // Suspend serial task while stack is not started
|
||||||
}
|
}
|
||||||
ESP_LOGD(MB_PORT_TAG,"%s Init serial.", __func__);
|
ESP_LOGD(MB_PORT_TAG,"%s Init serial.", __func__);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
@ -346,15 +355,15 @@ BOOL xMBMasterPortSerialInit( UCHAR ucPORT, ULONG ulBaudRate, UCHAR ucDataBits,
|
|||||||
void vMBMasterPortSerialClose(void)
|
void vMBMasterPortSerialClose(void)
|
||||||
{
|
{
|
||||||
vMBMasterPortRxSemaClose();
|
vMBMasterPortRxSemaClose();
|
||||||
(void)vTaskDelete(xMbTaskHandle);
|
(void)vTaskDelete(xMBMCtx.xMbTaskHandle);
|
||||||
ESP_ERROR_CHECK(uart_driver_delete(ucUartNumber));
|
ESP_ERROR_CHECK(uart_driver_delete(xMBMCtx.ucUartNumber));
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL xMBMasterPortSerialPutByte(CHAR ucByte)
|
BOOL xMBMasterPortSerialPutByte(CHAR ucByte)
|
||||||
{
|
{
|
||||||
// Send one byte to UART transmission buffer
|
// Send one byte to UART transmission buffer
|
||||||
// This function is called by Modbus stack
|
// This function is called by Modbus stack
|
||||||
UCHAR ucLength = uart_write_bytes(ucUartNumber, &ucByte, 1);
|
UCHAR ucLength = uart_write_bytes(xMBMCtx.ucUartNumber, &ucByte, 1);
|
||||||
return (ucLength == 1);
|
return (ucLength == 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -362,6 +371,6 @@ BOOL xMBMasterPortSerialPutByte(CHAR ucByte)
|
|||||||
BOOL xMBMasterPortSerialGetByte(CHAR* pucByte)
|
BOOL xMBMasterPortSerialGetByte(CHAR* pucByte)
|
||||||
{
|
{
|
||||||
assert(pucByte != NULL);
|
assert(pucByte != NULL);
|
||||||
USHORT usLength = uart_read_bytes(ucUartNumber, (uint8_t*)pucByte, 1, MB_SERIAL_RX_TOUT_TICKS);
|
USHORT usLength = uart_read_bytes(xMBMCtx.ucUartNumber, (uint8_t*)pucByte, 1, MB_SERIAL_RX_TOUT_TICKS);
|
||||||
return (usLength == 1);
|
return (usLength == 1);
|
||||||
}
|
}
|
||||||
|
@ -54,4 +54,4 @@ void vMBPortSetMode( UCHAR ucMode );
|
|||||||
PR_END_EXTERN_C
|
PR_END_EXTERN_C
|
||||||
#endif /* __cplusplus */
|
#endif /* __cplusplus */
|
||||||
|
|
||||||
#endif
|
#endif
|
@ -256,7 +256,7 @@ static esp_err_t master_init(void)
|
|||||||
.mode = MB_MODE_RTU,
|
.mode = MB_MODE_RTU,
|
||||||
#endif
|
#endif
|
||||||
.baudrate = MB_DEV_SPEED,
|
.baudrate = MB_DEV_SPEED,
|
||||||
.parity = MB_PARITY_NONE
|
.parity = UART_PARITY_EVEN
|
||||||
};
|
};
|
||||||
void* master_handler = NULL;
|
void* master_handler = NULL;
|
||||||
|
|
||||||
|
@ -108,7 +108,7 @@ void app_main(void)
|
|||||||
comm_info.slave_addr = MB_SLAVE_ADDR;
|
comm_info.slave_addr = MB_SLAVE_ADDR;
|
||||||
comm_info.port = MB_PORT_NUM;
|
comm_info.port = MB_PORT_NUM;
|
||||||
comm_info.baudrate = MB_DEV_SPEED;
|
comm_info.baudrate = MB_DEV_SPEED;
|
||||||
comm_info.parity = MB_PARITY_NONE;
|
comm_info.parity = UART_PARITY_EVEN;
|
||||||
ESP_ERROR_CHECK(mbc_slave_setup((void*)&comm_info));
|
ESP_ERROR_CHECK(mbc_slave_setup((void*)&comm_info));
|
||||||
|
|
||||||
// The code below initializes Modbus register area descriptors
|
// The code below initializes Modbus register area descriptors
|
||||||
|
Reference in New Issue
Block a user