?? uarthw_evmdm642.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.10.00.23 07-02-03 (ddk-b12)" */
/*
* ======== uarthw_evmdm642.c ========
*/
#include <std.h>
#define CHIP_DM642 1
#include <hwi.h>
#include <iom.h>
#include <csl.h>
#include <csl_irq.h>
#include <evmdm642.h>
#include <evmdm642_osd.h>
#include <uarthw.h>
#include <uarthw_evmdm642.h>
#include <uarthw_evmdm642hal.h>
#define DM642_CPLD_UART_BASE 0xa0000000
#define RBRREG(regset) (regset->uart[0])
#define THRREG(regset) (regset->uart[0])
#define DLLREG(regset) (regset->uart[0])
#define DLHREG(regset) (regset->uart[1])
#define IERREG(regset) (regset->uart[1])
#define FCRREG(regset) (regset->uart[2])
#define EFRREG(regset) (regset->uart[2])
#define IIRREG(regset) (regset->uart[2])
#define LCRREG(regset) (regset->uart[3])
#define MCRREG(regset) (regset->uart[4])
#define XON1REG(regset) (regset->uart[4])
#define LSRREG(regset) (regset->uart[5])
#define XON2REG(regset) (regset->uart[5])
#define MSRREG(regset) (regset->uart[6])
#define XOF1REG(regset) (regset->uart[6])
#define TCRREG(regset) (regset->uart[6])
#define SPRREG(regset) (regset->uart[7])
#define XOF2REG(regset) (regset->uart[7])
#define TLRREG(regset) (regset->uart[7])
#define FRDYREG(regset) (regset->uart[7])
#define getLineStatus(regset) ((Byte)LSRREG(regset))
#define getModemControlReg(regset) ((Byte)MCRREG(regset))
#define setModemControlReg(regset, c) MCRREG(regset) = (c)
#define getLineControlReg(regset) ((Byte)LCRREG(regset))
#define setLineControlReg(regset, c) LCRREG(regset) = (c)
#define disableRx(regset) (IERREG(regset) &= ~UART_IER_RXDATAEN)
#define disableTx(regset) (IERREG(regset) &= ~UART_IER_THREMPEN)
#define enableRx(regset) (IERREG(regset) |= UART_IER_RXDATAEN)
#define enableTx(regset) (IERREG(regset) |= UART_IER_THREMPEN)
#ifdef _DEBUG
#define getInt(regset) ((Byte)IIRREG(regset) & 0x3f)
#else
#define getInt(regset) ((Byte)IIRREG(regset) & 0x0f)
#endif /* _DEBUG */
#define NUMPORTS 4
#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
typedef struct UartRegs {
volatile unsigned short uart[8];
} UartRegs;
static void setupFlowParams(UARTHW_Handle hUart, Uns flowParam);
static void uartIsr(Ptr cbArg);
static Int uartRxFull(UartRegs * regs);
static UARTHW_EVMDM642_Params defaultParams = { \
UARTHW_EVMDM642_FLOW_NONE, \
UARTHW_EVMDM642_DISABLE_PARITY, \
UARTHW_EVMDM642_WORD8, \
UARTHW_EVMDM642_STOP1, \
UARTHW_EVMDM642_BAUD_115200 \
};
typedef struct UARTHW_Obj {
Int uartId; /* UART port ID */
Int rxDisabled; /* disabled flag */
UartRegs * regs; /* base pointer to reg set */
UARTHW_EVMDM642_Params *params;
UARTHW_Tcallback * cbFxns;
Ptr cbArg;
} UARTHW_Obj;
UARTHW_Obj portObj[NUMPORTS];
#ifdef _DEBUG
struct {
Int errInts;
Int mdmInts;
Int rhrInts;
Int thrInts;
Int rtoInts;
Int rxCnt;
Int rxXoff;
Int rtsCts;
} intStats[NUMPORTS] =
{
{0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0}
};
#endif /* _DEBUG */
/*
* ======== UARTHW_open ========
*
* This function is used to attach to the UART.
* 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)
{
volatile Char c;
UartRegs *regs;
UARTHW_EVMDM642_Params *uartParams = (UARTHW_EVMDM642_Params *)params;
UARTHW_Handle port;
if (uartId >= NUMPORTS) {
return (NULL); // invalid UART id
}
port = &portObj[uartId];
port->uartId = uartId;
regs = port->regs = (UartRegs *) (DM642_CPLD_UART_BASE + (uartId * sizeof(UartRegs)));
/*
* Initialize the isrhandler to the one given by
* generic uart.
*/
port->cbFxns = cbFxns;
port->cbArg = cbArg;
EVMDM642_OSD_init();
/* if (uartId == 0) {
EVMDM642_OSD_intHook(UARTA_IRQ, uartIsr, port);
}
else {
EVMDM642_OSD_intHook(UARTB_IRQ, uartIsr, port);
}
*/
switch(uartId)
{
case 0:
EVMDM642_OSD_intHook(UARTA_IRQ, uartIsr, port);
break;
case 1:
EVMDM642_OSD_intHook(UARTB_IRQ, uartIsr, port);
break;
case 2:
EVMDM642_OSD_intHook(UARTC_IRQ, uartIsr, port);
break;
case 3:
EVMDM642_OSD_intHook(UARTD_IRQ, uartIsr, port);
break;
}
/*
* Use the default attributes if one is not given
*/
if (uartParams == NULL) {
uartParams = &defaultParams;
}
/*
* Set EFR registers
*/
LCRREG(regs) = 0xBF; /* address secondary register set */
EFRREG(regs) = 0; //UART_EFR_AUTOCTS | UART_EFR_AUTORTS | UART_EFR_ENHFUNCEN; /* enable enhanced functions */
LCRREG(regs) = 0x00; /* back to primary register set */
MCRREG(regs) = 0x00;
MCRREG(regs) = UART_MCR_IRQENOP | UART_MCR_FIFORDYEN; /* enable IRQ and FIF rdy register */
IERREG(regs) = 0x00; /* set interrupt enable register */
FCRREG(regs) = 0x00; /* set FIFO control */
/*
* Set up baud rate and other comm parameters
*/
LCRREG(regs) = UART_LCR_DLTCHEN; /* enable divisor */
DLLREG(regs) = uartParams->baud;
DLHREG(regs) = uartParams->baud >> 8;
LCRREG(regs) = uartParams->wordSize | (uartParams->stopBits << 2) |
(uartParams->parity << 3);
FCRREG(regs) = /* FIFO control register */
UART_FCR_RXTRG16 | UART_FCR_TXTRG32 | UART_FCR_DMAMODE |
UART_FCR_RSTTXFIFO | UART_FCR_RSTRXFIFO | UART_FCR_FIFOEN;
IERREG(regs) = /* enable normal interrupts */
UART_IER_MDMSTATEN | UART_IER_RXLSTATEN | UART_IER_THREMPEN |
UART_IER_RXDATAEN;
LSRREG(regs); /* clear previous line status */
MSRREG(regs); /* modem status register */
MCRREG(regs); /* modem control register */
while (uartRxFull(regs)) { /* remove active characters */
c = (Byte)RBRREG(regs);
}
port->params = uartParams;
setupFlowParams(port, (uartParams->flowControl) & UARTHW_EVMDM642_HW_FLOW_MASK);
port->rxDisabled = 0; /* indicate we're enabled now */
enableRx(regs);
enableTx(regs);
return (port);
}
/*
* ======== UARTHW_getModemStatus ========
*
* This function is used to get the modem status for the UART.
*/
Int UARTHW_getModemStatus(UARTHW_Handle hUart, char *pmodemStatus)
{
*pmodemStatus = (Byte)MSRREG(hUart->regs);
return (IOM_COMPLETED);
}
/*
* ======== UARTHW_resetDevice ========
*
* This function is used to reset the UART 16c75x.
* Ideally this function should clear the transmit and
* receive fifos if the fifos are being used.
*/
void UARTHW_resetDevice(UARTHW_Handle hUart)
{
FCRREG(hUart->regs) =
UART_FCR_RXTRG16 | UART_FCR_TXTRG32 | UART_FCR_DMAMODE |
UART_FCR_RSTTXFIFO | UART_FCR_RSTRXFIFO | UART_FCR_FIFOEN;
}
/*
* ======== UARTHW_setBreak ========
*
* This function is used to set the break on/off for the UART 16c75x
*/
Int UARTHW_setBreak(UARTHW_Handle hUart, Int bBreak)
{
char lcrVal;
lcrVal = getLineControlReg(hUart->regs);
lcrVal = (lcrVal & LCRBRKMASK) | (bBreak << LCRBREAKPOS);
setLineControlReg(hUart->regs, lcrVal);
return (IOM_COMPLETED);
}
/*
* ======== UARTHW_setDTR ========
*
* This function is used to set the DTR signal for the UART 16c75x
*/
Int UARTHW_setDTR(UARTHW_Handle hUart, int dtrval)
{
char mcrVal;
mcrVal = getModemControlReg(hUart->regs);
mcrVal = (mcrVal & MCRDTRMASK) | dtrval;
setModemControlReg(hUart->regs, mcrVal);
return (IOM_COMPLETED);
}
/*
* ======== UARTHW_setRTS ========
*
* This function is used to set the RTS signal for the UART 16c75x
*/
Int UARTHW_setRTS(UARTHW_Handle hUart, int rtsval)
{
char mcrVal;
mcrVal = getModemControlReg(hUart->regs);
mcrVal = (mcrVal & MCRRTSMASK) | (rtsval << MCRRTSPOS);
setModemControlReg(hUart->regs, mcrVal);
return (IOM_COMPLETED);
}
/*
* ======== UARTHW_txEmpty ========
*
* This function is used to get the transmit buffer empty condition
*/
Int UARTHW_txEmpty(UARTHW_Handle hUart)
{
return ((Byte)LSRREG(hUart->regs) & UART_LSR_THREMPTY);
}
/*
* ======== UARTHW_writeChar ========
*
* This function is used to write a character to the transmit register
*/
void UARTHW_writeChar(UARTHW_Handle hUart, char c)
{
THRREG(hUart->regs) = c;
}
/*
* ======== UARTHW_enableRx ========
* Enable the Rx Interrupt of the UART.
*
*/
void UARTHW_enableRx(UARTHW_Handle hUart)
{
if (ATM_seti(&hUart->rxDisabled, 0)) {
enableRx(hUart->regs);
}
}
/*
* ======== UARTHW_disableRx ========
* Disable the Rx Interrupt of the UART.
*
*/
void UARTHW_disableRx(UARTHW_Handle hUart)
{
int gie;
gie = IRQ_globalDisable();
disableRx(hUart->regs);
hUart->rxDisabled = 1;
IRQ_globalRestore(gie);
}
/*
* ======== setupFlowParams ========
*
* This function is used to setup the UART 16c75x flow paramaters
*/
static void setupFlowParams(UARTHW_Handle hUart, Uns flowParam)
{
char mcrVal;
mcrVal = getModemControlReg(hUart->regs);
mcrVal &= AFERTSCTSMASK;
if (flowParam & UARTHW_EVMDM642_FLOW_AFE_RTSCTS) {
mcrVal |= AFERTSCTSFLW;
}
else if (flowParam & UARTHW_EVMDM642_FLOW_AFE_CTS) {
mcrVal |= AFECTSFLW;
}
else {
mcrVal |= AFEDISFLW;
}
setModemControlReg(hUart->regs, mcrVal);
}
/*
* ======== uartIsr ========
*
* This is the interrupt service handler used by the EVMDM642
* UART driver.
*/
static void uartIsr(Ptr portArg)
{
Int id;
Int argval;
Int temp;
UARTHW_Handle port = (UARTHW_Handle) portArg;
UARTHW_Tcallback *callbacks = port->cbFxns;
Ptr cbArg = port->cbArg;
/*
* While loop here since 16C752/4 holds interrupt line high until
* all interrupt conditions are handled (2 or more may be pending
* at same time). DM642 uses edge-triggered interrupts and would
* miss interrupts otherwise.
*/
while (!((id = getInt(port->regs)) & NOINTPENDING)) {
switch (id) {
case UART_INT_MSR: /* Modem status interrupt -- read and dispatch */
#ifdef _DEBUG
intStats[port->uartId].mdmInts++;
#endif /* _DEBUG */
argval = (Byte)MSRREG(port->regs);
(*callbacks[UARTHW_MODEM_STATUSHANDLER])(cbArg, argval);
break;
case UART_INT_THR: /* Transmit handler */
#ifdef _DEBUG
intStats[port->uartId].thrInts++;
#endif /* _DEBUG */
/* NOTE:
* This shouldn't be necessary, but sometimes the interrupt
* comes in before the transmitter is really empty. Still
* working on this one
*/
while (!(temp = UARTHW_txEmpty(port))) {
asm(" NOP");
}
(*callbacks[UARTHW_TXEMPTY_STATUSHANDLER])(cbArg, temp);
break;
case UART_INT_RHR: /* Receive Handler */
case UART_INT_RXTO: /* Receive time-out error */
#ifdef _DEBUG
if (id == UART_INT_RHR)
intStats[port->uartId].rhrInts++;
else
intStats[port->uartId].rtoInts++;
#endif /* _DEBUG */
while ((!port->rxDisabled) && uartRxFull(port->regs)) {
#ifdef _DEBUG
intStats[port->uartId].rxCnt++;
#endif /* _DEBUG */
argval = (Byte)RBRREG(port->regs);
(*callbacks[UARTHW_RXFULL_STATUSHANDLER])(cbArg, argval);
}
break;
case UART_INT_RLSERR: /* Receiver line status error */
#ifdef _DEBUG
intStats[port->uartId].errInts++;
#endif /* _DEBUG */
argval = (Byte)LSRREG(port->regs);
/*
* Isolate parity/framing/overrun and data ready
* Discard characters by reading the receiver buffer
* ready register, and get the line status again
*/
while ((argval & UART_LSR_ERRMASK) && (argval & UART_LSR_DATAIN)) {
(Byte)RBRREG(port->regs);
argval = (Byte)LSRREG(port->regs);
}
(*callbacks[UARTHW_LINE_STATUSHANDLER])(cbArg, argval);
break;
#ifdef _DEBUG
case UART_INT_XOFF: /* Xoff interrupt */
intStats[port->uartId].rxXoff++;
break;
case UART_INT_CTSRTS: /* RTS or CTS pin change to inactive */
intStats[port->uartId].rtsCts++;
break;
default:
while (1) {
/* should never get here ... */
asm(" NOP");
}
#endif /* _DEBUG */
}
}
}
/*
* ======== uartRxFull ========
* *
* This function is used to get the Receive Buffer Full condition
*/
static Int uartRxFull(UartRegs *regs)
{
return ((Byte)LSRREG(regs) & UART_LSR_DATAIN);
}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -