全志T113-S3裸机串口驱动(串口DMA发送,中断接收)

        前几年用V3S串口的时候,想用DMA进行收发,结果发现DMA只能接收32的整数倍数据,如今在T113-S3上面依旧存在这个问题,折腾很久依旧没有解决,最后只能通过DMA进行发送,中断进行接收,好在这个芯片的接收FIFO格外大,哪怕频繁接收也不会过多产生中断,除了串口0,其余的串口有200多个字节的收发FIFO,发送逻辑为发送的数据如果没有超过串口发送FIFO大小则直接通过FIFO发送,如果超过了,则使用DMA,提高效率。

        中断模式需要GIC支持,DMA模式需要DMA支持,寄存器都是自己定义的,但是名称与手册上面一致,大家可以按照手册上面分析,代码几乎与V3S兼容。

/*************************************************************************************************************
 * 文件名:			uart.c
 * 功能:			全志T113 UART通讯支持
 * 作者:			cp1300@139.com
 * 创建时间:		2020-08-11
 * 最后修改时间:	2023-10-2
 * 详细:			串口通信底层支持
 *					串口通讯DMA存在问题,如果不开启DMA BMODE则出现重复接收,数据不及时显示,如果开启BMODE则数据会及时显示
 *					但是存在超过8字节后有4字节接收为0,后面会出现4字节正常,4字节异常,交替:123456783456123490
 *				2024-07-06:开启了DMA发送,屏蔽DMA接收
*************************************************************************************************************/
#include "t113_system.h"
#include "uart.h"
#include "typedef.h"
#if UART_TX_DMA_EN	//使用发送
#include "dma.h"
//static DMA_CH_Type sg_UartRxDmaChannel[UART_ChMax] = {DMA_CH_NULL, DMA_CH_NULL, DMA_CH_NULL, DMA_CH_NULL , DMA_CH_NULL , DMA_CH_NULL };		//初始化为无效
//static const DMA_SOURCE_DRQ_TYPE scg_UartDmaRxDRQ[UART_ChMax] = {DMA_SOURCE_UART0_RX, DMA_SOURCE_UART1_RX, DMA_SOURCE_UART2_RX, DMA_SOURCE_UART3_RX , DMA_SOURCE_UART4_RX , DMA_SOURCE_UART5_RX };	//串口 DMA 源类型
static const DMA_DEST_DRQ_TYPE scg_UartDmaTxDRQ[UART_ChMax] = {DMA_DEST_UART0_TX, DMA_DEST_UART1_TX, DMA_DEST_UART2_TX, DMA_DEST_UART3_TX , DMA_DEST_UART4_TX , DMA_DEST_UART5_TX };				//串口 DMA 目标类型
static DMA_LLI_TYPE dma_tx_lln[UART_ChMax];                                                                                         //串口发送DMA链表
//static DMA_LLI_TYPE dma_rx_lln[UART_ChMax];                                                                                         //串口接收DMA链表
#endif //UART_TX_DMA_EN

#include "irq_gic400.h"
static const GIC_IRQ_Typedef scg_UartIrqType[UART_ChMax] = {GIC_IRQ_UART0, GIC_IRQ_UART1, GIC_IRQ_UART2, GIC_IRQ_UART3 , GIC_IRQ_UART4 , GIC_IRQ_UART5 };	//中断编号
void UART0_IRQHandler(void);//串口0接收中断
void UART1_IRQHandler(void);//串口1接收中断
void UART2_IRQHandler(void);//串口2接收中断
void UART3_IRQHandler(void);//串口3接收中断
void UART4_IRQHandler(void);//串口4接收中断
void UART5_IRQHandler(void);//串口5接收中断
static const void *scg_pUartIrqHandle[UART_ChMax] = { (const void*)UART0_IRQHandler, (const void *)UART1_IRQHandler, (const void *)UART2_IRQHandler, (const void *)UART3_IRQHandler
, (const void*)UART4_IRQHandler , (const void*)UART5_IRQHandler };

static const u32 scg_UARTx_Base[UART_ChMax] = {UART0_BASE, UART1_BASE, UART2_BASE, UART3_BASE , UART4_BASE , UART5_BASE };		//基址

//相关UART状态结构
typedef struct
{
	bool		isNewDataFlag;	//接收到新数据
	bool		isBuffFull;		//接收Buff满
	bool		isIntRx;		//是否开启中断接收
	u8 			*RxBuff;		//接收Buff指针
	u16			RxBuffSize;		//接收缓冲区大小,一帧数据大小
	u16 		UartRxCnt;		//接收数据计数器
	u8			TempData;		//用于接收溢出后读取数据寄存器,清除读取数据标志
} UartRx_TypeDef;
static UartRx_TypeDef sg_UartRx[UART_ChMax];

/*************************************************************************************************************************
*函数        	:	bool UARTx_Config(UART_CH_Type ch,UART_Config_TypeDef * cfg)
*功能        	:	串口配置
*参数        	:	ch:串口号;cfg:配置结构体
*返回        	:	TRUE:配置成功; FALSE: 配置失败
*依赖			: 	底层宏定义
*作者       	:	cp1300@139.com
*时间     		:	2020-08-11
*最后修改时间	:	2020-08-11
*说明        	:	调用前请提前停止发送
*************************************************************************************************************************/
bool UARTx_Config(UART_CH_Type ch,UART_Config_TypeDef * cfg)
{
	u32 temp;
	bool isBusy;
	
	if(ch > UART_ChMax - 1)
		return FALSE;	//端口号超出范围
	
	isBusy = (r_UARTx_USR(scg_UARTx_Base[ch]) & BIT0) ? TRUE : FALSE;	//获取忙状态
	if(isBusy) 											//当前忙
	{
		r_UARTx_HALT(scg_UARTx_Base[ch]) |= BIT1;		//使能忙时修改拨通了与LCR配置
	}
	else
	{
		r_UARTx_LCR(scg_UARTx_Base[ch]) &= ~BIT7;		//清除掉DLAB,此位必须清零才能访问其他寄存器;
	}
	
	//配置寄存器
	temp = 0;
	if(cfg->OddEvenVerify)								//开启了奇偶校验
	{
		temp |= BIT3;	
		if(cfg->OddEvenVerify == UART_EVEN)				//偶校验
		{
			temp |= BIT4;
		}
	}
	//停止位
	if(cfg->StopBitWidth == UART_STOP_2BIT)				//2个停止位
	{
		temp |= BIT2;	
	}

	//数据位数
	temp |= cfg->DataBitWidth & 0x3;
	//配置写入到LCR
	r_UARTx_LCR(scg_UARTx_Base[ch]) = temp;
	
	if(isBusy) 	
	{
		r_UARTx_HALT(scg_UARTx_Base[ch]) |= BIT2;		//更新忙时修改
		while(r_UARTx_HALT(scg_UARTx_Base[ch]) & BIT2);	//等待更新成功
		r_UARTx_HALT(scg_UARTx_Base[ch]) &= ~BIT1;		//清除忙时修改拨通了与LCR配置
	}
	
	return TRUE;
}



/*************************************************************************************************************************
* 函数	:	void UARTx_SetBaudRate(UART_CH_Type ch,u32 baud)
* 功能	:	串口波特率设置
* 参数	:	ch:通道选择,baud:波特率,如9600,115200等等
* 返回	:	无
* 依赖	:	底层宏定义
* 作者	:	cp1300@139.com
* 时间	:	2013316
* 最后修改时间 : 2013316
* 说明	: 	USART1~UART5,对应通道UART_CH1-UART_CH5
			设置前必须关闭串口
			会自动获取系统当前的时钟,
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

cp1300

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值