184 lines
6.6 KiB
C
184 lines
6.6 KiB
C
|
/* 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();
|
||
|
}
|