serial port front and back implemented

This commit is contained in:
Bogdan Pilyugin 2023-10-16 14:43:26 +02:00
parent b689ab7948
commit 76e3d6b8c9
6 changed files with 141 additions and 85 deletions

47
Kconfig
View File

@ -787,14 +787,14 @@ menu "WebGUIApp"
menu "Serial port configuration"
config UART_TRANSPORT_ENABLE
config WEBGUIAPP_UART_TRANSPORT_ENABLE
bool "Enabled serial port"
default n
help
Set enabled uart output data
if UART_TRANSPORT_ENABLE
config UART_PORT_NUM
if WEBGUIAPP_UART_TRANSPORT_ENABLE
config WEBGUIAPP_UART_PORT_NUM
int "UART port number"
range 0 2
default 2
@ -802,20 +802,26 @@ menu "WebGUIApp"
UART communication port number for the example.
See UART documentation for available port numbers.
config UART_TO_MQTT_BRIDGE_ENABLED
config WEBGUIAPP_UART_ON
bool "Port is ON by default"
default y
help
Default port switched ON or OFF state
config WEBGUIAPP_UART_TO_MQTT_BRIDGE_ENABLED
bool "Enabled UART<->MQTT bridge"
default n
help
Switch on bridge uart to mqtt, else uart operate same way as rest and mqtt data exchange
config UART_BAUD_RATE
config WEBGUIAPP_UART_BAUD_RATE
int "UART communication speed"
range 1200 115200
default 115200
help
UART communication speed.
config UART_RXD
config WEBGUIAPP_UART_RXD
int "UART RXD pin number"
range 0 39
default 35
@ -823,7 +829,7 @@ menu "WebGUIApp"
GPIO number for UART RX pin. See UART documentation for more information
about available pin numbers for UART.
config UART_TXD
config WEBGUIAPP_UART_TXD
int "UART TXD pin number"
range 0 33
default 33
@ -832,27 +838,18 @@ menu "WebGUIApp"
about available pin numbers for UART.
config UART_MODE_RS485_ENABLED
bool "Enabled RS485 mode"
default n
help
Set UART to RS485 mode with hardware driver
config WEBGUIAPP_UART_RTS
int "RS485 RE/DE pin number"
range -1 33
default 32
help
GPIO number for UART RTS pin. This pin is connected to
~RE/DE pin of RS485 transceiver to switch direction.
if UART_MODE_RS485_ENABLED
config UART_RTS
int "RS485 RE/DE pin number"
range -1 33
default 32
help
GPIO number for UART RTS pin. This pin is connected to
~RE/DE pin of RS485 transceiver to switch direction.
endif
config UART_BUF_SIZE
config WEBGUIAPP_UART_BUF_SIZE
int "UART RAM buffer size"
range 64 4096
range 64 8192
default 1024
help
UART buffer size both for rx and tx.

View File

@ -189,6 +189,22 @@ typedef struct
} gsmSettings;
#endif
#ifdef CONFIG_WEBGUIAPP_UART_TRANSPORT_ENABLE
struct
{
int Serialmode;
int BaudRate;
int InputBrake;
struct
{
bool IsSerialEnabled;
bool IsBridgeEnabled;
} Flags;
} serialSettings;
#endif
#ifdef CONFIG_WEBGUIAPP_LORAWAN_ENABLE
struct
{
char DevEui[8];
@ -201,6 +217,7 @@ typedef struct
} Flags1; // Flag structure
} lorawanSettings;
#endif
struct
{

View File

@ -53,8 +53,6 @@ uint8_t MQTT2MessagesQueueStorageArea[MQTT_MESSAGE_BUFER_LENTH * sizeof(MQTT_DAT
mqtt_client_t mqtt[CONFIG_WEBGUIAPP_MQTT_CLIENTS_NUM] = { 0 };
static void mqtt_system_event_handler(int idx, void *handler_args, esp_event_base_t base, int32_t event_id,
void *event_data);
@ -219,15 +217,17 @@ static void mqtt_system_event_handler(int idx, void *handler_args, esp_event_bas
ESP_LOGI(TAG, "sent subscribe successful, msg_id=%d", msg_id);
ESP_LOGI(TAG, "Subscribe to %s", topic);
#endif
#ifdef CONFIG_UART_TO_MQTT_BRIDGE_ENABLED
ComposeTopic(topic, idx, EXTERNAL_SERVICE_NAME, DOWNLINK_SUBTOPIC);
//Subscribe to the service called "APP"
msg_id = esp_mqtt_client_subscribe(client, (const char*) topic, 0);
if (GetSysConf()->serialSettings.Flags.IsBridgeEnabled)
{
ComposeTopic(topic, idx, EXTERNAL_SERVICE_NAME, DOWNLINK_SUBTOPIC);
//Subscribe to the service called "APP"
msg_id = esp_mqtt_client_subscribe(client, (const char*) topic, 0);
#if MQTT_DEBUG_MODE > 0
ESP_LOGI(TAG, "sent subscribe successful, msg_id=%d", msg_id);
ESP_LOGI(TAG, "Subscribe to %s", topic);
#endif
ESP_LOGI(TAG, "sent subscribe successful, msg_id=%d", msg_id);
ESP_LOGI(TAG, "Subscribe to %s", topic);
#endif
}
break;
case MQTT_EVENT_DISCONNECTED:
@ -289,14 +289,15 @@ static void mqtt_system_event_handler(int idx, void *handler_args, esp_event_bas
ESP_LOGE(TAG, "Out of free RAM for MQTT API handle");
}
#ifdef CONFIG_UART_TO_MQTT_BRIDGE_ENABLED
ComposeTopic(topic, idx, EXTERNAL_SERVICE_NAME, DOWNLINK_SUBTOPIC);
if (!memcmp(topic, event->topic, event->topic_len))
{
TransmitSerialPort(event->data, event->data_len);
}
#endif
if (GetSysConf()->serialSettings.Flags.IsBridgeEnabled)
{
ComposeTopic(topic, idx, EXTERNAL_SERVICE_NAME, DOWNLINK_SUBTOPIC);
if (!memcmp(topic, event->topic, event->topic_len))
{
TransmitSerialPort(event->data, event->data_len);
}
}
break;
case MQTT_EVENT_ERROR:
@ -502,26 +503,26 @@ static void mqtt2_user_event_handler(void *handler_args, esp_event_base_t base,
#define MAX_MQTT_LOG_MESSAGE (1024)
#define SPIRAL_LOG_TAG "SystemExtendedLog"
char data[MAX_MQTT_LOG_MESSAGE];
esp_err_t ExtendedLog(esp_log_level_t level, char *format, ...)
esp_err_t ExtendedLog(esp_log_level_t level, char *format, ...)
{
va_list arg;
va_start(arg, format);
va_end(arg);
vsnprintf(data, MAX_MQTT_LOG_MESSAGE, format, arg);
switch(level)
vsnprintf(data, MAX_MQTT_LOG_MESSAGE, format, arg);
switch (level)
{
case ESP_LOG_INFO:
case ESP_LOG_DEBUG:
case ESP_LOG_VERBOSE:
case ESP_LOG_NONE:
ESP_LOGI(SPIRAL_LOG_TAG, "%s", data);
break;
break;
case ESP_LOG_WARN:
ESP_LOGW(SPIRAL_LOG_TAG, "%s", data);
break;
break;
case ESP_LOG_ERROR:
ESP_LOGE(SPIRAL_LOG_TAG, "%s", data);
break;
break;
}
for (int idx = 0; idx < 2; idx++)
@ -549,4 +550,3 @@ esp_err_t ExtendedLog(esp_log_level_t level, char *format, ...)
return ESP_OK;
}

View File

@ -478,6 +478,18 @@ const rest_var_t SystemVariables[] =
{ 0, "gsm_visible", (bool*) (&VAR_FALSE), VAR_BOOL, R, 0, 1 },
#endif
#ifdef CONFIG_WEBGUIAPP_UART_TRANSPORT_ENABLE
{ 0, "serial_enab", &SysConfig.serialSettings.Flags.IsSerialEnabled, VAR_BOOL, RW, 0, 1 },
{ 0, "serial_bridge", &SysConfig.serialSettings.Flags.IsSerialEnabled, VAR_BOOL, RW, 0, 1 },
{ 0, "serial_mode", &SysConfig.serialSettings.Serialmode, VAR_INT, RW, 1, 2 },
{ 0, "serial_baud", &SysConfig.serialSettings.BaudRate, VAR_INT, RW, 1200, 4096000 },
{ 0, "serial_break", &SysConfig.serialSettings.InputBrake, VAR_INT, RW, 1, 50 },
{ 0, "serial_visible", (bool*) (&VAR_TRUE), VAR_BOOL, RW, 0, 1 },
#else
{ 0, "serial_visible", (bool*) (&VAR_FALSE), VAR_BOOL, R, 0, 1 },
#endif
#ifdef CONFIG_WEBGUIAPP_LORAWAN_ENABLE
{ 0, "lora_enab", &SysConfig.lorawanSettings.Flags1.bIsLoRaWANEnabled, VAR_BOOL, RW, 0, 1 },
{ 0, "lora_visible", (bool*) (&VAR_TRUE), VAR_BOOL, RW, 0, 1 },
@ -490,6 +502,11 @@ const rest_var_t SystemVariables[] =
{ 0, "lora_visible", (bool*) (&VAR_FALSE), VAR_BOOL, R, 0, 1 },
#endif
#ifdef CONFIG_WEBGUIAPP_MBTCP_ENABLED
{ 0, "mbtcp_enab", &SysConfig.modbusSettings.IsModbusTCPEnabled, VAR_BOOL, RW, 0, 1 },
{ 0, "mbtcp_port", &SysConfig.modbusSettings.ModbusTCPPort, VAR_INT, RW, 1, 65534 },

View File

@ -1,4 +1,4 @@
/*! Copyright 2023 Bogdan Pilyugin
/*! Copyright 2023 Bogdan Pilyugin
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -42,15 +42,16 @@
#define UART_TX_QUEUE_SIZE (5)
#define UART_RX_QUEUE_SIZE (5)
#define UART_DEBUG_MODE 0
#ifdef CONFIG_WEBGUIAPP_UART_TRANSPORT_ENABLE
QueueHandle_t UARTtxQueueHandle;
static StaticQueue_t xStaticUARTtxQueue;
uint8_t UARTtxQueueStorageArea[UART_TX_QUEUE_SIZE * sizeof(UART_DATA_SEND_STRUCT)];
static QueueHandle_t uart_event_queue;
static char rxbuf[CONFIG_UART_BUF_SIZE];
static char rxbuf[CONFIG_WEBGUIAPP_UART_BUF_SIZE];
esp_err_t TransmitSerialPort(char *data, int ln)
{
@ -95,8 +96,6 @@ static void ReceiveHandlerAPI()
}
}
void serial_RX_task(void *arg)
{
uart_event_t event;
@ -120,21 +119,22 @@ void serial_RX_task(void *arg)
if (event.timeout_flag)
{
bzero(rxbuf, CONFIG_UART_BUF_SIZE);
uart_get_buffered_data_len(CONFIG_UART_PORT_NUM, (size_t*) &buffered_size);
bzero(rxbuf, CONFIG_WEBGUIAPP_UART_BUF_SIZE);
uart_get_buffered_data_len(CONFIG_WEBGUIAPP_UART_PORT_NUM, (size_t*) &buffered_size);
if (buffered_size)
{
uart_read_bytes(CONFIG_UART_PORT_NUM, rxbuf, buffered_size, 100);
uart_read_bytes(CONFIG_WEBGUIAPP_UART_PORT_NUM, rxbuf, buffered_size, 100);
#if UART_DEBUG_MODE == 1
ESP_LOGI(TAG, "read of %d bytes: %s", buffered_size, rxbuf);
#endif
#ifdef CONFIG_UART_TO_MQTT_BRIDGE_ENABLED
ExternalServiceMQTTSend(rxbuf, buffered_size, 0);
ExternalServiceMQTTSend(rxbuf, buffered_size, 1);
#else
ReceiveHandlerAPI();
#endif
if (GetSysConf()->serialSettings.Flags.IsBridgeEnabled)
{
ExternalServiceMQTTSend(rxbuf, buffered_size, 0);
ExternalServiceMQTTSend(rxbuf, buffered_size, 1);
}
else
ReceiveHandlerAPI();
}
}
@ -148,7 +148,7 @@ void serial_RX_task(void *arg)
// If fifo overflow happened, you should consider adding flow control for your application.
// The ISR has already reset the rx FIFO,
// As an example, we directly flush the rx buffer here in order to read more data.
uart_flush_input(CONFIG_UART_PORT_NUM);
uart_flush_input(CONFIG_WEBGUIAPP_UART_PORT_NUM);
xQueueReset(uart_event_queue);
break;
//Event of UART ring buffer full
@ -156,7 +156,7 @@ void serial_RX_task(void *arg)
ESP_LOGE(TAG, "ring buffer full");
// If buffer full happened, you should consider encreasing your buffer size
// As an example, we directly flush the rx buffer here in order to read more data.
uart_flush_input(CONFIG_UART_PORT_NUM);
uart_flush_input(CONFIG_WEBGUIAPP_UART_PORT_NUM);
xQueueReset(uart_event_queue);
break;
//Event of UART RX break detected
@ -176,8 +176,8 @@ void serial_RX_task(void *arg)
//UART_PATTERN_DET
case UART_PATTERN_DET:
uart_get_buffered_data_len(CONFIG_UART_PORT_NUM, (size_t*) &buffered_size);
int pos = uart_pattern_pop_pos(CONFIG_UART_PORT_NUM);
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);
#if UART_DEBUG_MODE == 1
ESP_LOGI(TAG, "[UART PATTERN DETECTED] pos: %d, buffered size: %d", (int )pos, (int )buffered_size);
#endif
@ -186,14 +186,14 @@ void serial_RX_task(void *arg)
// There used to be a UART_PATTERN_DET event, but the pattern position queue is full so that it can not
// record the position. We should set a larger queue size.
// As an example, we directly flush the rx buffer here.
uart_flush_input(CONFIG_UART_PORT_NUM);
uart_flush_input(CONFIG_WEBGUIAPP_UART_PORT_NUM);
}
else
{
uart_read_bytes(CONFIG_UART_PORT_NUM, rxbuf, pos, 100 / portTICK_PERIOD_MS);
uart_read_bytes(CONFIG_WEBGUIAPP_UART_PORT_NUM, rxbuf, pos, 100 / portTICK_PERIOD_MS);
uint8_t pat[PATTERN_CHR_NUM + 1];
memset(pat, 0, sizeof(pat));
uart_read_bytes(CONFIG_UART_PORT_NUM, pat, PATTERN_CHR_NUM, 100 / portTICK_PERIOD_MS);
uart_read_bytes(CONFIG_WEBGUIAPP_UART_PORT_NUM, pat, PATTERN_CHR_NUM, 100 / portTICK_PERIOD_MS);
#if UART_DEBUG_MODE == 1
ESP_LOGI(TAG, "read data: %s", rxbuf);
ESP_LOGI(TAG, "read pat : %s", pat);
@ -217,11 +217,11 @@ void static serial_TX_task(void *arg)
while (1)
{
xQueueReceive(UARTtxQueueHandle, &DSS, portMAX_DELAY);
if (uart_write_bytes(CONFIG_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)
ESP_LOGE(TAG, "RS485 write data failure");
free(DSS.raw_data_ptr);
if (uart_wait_tx_done(CONFIG_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)
ESP_LOGE(TAG, "RS485 transmit data failure");
}
}
@ -229,7 +229,7 @@ void static serial_TX_task(void *arg)
void InitSerialPort(void)
{
uart_config_t uart_config = {
.baud_rate = CONFIG_UART_BAUD_RATE,
.baud_rate = GetSysConf()->serialSettings.BaudRate,
.data_bits = UART_DATA_8_BITS,
.parity = UART_PARITY_DISABLE,
.stop_bits = UART_STOP_BITS_1,
@ -237,15 +237,21 @@ void InitSerialPort(void)
.source_clk = UART_SCLK_APB,
};
ESP_ERROR_CHECK(uart_driver_install(CONFIG_UART_PORT_NUM, CONFIG_UART_BUF_SIZE * 2, 0, 20, &uart_event_queue, 0));
ESP_ERROR_CHECK(uart_param_config(CONFIG_UART_PORT_NUM, &uart_config));
ESP_ERROR_CHECK(uart_set_pin(CONFIG_UART_PORT_NUM, CONFIG_UART_TXD, CONFIG_UART_RXD, CONFIG_UART_RTS, -1));
ESP_ERROR_CHECK(uart_set_mode(CONFIG_UART_PORT_NUM, UART_MODE_RS485_HALF_DUPLEX));
ESP_ERROR_CHECK(
uart_driver_install(CONFIG_WEBGUIAPP_UART_PORT_NUM, CONFIG_WEBGUIAPP_UART_BUF_SIZE * 2, 0, 20, &uart_event_queue, 0));
ESP_ERROR_CHECK(uart_param_config(CONFIG_WEBGUIAPP_UART_PORT_NUM, &uart_config));
ESP_ERROR_CHECK(uart_set_pin(CONFIG_WEBGUIAPP_UART_PORT_NUM,
CONFIG_WEBGUIAPP_UART_TXD, CONFIG_WEBGUIAPP_UART_RXD, CONFIG_WEBGUIAPP_UART_RTS, -1));
ESP_ERROR_CHECK(uart_enable_rx_intr(CONFIG_UART_PORT_NUM));
ESP_ERROR_CHECK(uart_set_rx_timeout(CONFIG_UART_PORT_NUM, UART_READ_TOUT));
if (GetSysConf()->serialSettings.Serialmode == 2)
ESP_ERROR_CHECK(uart_set_mode(CONFIG_WEBGUIAPP_UART_PORT_NUM, UART_MODE_RS485_HALF_DUPLEX));
else
ESP_ERROR_CHECK(uart_set_mode(CONFIG_WEBGUIAPP_UART_PORT_NUM, UART_MODE_UART));
ESP_ERROR_CHECK(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(uart_enable_pattern_det_baud_intr(CONFIG_UART_PORT_NUM, '+', PATTERN_CHR_NUM, 9, 0, 0));
uart_pattern_queue_reset(CONFIG_UART_PORT_NUM, 20);
uart_pattern_queue_reset(CONFIG_WEBGUIAPP_UART_PORT_NUM, 20);
UARTtxQueueHandle = NULL;
UARTtxQueueHandle = xQueueCreateStatic(UART_TX_QUEUE_SIZE,
@ -253,12 +259,11 @@ void InitSerialPort(void)
UARTtxQueueStorageArea,
&xStaticUARTtxQueue);
xTaskCreate(serial_TX_task, "RS485txTask", 1024 * 2, (void*) 0, 7, NULL);
xTaskCreate(serial_RX_task, "RS485rxTask", 1024 * 4, (void*) 0, 12, NULL);
ESP_LOGI(TAG, "Serial port initialized on UART%d with baudrate %d", CONFIG_UART_PORT_NUM,
CONFIG_UART_BAUD_RATE);
xTaskCreate(serial_TX_task, "serial_tx", 1024 * 2, (void*) 0, 7, 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,
GetSysConf()->serialSettings.BaudRate);
}
#endif

View File

@ -169,6 +169,12 @@ esp_err_t WebGuiAppInit(void)
}
#endif
#endif
#if CONFIG_WEBGUIAPP_UART_TRANSPORT_ENABLE
InitSerialPort();
#endif
return ESP_OK;
}
@ -389,6 +395,20 @@ esp_netif_str_to_ip4(CONFIG_WEBGUIAPP_DNS3_ADDRESS_DEFAULT, (esp_ip4_addr_t*) &C
memcpy(Conf->lorawanSettings.AppEui, temp, 8);
#endif
#ifdef CONFIG_WEBGUIAPP_UART_TRANSPORT_ENABLE
Conf->serialSettings.Flags.IsSerialEnabled = false;
Conf->serialSettings.Flags.IsBridgeEnabled = false;
#ifdef CONFIG_WEBGUIAPP_UART_ON
Conf->serialSettings.Flags.IsSerialEnabled = true;
#endif
#ifdef CONFIG_WEBGUIAPP_UART_TO_MQTT_BRIDGE_ENABLED
Conf->serialSettings.Flags.IsBridgeEnabled = true;
#endif
Conf->serialSettings.Serialmode = 1;
Conf->serialSettings.BaudRate = CONFIG_WEBGUIAPP_UART_BAUD_RATE;
Conf->serialSettings.InputBrake = 50;
#endif
#ifdef CONFIG_WEBGUIAPP_MBTCP_ENABLED
Conf->modbusSettings.IsModbusTCPEnabled = false;
#if CONFIG_WEBGUIAPP_MBTCP_ON == 1