1. driver/uart/uart.c文件添加自定义函数 (ESP-IDF V5.2.2)
intr_handle_t uart_get_intr_handle( uart_port_t uart_num )
{
if( uart_num >= SOC_UART_HP_NUM )
{
return NULL;
}
return p_uart_obj[uart_num]->intr_handle;
}
uart_hal_context_t uart_get_context( uart_port_t uart_num )
{
uart_hal_context_t hal;
hal.dev = NULL;
if( uart_num >= SOC_UART_HP_NUM )
{
return hal;
}
hal = uart_context[uart_num].hal;
return hal;
}
2. 100ms调用一次 BspUart2Test
//.c文件
#include "bsp_uart.h"
#include "esp_attr.h"
#include "driver/uart.h"
#include "soc/uart_reg.h"
#include "hal/uart_hal.h"
#include "soc/interrupts.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
void IRAM_ATTR BspUart2IrqHandler( void *arg );
extern intr_handle_t uart_get_intr_handle( uart_port_t uart_num );
extern uart_hal_context_t uart_get_context( uart_port_t uart_num );
extern uint32_t uart_enable_tx_write_fifo(uart_port_t uart_num, const uint8_t *pbuf, uint32_t len);
//初始化
void BspUart2Init(void)
{
intr_handle_t handle;
uart_hal_context_t dev;
// esp_log_level_set(TAG, ESP_LOG_INFO);
uart_config_t uart_config =
{
.baud_rate = 115200,
.data_bits = UART_DATA_8_BITS, //8
.parity = UART_PARITY_DISABLE, //0
.stop_bits = UART_STOP_BITS_1, //1
.flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
.source_clk = UART_SCLK_DEFAULT,
};
uart_param_config( BSP_UART2_NUM, &uart_config );
uart_set_rx_timeout( BSP_UART2_NUM, 5 );
//uart_set_rx_full_threshold( BSP_UART2_NUM, BSP_UART2_RX_BUFF_SIZE );
// Set UART pins (using UART0 default pins ie no changes.)
uart_set_pin( BSP_UART2_NUM, BSP_UART2_PIN_TX, BSP_UART2_PIN_RX, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE );
//这里是关键点,必须要先uart_driver_install安装驱动,在把中断服务给释放掉
uart_driver_install( BSP_UART2_NUM, BSP_UART2_RX_BUFF_SIZE * 2, BSP_UART2_TX_BUFF_SIZE * 2, 0, NULL, 0 );
handle = uart_get_intr_handle( BSP_UART2_NUM );
//必须释放出中断函数
esp_intr_free( handle );
// Allocate interrupt
esp_err_t ret = esp_intr_alloc( ETS_UART2_INTR_SOURCE, ESP_INTR_FLAG_IRAM, BspUart2IrqHandler, NULL, NULL ); //ESP_INTR_FLAG_IRAM
if (ret != ESP_OK)
{
return;
}
//清除中断标志位
dev = uart_get_context( BSP_UART2_NUM );
uart_clear_intr_status( BSP_UART2_NUM, UART_INTR_RXFIFO_FULL | UART_INTR_RXFIFO_TOUT | UART_INTR_TXFIFO_EMPTY );
//使能串口接收中断
uart_enable_rx_intr( BSP_UART2_NUM );
//使能串口发送中断
//uart_enable_tx_intr( BSP_UART2_NUM, 1, 0 );
}
volatile uint8_t BspUart2RxDone = 0;
volatile uint32_t BspUart2RxSize = 0;
uint8_t BspUart2RxBuff[BSP_UART2_RX_BUFF_SIZE];
uint8_t BspUart2TxBuff[BSP_UART2_RX_BUFF_SIZE];
// 中断处理函数
void IRAM_ATTR BspUart2IrqHandler( void *arg )
{
uart_hal_context_t dev;
uint8_t flag;
int num;
int size;
int rSize;
uint32_t irqS;
//获取中断标志位
dev = uart_get_context( BSP_UART2_NUM );
irqS = uart_hal_get_intsts_mask( &dev );
if( irqS == 0 )
{
return;
}
//接收区满
if( irqS & UART_INTR_RXFIFO_FULL )
{
//清除中断标志位
uart_clear_intr_status( BSP_UART2_NUM, UART_INTR_RXFIFO_FULL );
//读取FIFO长度
flag = 0;
num = sizeof( BspUart2RxBuff );
rSize = uart_ll_get_rxfifo_len( dev.dev );
//读取数据
if( rSize )
{
if( (BspUart2RxSize + rSize) >= (BSP_UART2_RX_BUFF_SIZE - 1) )
{
rSize = BSP_UART2_RX_BUFF_SIZE - 1 - BspUart2RxSize;
if( rSize < 0 )
{
rSize = 0;
}
flag++;
}
size = rSize;
if( rSize )
{
uart_hal_read_rxfifo( &dev, BspUart2RxBuff + BspUart2RxSize, &size );
}
BspUart2RxSize += rSize;
if( flag )
{
uart_hal_rxfifo_rst( &dev );
}
}
}
//接收空闲
if( irqS & UART_INTR_RXFIFO_TOUT )
{
//清除中断标志位
uart_clear_intr_status( BSP_UART2_NUM, UART_INTR_RXFIFO_TOUT );
//读取FIFO长度
flag = 0;
num = sizeof( BspUart2RxBuff );
rSize = uart_ll_get_rxfifo_len( dev.dev );
//读取数据
if( rSize )
{
if( (BspUart2RxSize + rSize) >= (BSP_UART2_RX_BUFF_SIZE - 1) )
{
rSize = BSP_UART2_RX_BUFF_SIZE - 1 - BspUart2RxSize;
if( rSize < 0 )
{
rSize = 0;
}
flag++;
}
size = rSize;
if( rSize )
{
uart_hal_read_rxfifo( &dev, BspUart2RxBuff + BspUart2RxSize, &size );
}
BspUart2RxSize += rSize;
if( flag )
{
uart_hal_rxfifo_rst( &dev );
}
}
}
if( irqS & UART_INTR_RXFIFO_OVF )
{
uart_clear_intr_status( BSP_UART2_NUM, UART_INTR_RXFIFO_OVF );
}
//发送完成
if( irqS & UART_INTR_TXFIFO_EMPTY )
{
//清除中断标志位
uart_disable_intr_mask( BSP_UART2_NUM, UART_INTR_TXFIFO_EMPTY );
uart_clear_intr_status( BSP_UART2_NUM, UART_INTR_TXFIFO_EMPTY );
//发送完成
BspUart2RxDone = 1;
}
if( irqS & UART_INTR_TX_DONE )
{
//清除中断标志位
uart_disable_intr_mask( BSP_UART2_NUM, UART_INTR_TX_DONE );
uart_clear_intr_status( BSP_UART2_NUM, UART_INTR_TX_DONE );
//发送完成
BspUart2RxDone = 1;
}
}
//测试
void BspUart2Test( void )
{
uart_hal_context_t dev;
int i;
uint32_t size;
uint32_t tSize;
uint32_t offset;
size = BspUart2RxSize;
if( !size )
{
return;
}
BspUart2RxSize = 0;
if( size )
{
printf("\r\nsize: %d ", (int)size );
for( i = 0; (i < size) && (i < sizeof(BspUart2RxBuff)); i++ )
{
printf("%c", (char)BspUart2RxBuff[i] );
}
printf("\n" );
memcpy( BspUart2TxBuff, BspUart2RxBuff, size );
//清除中断标志位
uart_clear_intr_status( BSP_UART2_NUM, UART_INTR_TXFIFO_EMPTY );
//使能发送中断
BspUart2RxDone = 0;
uart_enable_tx_intr( BSP_UART2_NUM, 1, 0 );
//发送数据
offset = 0;
dev = uart_get_context( BSP_UART2_NUM );
while( (size > 0) && ((offset + size) < BSP_UART2_TX_BUFF_SIZE) )
{
tSize = uart_enable_tx_write_fifo( BSP_UART2_NUM, BspUart2TxBuff + offset, size );
size -= tSize;
offset += tSize;
}
uart_enable_tx_intr( BSP_UART2_NUM, 1, 0 );
//等待发送完成
while( !BspUart2RxDone )
{
vTaskDelay( 1 );
i++;
//超时
if( i > 300 )
{
printf("TX-TIMEOUT\r\n" );
return;
}
}
printf("TX-OK\r\n" );
}
}
//.h文件
#ifndef __BSP_UART_H
#define __BSP_UART_H
#include <stdbool.h>
#include <stdint.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#define DBUG_APP_AD_ENT 1
#define BSP_UART2_NUM UART_NUM_2
#define BSP_UART2_PIN_TX 40
#define BSP_UART2_PIN_RX 39
#define BSP_UART2_RX_BUFF_SIZE 1024
#define BSP_UART2_TX_BUFF_SIZE 1024
void BspUart2Init(void);
void BspUart2Test( void );
#endif