mirror of
https://github.com/espressif/esp-idf.git
synced 2025-08-04 13:14:32 +02:00
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()
This commit is contained in:
committed by
Michael (XIAO Xufeng)
parent
135aa51d06
commit
3abdd2207d
@@ -70,6 +70,8 @@ typedef enum {
|
|||||||
typedef struct {
|
typedef struct {
|
||||||
uart_event_type_t type; /*!< UART event type */
|
uart_event_type_t type; /*!< UART event type */
|
||||||
size_t size; /*!< UART data size for UART_DATA event*/
|
size_t size; /*!< UART data size for UART_DATA event*/
|
||||||
|
bool timeout_flag; /*!< UART data read timeout flag for UART_DATA event (no new data received during configured RX TOUT)*/
|
||||||
|
/*!< If the event is caused by FIFO-full interrupt, then there will be no event with the timeout flag before the next byte coming.*/
|
||||||
} uart_event_t;
|
} uart_event_t;
|
||||||
|
|
||||||
typedef intr_handle_t uart_isr_handle_t;
|
typedef intr_handle_t uart_isr_handle_t;
|
||||||
@@ -845,6 +847,21 @@ esp_err_t uart_wait_tx_idle_polling(uart_port_t uart_num);
|
|||||||
*/
|
*/
|
||||||
esp_err_t uart_set_loop_back(uart_port_t uart_num, bool loop_back_en);
|
esp_err_t uart_set_loop_back(uart_port_t uart_num, bool loop_back_en);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Configure behavior of UART RX timeout interrupt.
|
||||||
|
*
|
||||||
|
* When always_rx_timeout is true, timeout interrupt is triggered even if FIFO is full.
|
||||||
|
* This function can cause extra timeout interrupts triggered only to send the timeout event.
|
||||||
|
* Call this function only if you want to ensure timeout interrupt will always happen after a byte stream.
|
||||||
|
*
|
||||||
|
* @param uart_num UART number
|
||||||
|
* @param always_rx_timeout_en Set to false enable the default behavior of timeout interrupt,
|
||||||
|
* set it to true to always trigger timeout interrupt.
|
||||||
|
*
|
||||||
|
* * @return None
|
||||||
|
*/
|
||||||
|
void uart_set_always_rx_timeout(uart_port_t uart_num, bool always_rx_timeout_en);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@@ -104,6 +104,7 @@ typedef struct {
|
|||||||
intr_handle_t intr_handle; /*!< UART interrupt handle*/
|
intr_handle_t intr_handle; /*!< UART interrupt handle*/
|
||||||
uart_mode_t uart_mode; /*!< UART controller actual mode set by uart_set_mode() */
|
uart_mode_t uart_mode; /*!< UART controller actual mode set by uart_set_mode() */
|
||||||
bool coll_det_flg; /*!< UART collision detection flag */
|
bool coll_det_flg; /*!< UART collision detection flag */
|
||||||
|
bool rx_always_timeout_flg; /*!< UART always detect rx timeout flag */
|
||||||
|
|
||||||
//rx parameters
|
//rx parameters
|
||||||
int rx_buffered_len; /*!< UART cached data length */
|
int rx_buffered_len; /*!< UART cached data length */
|
||||||
@@ -808,6 +809,10 @@ static void UART_ISR_ATTR uart_rx_intr_handler_default(void *param)
|
|||||||
pat_flg = 0;
|
pat_flg = 0;
|
||||||
}
|
}
|
||||||
if (p_uart->rx_buffer_full_flg == false) {
|
if (p_uart->rx_buffer_full_flg == false) {
|
||||||
|
rx_fifo_len = uart_hal_get_rxfifo_len(&(uart_context[uart_num].hal));
|
||||||
|
if ((p_uart_obj[uart_num]->rx_always_timeout_flg) && !(uart_intr_status & UART_INTR_RXFIFO_TOUT)) {
|
||||||
|
rx_fifo_len--; // leave one byte in the fifo in order to trigger uart_intr_rxfifo_tout
|
||||||
|
}
|
||||||
uart_hal_read_rxfifo(&(uart_context[uart_num].hal), p_uart->rx_data_buf, &rx_fifo_len);
|
uart_hal_read_rxfifo(&(uart_context[uart_num].hal), p_uart->rx_data_buf, &rx_fifo_len);
|
||||||
uint8_t pat_chr = 0;
|
uint8_t pat_chr = 0;
|
||||||
uint8_t pat_num = 0;
|
uint8_t pat_num = 0;
|
||||||
@@ -825,6 +830,7 @@ static void UART_ISR_ATTR uart_rx_intr_handler_default(void *param)
|
|||||||
uart_hal_clr_intsts_mask(&(uart_context[uart_num].hal), UART_INTR_RXFIFO_TOUT | UART_INTR_RXFIFO_FULL);
|
uart_hal_clr_intsts_mask(&(uart_context[uart_num].hal), UART_INTR_RXFIFO_TOUT | UART_INTR_RXFIFO_FULL);
|
||||||
uart_event.type = UART_DATA;
|
uart_event.type = UART_DATA;
|
||||||
uart_event.size = rx_fifo_len;
|
uart_event.size = rx_fifo_len;
|
||||||
|
uart_event.timeout_flag = (uart_intr_status & UART_INTR_RXFIFO_TOUT) ? true : false;
|
||||||
UART_ENTER_CRITICAL_ISR(&uart_selectlock);
|
UART_ENTER_CRITICAL_ISR(&uart_selectlock);
|
||||||
if (p_uart->uart_select_notif_callback) {
|
if (p_uart->uart_select_notif_callback) {
|
||||||
p_uart->uart_select_notif_callback(uart_num, UART_SELECT_READ_NOTIF, &HPTaskAwoken);
|
p_uart->uart_select_notif_callback(uart_num, UART_SELECT_READ_NOTIF, &HPTaskAwoken);
|
||||||
@@ -1296,6 +1302,7 @@ esp_err_t uart_driver_install(uart_port_t uart_num, int rx_buffer_size, int tx_b
|
|||||||
p_uart_obj[uart_num]->uart_num = uart_num;
|
p_uart_obj[uart_num]->uart_num = uart_num;
|
||||||
p_uart_obj[uart_num]->uart_mode = UART_MODE_UART;
|
p_uart_obj[uart_num]->uart_mode = UART_MODE_UART;
|
||||||
p_uart_obj[uart_num]->coll_det_flg = false;
|
p_uart_obj[uart_num]->coll_det_flg = false;
|
||||||
|
p_uart_obj[uart_num]->rx_always_timeout_flg = false;
|
||||||
p_uart_obj[uart_num]->tx_fifo_sem = xSemaphoreCreateBinary();
|
p_uart_obj[uart_num]->tx_fifo_sem = xSemaphoreCreateBinary();
|
||||||
xSemaphoreGive(p_uart_obj[uart_num]->tx_fifo_sem);
|
xSemaphoreGive(p_uart_obj[uart_num]->tx_fifo_sem);
|
||||||
p_uart_obj[uart_num]->tx_done_sem = xSemaphoreCreateBinary();
|
p_uart_obj[uart_num]->tx_done_sem = xSemaphoreCreateBinary();
|
||||||
@@ -1342,7 +1349,7 @@ esp_err_t uart_driver_install(uart_port_t uart_num, int rx_buffer_size, int tx_b
|
|||||||
.intr_enable_mask = UART_INTR_CONFIG_FLAG,
|
.intr_enable_mask = UART_INTR_CONFIG_FLAG,
|
||||||
.rxfifo_full_thresh = UART_FULL_THRESH_DEFAULT,
|
.rxfifo_full_thresh = UART_FULL_THRESH_DEFAULT,
|
||||||
.rx_timeout_thresh = UART_TOUT_THRESH_DEFAULT,
|
.rx_timeout_thresh = UART_TOUT_THRESH_DEFAULT,
|
||||||
.txfifo_empty_intr_thresh = UART_EMPTY_THRESH_DEFAULT
|
.txfifo_empty_intr_thresh = UART_EMPTY_THRESH_DEFAULT,
|
||||||
};
|
};
|
||||||
uart_module_enable(uart_num);
|
uart_module_enable(uart_num);
|
||||||
uart_hal_disable_intr_mask(&(uart_context[uart_num].hal), UART_INTR_MASK);
|
uart_hal_disable_intr_mask(&(uart_context[uart_num].hal), UART_INTR_MASK);
|
||||||
@@ -1549,3 +1556,13 @@ esp_err_t uart_set_loop_back(uart_port_t uart_num, bool loop_back_en)
|
|||||||
uart_hal_set_loop_back(&(uart_context[uart_num].hal), loop_back_en);
|
uart_hal_set_loop_back(&(uart_context[uart_num].hal), loop_back_en);
|
||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void uart_set_always_rx_timeout(uart_port_t uart_num, bool always_rx_timeout)
|
||||||
|
{
|
||||||
|
uint16_t rx_tout = uart_hal_get_rx_tout_thr(&(uart_context[uart_num].hal));
|
||||||
|
if (rx_tout) {
|
||||||
|
p_uart_obj[uart_num]->rx_always_timeout_flg = always_rx_timeout;
|
||||||
|
} else {
|
||||||
|
p_uart_obj[uart_num]->rx_always_timeout_flg = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -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
|
||||||
@@ -80,7 +80,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;
|
||||||
@@ -121,7 +121,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));
|
||||||
@@ -132,7 +132,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));
|
||||||
|
@@ -127,13 +127,14 @@ typedef struct {
|
|||||||
/**
|
/**
|
||||||
* @brief Read data from the UART rxfifo
|
* @brief Read data from the UART rxfifo
|
||||||
*
|
*
|
||||||
* @param hal Context of the HAL layer
|
* @param[in] hal Context of the HAL layer
|
||||||
* @param buf Pointer to the buffer used to store the read data. The buffer size should be large than 128 byts
|
* @param[in] buf Pointer to the buffer used to store the read data. The buffer size should be large than 128 byte
|
||||||
* @param rd_len The length has been read out from the rxfifo
|
* @param[inout] inout_rd_len As input, the size of output buffer to read (set to 0 to read all available data).
|
||||||
|
* As output, returns the actual size written into the output buffer.
|
||||||
*
|
*
|
||||||
* @return None
|
* @return None
|
||||||
*/
|
*/
|
||||||
void uart_hal_read_rxfifo(uart_hal_context_t *hal, uint8_t *buf, int *rd_len);
|
void uart_hal_read_rxfifo(uart_hal_context_t *hal, uint8_t *buf, int *inout_rd_len);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Write data into the UART txfifo
|
* @brief Write data into the UART txfifo
|
||||||
@@ -448,6 +449,24 @@ uint8_t uart_hal_get_symb_len(uart_hal_context_t *hal);
|
|||||||
*/
|
*/
|
||||||
uint16_t uart_hal_get_max_rx_timeout_thrd(uart_hal_context_t *hal);
|
uint16_t uart_hal_get_max_rx_timeout_thrd(uart_hal_context_t *hal);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the timeout threshold value set for receiver.
|
||||||
|
*
|
||||||
|
* @param hw Beginning address of the peripheral registers.
|
||||||
|
*
|
||||||
|
* @return tout_thr The timeout value. If timeout is disabled then returns 0.
|
||||||
|
*/
|
||||||
|
#define uart_hal_get_rx_tout_thr(hal) uart_ll_get_rx_tout_thr((hal)->dev)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the length of readable data in UART rxfifo.
|
||||||
|
*
|
||||||
|
* @param hw Beginning address of the peripheral registers.
|
||||||
|
*
|
||||||
|
* @return The readable data length in rxfifo.
|
||||||
|
*/
|
||||||
|
#define uart_hal_get_rxfifo_len(hal) uart_ll_get_rxfifo_len((hal)->dev)
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@@ -807,6 +807,26 @@ static inline void uart_ll_set_rx_tout(uart_dev_t *hw, uint16_t tout_thr)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the timeout value for receiver receiving a byte.
|
||||||
|
*
|
||||||
|
* @param hw Beginning address of the peripheral registers.
|
||||||
|
*
|
||||||
|
* @return tout_thr The timeout threshold value. If timeout feature is disabled returns 0.
|
||||||
|
*/
|
||||||
|
static inline uint16_t uart_ll_get_rx_tout_thr(uart_dev_t *hw)
|
||||||
|
{
|
||||||
|
uint16_t tout_thrd = 0;
|
||||||
|
if (hw->conf1.rx_tout_en > 0) {
|
||||||
|
if (hw->conf0.tick_ref_always_on == 0) {
|
||||||
|
tout_thrd = (uint16_t)(hw->conf1.rx_tout_thrhd / UART_LL_TOUT_REF_FACTOR_DEFAULT);
|
||||||
|
} else {
|
||||||
|
tout_thrd = (uint16_t)(hw->conf1.rx_tout_thrhd << 3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return tout_thrd;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get UART maximum timeout threshold.
|
* @brief Get UART maximum timeout threshold.
|
||||||
*
|
*
|
||||||
@@ -816,13 +836,13 @@ static inline void uart_ll_set_rx_tout(uart_dev_t *hw, uint16_t tout_thr)
|
|||||||
*/
|
*/
|
||||||
static inline uint16_t uart_ll_max_tout_thrd(uart_dev_t *hw)
|
static inline uint16_t uart_ll_max_tout_thrd(uart_dev_t *hw)
|
||||||
{
|
{
|
||||||
uint16_t tout_sym = 0;
|
uint16_t tout_thrd = 0;
|
||||||
if (hw->conf0.tick_ref_always_on == 0) {
|
if (hw->conf0.tick_ref_always_on == 0) {
|
||||||
tout_sym = (uint16_t)(UART_RX_TOUT_THRHD_V / UART_LL_TOUT_REF_FACTOR_DEFAULT);
|
tout_thrd = (uint16_t)(UART_RX_TOUT_THRHD_V / UART_LL_TOUT_REF_FACTOR_DEFAULT);
|
||||||
} else {
|
} else {
|
||||||
tout_sym = (uint16_t)(UART_RX_TOUT_THRHD_V << 3);
|
tout_thrd = (uint16_t)(UART_RX_TOUT_THRHD_V << 3);
|
||||||
}
|
}
|
||||||
return tout_sym;
|
return tout_thrd;
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef UART_LL_TOUT_REF_FACTOR_DEFAULT
|
#undef UART_LL_TOUT_REF_FACTOR_DEFAULT
|
||||||
|
@@ -772,6 +772,22 @@ static inline void uart_ll_set_rx_tout(uart_dev_t *hw, uint16_t tout_thrd)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the timeout value for receiver receiving a byte.
|
||||||
|
*
|
||||||
|
* @param hw Beginning address of the peripheral registers.
|
||||||
|
*
|
||||||
|
* @return tout_thr The timeout threshold value. If timeout feature is disabled returns 0.
|
||||||
|
*/
|
||||||
|
static inline uint16_t uart_ll_get_rx_tout_thr(uart_dev_t *hw)
|
||||||
|
{
|
||||||
|
uint16_t tout_thrd = 0;
|
||||||
|
if(hw->conf1.rx_tout_en > 0) {
|
||||||
|
tout_thrd = hw->mem_conf.rx_tout_thrhd;
|
||||||
|
}
|
||||||
|
return tout_thrd;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get UART maximum timeout threshold.
|
* @brief Get UART maximum timeout threshold.
|
||||||
*
|
*
|
||||||
|
@@ -40,9 +40,9 @@ void uart_hal_write_txfifo(uart_hal_context_t *hal, const uint8_t *buf, uint32_t
|
|||||||
uart_ll_write_txfifo(hal->dev, buf, fill_len);
|
uart_ll_write_txfifo(hal->dev, buf, fill_len);
|
||||||
}
|
}
|
||||||
|
|
||||||
void uart_hal_read_rxfifo(uart_hal_context_t *hal, uint8_t *buf, int *rd_len)
|
void uart_hal_read_rxfifo(uart_hal_context_t *hal, uint8_t *buf, int *inout_rd_len)
|
||||||
{
|
{
|
||||||
uint16_t read_len = uart_ll_get_rxfifo_len(hal->dev);
|
uint16_t read_len = (*inout_rd_len > 0) ? *inout_rd_len : uart_ll_get_rxfifo_len(hal->dev);
|
||||||
*rd_len = read_len;
|
*inout_rd_len = read_len;
|
||||||
uart_ll_read_rxfifo(hal->dev, buf, read_len);
|
uart_ll_read_rxfifo(hal->dev, buf, read_len);
|
||||||
}
|
}
|
||||||
|
@@ -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