DSP UART配置和使用

一,初始化

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

 

おすすめ

転載: blog.csdn.net/wangjie36/article/details/117902962