📄 uarthw_dsk5402.c
字号:
/*
* Copyright 2003 by Texas Instruments Incorporated.
* All rights reserved. Property of Texas Instruments Incorporated.
* Restricted rights to use, duplicate or disclose this code are
* granted through contract.
*
*/
/* "@(#) DDK 1.11.00.00 11-04-03 (ddk-b13)" */
/*
* ======== uarthw_dsk5402.c ========
*/
#define CHIP_5402 1
#include <std.h>
#include <hwi.h>
#include <iom.h>
#include <csl.h>
#include <csl_irq.h>
#include <uarthw.h>
#include <uarthw_dsk5402.h>
/* uart register definitions */
#define RBRREG port4000
#define THRREG port4000
#define DLLREG port4000
#define DLMREG port4001
#define IERREG port4001
#define IIRREG port4002
#define FCRREG port4002
#define LCRREG port4003
#define MCRREG port4004
#define LSRREG port4005
#define MSRREG port4006
#define SCRREG port4007
#define getLineStatus() (LSRREG & 0xff)
#define getModemControlReg() (MCRREG & 0xff)
#define setModemControlReg(c) MCRREG =(c)
#define getLineControlReg() (LCRREG & 0xff)
#define setLineControlReg(c) LCRREG =(c)
#define disableRx() (IERREG = IERREG & 0xFe)
#define disableTx() (IERREG = IERREG & 0xFd)
#define enableRx() (IERREG = IERREG | 0x01)
#define enableTx() (IERREG = IERREG | 0x02)
#define getInt() (IIRREG & 0xf)
#define NOINTPENDING 0x01
#define IDENTIFYINT(id) ((id>>1)&0x03)
#define MCRDTRMASK 0xFE
#define MCRRTSMASK 0xFD
#define LCRBRKMASK 0xBF
#define AFERTSCTSMASK 0xDD
#define AFERTSCTSFLW 0x22
#define AFECTSFLW 0x20
#define AFEDISFLW 0x00
#define LCRBREAKPOS 6
#define MCRRTSPOS 1
#define UARTINTERRUPT IRQ_EVT_INT1
#define UARTHW_DSK5402_INTR_MASK_DEFAULT 1
/* uart register addresses */
extern volatile ioport unsigned int port4000;
extern volatile ioport unsigned int port4001;
extern volatile ioport unsigned int port4002;
extern volatile ioport unsigned int port4003;
extern volatile ioport unsigned int port4004;
extern volatile ioport unsigned int port4005;
extern volatile ioport unsigned int port4006;
extern volatile ioport unsigned int port4007;
static void setupFlowParams(Uns flowParam);
static void uartIsr(Ptr cbArg);
static Int uartRxFull();
static UARTHW_DSK5402_Params defaultParams = { \
UARTHW_DSK5402_FLOW_AFE_RTSCTS, \
UARTHW_DSK5402_DISABLE_PARITY, \
UARTHW_DSK5402_WORD8, \
UARTHW_DSK5402_STOP1, \
UARTHW_DSK5402_BAUD_115200, \
UARTHW_DSK5402_INTR_MASK_DEFAULT \
};
static UARTHW_Tcallback *callbacks;
/*
* ======== UARTHW_open ========
*
* This function is used to attach to the UART 16550.
* Typically this function plugs the UART interrupt vector with
* the internal driver supplied isr routine.
* Initializes the UART, UART flow parameters and UART communication parameters
*
*/
UARTHW_Handle UARTHW_open(Int uartId, Ptr params, Ptr cbArg, UARTHW_Tcallback *cbFxns)
{
HWI_Attrs hwattr;
volatile Char c;
UARTHW_DSK5402_Params *uartParams = (UARTHW_DSK5402_Params *)params;
if (uartId > 0) {
return (NULL); /* only supports one UART */
}
/*
* Initialize the isrhandler to the one given by
* generic uart.
*/
callbacks = cbFxns;
hwattr.intrMask = uartParams->intrMask;
hwattr.arg = (Arg)cbArg;
HWI_dispatchPlug(UARTINTERRUPT, (Fxn)uartIsr, &hwattr);
/*
* Use the default attributes if one is not given
*/
if (uartParams == NULL) {
uartParams = &defaultParams;
}
/*
* Setup the baud and other communication parameters
*/
LCRREG = 0x80;
DLLREG = uartParams->baud;
DLMREG = uartParams->baud >> 8;
/* deselect divisor latch register */
LCRREG = uartParams->wordSize | (uartParams->stopBits << 2) |
(uartParams->parity << 3);
/*
* Initialize the rest of the UART
*/
FCRREG = 0x87; /* FIFO control register */
IERREG = 0xff; /* enable all interrupts */
LSRREG = 0x00; /* to clear the previous line status */
MSRREG = 0x00; /* modem status register */
MCRREG = 0x00;
/* read the UART receive buffer to clear it */
while (uartRxFull()) {
c = (RBRREG & 0xFF);
}
setupFlowParams((uartParams->flowControl) & UARTHW_DSK5402_HW_FLOW_MASK);
enableRx();
enableTx();
IRQ_enable(UARTINTERRUPT);
return ((UARTHW_Handle)1); /* non-zero means success */
}
/*
* ======== UARTHW_getModemStatus ========
*
* This function is used to get the modem status for the UART 16550
*/
Int UARTHW_getModemStatus(UARTHW_Handle hUart, char *pmodemStatus)
{
*pmodemStatus = (char)(MSRREG & 0xff);
return (IOM_COMPLETED);
}
/*
* ======== UARTHW_resetDevice ========
*
* This function is used to reset the UART 16550.
* Ideally this function should clear the transmit and
* receive fifos if the fifos are being used.
*/
void UARTHW_resetDevice(UARTHW_Handle hUart)
{
FCRREG |= 0x06;
}
/*
* ======== UARTHW_setBreak ========
*
* This function is used to set the break on/off for the UART 16550
*/
Int UARTHW_setBreak(UARTHW_Handle hUart, Int bBreak)
{
char lcrVal;
lcrVal = getLineControlReg();
lcrVal = (lcrVal& LCRBRKMASK)|(bBreak<<LCRBREAKPOS);
setLineControlReg(lcrVal);
return (IOM_COMPLETED);
}
/*
* ======== UARTHW_setDTR ========
*
* This function is used to set the DTR signal for the UART 16550
*/
Int UARTHW_setDTR(UARTHW_Handle hUart, int dtrval)
{
char mcrVal;
mcrVal = getModemControlReg();
mcrVal = (mcrVal& MCRDTRMASK)|dtrval;
setModemControlReg(mcrVal);
return (IOM_COMPLETED);
}
/*
* ======== UARTHW_setRTS ========
*
* This function is used to set the RTS signal for the UART 16550
*/
Int UARTHW_setRTS(UARTHW_Handle hUart, int rtsval)
{
char mcrVal;
mcrVal = getModemControlReg();
mcrVal = (mcrVal& MCRRTSMASK)|(rtsval<<MCRRTSPOS);
setModemControlReg(mcrVal);
return (IOM_COMPLETED);
}
/*
* ======== UARTHW_txEmpty ========
*
* This function is used to get the transmit buffer empty condition
*/
Int UARTHW_txEmpty(UARTHW_Handle hUart)
{
return (LSRREG & 0x20);
}
/*
* ======== UARTHW_writeChar ========
*
* This function is used to write a character to the transmit register
*/
void UARTHW_writeChar(UARTHW_Handle hUart, char c)
{
THRREG = c;
}
/*
* ======== UARTHW_enableRx ========
*
* This function is used to enable the Rx interrupt Handler
*/
void UARTHW_enableRx(UARTHW_Handle hUart)
{
enableRx();
}
/*
* ======== UARTHW_disableRx ========
*
* This function is used to disable the Rx interrupt Handler
*/
void UARTHW_disableRx(UARTHW_Handle hUart)
{
disableRx();
}
/*
* ======== setupFlowParams ========
*
* This function is used to setup the UART 16550 flow paramaters
*/
static void setupFlowParams(Uns flowParam)
{
char mcrVal;
mcrVal = getModemControlReg();
if (flowParam & UARTHW_DSK5402_FLOW_AFE_RTSCTS) {
mcrVal=(mcrVal & AFERTSCTSMASK)|AFERTSCTSFLW;
}
else if (flowParam & UARTHW_DSK5402_FLOW_AFE_CTS) {
mcrVal=(mcrVal & AFERTSCTSMASK)|AFECTSFLW;
}
else {
mcrVal=(mcrVal & AFERTSCTSMASK)|AFEDISFLW;
}
setModemControlReg(mcrVal);
}
/*
* ======== uartIsr ========
*
* This is the interrupt service handler used by the DSK 5402
* UART driver.
*/
static void uartIsr(Ptr cbArg)
{
Int id;
Int argval;
/*
* While loop here since 16550 holds interrupt line high until
* all interrupt conditions are handled (2 or more may be pending
* at same time). 'C54x uses edge-triggered interrupts and would
* miss interrupts otherwise.
*/
while ((id = getInt()) != NOINTPENDING) {
id = IDENTIFYINT(id);
if (id == UARTHW_RXFULL_STATUSHANDLER) {
if (uartRxFull()) {
argval=(RBRREG & 0xff);
(*callbacks[id])(cbArg, argval);
}
}
else if (id == UARTHW_TXEMPTY_STATUSHANDLER) {
(*callbacks[id])(cbArg, 0);
}
else if (id == UARTHW_LINE_STATUSHANDLER) {
argval = (LSRREG & 0xff);
while ((argval & 0x0E) && (argval & 0x01)) {
(RBRREG & 0xff);
argval = (LSRREG & 0xff);
}
(*callbacks[id])(cbArg, argval);
}
else if (id == UARTHW_MODEM_STATUSHANDLER) {
argval = (MSRREG & 0xff);
(*callbacks[id])(cbArg, argval);
}
}
}
/*
* ======== uartRxFull ========
*
* This function is used to get the Receive Buffer Full condition
*/
static Int uartRxFull()
{
return (LSRREG & 0x01);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -