1 /* UART Events Example
2 
3    This example code is in the Public Domain (or CC0 licensed, at your option.)
4 
5    Unless required by applicable law or agreed to in writing, this
6    software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
7    CONDITIONS OF ANY KIND, either express or implied.
8 */
9 #include <stdio.h>
10 #include <string.h>
11 #include "freertos/FreeRTOS.h"
12 #include "freertos/task.h"
13 #include "freertos/queue.h"
14 #include "driver/uart.h"
15 #include "esp_log.h"
16 
17 static const char *TAG = "uart_events";
18 
19 /**
20  * This example shows how to use the UART driver to handle special UART events.
21  *
22  * It also reads data from UART0 directly, and echoes it to console.
23  *
24  * - Port: UART0
25  * - Receive (Rx) buffer: on
26  * - Transmit (Tx) buffer: off
27  * - Flow control: off
28  * - Event queue: on
29  * - Pin assignment: TxD (default), RxD (default)
30  */
31 
32 #define EX_UART_NUM UART_NUM_0
33 #define PATTERN_CHR_NUM    (3)         /*!< Set the number of consecutive and identical characters received by receiver which defines a UART pattern*/
34 
35 #define BUF_SIZE (1024)
36 #define RD_BUF_SIZE (BUF_SIZE)
37 static QueueHandle_t uart0_queue;
38 
uart_event_task(void * pvParameters)39 static void uart_event_task(void *pvParameters)
40 {
41     uart_event_t event;
42     size_t buffered_size;
43     uint8_t* dtmp = (uint8_t*) malloc(RD_BUF_SIZE);
44     for(;;) {
45         //Waiting for UART event.
46         if(xQueueReceive(uart0_queue, (void * )&event, (portTickType)portMAX_DELAY)) {
47             bzero(dtmp, RD_BUF_SIZE);
48             ESP_LOGI(TAG, "uart[%d] event:", EX_UART_NUM);
49             switch(event.type) {
50                 //Event of UART receving data
51                 /*We'd better handler data event fast, there would be much more data events than
52                 other types of events. If we take too much time on data event, the queue might
53                 be full.*/
54                 case UART_DATA:
55                     ESP_LOGI(TAG, "[UART DATA]: %d", event.size);
56                     uart_read_bytes(EX_UART_NUM, dtmp, event.size, portMAX_DELAY);
57                     ESP_LOGI(TAG, "[DATA EVT]:");
58                     uart_write_bytes(EX_UART_NUM, (const char*) dtmp, event.size);
59                     break;
60                 //Event of HW FIFO overflow detected
61                 case UART_FIFO_OVF:
62                     ESP_LOGI(TAG, "hw fifo overflow");
63                     // If fifo overflow happened, you should consider adding flow control for your application.
64                     // The ISR has already reset the rx FIFO,
65                     // As an example, we directly flush the rx buffer here in order to read more data.
66                     uart_flush_input(EX_UART_NUM);
67                     xQueueReset(uart0_queue);
68                     break;
69                 //Event of UART ring buffer full
70                 case UART_BUFFER_FULL:
71                     ESP_LOGI(TAG, "ring buffer full");
72                     // If buffer full happened, you should consider encreasing your buffer size
73                     // As an example, we directly flush the rx buffer here in order to read more data.
74                     uart_flush_input(EX_UART_NUM);
75                     xQueueReset(uart0_queue);
76                     break;
77                 //Event of UART RX break detected
78                 case UART_BREAK:
79                     ESP_LOGI(TAG, "uart rx break");
80                     break;
81                 //Event of UART parity check error
82                 case UART_PARITY_ERR:
83                     ESP_LOGI(TAG, "uart parity error");
84                     break;
85                 //Event of UART frame error
86                 case UART_FRAME_ERR:
87                     ESP_LOGI(TAG, "uart frame error");
88                     break;
89                 //UART_PATTERN_DET
90                 case UART_PATTERN_DET:
91                     uart_get_buffered_data_len(EX_UART_NUM, &buffered_size);
92                     int pos = uart_pattern_pop_pos(EX_UART_NUM);
93                     ESP_LOGI(TAG, "[UART PATTERN DETECTED] pos: %d, buffered size: %d", pos, buffered_size);
94                     if (pos == -1) {
95                         // There used to be a UART_PATTERN_DET event, but the pattern position queue is full so that it can not
96                         // record the position. We should set a larger queue size.
97                         // As an example, we directly flush the rx buffer here.
98                         uart_flush_input(EX_UART_NUM);
99                     } else {
100                         uart_read_bytes(EX_UART_NUM, dtmp, pos, 100 / portTICK_PERIOD_MS);
101                         uint8_t pat[PATTERN_CHR_NUM + 1];
102                         memset(pat, 0, sizeof(pat));
103                         uart_read_bytes(EX_UART_NUM, pat, PATTERN_CHR_NUM, 100 / portTICK_PERIOD_MS);
104                         ESP_LOGI(TAG, "read data: %s", dtmp);
105                         ESP_LOGI(TAG, "read pat : %s", pat);
106                     }
107                     break;
108                 //Others
109                 default:
110                     ESP_LOGI(TAG, "uart event type: %d", event.type);
111                     break;
112             }
113         }
114     }
115     free(dtmp);
116     dtmp = NULL;
117     vTaskDelete(NULL);
118 }
119 
app_main(void)120 void app_main(void)
121 {
122     esp_log_level_set(TAG, ESP_LOG_INFO);
123 
124     /* Configure parameters of an UART driver,
125      * communication pins and install the driver */
126     uart_config_t uart_config = {
127         .baud_rate = 115200,
128         .data_bits = UART_DATA_8_BITS,
129         .parity = UART_PARITY_DISABLE,
130         .stop_bits = UART_STOP_BITS_1,
131         .flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
132         .source_clk = UART_SCLK_APB,
133     };
134     //Install UART driver, and get the queue.
135     uart_driver_install(EX_UART_NUM, BUF_SIZE * 2, BUF_SIZE * 2, 20, &uart0_queue, 0);
136     uart_param_config(EX_UART_NUM, &uart_config);
137 
138     //Set UART log level
139     esp_log_level_set(TAG, ESP_LOG_INFO);
140     //Set UART pins (using UART0 default pins ie no changes.)
141     uart_set_pin(EX_UART_NUM, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE);
142 
143     //Set uart pattern detect function.
144     uart_enable_pattern_det_baud_intr(EX_UART_NUM, '+', PATTERN_CHR_NUM, 9, 0, 0);
145     //Reset the pattern queue length to record at most 20 pattern positions.
146     uart_pattern_queue_reset(EX_UART_NUM, 20);
147 
148     //Create a task to handler UART event from ISR
149     xTaskCreate(uart_event_task, "uart_event_task", 2048, NULL, 12, NULL);
150 }
151