#include <stdio.h>
#include <string.h>
#include <std.h>
#include <sys.h>
#include "uart.h"
#include "emif.h"
unsigned char HW_uart_putchar(HW_uart_handle hUart, unsigned char data);
unsigned char HW_uart_getchar(HW_uart_handle hUart, unsigned char *data);
void HW_UartInit(HW_uart_handle *hUart, unsigned int baudrate, int port);
static unsigned char HW_rget(HW_uart_handle hUart, unsigned int regnum);
static void HW_rset(HW_uart_handle hUart, unsigned int regnum, unsigned char regval);
static void HW_uart_rset(HW_uart_handle hUart, unsigned int regnum, unsigned char regval);
static unsigned char HW_uart_rget(HW_uart_handle hUart, unsigned int regnum);
static void HW_uart_config(HW_UART_CONFIG *uartcfg);
static HW_UART_CONFIG uartcfg;
/*
* Set a UART register
*/
/* Read an 8-bit value from a EMIF interface */
static unsigned char HW_rget(HW_uart_handle hUart, unsigned int regnum)
{
Uint8 *pdata;
/* Return lower 8 bits of register */
if(hUart == HW_UARTA)
pdata = (Uint8 *)(HW_UARTA_BASEADDR + regnum);
else
pdata = (Uint8 *)(HW_UARTB_BASEADDR + regnum);
return (*pdata & 0xff);
}
/* Write an 8-bit value to a EMIF interface */
static void HW_rset(HW_uart_handle hUart, unsigned int regnum, unsigned char regval)
{
Uint8 *pdata;
/* Write lower 8 bits of register */
if(hUart == HW_UARTA)
pdata = (Uint8 *)(HW_UARTA_BASEADDR + regnum);
else
pdata = (Uint8 *)(HW_UARTB_BASEADDR + regnum);
*pdata= (regval & 0xff);
}
/*
* Get the value of a UART register
*/
static void HW_uart_rset(HW_uart_handle hUart, unsigned int regnum, unsigned char regval)
{
Int16 regindex, lcr;
/* Register index is determined by lower 3 bits and the target UART */
regindex = regnum & 0x7;
/* If regnum between 0x08 and 0x0F, set bit 7 of LCR to access register */
//if ((regnum & 0x18) == 0x8)
if((regnum == 0x8)||(regnum == 0x9))
{
lcr = HW_uart_rget(hUart, HW_UART_LCR);
HW_uart_rset(hUart, HW_UART_LCR, lcr | 0x80);
HW_waitusec(1);
HW_rset(hUart, regindex, regval);
HW_waitusec(1);
HW_uart_rset(hUart, HW_UART_LCR, lcr);
HW_waitusec(1);
}
else
{
HW_rset(hUart, regindex, regval);
HW_waitusec(10);
}
}
static unsigned char HW_uart_rget(HW_uart_handle hUart, unsigned int regnum)
{
Int16 regindex, lcr;
Uint8 returnval;
/* Register index is determined by lower 3 bits and the target UART */
regindex = regnum & 0x7;
/* If regnum between 0x08 and 0x0F, set bit 7 of LCR to access register */
//if ((regnum & 0x08) == 0x8)//原来这么写
//if ((regnum & 0x08) == 0x8)
if((regnum == 0x8)||(regnum == 0x9))
{
lcr = HW_uart_rget(hUart, HW_UART_LCR);
HW_uart_rset(hUart, HW_UART_LCR, lcr | 0x80);
HW_waitusec(1);
returnval = HW_rget(hUart, regindex);
HW_uart_rset(hUart, HW_UART_LCR, lcr);
HW_waitusec(1);
}
else
{
returnval = HW_rget(hUart, regindex);
}
return returnval;
}
unsigned char HW_uart_getchar(HW_uart_handle hUart, unsigned char *data)
{
Uint8 status;
Bool ret;
status = HW_uart_rget(hUart, HW_UART_LSR);
if ((status & 1) != 0) // DR
ret = TRUE;
else
ret = FALSE;
if(ret)
{
*data = HW_uart_rget(hUart, HW_UART_RBR);
}
return ret;
}
unsigned char HW_uart_putchar(HW_uart_handle hUart, unsigned char data)
{
Uint8 status;
Bool ret;
status = HW_uart_rget(hUart, HW_UART_LSR);
if ((status & 0x20) != 0) // THRE
ret = TRUE;
else
ret = FALSE;
if(ret)
{
HW_uart_rset(hUart, HW_UART_THR, data);
}
return ret;
}
static void HW_uart_config(HW_UART_CONFIG *uartcfg)
{
uartcfg->regs[0] = 0x00; // IER
//uartcfg->regs[1] = 0x07; // FCR - FIFO Mode, 16 character trigger level
//uartcfg->regs[1] = 0x37; // FCR - FIFO Mode, 8 character fifo for receive,
//56 character for transfer trigger level
uartcfg->regs[1] = 0x57; // FCR - FIFO Mode, 16 character fifo for receive,
//16 character for transfer trigger level
uartcfg->regs[2] = 0x03; // LCR - 8 bits, no parity, 1 stop
uartcfg->regs[3] = 0x00; // MCR
}
/* UART initialize */
void HW_UartInit(HW_uart_handle *hUart, unsigned int baudrate, int port)
{
*hUart = port;
HW_uart_config(&uartcfg);
HW_uart_rset(*hUart, HW_UART_IER, uartcfg.regs[0]);
HW_uart_rset(*hUart, HW_UART_FCR, uartcfg.regs[1]);
HW_uart_rset(*hUart, HW_UART_LCR, uartcfg.regs[2]);
HW_uart_rset(*hUart, HW_UART_MCR, uartcfg.regs[3]);
/* Set up baud divisor clock */
HW_uart_rset(*hUart, HW_UART_DLL, baudrate & 0xff);
HW_uart_rset(*hUart, HW_UART_DLH, (baudrate >> 8) & 0xff);
/* Clear any outstanding receive characters */
HW_uart_rget(*hUart, HW_UART_RBR);
}