refactor(driver): Refactor uart driver for esp8266 idf

This commit is contained in:
xiewenxiang
2018-06-13 19:48:16 +08:00
committed by XiongYu
parent 220c26ad48
commit 97335027c7
16 changed files with 3762 additions and 26 deletions

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_echo
include $(IDF_PATH)/make/project.mk

View File

@ -0,0 +1,61 @@
# _UART Echo Example_
_This is an example which echoes any data it receives on UART0 back to the sender._
## How to use example
### Hardware Required
1. Connect an external serial interface to an ESP8266 board. The external interface should have 3.3V outputs. You may use e.g. 3.3V compatible USB-to-serial dongle:
| ESP8266 Interface | #define | ESP8266 Pin | External UART Pin |
| --- | --- | --- | --- |
| Transmit Data (TxD) | ECHO_TEST_TXD | GPIO26 | RxD |
| Receive Data (RxD) | ECHO_TEST_RXD | GPIO25 | TxD |
| Ground | n/a | GND | GND |
2. Verify if echo indeed comes from ESP8266 by disconnecting either 'TxD' or 'RxD' pin. There should be no any echo once any pin is disconnected.
* Using a hardware flow control
This is an optional check to verify if the hardware flow control works. To set it up you need an external serial interface that has RTS and CTS signals.
1. Connect the extra RTS/CTS signals as below
| ESP8266 Interface | #define | ESP8266 Pin | External UART Pin |
| --- | --- | --- | --- |
| Request to Send (RTS) | ECHO_TEST_RTS | GPIO13 | CTS |
| Clear to Send (CTS) | ECHO_TEST_CTS | GPIO12 | RTS |
2. Configure UART0 driver to use the hardware flow control by setting `.flow_ctrl = UART_HW_FLOWCTRL_CTS_RTS` and adding `.rx_flow_ctrl_thresh = 122`
### Configure the project
```
make menuconfig
```
* Set serial port under Serial Flasher Options.
* `make monitor` baud rate set to what you set in the example.
### Build and Flash
Build the project and flash it to the board, then run monitor tool to view serial output:
```
make -j4 flash monitor
```
(To exit the serial monitor, type ``Ctrl-]``.)
See the Getting Started Guide for full steps to configure and use ESP-IDF to build projects.
## Example Output
```
I (180) boot: Loaded app from partition at offset 0x10000
I (0) system_api: Base MAC address is not set, read default base MAC address from BLK0 of EFUSE
I (0) system_api: Base MAC address is not set, read default base MAC address from BLK0 of EFUSE
0123456789
```

View File

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

View File

@ -0,0 +1,65 @@
// Copyright 2018-2025 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/uart.h"
/**
* This is an example which echos any data it receives on UART0 back to the sender,
* with hardware flow control turned off. It does not use UART driver event queue.
*
* - Port: UART0
* - Receive (Rx) buffer: on
* - Transmit (Tx) buffer: off
* - Flow control: off
* - Event queue: off
*/
#define BUF_SIZE (1024)
static void echo_task()
{
// Configure parameters of an UART driver,
// communication pins and install the driver
uart_config_t uart_config = {
.baud_rate = 74880,
.data_bits = UART_DATA_8_BITS,
.parity = UART_PARITY_DISABLE,
.stop_bits = UART_STOP_BITS_1,
.flow_ctrl = UART_HW_FLOWCTRL_DISABLE
};
uart_param_config(UART_NUM_0, &uart_config);
uart_driver_install(UART_NUM_0, BUF_SIZE * 2, 0, 0, NULL);
// Configure a temporary buffer for the incoming data
uint8_t *data = (uint8_t *) malloc(BUF_SIZE);
while (1) {
// Read data from the UART
int len = uart_read_bytes(UART_NUM_0, data, BUF_SIZE, 20 / portTICK_RATE_MS);
// Write data back to the UART
uart_write_bytes(UART_NUM_0, (const char *) data, len);
}
}
void app_main()
{
xTaskCreate(echo_task, "uart_echo_task", 1024, NULL, 10, NULL);
}

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_events
include $(IDF_PATH)/make/project.mk

View File

@ -0,0 +1,45 @@
# _UART Events Example_
_This example shows how to use the UART driver to handle special UART events. It also reads data from UART0 directly, and echoes it to console._
* Compile and load example from terminl running `make flash monitor`
* Being in 'monotor' type samething to see the `UART_DATA` events and the typed data displayed.
## How to use example
### Configure the project
```
make menuconfig
```
* Set serial port under Serial Flasher Options.
* `make monitor` baud rate set to what you set in the example.
### Build and Flash
Build the project and flash it to the board, then run monitor tool to view serial output:
```
make -j4 flash monitor
```
(To exit the serial monitor, type ``Ctrl-]``.)
See the Getting Started Guide for full steps to configure and use ESP-IDF to build projects.
## Example Output
* Paste `0123456789` to monitor, the `UART DATA` event will be received.
```
I (185) boot: Loaded app from partition at offset 0x10000
I (0) system_api: Base MAC address is not set, read default base MAC address from BLK0 of EFUSE
I (0) system_api: Base MAC address is not set, read default base MAC address from BLK0 of EFUSE
I (0) uart: queue free spaces: 100
I (15) uart_events: uart[0] event:
I (15) uart_events: [UART DATA]: 10
I (15) uart_events: [DATA EVT]:
0123456789
```

View File

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

View File

@ -0,0 +1,128 @@
// Copyright 2018-2025 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#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_events";
/**
* This example shows how to use the UART driver to handle special UART events.
*
* It also reads data from UART0 directly, and echoes it to console.
*
* - Port: UART0
* - Receive (Rx) buffer: on
* - Transmit (Tx) buffer: on
* - Flow control: off
* - Event queue: on
* - Pin assignment: TxD (default), RxD (default)
*/
#define EX_UART_NUM UART_NUM_0
#define BUF_SIZE (1024)
#define RD_BUF_SIZE (BUF_SIZE)
static QueueHandle_t uart0_queue;
static void uart_event_task(void *pvParameters)
{
uart_event_t event;
size_t buffered_size;
uint8_t *dtmp = (uint8_t *) malloc(RD_BUF_SIZE);
for (;;) {
// Waiting for UART event.
if (xQueueReceive(uart0_queue, (void *)&event, (portTickType)portMAX_DELAY)) {
bzero(dtmp, RD_BUF_SIZE);
ESP_LOGI(TAG, "uart[%d] event:", EX_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.
case UART_DATA:
ESP_LOGI(TAG, "[UART DATA]: %d", event.size);
uart_read_bytes(EX_UART_NUM, dtmp, event.size, portMAX_DELAY);
ESP_LOGI(TAG, "[DATA EVT]:");
uart_write_bytes(EX_UART_NUM, (const char *) dtmp, event.size);
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(EX_UART_NUM);
xQueueReset(uart0_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(EX_UART_NUM);
xQueueReset(uart0_queue);
break;
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 app_main()
{
// Configure parameters of an UART driver,
// communication pins and install the driver
uart_config_t uart_config = {
.baud_rate = 74880,
.data_bits = UART_DATA_8_BITS,
.parity = UART_PARITY_DISABLE,
.stop_bits = UART_STOP_BITS_1,
.flow_ctrl = UART_HW_FLOWCTRL_DISABLE
};
uart_param_config(EX_UART_NUM, &uart_config);
// Install UART driver, and get the queue.
uart_driver_install(EX_UART_NUM, BUF_SIZE * 2, BUF_SIZE * 2, 100, &uart0_queue);
// Create a task to handler UART event from ISR
xTaskCreate(uart_event_task, "uart_event_task", 2048, NULL, 12, NULL);
}