271 lines
8.7 KiB
C
271 lines
8.7 KiB
C
/*
|
|
* uart.c
|
|
*
|
|
* Created on: Jan 10, 2023
|
|
* Author: Partha
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include "freertos/FreeRTOS.h"
|
|
#include "freertos/task.h"
|
|
#include "freertos/queue.h"
|
|
#include "driver/uart.h"
|
|
#include "esp_log.h"
|
|
#include "uart_ifx.h"
|
|
|
|
static const char *TAG = "UART_IFX";
|
|
#define LOG_LOCAL_LEVEL ESP_LOG_INFO
|
|
|
|
#define BUF_SIZE 4096
|
|
#define RD_BUF_SIZE (BUF_SIZE)
|
|
|
|
static QueueHandle_t uart0_queue;
|
|
static QueueHandle_t uart1_queue;
|
|
|
|
static uint8_t buffer1[BUF_SIZE];
|
|
static uint8_t buffer2[BUF_SIZE];
|
|
|
|
QueueHandle_t uart0_data_queue;
|
|
QueueHandle_t uart1_data_queue;
|
|
|
|
bool uart1_rx_needed = false;
|
|
|
|
static size_t buffer2_size = 0;
|
|
|
|
static void uart0_event_task(void *pvParameters)
|
|
{
|
|
uart_event_t event;
|
|
|
|
for(;;)
|
|
{
|
|
//Waiting for UART event.
|
|
if(xQueueReceive(uart0_queue, (void * )&event, (TickType_t)portMAX_DELAY))
|
|
{
|
|
bzero(buffer1, RD_BUF_SIZE);
|
|
ESP_LOGI(TAG, "uart[%d] event:", UART_NUM_0);
|
|
|
|
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_0, buffer1, event.size, portMAX_DELAY);
|
|
|
|
for(int index = 0; index < event.size; index++)
|
|
{
|
|
xQueueSend(uart0_data_queue, &buffer1[index], 10);
|
|
}
|
|
uart_ifx_uart0_rx_cb();*/
|
|
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_0);
|
|
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 increasing your buffer size
|
|
// As an example, we directly flush the rx buffer here in order to read more data.
|
|
uart_flush_input(UART_NUM_0);
|
|
xQueueReset(uart0_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;
|
|
}
|
|
}
|
|
}
|
|
vTaskDelete(NULL);
|
|
}
|
|
|
|
|
|
static void uart1_event_task(void *pvParameters)
|
|
{
|
|
uart_event_t event;
|
|
portMUX_TYPE uMutex = portMUX_INITIALIZER_UNLOCKED;
|
|
|
|
for(;;)
|
|
{
|
|
//Waiting for UART event.
|
|
if(xQueueReceive(uart1_queue, (void * )&event, (TickType_t)portMAX_DELAY))
|
|
{
|
|
bzero(buffer2, RD_BUF_SIZE);
|
|
//ESP_LOGI(TAG, "uart[%d] event:", UART_NUM_1);
|
|
|
|
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_1, buffer2, event.size, portMAX_DELAY);
|
|
if(uart1_rx_needed)
|
|
{
|
|
buffer2_size = event.size;
|
|
//ESP_LOGI(TAG, "UART Rx: %s", buffer2);
|
|
taskENTER_CRITICAL(&uMutex);
|
|
for(int index = 0; index < event.size; index++)
|
|
{
|
|
xQueueSend(uart1_data_queue, &buffer2[index], 1000);
|
|
}
|
|
taskEXIT_CRITICAL(&uMutex);
|
|
uart_ifx_uart1_rx_cb();
|
|
}
|
|
//ESP_LOGI(TAG, "UART RX: %s%s", buffer2, (!uart1_rx_needed)?" [MISSED]":"");
|
|
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_1);
|
|
xQueueReset(uart1_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 increasing your buffer size
|
|
// As an example, we directly flush the rx buffer here in order to read more data.
|
|
uart_flush_input(UART_NUM_1);
|
|
xQueueReset(uart1_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;
|
|
}
|
|
}
|
|
}
|
|
vTaskDelete(NULL);
|
|
}
|
|
|
|
void uart_create_rx_tasks(void)
|
|
{
|
|
//Create a task to handler UART event from ISR
|
|
//xTaskCreate(uart0_event_task, "uart0_event_task", 2048, NULL, 18, NULL);
|
|
xTaskCreate(uart1_event_task, "uart1_event_task", 2048, NULL, 19, NULL);
|
|
}
|
|
|
|
void uart_ifx_init(void)
|
|
{
|
|
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,
|
|
.source_clk = UART_SCLK_APB,
|
|
};
|
|
|
|
//Install UART driver, and get the queue.
|
|
//ESP_ERROR_CHECK(uart_driver_install(UART_NUM_0, (BUF_SIZE+1024), (BUF_SIZE+1024), 20, &uart0_queue, 0));
|
|
//ESP_ERROR_CHECK(uart_param_config(UART_NUM_0, &uart_config));
|
|
|
|
ESP_ERROR_CHECK(uart_driver_install(UART_NUM_1, (BUF_SIZE+1024), (BUF_SIZE+1024), 20, &uart1_queue, 0));
|
|
ESP_ERROR_CHECK(uart_param_config(UART_NUM_1, &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_0, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE));
|
|
ESP_ERROR_CHECK(uart_set_pin(UART_NUM_1, 17, 18, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE));
|
|
|
|
//uart0_data_queue = xQueueCreate(BUF_SIZE, sizeof(uint8_t));
|
|
uart1_data_queue = xQueueCreate(BUF_SIZE, sizeof(uint8_t));
|
|
}
|
|
|
|
uint8_t uart_ifx_uart0_ifx_get_rx_data(uint8_t *rx)
|
|
{
|
|
if(xQueueReceive(uart0_data_queue, rx, (TickType_t)100) == pdPASS)
|
|
{
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
uint8_t uart_ifx_uart1_ifx_get_rx_data(uint8_t *rx)
|
|
{
|
|
if(xQueueReceive(uart1_data_queue, rx, (TickType_t)100) == pdPASS)
|
|
{
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
void uart_ifx_uart0_send_byte(uint8_t data)
|
|
{
|
|
uart_write_bytes(UART_NUM_0, &data, 1);
|
|
}
|
|
|
|
void uart_ifx_uart1_send_byte(uint8_t data)
|
|
{
|
|
uart_write_bytes(UART_NUM_1, &data, 1);
|
|
}
|
|
|
|
void uart_ifx_uart0_send_bytes(uint8_t *data, size_t length)
|
|
{
|
|
uart_write_bytes(UART_NUM_0, data, length);
|
|
}
|
|
|
|
void uart_ifx_uart1_send_bytes(uint8_t *data, size_t length)
|
|
{
|
|
uart_write_bytes(UART_NUM_1, data, length);
|
|
}
|
|
|
|
uint8_t *uart_ifx_uart1_get_rx_buffer(size_t *len)
|
|
{
|
|
*len = buffer2_size;
|
|
return buffer2;
|
|
}
|
|
|