Merge branch 'feature/uart' into 'master'

driver: uart

1. add uart rx buffer data length API
2. add uart pattern detect event
3. add uart example code
4. modify uart_isr_register API
5. modify uart.rst
6. fix parity err event and frame err event.

See merge request !321
This commit is contained in:
Wang Jia Lin 2016-12-21 14:10:37 +08:00
commit 168190d7e4
6 changed files with 326 additions and 50 deletions

View file

@ -23,6 +23,7 @@ extern "C" {
#include "soc/uart_reg.h"
#include "soc/uart_struct.h"
#include "esp_err.h"
#include "esp_intr_alloc.h"
#include "driver/periph_ctrl.h"
#include "freertos/FreeRTOS.h"
#include "freertos/semphr.h"
@ -129,6 +130,7 @@ typedef enum {
UART_PARITY_ERR, /*!< UART RX parity event*/
UART_DATA_BREAK, /*!< UART TX data and break event*/
UART_EVENT_MAX, /*!< UART event max index*/
UART_PATTERN_DET, /*!< UART pattern detected */
} uart_event_type_t;
/**
@ -139,6 +141,8 @@ typedef struct {
size_t size; /*!< UART data size for UART_DATA event*/
} uart_event_t;
typedef intr_handle_t uart_isr_handle_t;
/**
* @brief Set UART data bits.
*
@ -372,12 +376,14 @@ esp_err_t uart_enable_tx_intr(uart_port_t uart_num, int enable, int thresh);
* @param arg parameter for handler function
* @param intr_alloc_flags Flags used to allocate the interrupt. One or multiple (ORred)
* ESP_INTR_FLAG_* values. See esp_intr_alloc.h for more info.
* @param handle Pointer to return handle. If non-NULL, a handle for the interrupt will
* be returned here.
*
* @return
* - ESP_OK Success
* - ESP_FAIL Parameter error
*/
esp_err_t uart_isr_register(uart_port_t uart_num, void (*fn)(void*), void * arg, int intr_alloc_flags);
esp_err_t uart_isr_register(uart_port_t uart_num, void (*fn)(void*), void * arg, int intr_alloc_flags, uart_isr_handle_t *handle);
/**
@ -463,9 +469,11 @@ esp_err_t uart_intr_config(uart_port_t uart_num, const uart_intr_config_t *intr_
* @brief Install UART driver.
*
* UART ISR handler will be attached to the same CPU core that this function is running on.
* Users should know that which CPU is running and then pick a INUM that is not used by system.
* We can find the information of INUM and interrupt level in soc.h.
*
* @param uart_num UART_NUM_0, UART_NUM_1 or UART_NUM_2
* @param rx_buffer_size UART RX ring buffer size
* @param rx_buffer_size UART RX ring buffer size, rx_buffer_size should be greater than UART_FIFO_LEN.
* @param tx_buffer_size UART TX ring buffer size.
* If set to zero, driver will not use TX buffer, TX function will block task until all data have been sent out..
* @param queue_size UART event queue size/depth.
@ -586,6 +594,48 @@ int uart_read_bytes(uart_port_t uart_num, uint8_t* buf, uint32_t length, TickTyp
*/
esp_err_t uart_flush(uart_port_t uart_num);
/**
* @brief UART get RX ring buffer cached data length
*
* @param uart_num UART port number.
* @param size Pointer of size_t to accept cached data length
*
* @return
* - ESP_OK Success
* - ESP_FAIL Parameter error
*/
esp_err_t uart_get_buffered_data_len(uart_port_t uart_num, size_t* size);
/**
* @brief UART disable pattern detect function.
* Designed for applications like 'AT commands'.
* When the hardware detect a series of one same character, the interrupt will be triggered.
*
* @param uart_num UART port number.
*
* @return
* - ESP_OK Success
* - ESP_FAIL Parameter error
*/
esp_err_t uart_disable_pattern_det_intr(uart_port_t uart_num);
/**
* @brief UART enable pattern detect function.
* Designed for applications like 'AT commands'.
* When the hardware detect a series of one same character, the interrupt will be triggered.
*
* @param uart_num UART port number.
* @param pattern_chr character of the pattern
* @param chr_num number of the character, 8bit value.
* @param chr_tout timeout of the interval between each pattern characters, 24bit value, unit is APB(80Mhz) clock cycle.
* @param post_idle idle time after the last pattern character, 24bit value, unit is APB(80Mhz) clock cycle.
* @param pre_idle idle time before the first pattern character, 24bit value, unit is APB(80Mhz) clock cycle.
*
* @return
* - ESP_OK Success
* - ESP_FAIL Parameter error
*/
esp_err_t uart_enable_pattern_det_intr(uart_port_t uart_num, char pattern_chr, uint8_t chr_num, int chr_tout, int post_idle, int pre_idle);
/***************************EXAMPLE**********************************
*
*
@ -593,6 +643,7 @@ esp_err_t uart_flush(uart_port_t uart_num);
* @code{c}
* //1. Setup UART
* #include "freertos/queue.h"
* #define UART_INTR_NUM 17 //choose one interrupt number from soc.h
* //a. Set UART parameter
* int uart_num = 0; //uart port number
* uart_config_t uart_config = {
@ -655,7 +706,7 @@ esp_err_t uart_flush(uart_port_t uart_num);
* //Set UART1 pins(TX: IO16, RX: IO17, RTS: IO18, CTS: IO19)
* uart_set_pin(uart_num, 16, 17, 18, 19);
* //Install UART driver( We don't need an event queue here)
* uart_driver_install(uart_num, 1024 * 2, 1024*4, 10, NULL, 0);
* uart_driver_install(uart_num, 1024 * 2, 1024*4, 0, NULL, 0);
* uint8_t data[1000];
* while(1) {
* //Read data from UART
@ -689,7 +740,6 @@ esp_err_t uart_flush(uart_port_t uart_num);
* ESP_LOGI(TAG,"data, len: %d", event.size);
* int len = uart_read_bytes(uart_num, dtmp, event.size, 10);
* ESP_LOGI(TAG, "uart read: %d", len);
uart_write_bytes(uart_num, (const char*)dtmp, len);
* break;
* //Event of HW FIFO overflow detected
* case UART_FIFO_OVF:

View file

@ -59,6 +59,7 @@ typedef struct {
QueueHandle_t xQueueUart; /*!< UART queue handler*/
intr_handle_t intr_handle; /*!< UART interrupt handle*/
//rx parameters
int rx_buffered_len; /*!< UART cached data length */
SemaphoreHandle_t rx_mux; /*!< UART RX data mutex*/
int rx_buf_size; /*!< RX ring buffer size */
RingbufHandle_t rx_ring_buf; /*!< RX ring buffer handler*/
@ -260,22 +261,38 @@ esp_err_t uart_disable_intr_mask(uart_port_t uart_num, uint32_t disable_mask)
return ESP_OK;
}
esp_err_t uart_enable_pattern_det_intr(uart_port_t uart_num, char pattern_chr, uint8_t chr_num, int chr_tout, int post_idle, int pre_idle)
{
UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_FAIL);
UART_CHECK(chr_tout >= 0 && chr_tout <= UART_RX_GAP_TOUT_V, "uart pattern set error\n", ESP_FAIL);
UART_CHECK(post_idle >= 0 && post_idle <= UART_POST_IDLE_NUM_V, "uart pattern set error\n", ESP_FAIL);
UART_CHECK(pre_idle >= 0 && pre_idle <= UART_PRE_IDLE_NUM_V, "uart pattern set error\n", ESP_FAIL);
UART[uart_num]->at_cmd_char.data = pattern_chr;
UART[uart_num]->at_cmd_char.char_num = chr_num;
UART[uart_num]->at_cmd_gaptout.rx_gap_tout = chr_tout;
UART[uart_num]->at_cmd_postcnt.post_idle_num = post_idle;
UART[uart_num]->at_cmd_precnt.pre_idle_num = pre_idle;
return uart_enable_intr_mask(uart_num, UART_AT_CMD_CHAR_DET_INT_ENA_M);
}
esp_err_t uart_disable_pattern_det_intr(uart_port_t uart_num)
{
return uart_disable_intr_mask(uart_num, UART_AT_CMD_CHAR_DET_INT_ENA_M);
}
esp_err_t uart_enable_rx_intr(uart_port_t uart_num)
{
uart_enable_intr_mask(uart_num, UART_RXFIFO_FULL_INT_ENA|UART_RXFIFO_TOUT_INT_ENA);
return ESP_OK;
return uart_enable_intr_mask(uart_num, UART_RXFIFO_FULL_INT_ENA|UART_RXFIFO_TOUT_INT_ENA);
}
esp_err_t uart_disable_rx_intr(uart_port_t uart_num)
{
uart_disable_intr_mask(uart_num, UART_RXFIFO_FULL_INT_ENA|UART_RXFIFO_TOUT_INT_ENA);
return ESP_OK;
return uart_disable_intr_mask(uart_num, UART_RXFIFO_FULL_INT_ENA|UART_RXFIFO_TOUT_INT_ENA);
}
esp_err_t uart_disable_tx_intr(uart_port_t uart_num)
{
uart_disable_intr_mask(uart_num, UART_TXFIFO_EMPTY_INT_ENA);
return ESP_OK;
return uart_disable_intr_mask(uart_num, UART_TXFIFO_EMPTY_INT_ENA);
}
esp_err_t uart_enable_tx_intr(uart_port_t uart_num, int enable, int thresh)
@ -290,21 +307,21 @@ esp_err_t uart_enable_tx_intr(uart_port_t uart_num, int enable, int thresh)
return ESP_OK;
}
esp_err_t uart_isr_register(uart_port_t uart_num, void (*fn)(void*), void * arg, int intr_alloc_flags)
esp_err_t uart_isr_register(uart_port_t uart_num, void (*fn)(void*), void * arg, int intr_alloc_flags, uart_isr_handle_t *handle)
{
int ret;
UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_FAIL);
UART_ENTER_CRITICAL(&uart_spinlock[uart_num]);
switch(uart_num) {
case UART_NUM_1:
ret=esp_intr_alloc(ETS_UART1_INTR_SOURCE, intr_alloc_flags, fn, arg, &p_uart_obj[uart_num]->intr_handle);
ret=esp_intr_alloc(ETS_UART1_INTR_SOURCE, intr_alloc_flags, fn, arg, handle);
break;
case UART_NUM_2:
ret=esp_intr_alloc(ETS_UART2_INTR_SOURCE, intr_alloc_flags, fn, arg, &p_uart_obj[uart_num]->intr_handle);
ret=esp_intr_alloc(ETS_UART2_INTR_SOURCE, intr_alloc_flags, fn, arg, handle);
break;
case UART_NUM_0:
default:
ret=esp_intr_alloc(ETS_UART0_INTR_SOURCE, intr_alloc_flags, fn, arg, &p_uart_obj[uart_num]->intr_handle);
ret=esp_intr_alloc(ETS_UART0_INTR_SOURCE, intr_alloc_flags, fn, arg, handle);
break;
}
UART_EXIT_CRITICAL(&uart_spinlock[uart_num]);
@ -595,6 +612,9 @@ static void IRAM_ATTR uart_rx_intr_handler_default(void *param)
p_uart->rx_buffer_full_flg = true;
uart_event.type = UART_BUFFER_FULL;
} else {
UART_ENTER_CRITICAL_ISR(&uart_spinlock[uart_num]);
p_uart->rx_buffered_len += p_uart->rx_stash_len;
UART_EXIT_CRITICAL_ISR(&uart_spinlock[uart_num]);
uart_event.type = UART_DATA;
}
if(HPTaskAwoken == pdTRUE) {
@ -618,10 +638,10 @@ static void IRAM_ATTR uart_rx_intr_handler_default(void *param)
} else if(uart_intr_status & UART_BRK_DET_INT_ST_M) {
uart_reg->int_clr.brk_det = 1;
uart_event.type = UART_BREAK;
} else if(uart_intr_status & UART_PARITY_ERR_INT_ST_M ) {
} else if(uart_intr_status & UART_FRM_ERR_INT_ST_M) {
uart_reg->int_clr.parity_err = 1;
uart_event.type = UART_FRAME_ERR;
} else if(uart_intr_status & UART_FRM_ERR_INT_ST_M) {
} else if(uart_intr_status & UART_PARITY_ERR_INT_ST_M) {
uart_reg->int_clr.frm_err = 1;
uart_event.type = UART_PARITY_ERR;
} else if(uart_intr_status & UART_TX_BRK_DONE_INT_ST_M) {
@ -647,6 +667,9 @@ static void IRAM_ATTR uart_rx_intr_handler_default(void *param)
uart_reg->int_ena.tx_brk_idle_done = 0;
uart_reg->int_clr.tx_brk_idle_done = 1;
UART_EXIT_CRITICAL_ISR(&uart_spinlock[uart_num]);
} else if(uart_intr_status & UART_AT_CMD_CHAR_DET_INT_ST_M) {
uart_reg->int_clr.at_cmd_char_det = 1;
uart_event.type = UART_PATTERN_DET;
} else if(uart_intr_status & UART_TX_DONE_INT_ST_M) {
UART_ENTER_CRITICAL_ISR(&uart_spinlock[uart_num]);
uart_reg->int_ena.tx_done = 0;
@ -656,8 +679,7 @@ static void IRAM_ATTR uart_rx_intr_handler_default(void *param)
if(HPTaskAwoken == pdTRUE) {
portYIELD_FROM_ISR() ;
}
}
else {
} else {
uart_reg->int_clr.val = uart_intr_status; /*simply clear all other intr status*/
uart_event.type = UART_EVENT_MAX;
}
@ -833,6 +855,9 @@ int uart_read_bytes(uart_port_t uart_num, uint8_t* buf, uint32_t length, TickTyp
p_uart_obj[uart_num]->rx_cur_remain = size;
} else {
xSemaphoreGive(p_uart_obj[uart_num]->rx_mux);
UART_ENTER_CRITICAL(&uart_spinlock[uart_num]);
p_uart_obj[uart_num]->rx_buffered_len -= copy_len;
UART_EXIT_CRITICAL(&uart_spinlock[uart_num]);
return copy_len;
}
}
@ -853,6 +878,9 @@ int uart_read_bytes(uart_port_t uart_num, uint8_t* buf, uint32_t length, TickTyp
if(p_uart_obj[uart_num]->rx_buffer_full_flg) {
BaseType_t res = xRingbufferSend(p_uart_obj[uart_num]->rx_ring_buf, p_uart_obj[uart_num]->rx_data_buf, p_uart_obj[uart_num]->rx_stash_len, 1);
if(res == pdTRUE) {
UART_ENTER_CRITICAL(&uart_spinlock[uart_num]);
p_uart_obj[uart_num]->rx_buffered_len += p_uart_obj[uart_num]->rx_stash_len;
UART_EXIT_CRITICAL(&uart_spinlock[uart_num]);
p_uart_obj[uart_num]->rx_buffer_full_flg = false;
uart_enable_rx_intr(p_uart_obj[uart_num]->uart_num);
}
@ -860,9 +888,20 @@ int uart_read_bytes(uart_port_t uart_num, uint8_t* buf, uint32_t length, TickTyp
}
}
xSemaphoreGive(p_uart_obj[uart_num]->rx_mux);
UART_ENTER_CRITICAL(&uart_spinlock[uart_num]);
p_uart_obj[uart_num]->rx_buffered_len -= copy_len;
UART_EXIT_CRITICAL(&uart_spinlock[uart_num]);
return copy_len;
}
esp_err_t uart_get_buffered_data_len(uart_port_t uart_num, size_t* size)
{
UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_FAIL);
UART_CHECK((p_uart_obj[uart_num]), "uart driver error", ESP_FAIL);
*size = p_uart_obj[uart_num]->rx_buffered_len;
return ESP_OK;
}
esp_err_t uart_flush(uart_port_t uart_num)
{
UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_FAIL);
@ -873,10 +912,13 @@ esp_err_t uart_flush(uart_port_t uart_num)
//rx sem protect the ring buffer read related functions
xSemaphoreTake(p_uart->rx_mux, (portTickType)portMAX_DELAY);
esp_intr_disable(p_uart->intr_handle);
uart_disable_rx_intr(p_uart_obj[uart_num]->uart_num);
while(true) {
if(p_uart->rx_head_ptr) {
vRingbufferReturnItem(p_uart->rx_ring_buf, p_uart->rx_head_ptr);
UART_ENTER_CRITICAL(&uart_spinlock[uart_num]);
p_uart_obj[uart_num]->rx_buffered_len -= p_uart->rx_cur_remain;
UART_EXIT_CRITICAL(&uart_spinlock[uart_num]);
p_uart->rx_ptr = NULL;
p_uart->rx_cur_remain = 0;
p_uart->rx_head_ptr = NULL;
@ -885,47 +927,33 @@ esp_err_t uart_flush(uart_port_t uart_num)
if(data == NULL) {
break;
}
UART_ENTER_CRITICAL(&uart_spinlock[uart_num]);
p_uart_obj[uart_num]->rx_buffered_len -= size;
UART_EXIT_CRITICAL(&uart_spinlock[uart_num]);
vRingbufferReturnItem(p_uart->rx_ring_buf, data);
if(p_uart_obj[uart_num]->rx_buffer_full_flg) {
BaseType_t res = xRingbufferSend(p_uart_obj[uart_num]->rx_ring_buf, p_uart_obj[uart_num]->rx_data_buf, p_uart_obj[uart_num]->rx_stash_len, 1);
if(res == pdTRUE) {
UART_ENTER_CRITICAL(&uart_spinlock[uart_num]);
p_uart_obj[uart_num]->rx_buffered_len += p_uart_obj[uart_num]->rx_stash_len;
UART_EXIT_CRITICAL(&uart_spinlock[uart_num]);
p_uart_obj[uart_num]->rx_buffer_full_flg = false;
}
}
}
p_uart->rx_ptr = NULL;
p_uart->rx_cur_remain = 0;
p_uart->rx_head_ptr = NULL;
esp_intr_enable(p_uart->intr_handle);
xSemaphoreGive(p_uart->rx_mux);
if(p_uart->tx_buf_size > 0) {
xSemaphoreTake(p_uart->tx_mux, (portTickType)portMAX_DELAY);
esp_intr_disable(p_uart->intr_handle);
UART_ENTER_CRITICAL(&uart_spinlock[uart_num]);
UART[uart_num]->int_ena.txfifo_empty = 0;
UART[uart_num]->int_clr.txfifo_empty = 1;
UART_EXIT_CRITICAL(&uart_spinlock[uart_num]);
do {
data = (uint8_t*) xRingbufferReceive(p_uart->tx_ring_buf, &size, (portTickType) 0);
if(data == NULL) {
break;
}
vRingbufferReturnItem(p_uart->rx_ring_buf, data);
} while(1);
p_uart->tx_brk_flg = 0;
p_uart->tx_brk_len = 0;
p_uart->tx_head = NULL;
p_uart->tx_len_cur = 0;
p_uart->tx_len_tot = 0;
p_uart->tx_ptr = NULL;
p_uart->tx_waiting_brk = 0;
p_uart->tx_waiting_fifo = false;
esp_intr_enable(p_uart->intr_handle);
xSemaphoreGive(p_uart->tx_mux);
}
uart_reset_fifo(uart_num);
uart_enable_rx_intr(p_uart_obj[uart_num]->uart_num);
xSemaphoreGive(p_uart->rx_mux);
return ESP_OK;
}
esp_err_t uart_driver_install(uart_port_t uart_num, int rx_buffer_size, int tx_buffer_size, int queue_size, void* uart_queue, int intr_alloc_flags)
{
UART_CHECK((uart_num < UART_NUM_MAX), "uart_num error", ESP_FAIL);
UART_CHECK((rx_buffer_size > 0), "uart rx buffer length error", ESP_FAIL);
UART_CHECK((rx_buffer_size > UART_FIFO_LEN), "uart rx buffer length error(>128)", ESP_FAIL);
if(p_uart_obj[uart_num] == NULL) {
p_uart_obj[uart_num] = (uart_obj_t*) malloc(sizeof(uart_obj_t));
if(p_uart_obj[uart_num] == NULL) {
@ -946,6 +974,7 @@ esp_err_t uart_driver_install(uart_port_t uart_num, int rx_buffer_size, int tx_b
p_uart_obj[uart_num]->tx_brk_flg = 0;
p_uart_obj[uart_num]->tx_brk_len = 0;
p_uart_obj[uart_num]->tx_waiting_brk = 0;
p_uart_obj[uart_num]->rx_buffered_len = 0;
if(uart_queue) {
p_uart_obj[uart_num]->xQueueUart = xQueueCreate(queue_size, sizeof(uart_event_t));
@ -971,7 +1000,7 @@ esp_err_t uart_driver_install(uart_port_t uart_num, int rx_buffer_size, int tx_b
ESP_LOGE(UART_TAG, "UART driver already installed");
return ESP_FAIL;
}
uart_isr_register(uart_num, uart_rx_intr_handler_default, p_uart_obj[uart_num], intr_alloc_flags);
uart_isr_register(uart_num, uart_rx_intr_handler_default, p_uart_obj[uart_num], intr_alloc_flags, &p_uart_obj[uart_num]->intr_handle);
uart_intr_config_t uart_intr = {
.intr_enable_mask = UART_RXFIFO_FULL_INT_ENA_M
| UART_RXFIFO_TOUT_INT_ENA_M

View file

@ -94,5 +94,7 @@ Functions
.. doxygenfunction:: uart_write_bytes_with_break
.. doxygenfunction:: uart_read_bytes
.. doxygenfunction:: uart_flush
.. doxygenfunction:: uart_get_buffered_data_len
.. doxygenfunction:: uart_disable_pattern_det_intr
.. doxygenfunction:: uart_enable_pattern_det_intr

View file

@ -0,0 +1,9 @@
#
# This is a project Makefile. It is assumed the directory this Makefile resides in is a
# project subdirectory.
#
PROJECT_NAME := uart
include $(IDF_PATH)/make/project.mk

View file

@ -0,0 +1,3 @@
#
# Main Makefile. This is basically the same as a component makefile.
#

View file

@ -0,0 +1,183 @@
/* Uart Example
This example code is in the Public Domain (or CC0 licensed, at your option.)
Unless required by applicable law or agreed to in writing, this
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied.
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_system.h"
#include "nvs_flash.h"
#include "driver/uart.h"
#include "freertos/queue.h"
#include "esp_log.h"
#include "soc/uart_struct.h"
static const char *TAG = "uart_example";
/**
* Test code brief
* This example shows how to configure uart settings and install uart driver.
*
* uart_evt_test() is an example that read and write data on UART0, and handler some of the special events.
* - port: UART0
* - rx buffer: on
* - tx buffer: on
* - flow control: off
* - event queue: on
* - pin assignment: txd(default), rxd(default)
*
* uart_echo_test() is an example that read and write data on UART1, with hardware flow control turning on.
* - port: UART1
* - rx buffer: on
* - tx buffer: off
* - flow control: on
* - event queue: off
* - pin assignment: txd(io4), rxd(io5), rts(18), cts(19)
*/
#define BUF_SIZE (1024)
#define ECHO_TEST_TXD (4)
#define ECHO_TEST_RXD (5)
#define ECHO_TEST_RTS (18)
#define ECHO_TEST_CTS (19)
QueueHandle_t uart0_queue;
void uart_task(void *pvParameters)
{
int uart_num = (int) pvParameters;
uart_event_t event;
size_t buffered_size;
uint8_t* dtmp = (uint8_t*) malloc(BUF_SIZE);
for(;;) {
//Waiting for UART event.
if(xQueueReceive(uart0_queue, (void * )&event, (portTickType)portMAX_DELAY)) {
ESP_LOGI(TAG, "uart[%d] event:", uart_num);
switch(event.type) {
//Event of UART receving 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.
in this example, we don't process data in event, but read data outside.*/
case UART_DATA:
uart_get_buffered_data_len(uart_num, &buffered_size);
ESP_LOGI(TAG, "data, len: %d; buffered len: %d", event.size, buffered_size);
break;
//Event of HW FIFO overflow detected
case UART_FIFO_OVF:
ESP_LOGI(TAG, "hw fifo overflow\n");
//If fifo overflow happened, you should consider adding flow control for your application.
//We can read data out out the buffer, or directly flush the rx buffer.
uart_flush(uart_num);
break;
//Event of UART ring buffer full
case UART_BUFFER_FULL:
ESP_LOGI(TAG, "ring buffer full\n");
//If buffer full happened, you should consider encreasing your buffer size
//We can read data out out the buffer, or directly flush the rx buffer.
uart_flush(uart_num);
break;
//Event of UART RX break detected
case UART_BREAK:
ESP_LOGI(TAG, "uart rx break\n");
break;
//Event of UART parity check error
case UART_PARITY_ERR:
ESP_LOGI(TAG, "uart parity error\n");
break;
//Event of UART frame error
case UART_FRAME_ERR:
ESP_LOGI(TAG, "uart frame error\n");
break;
//UART_PATTERN_DET
case UART_PATTERN_DET:
ESP_LOGI(TAG, "uart pattern detected\n");
break;
//Others
default:
ESP_LOGI(TAG, "uart event type: %d\n", event.type);
break;
}
}
}
free(dtmp);
dtmp = NULL;
vTaskDelete(NULL);
}
void uart_evt_test()
{
int uart_num = UART_NUM_0;
uart_config_t uart_config = {
.baud_rate = 115200,
.data_bits = UART_DATA_8_BITS,
.parity = UART_PARITY_DISABLE,
.stop_bits = UART_STOP_BITS_1,
.flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
.rx_flow_ctrl_thresh = 122,
};
//Set UART parameters
uart_param_config(uart_num, &uart_config);
//Set UART log level
esp_log_level_set(TAG, ESP_LOG_INFO);
//Install UART driver, and get the queue.
uart_driver_install(uart_num, BUF_SIZE * 2, BUF_SIZE * 2, 10, &uart0_queue, 0);
//Set UART pins,(-1: default pin, no change.)
//For UART0, we can just use the default pins.
//uart_set_pin(uart_num, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE);
//Set uart pattern detect function.
uart_enable_pattern_det_intr(uart_num, '+', 3, 10000, 10, 10);
//Create a task to handler UART event from ISR
xTaskCreate(uart_task, "uart_task", 2048, (void*)uart_num, 12, NULL);
//process data
uint8_t* data = (uint8_t*) malloc(BUF_SIZE);
do {
int len = uart_read_bytes(uart_num, data, BUF_SIZE, 100 / portTICK_RATE_MS);
if(len > 0) {
ESP_LOGI(TAG, "uart read : %d", len);
uart_write_bytes(uart_num, (const char*)data, len);
}
} while(1);
}
//an example of echo test with hardware flow control on UART1
void uart_echo_test()
{
int uart_num = UART_NUM_1;
uart_config_t uart_config = {
.baud_rate = 115200,
.data_bits = UART_DATA_8_BITS,
.parity = UART_PARITY_DISABLE,
.stop_bits = UART_STOP_BITS_1,
.flow_ctrl = UART_HW_FLOWCTRL_CTS_RTS,
.rx_flow_ctrl_thresh = 122,
};
//Configure UART1 parameters
uart_param_config(uart_num, &uart_config);
//Set UART1 pins(TX: IO4, RX: I05, RTS: IO18, CTS: IO19)
uart_set_pin(uart_num, ECHO_TEST_TXD, ECHO_TEST_RXD, ECHO_TEST_RTS, ECHO_TEST_CTS);
//Install UART driver( We don't need an event queue here)
//In this example we don't even use a buffer for sending data.
uart_driver_install(uart_num, BUF_SIZE * 2, 0, 0, NULL, 0);
uint8_t* data = (uint8_t*) malloc(BUF_SIZE);
while(1) {
//Read data from UART
int len = uart_read_bytes(uart_num, data, BUF_SIZE, 20 / portTICK_RATE_MS);
//Write data back to UART
uart_write_bytes(uart_num, (const char*) data, len);
}
}
void app_main()
{
//A uart read/write example without event queue;
xTaskCreate(uart_echo_test, "uart_echo_test", 1024, NULL, 10, NULL);
//A uart example with event queue.
uart_evt_test();
}