Remote_Wifi_Switch/main/uart_ifx.c
2025-02-21 15:26:53 +05:30

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;
}