serial port settings fixed

This commit is contained in:
Bogdan Pilyugin 2025-01-23 20:10:39 +02:00
parent e8e8876686
commit 94af947d1f
2 changed files with 100 additions and 68 deletions

View File

@ -552,7 +552,7 @@ const rest_var_t SystemVariables[] =
{ 0, "serial_enab", &SysConfig.serialSettings.Flags.IsSerialEnabled, VAR_BOOL, RW, 0, 1 }, { 0, "serial_enab", &SysConfig.serialSettings.Flags.IsSerialEnabled, VAR_BOOL, RW, 0, 1 },
{ 0, "serial_bridge", &SysConfig.serialSettings.Flags.IsBridgeEnabled, VAR_BOOL, RW, 0, 1 }, { 0, "serial_bridge", &SysConfig.serialSettings.Flags.IsBridgeEnabled, VAR_BOOL, RW, 0, 1 },
{ 0, "serial_mode", &funct_serial_mode, VAR_FUNCT, R, 1, 2 }, { 0, "serial_mode", &funct_serial_mode, VAR_FUNCT, R, 1, 2 },
{ 0, "serial_baud", &SysConfig.serialSettings.BaudRate, VAR_INT, RW, 1200, 4096000 }, { 0, "serial_baud", &SysConfig.serialSettings.BaudRate, VAR_INT, RW, 1200, 8192000 },
{ 0, "serial_bits", &SysConfig.serialSettings.DataBits, VAR_INT, RW, 0, 3 }, { 0, "serial_bits", &SysConfig.serialSettings.DataBits, VAR_INT, RW, 0, 3 },
{ 0, "serial_parity", &SysConfig.serialSettings.Parity, VAR_INT, RW, 0, 3 }, { 0, "serial_parity", &SysConfig.serialSettings.Parity, VAR_INT, RW, 0, 3 },

View File

@ -38,7 +38,7 @@
#include "driver/gpio.h" #include "driver/gpio.h"
#define TAG "serial_port" #define TAG "serial_port"
#define UART_READ_TOUT (100) // 3.5T * 8 = 28 ticks, TOUT=3 -> ~24..33 ticks #define UART_READ_TOUT (80) // 3.5T * 8 = 28 ticks, TOUT=3 -> ~24..33 ticks
#define PATTERN_CHR_NUM (3) /*!< Set the number of consecutive and identical characters received by receiver which defines a UART pattern*/ #define PATTERN_CHR_NUM (3) /*!< Set the number of consecutive and identical characters received by receiver which defines a UART pattern*/
#define UART_TX_QUEUE_SIZE (5) #define UART_TX_QUEUE_SIZE (5)
@ -104,24 +104,23 @@ void serial_RX_task(void *arg)
for (;;) for (;;)
{ {
//Waiting for UART event. // Waiting for UART event.
if (xQueueReceive(uart_event_queue, (void*) &event, portMAX_DELAY)) if (xQueueReceive(uart_event_queue, (void *)&event, portMAX_DELAY))
{ {
#if UART_DEBUG_MODE == 1 #if UART_DEBUG_MODE == 1
ESP_LOGI(TAG, "uart[%d] event:%d", CONFIG_UART_PORT_NUM, event.type); ESP_LOGI(TAG, "uart[%d] event:%d", CONFIG_UART_PORT_NUM, event.type);
#endif #endif
switch (event.type) switch (event.type)
{ {
//Event of UART receving data // Event of UART receving data
/*We'd better handler data event fast, there would be much more data events than /*We'd better handler data event fast, there would be much more data events than
other types of events. If we take too much time on data event, the queue might other types of events. If we take too much time on data event, the queue might
be full.*/ be full.*/
case UART_DATA: case UART_DATA:
if (event.timeout_flag) if (event.timeout_flag)
{ {
bzero(rxbuf, CONFIG_WEBGUIAPP_UART_BUF_SIZE); bzero(rxbuf, CONFIG_WEBGUIAPP_UART_BUF_SIZE);
uart_get_buffered_data_len(CONFIG_WEBGUIAPP_UART_PORT_NUM, (size_t*) &buffered_size); uart_get_buffered_data_len(CONFIG_WEBGUIAPP_UART_PORT_NUM, (size_t *)&buffered_size);
if (buffered_size) if (buffered_size)
{ {
uart_read_bytes(CONFIG_WEBGUIAPP_UART_PORT_NUM, rxbuf, buffered_size, 100); uart_read_bytes(CONFIG_WEBGUIAPP_UART_PORT_NUM, rxbuf, buffered_size, 100);
@ -136,11 +135,10 @@ void serial_RX_task(void *arg)
} }
else else
ReceiveHandlerAPI(); ReceiveHandlerAPI();
} }
} }
break; break;
//Event of HW FIFO overflow detected // Event of HW FIFO overflow detected
case UART_FIFO_OVF: case UART_FIFO_OVF:
#if UART_DEBUG_MODE == 1 #if UART_DEBUG_MODE == 1
@ -152,7 +150,7 @@ void serial_RX_task(void *arg)
uart_flush_input(CONFIG_WEBGUIAPP_UART_PORT_NUM); uart_flush_input(CONFIG_WEBGUIAPP_UART_PORT_NUM);
xQueueReset(uart_event_queue); xQueueReset(uart_event_queue);
break; break;
//Event of UART ring buffer full // Event of UART ring buffer full
case UART_BUFFER_FULL: case UART_BUFFER_FULL:
ESP_LOGE(TAG, "ring buffer full"); ESP_LOGE(TAG, "ring buffer full");
// If buffer full happened, you should consider encreasing your buffer size // If buffer full happened, you should consider encreasing your buffer size
@ -160,27 +158,27 @@ void serial_RX_task(void *arg)
uart_flush_input(CONFIG_WEBGUIAPP_UART_PORT_NUM); uart_flush_input(CONFIG_WEBGUIAPP_UART_PORT_NUM);
xQueueReset(uart_event_queue); xQueueReset(uart_event_queue);
break; break;
//Event of UART RX break detected // Event of UART RX break detected
case UART_BREAK: case UART_BREAK:
#if UART_DEBUG_MODE == 1 #if UART_DEBUG_MODE == 1
ESP_LOGI(TAG, "uart rx break"); ESP_LOGI(TAG, "uart rx break");
#endif #endif
break; break;
//Event of UART parity check error // Event of UART parity check error
case UART_PARITY_ERR: case UART_PARITY_ERR:
ESP_LOGE(TAG, "uart parity error"); ESP_LOGE(TAG, "uart parity error");
break; break;
//Event of UART frame error // Event of UART frame error
case UART_FRAME_ERR: case UART_FRAME_ERR:
ESP_LOGE(TAG, "uart frame error"); ESP_LOGE(TAG, "uart frame error");
break; break;
//UART_PATTERN_DET // UART_PATTERN_DET
case UART_PATTERN_DET: case UART_PATTERN_DET:
uart_get_buffered_data_len(CONFIG_WEBGUIAPP_UART_PORT_NUM, (size_t*) &buffered_size); uart_get_buffered_data_len(CONFIG_WEBGUIAPP_UART_PORT_NUM, (size_t *)&buffered_size);
int pos = uart_pattern_pop_pos(CONFIG_WEBGUIAPP_UART_PORT_NUM); int pos = uart_pattern_pop_pos(CONFIG_WEBGUIAPP_UART_PORT_NUM);
#if UART_DEBUG_MODE == 1 #if UART_DEBUG_MODE == 1
ESP_LOGI(TAG, "[UART PATTERN DETECTED] pos: %d, buffered size: %d", (int )pos, (int )buffered_size); ESP_LOGI(TAG, "[UART PATTERN DETECTED] pos: %d, buffered size: %d", (int)pos, (int)buffered_size);
#endif #endif
if (pos == -1) if (pos == -1)
{ {
@ -202,7 +200,7 @@ void serial_RX_task(void *arg)
} }
break; break;
//Others // Others
default: default:
ESP_LOGW(TAG, "uart event type: %d", event.type); ESP_LOGW(TAG, "uart event type: %d", event.type);
break; break;
@ -218,8 +216,7 @@ void static serial_TX_task(void *arg)
while (1) while (1)
{ {
xQueueReceive(UARTtxQueueHandle, &DSS, portMAX_DELAY); xQueueReceive(UARTtxQueueHandle, &DSS, portMAX_DELAY);
if (uart_write_bytes(CONFIG_WEBGUIAPP_UART_PORT_NUM, DSS.raw_data_ptr, DSS.data_length) if (uart_write_bytes(CONFIG_WEBGUIAPP_UART_PORT_NUM, DSS.raw_data_ptr, DSS.data_length) != DSS.data_length)
!= DSS.data_length)
ESP_LOGE(TAG, "RS485 write data failure"); ESP_LOGE(TAG, "RS485 write data failure");
free(DSS.raw_data_ptr); free(DSS.raw_data_ptr);
if (uart_wait_tx_done(CONFIG_WEBGUIAPP_UART_PORT_NUM, pdMS_TO_TICKS(1000)) != ESP_OK) if (uart_wait_tx_done(CONFIG_WEBGUIAPP_UART_PORT_NUM, pdMS_TO_TICKS(1000)) != ESP_OK)
@ -238,43 +235,78 @@ void InitSerialPort(void)
.source_clk = UART_SCLK_APB, .source_clk = UART_SCLK_APB,
}; };
//uart_config.data_bits = (uint8_t) GetSysConf()->serialSettings.DataBits; //uart_config.data_bits = (uint8_t)GetSysConf()->serialSettings.DataBits;
//uart_config.parity = (uint8_t) GetSysConf()->serialSettings.Parity;
//uart_config.stop_bits = (uint8_t) GetSysConf()->serialSettings.StopBits;
ESP_LOGI(TAG, "UART data_bits:%d parity:%d stop_bits:%d", switch (GetSysConf()->serialSettings.DataBits)
GetSysConf()->serialSettings.DataBits, {
GetSysConf()->serialSettings.Parity, case 0:
GetSysConf()->serialSettings.StopBits); uart_config.data_bits = UART_DATA_5_BITS;
break;
case 1:
uart_config.data_bits = UART_DATA_6_BITS;
break;
case 2:
uart_config.data_bits = UART_DATA_7_BITS;
break;
case 3:
uart_config.data_bits = UART_DATA_8_BITS;
break;
}
ESP_ERROR_CHECK(
uart_driver_install(CONFIG_WEBGUIAPP_UART_PORT_NUM, CONFIG_WEBGUIAPP_UART_BUF_SIZE * 2, 0, 20, &uart_event_queue, 0)); switch (GetSysConf()->serialSettings.Parity)
ESP_ERROR_CHECK(uart_param_config(CONFIG_WEBGUIAPP_UART_PORT_NUM, &uart_config)); {
ESP_ERROR_CHECK(uart_set_pin(CONFIG_WEBGUIAPP_UART_PORT_NUM, case 0:
CONFIG_WEBGUIAPP_UART_TXD, CONFIG_WEBGUIAPP_UART_RXD, CONFIG_WEBGUIAPP_UART_RTS, -1)); uart_config.parity = UART_PARITY_DISABLE;
break;
case 2:
uart_config.parity = UART_PARITY_EVEN;
break;
case 3:
uart_config.parity = UART_PARITY_ODD;
break;
}
switch (GetSysConf()->serialSettings.StopBits)
{
case 1:
uart_config.stop_bits = UART_STOP_BITS_1;
break;
case 2:
uart_config.stop_bits = UART_STOP_BITS_1_5;
break;
case 3:
uart_config.stop_bits = UART_STOP_BITS_2;
break;
}
// uart_config.stop_bits = (uint8_t) GetSysConf()->serialSettings.StopBits;
ESP_LOGI(TAG, "UART data_bits:%d parity:%d stop_bits:%d", GetSysConf()->serialSettings.DataBits, GetSysConf()->serialSettings.Parity, GetSysConf()->serialSettings.StopBits);
ESP_ERROR_CHECK_WITHOUT_ABORT(uart_driver_install(CONFIG_WEBGUIAPP_UART_PORT_NUM, CONFIG_WEBGUIAPP_UART_BUF_SIZE * 2, 0, 20, &uart_event_queue, 0));
ESP_ERROR_CHECK_WITHOUT_ABORT(uart_param_config(CONFIG_WEBGUIAPP_UART_PORT_NUM, &uart_config));
ESP_ERROR_CHECK_WITHOUT_ABORT(uart_set_pin(CONFIG_WEBGUIAPP_UART_PORT_NUM, CONFIG_WEBGUIAPP_UART_TXD, CONFIG_WEBGUIAPP_UART_RXD, CONFIG_WEBGUIAPP_UART_RTS, -1));
#ifdef CONFIG_WEBGUIAPP_UART_MODE_UART #ifdef CONFIG_WEBGUIAPP_UART_MODE_UART
ESP_ERROR_CHECK(uart_set_mode(CONFIG_WEBGUIAPP_UART_PORT_NUM, UART_MODE_UART)); ESP_ERROR_CHECK_WITHOUT_ABORT(uart_set_mode(CONFIG_WEBGUIAPP_UART_PORT_NUM, UART_MODE_UART));
#elif CONFIG_WEBGUIAPP_UART_MODE_RS485 #elif CONFIG_WEBGUIAPP_UART_MODE_RS485
ESP_ERROR_CHECK(uart_set_mode(CONFIG_WEBGUIAPP_UART_PORT_NUM, UART_MODE_RS485_HALF_DUPLEX)); ESP_ERROR_CHECK_WITHOUT_ABORT(uart_set_mode(CONFIG_WEBGUIAPP_UART_PORT_NUM, UART_MODE_RS485_HALF_DUPLEX));
#endif #endif
ESP_ERROR_CHECK(uart_enable_rx_intr(CONFIG_WEBGUIAPP_UART_PORT_NUM)); ESP_ERROR_CHECK_WITHOUT_ABORT(uart_enable_rx_intr(CONFIG_WEBGUIAPP_UART_PORT_NUM));
ESP_ERROR_CHECK(uart_set_rx_timeout(CONFIG_WEBGUIAPP_UART_PORT_NUM, UART_READ_TOUT)); ESP_ERROR_CHECK_WITHOUT_ABORT(uart_set_rx_timeout(CONFIG_WEBGUIAPP_UART_PORT_NUM, UART_READ_TOUT));
//ESP_ERROR_CHECK(uart_enable_pattern_det_baud_intr(CONFIG_UART_PORT_NUM, '+', PATTERN_CHR_NUM, 9, 0, 0)); // ESP_ERROR_CHECK_WITHOUT_ABORT(uart_enable_pattern_det_baud_intr(CONFIG_UART_PORT_NUM, '+', PATTERN_CHR_NUM, 9, 0, 0));
uart_pattern_queue_reset(CONFIG_WEBGUIAPP_UART_PORT_NUM, 20); uart_pattern_queue_reset(CONFIG_WEBGUIAPP_UART_PORT_NUM, 20);
UARTtxQueueHandle = NULL; UARTtxQueueHandle = NULL;
UARTtxQueueHandle = xQueueCreateStatic(UART_TX_QUEUE_SIZE, UARTtxQueueHandle = xQueueCreateStatic(UART_TX_QUEUE_SIZE, sizeof(UART_DATA_SEND_STRUCT), UARTtxQueueStorageArea, &xStaticUARTtxQueue);
sizeof(UART_DATA_SEND_STRUCT),
UARTtxQueueStorageArea,
&xStaticUARTtxQueue);
xTaskCreate(serial_TX_task, "serial_tx", 1024 * 2, (void*) 0, 7, NULL); xTaskCreate(serial_TX_task, "serial_tx", 1024 * 2, (void *)0, 7, NULL);
xTaskCreate(serial_RX_task, "serial_rx", 1024 * 4, (void*) 0, 12, NULL); xTaskCreate(serial_RX_task, "serial_rx", 1024 * 4, (void *)0, 12, NULL);
ESP_LOGI(TAG, "Serial port initialized on UART%d with baudrate %d", CONFIG_WEBGUIAPP_UART_PORT_NUM, ESP_LOGI(TAG, "Serial port initialized on UART%d with baudrate %d", CONFIG_WEBGUIAPP_UART_PORT_NUM, GetSysConf()->serialSettings.BaudRate);
GetSysConf()->serialSettings.BaudRate);
} }
#endif #endif