一,初始化
1,给UART模块上电
2,执行必要的设备pin多路复用设置(请参阅设备特定的数据手册)。
3,配置
(1)通过将适当的时钟除数值写入除数锁存寄存器(DLL和DLH)来设置所需的波特率
(2)1GHz主频下 UART输入频率166666666Hz
4,如果要使用FIFO(FCR中的FIFOEN=1),则必须先设置FCR中的FIFOEN位,然后再配置FCR中的其他位。选择所需的触发电平,并通过将适当的值写入FIFO控制寄存器(FCR)来启用FIFO。通过设置TXCLR=1和RXCLR=1,清除发射机FIFO和接收机FIFO。
5,通过将适当的值写入线路控制寄存器(LCR)来选择所需的协议设置。e、 g.设置PEN=0(无奇偶校验),STB=0(1停止位),WLS=0x3(8位)
6,如果需要中断,请设置IER控制器。
7,如果需要自动流量控制,将适当的值写入调制解调器控制寄存器(MCR)。请注意,所有UART都不支持自动流量控制,有关支持的功能,请参阅设备特定的数据手册。
8,通过配置空闲位来选择对仿真挂起事件的所需响应,并通过在电源和仿真管理寄存器(PWREMU\u MGMT)中设置UTRST和URRST位来启用UART。这里我设置UTRST=1(发射机已启用),URRST=1(接收器已启用),FREE=1(启用自由运行模式;UART继续正常运行)
9,根据需求配置中断 IER寄存器(一般配置为IER=0x5,即接收中断和receiver line status异常中断)
10,映射中断函数到中断向量表。
二,串口数据发送
UART发送器部分包括发送器保持寄存器(THR)和发送器移位寄存器(TSR)。当UART处于FIFO模式时,THR是一个16字节的FIFO。发送器部分控制是UART线路控制寄存器(LCR)的功能。 串口发送时,只需要判断THR(即FIFO)为空,想THR写入即可。
1.读取TEMT in LSR来判断THR和TSR是否为空, 循环等待直到THRE =1
2.可以加一点延迟,为了稳定我这里加了30us延迟,如果不加延迟也能稳定运行可以不加
3.循环发送数据
a.写入数据到THR
b.等待UART发送数据,发送完成后THRE=1
c.重复执行a,b,直到数据发送完成
三,串口数据接收
接收时,判断RBR中有未读数据,读出该数据,再判断是否有新数据,有则继续读出来。但是一次中断读取次数不能超过配置的FIFO大小,超出则溢出了。当达到FIFO大小时,例如有8字节,读出8字节后则停止,等待下一次UART中断,再读数据。
1.读取IIR状态,判断是否属于receiver相关中断(INTID = 2 | INTID = 3 | INTID = 6)
2.读取DR in LSR来判断Data是否ready, 循环等待直到DR =1
3.循环读取数据
a.等待DR=1 in LSR register
b.从RBR中读出数据到内存
c.判断读取字节数是否超出FIFO长度,超出则结束读取,等待下一个接收中断
d.重复执行a,b,直到数据发送完成
四,串口uart初始化
void DebugUartInit(void)
{
RK6748_uartInit(DEBUG_PORT,DEBUG_PORT_BaudRate);
RK6748_uartIntEnable(DEBUG_PORT);
SetupInt();
ConfigureIntUART1();
}
/*========================================================*
* 文件模块说明:
*C6748的串口驱动,1和2是RS232,0是TTL
* 文件版本: V1.0.0
* 开发人员: Rock
* 创建时间: 2013-11-01
* Copyright(c) 2013-2015 Rock-Embed Limited Co.
*========================================================*/
#include "types.h"
#include "rk6748.h"
#include "test_uart.h"
// pinmux defines.
#define PINMUX_UART0_REG (3)
#define PINMUX_UART0_MASK (0x0000FFFF)
#define PINMUX_UART0_VAL (0x00002222)
#define PINMUX_UART1_REG_0 (0)
#define PINMUX_UART1_MASK_0 (0x00FF0000)
#define PINMUX_UART1_VAL_0 (0x00220000)
#define PINMUX_UART1_REG_1 (4)
#define PINMUX_UART1_MASK_1 (0xFF000000)
#define PINMUX_UART1_VAL_1 (0x22000000)
#define PINMUX_UART2_REG_0 (0)
#define PINMUX_UART2_MASK_0 (0xFF000000)
#define PINMUX_UART2_VAL_0 (0x44000000)
#define PINMUX_UART2_REG_1 (4)
#define PINMUX_UART2_MASK_1 (0x00FF0000)
#define PINMUX_UART2_VAL_1 (0x00220000)
#define UART_REG_READ(base,reg, result) \
((result) = (*(volatile UINT32 *)((UINT32)base + (reg))))
#define UART_REG_WRITE(base,reg, data) \
((*(volatile UINT32 *)((UINT32)base + (reg))) = (data))
UINT8 LRecvBuf[1024];
UINT32 LBufRecvCounter;
UINT32 RK6748_uartBase[]={UART0_BASE,UART1_BASE,UART2_BASE};
UINT8 RK6748_uartInit(UINT8 bySioNum,UINT32 dwBaudRate)//int baudrate
{
UINT32 base,divisor;
UINT8 byLCR;
UINT32 i;
switch (bySioNum)
{
case 0:
RK6748_lpscTransition(PSC0, DOMAIN0, LPSC_UART0, PSC_ENABLE);
RK6748_pinmuxConfig(PINMUX_UART0_REG, PINMUX_UART0_MASK, PINMUX_UART0_VAL);
break;
case 1:
RK6748_lpscTransition(PSC1, DOMAIN0, LPSC_UART1, PSC_ENABLE);
RK6748_pinmuxConfig(PINMUX_UART1_REG_0, PINMUX_UART1_MASK_0, PINMUX_UART1_VAL_0);
RK6748_pinmuxConfig(PINMUX_UART1_REG_1, PINMUX_UART1_MASK_1, PINMUX_UART1_VAL_1);
break;
case 2:
RK6748_lpscTransition(PSC1, DOMAIN0, LPSC_UART2, PSC_ENABLE);
RK6748_pinmuxConfig(PINMUX_UART2_REG_0, PINMUX_UART2_MASK_0, PINMUX_UART2_VAL_0);
RK6748_pinmuxConfig(PINMUX_UART2_REG_1, PINMUX_UART2_MASK_1, PINMUX_UART2_VAL_1);
break;
default:
return (ERR_INIT_FAIL);
}
base=RK6748_uartBase[bySioNum];//通道号3--4,应用接口是3--4
if(bySioNum>=4)
return ERR_FAIL;
byLCR = 0x03;// 8-Data's Bit-Length 1-Stopping Bit-Length no-Parity & Parity
/* initialize each channel's driver function pointers */
divisor = 200000000 / ( dwBaudRate * 16);//24000000 / ( baudrate * 16);
//divisor = 200000000 / ( g_tSioCtrl[bySioNum].dwBaudRate * 16);
/* reset the chip */
UART_REG_WRITE(base,UART_PWREMU_MGMT,0x0000);
for(i=0;i<10000;i++);
//设置波特率
UART_REG_WRITE(base,UART_LCR,byLCR|0x80);
UART_REG_WRITE(base,UART_THR,divisor & 0xff);
UART_REG_WRITE(base,UART_IER,divisor >> 8);
UART_REG_WRITE(base,UART_LCR,byLCR);
//配置寄存器,使能fifo,8字节
UART_REG_WRITE(base,UART_FCR,0x0001);
UART_REG_WRITE(base,UART_FCR,0x0006);
UART_REG_WRITE(base,UART_IER,0x0000);
UART_REG_WRITE(base,UART_LCR,byLCR);
UART_REG_WRITE(base,UART_MCR,0x0000);
UART_REG_WRITE(base,UART_FCR,0x0089);
UART_REG_WRITE(base,UART_PWREMU_MGMT,0x6001);
UART_REG_WRITE(base,UART_FCR,0x00cf);
return (ERR_NO_ERROR);
}
//-----------------------------------------------------------------------------
// helper function to compute the number of bytes in a string.
//-----------------------------------------------------------------------------
static UINT32 getStringLength(char *in_string)
{
UINT32 numBytes = 0;
while (in_string[numBytes] != 0)
{
numBytes++;
}
return numBytes;
}
//串口发送
void RK6748_uartSend(UINT8 bySioNum ,char *pData)//2/从2开始打印口,前置通信口
{
UINT32 i,base;
UINT32 status_lsr=0;
int len=0;
len=getStringLength(pData);
base=RK6748_uartBase[bySioNum];
//等待发送fifo空
while((status_lsr & 0x40) != 0x40)
UART_REG_READ(base,UART_LSR, status_lsr);
for(i=0;i<500;i++);//delay 30us
for(i=0;i<len;i++)
{
status_lsr=0;
UART_REG_WRITE(base,UART_THR, *pData++);
//等待发送fifo空
while((status_lsr & 0x40) != 0x40)
UART_REG_READ(base,UART_LSR, status_lsr);
}
//等待发送fifo空
while((status_lsr & 0x40) != 0x40)
UART_REG_READ(base,UART_LSR, status_lsr);
}
//串口发送
void RK6748_uartSendByte(UINT8 bySioNum ,char pdata)//2/从2开始打印口,前置通信口
{
UINT32 base;
UINT32 status_lsr=0;
base=RK6748_uartBase[bySioNum];
UART_REG_WRITE(base,UART_THR, pdata);
//等待发送fifo空
while((status_lsr & 0x40) != 0x40)
UART_REG_READ(base,UART_LSR, status_lsr);
}
//串口接收
void RK6748_uartRx(UINT8 bySioNum)
{
UINT32 status_iir,inData, status_lsr,status;
int rxdloop = 0;
UINT32 base;
base=RK6748_uartBase[bySioNum];
UART_REG_READ(base,UART_IIR, status_iir);
status_iir &=0x0e;
if((status_iir == 0x04)|(status_iir == 0x0C)|(status_iir == 0x06)) //rx-int
{
UART_REG_READ(base,UART_LSR, status_lsr);
while((status_lsr & 0x01) == 0x01)
{
UART_REG_READ(base,UART_RBR, inData);
LRecvBuf[LBufRecvCounter++]=(char)inData;
UART_REG_READ(base,UART_LSR, status_lsr);
//接收回环测试,收到一个字节发送一个字节
RK6748_uartSendByte(bySioNum,inData);
rxdloop++;
if(rxdloop>=8)
break; //8字节FIFO,读到8就跳出来,多读会出错
}
}
}
void RK6748_uartRxInt0(void)
{
RK6748_uartRx(0);
}
void RK6748_uartRxInt1(void)
{
RK6748_uartRx(1);
}
void RK6748_uartRxInt2(void)
{
RK6748_uartRx(2);
}
void RK6748_uartIntEnable(UINT8 bySioNum)
{
UINT32 base;
base=RK6748_uartBase[bySioNum];
// 使能接受中断,禁止发送中断
UART_REG_WRITE(base,UART_IER, 0x05);
}
void RK6748_uartIntDisable(UINT8 bySioNum)
{
UINT32 base;
base=RK6748_uartBase[bySioNum];
// 禁止发送和接受中断
UART_REG_WRITE(base,UART_IER, 0x00);
}