From baa0aad20e20f9b0f82b780c7a6ebebaae204c7a Mon Sep 17 00:00:00 2001 From: aleks Date: Thu, 10 Dec 2020 17:30:08 +0100 Subject: [PATCH 1/4] freemodbus: fix modbus rs485 rts enable fail v42 --- components/freemodbus/port/portserial.c | 2 +- components/freemodbus/port/portserial_m.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/components/freemodbus/port/portserial.c b/components/freemodbus/port/portserial.c index ccbb4bd284..d3f1455313 100644 --- a/components/freemodbus/port/portserial.c +++ b/components/freemodbus/port/portserial.c @@ -120,7 +120,7 @@ BOOL xMBPortSerialTxPoll(void) } ESP_LOGD(TAG, "MB_TX_buffer send: (%d) bytes\n", (uint16_t)usCount); // 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_idle_polling(ucUartNumber); vMBPortSerialEnable(TRUE, FALSE); MB_PORT_CHECK((xTxStatus == ESP_OK), FALSE, "mb serial sent buffer failure."); return TRUE; diff --git a/components/freemodbus/port/portserial_m.c b/components/freemodbus/port/portserial_m.c index 80c2306c33..8bcd0f012a 100644 --- a/components/freemodbus/port/portserial_m.c +++ b/components/freemodbus/port/portserial_m.c @@ -122,8 +122,8 @@ BOOL xMBMasterPortSerialTxPoll(void) } ESP_LOGD(TAG, "MB_TX_buffer sent: (%d) bytes.", (uint16_t)(usCount - 1)); // Waits while UART sending the packet - esp_err_t xTxStatus = uart_wait_tx_done(ucUartNumber, MB_SERIAL_TX_TOUT_TICKS); - vMBMasterPortSerialEnable( TRUE, FALSE ); + esp_err_t xTxStatus = uart_wait_tx_idle_polling(ucUartNumber); + vMBMasterPortSerialEnable(TRUE, FALSE); MB_PORT_CHECK((xTxStatus == ESP_OK), FALSE, "mb serial sent buffer failure."); return TRUE; } From bc1f50dc0faa7909e48b9c620497f2a5930cb37f Mon Sep 17 00:00:00 2001 From: aleks Date: Mon, 26 Jul 2021 07:40:10 +0200 Subject: [PATCH 2/4] freemodbus: fix rts enable fail when transmit frame --- components/freemodbus/port/port.h | 8 ++++---- components/freemodbus/port/portserial.c | 2 +- components/freemodbus/port/portserial_m.c | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/components/freemodbus/port/port.h b/components/freemodbus/port/port.h index 2115db2082..7c29d14cf2 100644 --- a/components/freemodbus/port/port.h +++ b/components/freemodbus/port/port.h @@ -65,10 +65,10 @@ #define MB_SERIAL_BUF_SIZE (CONFIG_FMB_SERIAL_BUF_SIZE) // common definitions for serial port implementations -#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_RX_TOUT_MS (1) -#define MB_SERIAL_RX_TOUT_TICKS (pdMS_TO_TICKS(MB_SERIAL_RX_TOUT_MS)) // timeout for receive +#define MB_SERIAL_TX_TOUT_MS (2200) // maximum time for transmission of longest allowed frame buffer +#define MB_SERIAL_TX_TOUT_TICKS pdMS_TO_TICKS(MB_SERIAL_TX_TOUT_MS) // timeout for transmission +#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) diff --git a/components/freemodbus/port/portserial.c b/components/freemodbus/port/portserial.c index d3f1455313..ccbb4bd284 100644 --- a/components/freemodbus/port/portserial.c +++ b/components/freemodbus/port/portserial.c @@ -120,7 +120,7 @@ BOOL xMBPortSerialTxPoll(void) } ESP_LOGD(TAG, "MB_TX_buffer send: (%d) bytes\n", (uint16_t)usCount); // Waits while UART sending the packet - esp_err_t xTxStatus = uart_wait_tx_idle_polling(ucUartNumber); + esp_err_t xTxStatus = uart_wait_tx_done(ucUartNumber, MB_SERIAL_TX_TOUT_TICKS); vMBPortSerialEnable(TRUE, FALSE); MB_PORT_CHECK((xTxStatus == ESP_OK), FALSE, "mb serial sent buffer failure."); return TRUE; diff --git a/components/freemodbus/port/portserial_m.c b/components/freemodbus/port/portserial_m.c index 8bcd0f012a..00021117e5 100644 --- a/components/freemodbus/port/portserial_m.c +++ b/components/freemodbus/port/portserial_m.c @@ -122,7 +122,7 @@ BOOL xMBMasterPortSerialTxPoll(void) } ESP_LOGD(TAG, "MB_TX_buffer sent: (%d) bytes.", (uint16_t)(usCount - 1)); // Waits while UART sending the packet - esp_err_t xTxStatus = uart_wait_tx_idle_polling(ucUartNumber); + esp_err_t xTxStatus = uart_wait_tx_done(ucUartNumber, MB_SERIAL_TX_TOUT_TICKS); vMBMasterPortSerialEnable(TRUE, FALSE); MB_PORT_CHECK((xTxStatus == ESP_OK), FALSE, "mb serial sent buffer failure."); return TRUE; From a6e524418d12d2203487361220b0c308042a257a Mon Sep 17 00:00:00 2001 From: aleks Date: Mon, 26 Jul 2021 07:50:53 +0200 Subject: [PATCH 3/4] freemodbus: fix uart_wait_tx_done() reenable tx_done interrupt --- components/driver/uart.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/components/driver/uart.c b/components/driver/uart.c index 2a0392d39f..cf0401535a 100644 --- a/components/driver/uart.c +++ b/components/driver/uart.c @@ -1126,7 +1126,6 @@ esp_err_t uart_wait_tx_done(uart_port_t uart_num, TickType_t ticks_to_wait) xSemaphoreGive(p_uart_obj[uart_num]->tx_mux); return ESP_OK; } - uart_hal_clr_intsts_mask(&(uart_context[uart_num].hal), UART_INTR_TX_DONE); UART_ENTER_CRITICAL(&(uart_context[uart_num].spinlock)); uart_hal_ena_intr_mask(&(uart_context[uart_num].hal), UART_INTR_TX_DONE); UART_EXIT_CRITICAL(&(uart_context[uart_num].spinlock)); @@ -1140,9 +1139,7 @@ esp_err_t uart_wait_tx_done(uart_port_t uart_num, TickType_t ticks_to_wait) //take 2nd tx_done_sem, wait given from ISR res = xSemaphoreTake(p_uart_obj[uart_num]->tx_done_sem, (portTickType)ticks_to_wait); if (res == pdFALSE) { - UART_ENTER_CRITICAL(&(uart_context[uart_num].spinlock)); - uart_hal_disable_intr_mask(&(uart_context[uart_num].hal), UART_INTR_TX_DONE); - UART_EXIT_CRITICAL(&(uart_context[uart_num].spinlock)); + // The TX_DONE interrupt will be disabled in ISR xSemaphoreGive(p_uart_obj[uart_num]->tx_mux); return ESP_ERR_TIMEOUT; } From b8e62ce4b2c9beb871d0753a38d5a30915c6da15 Mon Sep 17 00:00:00 2001 From: Song Ruo Jing Date: Thu, 22 Sep 2022 14:21:01 +0800 Subject: [PATCH 4/4] uart: Fix unwanted processing of TX_DONE interrupt immediately after calling uart_wait_tx_done() In previous transmission(s), the TX_DONE interrupt raw bit may be raised, but never been cleared. TX_DONE interrrupt status bit should be cleared before enabling it to check the new transmission. --- components/driver/uart.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/components/driver/uart.c b/components/driver/uart.c index cf0401535a..6ed81321b6 100644 --- a/components/driver/uart.c +++ b/components/driver/uart.c @@ -1126,6 +1126,9 @@ esp_err_t uart_wait_tx_done(uart_port_t uart_num, TickType_t ticks_to_wait) xSemaphoreGive(p_uart_obj[uart_num]->tx_mux); return ESP_OK; } + if (!UART_IS_MODE_SET(uart_num, UART_MODE_RS485_HALF_DUPLEX)) { + uart_hal_clr_intsts_mask(&(uart_context[uart_num].hal), UART_INTR_TX_DONE); + } UART_ENTER_CRITICAL(&(uart_context[uart_num].spinlock)); uart_hal_ena_intr_mask(&(uart_context[uart_num].hal), UART_INTR_TX_DONE); UART_EXIT_CRITICAL(&(uart_context[uart_num].spinlock));