VPM642采用TL16C752B通用异步收发器UART,其上包含两路相互独立的异步收发器,接受和发送各带64字节FIFO,并且各自带有Modem接口信号,最高传输速率为1.5Mbps
在VPM642中,TL16C752B(以下简称752B)与EMIFA之CE1相连。
752B每个通道包含18个寄存器,通过地址A2~A0以及寄存器位对他们进行寻址。A,B两通道分别由片选信号选通。
A,B两通道所占地址范围如下:
- UART A 0x 9008 0000 ~ 0x 9008 0007
- UART B 0x 9008 0008 ~ 0x 9008 000F
此外752B还提供两个中断请求信号INTA,INTB分别用于通道A,B申请DM642中断,在VPM642中,INTA与INTB相与,复用DM642之 INT5
752B寄存器:
黑色部分为2次寻址。
下面在程序中定义这些寄存器:
#define SEEDDM642_UART_RBR 0x00
// Read
#define SEEDDM642_UART_THR 0x00 // Write
#define SEEDDM642_UART_IER 0x01
#define SEEDDM642_UART_IIR 0x02 // Read
#define SEEDDM642_UART_FCR 0x02 // Write
#define SEEDDM642_UART_LCR 0x03
#define SEEDDM642_UART_MCR 0x04
#define SEEDDM642_UART_LSR 0x05
#define SEEDDM642_UART_SCR 0x07
#define SEEDDM642_UART_DLL 0x08
#define SEEDDM642_UART_DLH 0x09
#define SEEDDM642_UART_EFR 0x0A
#define SEEDDM642_UART_XON1 0x0C
#define SEEDDM642_UART_XON2 0x0D
#define SEEDDM642_UART_XOFF1 0x0E
#define SEEDDM642_UART_XOFF2 0x0F
#define SEEDDM642_UART_TCR 0x16
#define SEEDDM642_UART_TLR 0x17
#define SEEDDM642_UART_THR 0x00 // Write
#define SEEDDM642_UART_IER 0x01
#define SEEDDM642_UART_IIR 0x02 // Read
#define SEEDDM642_UART_FCR 0x02 // Write
#define SEEDDM642_UART_LCR 0x03
#define SEEDDM642_UART_MCR 0x04
#define SEEDDM642_UART_LSR 0x05
#define SEEDDM642_UART_SCR 0x07
#define SEEDDM642_UART_DLL 0x08
#define SEEDDM642_UART_DLH 0x09
#define SEEDDM642_UART_EFR 0x0A
#define SEEDDM642_UART_XON1 0x0C
#define SEEDDM642_UART_XON2 0x0D
#define SEEDDM642_UART_XOFF1 0x0E
#define SEEDDM642_UART_XOFF2 0x0F
#define SEEDDM642_UART_TCR 0x16
#define SEEDDM642_UART_TLR 0x17
上述寄存器中比较重要的是:
- 中断使能寄存器IER
- FIFO控制寄存器 FCR
- 线路控制寄存器LCR
- Modem控制寄存器 MCR
下面是初始化过程:
SEEDDM642_UART_Config UartConfig ={
0x00, /*寄存器IER*/
0x57, /*寄存器FCR*/
0x03, /*寄存器LCR*/
0x01, /*寄存器MCR*/
};
0x00, /*寄存器IER*/
0x57, /*寄存器FCR*/
0x03, /*寄存器LCR*/
0x01, /*寄存器MCR*/
};
定义串口A句柄
SEEDDM642_UART_Handle SEEDuartHandleA;
打开串口
/* Open UART */
SEEDuartHandleA = SEEDDM642_UART_open(SEEDDM642_UARTA,
SEEDDM642_UART_BAUD9600,
&UartConfig);
SEEDuartHandleA = SEEDDM642_UART_open(SEEDDM642_UARTA,
SEEDDM642_UART_BAUD9600,
&UartConfig);
打开串口函数实现
SEEDDM642_UART_Handle SEEDDM642_UART_open(Int16 devid,
Int16 baudrate,
SEEDDM642_UART_Config *config)
{
SEEDDM642_UART_Handle hUart;
Int16 dl;
/* Assign handle */
hUart = devid;
/* Set registers based on config structure */
/*设置MCR*/
SEEDDM642_UART_rset(hUart, SEEDDM642_UART_MCR,config -> regs[3]);
/*将EFR寄存器的第4位关闭*/ //静止TL16C752B增强功能
SEEDDM642_UART_rset(hUart, SEEDDM642_UART_EFR, dl);
/*设置串口的MCR*/
SEEDDM642_UART_rset(hUart, SEEDDM642_UART_MCR, config -> regs[3]);
/*设置串口的IER*/ // 0X9008 0001 处置0
SEEDDM642_UART_rset(hUart, SEEDDM642_UART_IER, config -> regs[0]);
/*设置串口的FCR*/
SEEDDM642_UART_rset(hUart, SEEDDM642_UART_FCR, config -> regs[1]);
/*设置串口的LCR*/
SEEDDM642_UART_rset(hUart, SEEDDM642_UART_LCR, config -> regs[2]);
/* Set up baud divisor clock,设置波待率 */
dl = SEEDDM642_UART_rget(hUart, SEEDDM642_UART_MCR);
if((dl & 0x80)==0x80)
{
baudrate = (baudrate/4);
}
SEEDDM642_UART_rset(hUart, SEEDDM642_UART_DLL, baudrate & 0xff);
dl = SEEDDM642_UART_rget(hUart, SEEDDM642_UART_DLL);
SEEDDM642_UART_rset(hUart, SEEDDM642_UART_DLH, (baudrate >> 8) & 0xff);
dl = SEEDDM642_UART_rget(hUart, SEEDDM642_UART_DLH);
/* Clear any outstanding receive characters,清空接收寄存器 */
SEEDDM642_UART_rget(hUart, SEEDDM642_UART_RBR);
return hUart;
}
Int16 baudrate,
SEEDDM642_UART_Config *config)
{
SEEDDM642_UART_Handle hUart;
Int16 dl;
/* Assign handle */
hUart = devid;
/* Set registers based on config structure */
/*设置MCR*/
SEEDDM642_UART_rset(hUart, SEEDDM642_UART_MCR,config -> regs[3]);
/*将EFR寄存器的第4位关闭*/ //静止TL16C752B增强功能
SEEDDM642_UART_rset(hUart, SEEDDM642_UART_EFR, dl);
/*设置串口的MCR*/
SEEDDM642_UART_rset(hUart, SEEDDM642_UART_MCR, config -> regs[3]);
/*设置串口的IER*/ // 0X9008 0001 处置0
SEEDDM642_UART_rset(hUart, SEEDDM642_UART_IER, config -> regs[0]);
/*设置串口的FCR*/
SEEDDM642_UART_rset(hUart, SEEDDM642_UART_FCR, config -> regs[1]);
/*设置串口的LCR*/
SEEDDM642_UART_rset(hUart, SEEDDM642_UART_LCR, config -> regs[2]);
/* Set up baud divisor clock,设置波待率 */
dl = SEEDDM642_UART_rget(hUart, SEEDDM642_UART_MCR);
if((dl & 0x80)==0x80)
{
baudrate = (baudrate/4);
}
SEEDDM642_UART_rset(hUart, SEEDDM642_UART_DLL, baudrate & 0xff);
dl = SEEDDM642_UART_rget(hUart, SEEDDM642_UART_DLL);
SEEDDM642_UART_rset(hUart, SEEDDM642_UART_DLH, (baudrate >> 8) & 0xff);
dl = SEEDDM642_UART_rget(hUart, SEEDDM642_UART_DLH);
/* Clear any outstanding receive characters,清空接收寄存器 */
SEEDDM642_UART_rget(hUart, SEEDDM642_UART_RBR);
return hUart;
}
串口读取:
Int16 SEEDDM642_UART_getChar(SEEDDM642_UART_Handle hUart)
{
Int16 status;
while(1)
{
status = SEEDDM642_UART_rget(hUart, SEEDDM642_UART_LSR);
if ((status & 1) != 0) // DR
break;
}
return SEEDDM642_UART_rget(hUart, SEEDDM642_UART_RBR);
}
{
Int16 status;
while(1)
{
status = SEEDDM642_UART_rget(hUart, SEEDDM642_UART_LSR);
if ((status & 1) != 0) // DR
break;
}
return SEEDDM642_UART_rget(hUart, SEEDDM642_UART_RBR);
}
串口写入:
void SEEDDM642_UART_putChar(SEEDDM642_UART_Handle hUart, Uint16 data)
{
Int16 status;
while(1)
{
status = SEEDDM642_UART_rget(hUart, SEEDDM642_UART_LSR);
if ((status & 0x20) != 0) // THRE
break;
}
// SEEDDM642_waitusec(3);
SEEDDM642_UART_rset(hUart, SEEDDM642_UART_THR, data);
}
{
Int16 status;
while(1)
{
status = SEEDDM642_UART_rget(hUart, SEEDDM642_UART_LSR);
if ((status & 0x20) != 0) // THRE
break;
}
// SEEDDM642_waitusec(3);
SEEDDM642_UART_rset(hUart, SEEDDM642_UART_THR, data);
}
设置752B寄存器:
void SEEDDM642_UART_rset(SEEDDM642_UART_Handle hUart,
Int16 regnum,
Int16 regval)
{
Int16 regindex, lcr;
/* Register index is determined by lower 3 bits and the target UART */
regindex = regnum & 0x7;
if (hUart == 1)
regindex += 8;
/*是否为高位的寄存器*/
/* If regnum between 0x08 and 0x0F, set bit 7 of LCR to access register */
if ((regnum & 0x18) == 0x8)
{
lcr = SEEDDM642_UART_rget(hUart, SEEDDM642_UART_LCR);
SEEDDM642_waitusec(1);
//将线路控制寄存器LCR最高位DLAB设置成1,表示访问大于 0x07的寄存器
SEEDDM642_UART_rset(hUart, SEEDDM642_UART_LCR, lcr | 0x80);
SEEDDM642_waitusec(1);
//设置寄存器值
SEEDDM642_rset(regindex, regval);
SEEDDM642_waitusec(1);
SEEDDM642_UART_rset(hUart, SEEDDM642_UART_LCR, lcr);
SEEDDM642_waitusec(1);
}
else
{
SEEDDM642_rset(regindex, regval);
SEEDDM642_waitusec(1);
}
}
Int16 regnum,
Int16 regval)
{
Int16 regindex, lcr;
/* Register index is determined by lower 3 bits and the target UART */
regindex = regnum & 0x7;
if (hUart == 1)
regindex += 8;
/*是否为高位的寄存器*/
/* If regnum between 0x08 and 0x0F, set bit 7 of LCR to access register */
if ((regnum & 0x18) == 0x8)
{
lcr = SEEDDM642_UART_rget(hUart, SEEDDM642_UART_LCR);
SEEDDM642_waitusec(1);
//将线路控制寄存器LCR最高位DLAB设置成1,表示访问大于 0x07的寄存器
SEEDDM642_UART_rset(hUart, SEEDDM642_UART_LCR, lcr | 0x80);
SEEDDM642_waitusec(1);
//设置寄存器值
SEEDDM642_rset(regindex, regval);
SEEDDM642_waitusec(1);
SEEDDM642_UART_rset(hUart, SEEDDM642_UART_LCR, lcr);
SEEDDM642_waitusec(1);
}
else
{
SEEDDM642_rset(regindex, regval);
SEEDDM642_waitusec(1);
}
}
获得752B寄存器值:
Int16 SEEDDM642_UART_rget(SEEDDM642_UART_Handle hUart,
Int16 regnum)
{
Int16 regindex, returnval, lcr;
/* Register index is determined by lower 3 bits and the target UART */
regindex = regnum & 0x7;
if (hUart == 1)
regindex += 8;
/* If regnum between 0x08 and 0x0F, set bit 7 of LCR to access register */
if ((regnum & 0x18) == 0x8)
{
lcr = SEEDDM642_UART_rget(hUart, SEEDDM642_UART_LCR);
SEEDDM642_UART_rset(hUart, SEEDDM642_UART_LCR, lcr | 0x80);
returnval = SEEDDM642_rget(regindex);
SEEDDM642_UART_rset(hUart, SEEDDM642_UART_LCR, lcr);
}
else
{
returnval = SEEDDM642_rget(regindex);
}
return returnval;
}
Int16 regnum)
{
Int16 regindex, returnval, lcr;
/* Register index is determined by lower 3 bits and the target UART */
regindex = regnum & 0x7;
if (hUart == 1)
regindex += 8;
/* If regnum between 0x08 and 0x0F, set bit 7 of LCR to access register */
if ((regnum & 0x18) == 0x8)
{
lcr = SEEDDM642_UART_rget(hUart, SEEDDM642_UART_LCR);
SEEDDM642_UART_rset(hUart, SEEDDM642_UART_LCR, lcr | 0x80);
returnval = SEEDDM642_rget(regindex);
SEEDDM642_UART_rset(hUart, SEEDDM642_UART_LCR, lcr);
}
else
{
returnval = SEEDDM642_rget(regindex);
}
return returnval;
}
DM642读写EMIFA
#define EVMDM642_FPGASDRAM_BASE 0x80000000
/* Read an 8-bit value from a CPLD register */
Uint8 SEEDDM642_rget(Int16 regnum)
{
Uint8 *pdata;
/* Return lower 8 bits of register */
pdata = (Uint8 *)(SEEDDM642_CPLD_BASE + regnum);
return (*pdata & 0xff);
}
/* Write an 8-bit value to a CPLD register */
void SEEDDM642_rset(Int16 regnum, Uint8 regval)
{
Uint8 *pdata;
/* Write lower 8 bits of register */
pdata = (Uint8 *)(SEEDDM642_CPLD_BASE + regnum);
*pdata = (regval & 0xff);
}
/* Read an 8-bit value from a CPLD register */
Uint8 SEEDDM642_rget(Int16 regnum)
{
Uint8 *pdata;
/* Return lower 8 bits of register */
pdata = (Uint8 *)(SEEDDM642_CPLD_BASE + regnum);
return (*pdata & 0xff);
}
/* Write an 8-bit value to a CPLD register */
void SEEDDM642_rset(Int16 regnum, Uint8 regval)
{
Uint8 *pdata;
/* Write lower 8 bits of register */
pdata = (Uint8 *)(SEEDDM642_CPLD_BASE + regnum);
*pdata = (regval & 0xff);
}