uarthw_evmdm642.c
上传用户:dahaojd
上传日期:2008-01-29
资源大小:14357k
文件大小:14k
- /*
- * 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 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) (LSRREG(regset))
- #define getModemControlReg(regset) (MCRREG(regset))
- #define setModemControlReg(regset, c) MCRREG(regset) = (c)
- #define getLineControlReg(regset) (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) (IIRREG(regset) & 0x3f)
- #else
- #define getInt(regset) (IIRREG(regset) & 0x0f)
- #endif /* _DEBUG */
- #define NUMPORTS 2
- #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 Byte 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}
- };
- #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 *) (EVMDM642_CPLD_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);
- }
- /*
- * 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) =
- 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 = 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 = 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 (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 = 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 = 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 = 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)) {
- RBRREG(port->regs);
- argval = 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 (LSRREG(regs) & UART_LSR_DATAIN);
- }