/* * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ #include #include #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "freertos/queue.h" #include "driver/uart.h" #include "esp_log.h" static const char *TAG = "UART"; /** * - Port: UART0 * - Receive (Rx) buffer: on * - Transmit (Tx) buffer: off * - Flow control: off * - Event queue: on * - Pin assignment: TxD (default), RxD (default) */ #define UART_TXD (CONFIG_UART_TXD) #define UART_RXD (CONFIG_UART_RXD) #define UART_RTS (UART_PIN_NO_CHANGE) #define UART_CTS (UART_PIN_NO_CHANGE) #define UART_NUM (CONFIG_UART_PORT_NUM) #define UART_BAUD_RATE (CONFIG_UART_BAUD_RATE) #define UART_TASK_STACK_SIZE (CONFIG_TASK_STACK_SIZE) #define PATTERN_CHR_NUM (3) /*!< Set the number of consecutive and identical characters received by receiver which defines a UART pattern*/ #define BUF_SIZE (1024) #define RD_BUF_SIZE (BUF_SIZE) void Command_Parse(char* Cmd); static QueueHandle_t uart_queue; static void uart_receive_task(void *pvParameters) { uart_event_t event; uint8_t* dtmp = (uint8_t*) malloc(RD_BUF_SIZE); for (;;) { //Waiting for UART event. if (xQueueReceive(uart_queue, (void *)&event, portMAX_DELAY)) { bzero(dtmp, RD_BUF_SIZE); ESP_LOGI(TAG, "uart[%d] event:", UART_NUM); switch (event.type) { //Event of UART receiving data /*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 be full.*/ case UART_DATA: ESP_LOGI(TAG, "[UART DATA]: %d", event.size); uart_read_bytes(UART_NUM, dtmp, event.size, portMAX_DELAY); ESP_LOGI(TAG, "[DATA EVT]:"); Command_Parse((char*)dtmp); break; //Event of HW FIFO overflow detected case UART_FIFO_OVF: ESP_LOGI(TAG, "hw fifo overflow"); // 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(UART_NUM); xQueueReset(uart_queue); break; //Event of UART ring buffer full case UART_BUFFER_FULL: ESP_LOGI(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(UART_NUM); xQueueReset(uart_queue); break; //Event of UART RX break detected case UART_BREAK: ESP_LOGI(TAG, "uart rx break"); break; //Event of UART parity check error case UART_PARITY_ERR: ESP_LOGI(TAG, "uart parity error"); break; //Event of UART frame error case UART_FRAME_ERR: ESP_LOGI(TAG, "uart frame error"); break; //Others default: ESP_LOGI(TAG, "uart event type: %d", event.type); break; } } } free(dtmp); dtmp = NULL; vTaskDelete(NULL); } void initialise_uart(void) { /* Configure parameters of an UART driver, * communication pins and install the driver */ uart_config_t uart_config = { .baud_rate = UART_BAUD_RATE, .data_bits = UART_DATA_8_BITS, .parity = UART_PARITY_DISABLE, .stop_bits = UART_STOP_BITS_1, .flow_ctrl = UART_HW_FLOWCTRL_DISABLE, .source_clk = UART_SCLK_APB, }; //Install UART driver, and get the queue. uart_driver_install(UART_NUM, BUF_SIZE, BUF_SIZE * 4, 20, &uart_queue, 0); uart_param_config(UART_NUM, &uart_config); //Set UART log level esp_log_level_set(TAG, ESP_LOG_INFO); //Set UART pins (using UART0 default pins ie no changes.) ESP_ERROR_CHECK(uart_set_pin(UART_NUM, UART_TXD, UART_RXD, UART_RTS, UART_CTS)); //Create a task to handler UART event from ISR xTaskCreate(uart_receive_task, "uart_receive_task", UART_TASK_STACK_SIZE, NULL, 12, NULL); }