uarthw_mcbsp.c
上传用户:dahaojd
上传日期:2008-01-29
资源大小:14357k
文件大小:9k
- /*
- * 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_mcbsp.c ========
- */
-
- #include <std.h>
- #include <iom.h>
- #include <uarthw.h>
- #include <uarthw_mcbsp.h>
- #define LSRREG (portObj.LSRVAL)
- #define THRREG (portObj.THRVAL)
- #define LSRCLEARRXFULLMASK 0xFE
- #define LSRCLEARTXEMPTYMASK 0xDF
- #define LSRCLEARRXFEMASK 0xF7
- #define LSRSETTXEMPTYMASK 0x20
- #define LSRSETRXFULLMASK 0x01
- #define LSRSETRXFEMASK 0x08
- #define CURRENTTXOFFSET portObj.txOffset
- #define CURRENTRXOFFSET portObj.rxOffset
- static void processTx(MdUns *buffer);
- static void processRx(MdUns *buffer);
- typedef struct UARTHW_Obj {
- Byte THRVAL;
- Byte LSRVAL;
- MdUns * txBuffer;
- MdUns * rxBuffer;
- Uns txOffset;
- Uns rxOffset;
- Bool breakOn;
- Ptr cbArg;
- UARTHW_Tcallback *cbFxns;
- } UARTHW_Obj;
- /*
- * This driver only supports a single UART.
- */
- static UARTHW_Obj portObj;
- #if defined(_54_) || defined(_55_)
- /* rxBuffer and txBuffer must be aligned for the DMA to work correctly */
- #pragma DATA_ALIGN(rxBuffer, 32)
- #pragma DATA_ALIGN(txBuffer, 32)
- #endif
- /*
- * CACHE issue on c6x1x! For 6x1x these buffers need to be in on-chip
- * memory (cache needs to be split) or cache needs to be disabled. You can
- * do this by setting 3-way cache, defining a new on-chip memory section
- * and placing .bss in on-chip memory. This probably needs to be a
- * parameter so that 6x version can do correct cache management.
- */
- static MdUns rxBuffer[UARTHW_MCBSP_MAXBITS * 2];
- static MdUns txBuffer[UARTHW_MCBSP_MAXBITS * 2];
- /*
- * ======== UARTHW_open ========
- * This function is used to attach to the software UART.
- * Typically this function plugs the UART interrupt vector with
- * the internal driver supplied isr routine.
- */
- UARTHW_Handle UARTHW_open(Int uartId, Ptr attrs, Ptr cbArg, UARTHW_Tcallback
- *cbFxns)
- {
- Uns i;
-
- if (uartId != 0) {
- return (NULL);
- }
- /* save the callback functions and argument */
- portObj.cbFxns = cbFxns;
- portObj.cbArg = cbArg;
-
- /* Initialize the uart parameters given by the app */
- portObj.txBuffer = txBuffer;
- portObj.rxBuffer = rxBuffer;
- portObj.breakOn = FALSE;
- /* Initialize the Rx and Tx buffers to all 0xFFFF */
- for (i = 0; i < UARTHW_MCBSP_MAXBITS * 2; i++) {
- portObj.txBuffer[i] = portObj.rxBuffer[i] = 0xFFFF;
- }
- /* set the initial offsets */
- CURRENTRXOFFSET = 0;
- CURRENTTXOFFSET = 0;
-
- /* Enable the device */
- LSRREG = 0x20;
- THRREG = 0x00;
-
- /* start the MCBSP/DMA ping-pong buffering and ISRs ... */
- UARTHW_MCBSP_start(portObj.rxBuffer, portObj.txBuffer, attrs);
- return (&portObj);
- }
- /*
- * ======== UARTHW_disableRx ========
- * This is an empty function for the McBSP implementation since this
- * implementation does not support flow control.
- */
- void UARTHW_disableRx(UARTHW_Handle hUart)
- {
- }
- /*
- * ======== UARTHW_enableRx ========
- * This is an empty function for the McBSP implementation since this
- * implementation does not support flow control.
- */
- void UARTHW_enableRx(UARTHW_Handle hUart)
- {
- }
- /*
- * ======== UARTHW_getModemStatus ========
- * This function is not implemented by the simulated McBSP UART driver.
- */
- Int UARTHW_getModemStatus(UARTHW_Handle hUart, Char *pmodemStatus)
- {
- *pmodemStatus = 0;
-
- return (IOM_ENOTIMPL);
- }
- /*
- * ======== UARTHW_resetDevice ========
- * This function is used to reset the UART.
- * Currently this is a dummy function.
- */
- void UARTHW_resetDevice(UARTHW_Handle hUart)
- {
- }
- /*
- * ======== UARTHW_setBreak ========
- * This function is used to set the break on/off for the simulated UART
- */
- Int UARTHW_setBreak(UARTHW_Handle hUart, Int bBreak)
- {
- portObj.breakOn = (Bool)bBreak;
-
- if (!bBreak) {
- (*(portObj.cbFxns)[UARTHW_TXEMPTY_STATUSHANDLER])(portObj.cbArg, 0);
- }
- return (IOM_COMPLETED);
- }
- /*
- * ======== UARTHW_setDTR ========
- * This function is not implemented by the simulated McBSP UART driver.
- */
- Int UARTHW_setDTR(UARTHW_Handle hUart, Int dtrval)
- {
- return (IOM_ENOTIMPL);
- }
- /*
- * ======== UARTHW_setRTS ========
- * This function is not implemented by the simulated McBSP UART driver.
- */
- Int UARTHW_setRTS(UARTHW_Handle hUart, Int rtsval)
- {
- return (IOM_ENOTIMPL);
- }
- /*
- * ======== UARTHW_writeChar ========
- *
- * This function is used to write a character to the transmit register
- */
- void UARTHW_writeChar(UARTHW_Handle hUart, Char c)
- {
- THRREG = c;
- LSRREG = LSRREG & LSRCLEARTXEMPTYMASK;
- }
- /*
- * ======== UARTHW_txEmpty ========
- *
- * This function is used to get the transmit buffer empty condition
- */
- Int UARTHW_txEmpty(UARTHW_Handle hUart)
- {
- return (LSRREG & 0x20);
- }
- /*
- * -------- support functions --------
- */
- /*
- * ======== decodeBit ========
- *
- * This function decoded the received character by testing the
- * center 4 bits of the baud. A majority rule is used for the
- * decoding
- */
- static Bool decodeBit(Uns value)
- {
- /* Test middle 4 bits in received raw data */
- value = ((value >> 6) & 0x0F );
- if ((value == 7) || (value > 10)) {
- return (1);
- }
- else {
- return (0);
- }
- }
- /*
- * ======== UARTHW_MCBSP_dmaRxIsr ========
- *
- * This is the interrupt service handler used by the DSK 5402
- * McBSP driver for the receive channel.
- */
- Void UARTHW_MCBSP_dmaRxIsr(void)
- {
- MdUns *bufp;
- bufp = &(portObj.rxBuffer[CURRENTRXOFFSET]);
- CURRENTRXOFFSET = CURRENTRXOFFSET ^ UARTHW_MCBSP_RxPKTBITS;
- processRx(bufp);
- }
- /*
- * ======== UARTHW_MCBSP_dmaTxIsr ========
- *
- * This is the interrupt service handler used by the DSK 5402
- * McBSP driver for the transmit channel
- */
- Void UARTHW_MCBSP_dmaTxIsr(Void)
- {
- MdUns *bufp;
- bufp = &(portObj.txBuffer[CURRENTTXOFFSET]);
- CURRENTTXOFFSET = CURRENTTXOFFSET ^ UARTHW_MCBSP_TxPKTBITS;
- processTx(bufp);
- }
- /*
- * ======== processRx ========
- * Process Reception function : Reception of a buffer from the
- * McBSP and reformat it to get the associated character value
- */
- static void processRx(MdUns *buffer)
- {
- Uns rawData = 0;
- Bool bitValue;
- Uns bitCnt;
- Int rxchar = 0;
- /*
- * Point to start of data in dma buffer
- * skip the start bit
- */
- rawData = *buffer++;
- /* get the value of the majority of the bits */
- bitValue = decodeBit(rawData);
-
- /*The start bit should be zero */
- if (bitValue != 0) {
- LSRREG = LSRREG | LSRSETRXFEMASK;
- (*(portObj.cbFxns)[UARTHW_LINE_STATUSHANDLER])(portObj.cbArg, LSRREG);
- LSRREG = LSRREG & LSRCLEARRXFEMASK;
- }
-
- /* Walk through each data bit */
- for (bitCnt = 0; bitCnt < UARTHW_MCBSP_DATABITS; bitCnt++) {
- /* read raw bit (word) from dma buffer */
- rawData = *buffer++;
- /* get the value of the majority of the bits */
- bitValue = decodeBit(rawData);
-
- /* put received bit into proper place */
- rxchar += bitValue << bitCnt;
- }
-
- (*(portObj.cbFxns)[UARTHW_RXFULL_STATUSHANDLER])(portObj.cbArg, rxchar);
- }
- /*
- * ======== processTx ========
- *
- * Process transmission function : this function is filling the
- * xmitbuffer with appropriate data or 0xFFFF if idle mode.
- */
- static void processTx(MdUns *buffer)
- {
- Uns bitCnt;
-
- /* Check if break is on . Note that this code can be further optimized */
- if (portObj.breakOn) {
- for (bitCnt = 0; bitCnt < UARTHW_MCBSP_TxPKTBITS; bitCnt++) {
- *buffer++ = 0x0000;
- }
- return;
- }
- /*
- * If new char waiting to be sent
- */
- if (!UARTHW_txEmpty(&portObj)) {
- /* Mark output Fifo as empty */
- LSRREG = LSRREG | LSRSETTXEMPTYMASK;
- /* Set start bit in buffer */
- *buffer++ = 0x0000;
- /* Walk through each data bit */
- for (bitCnt = 0; bitCnt < UARTHW_MCBSP_DATABITS; bitCnt++) {
- /* determine state of bit and set dma buffer value */
- if ((THRREG >> bitCnt & 0x1) == 1 ) {
- *buffer++ = 0xFFFF;
- }
- else {
- *buffer++ = 0x0000;
- }
- }
-
- (*(portObj.cbFxns)[UARTHW_TXEMPTY_STATUSHANDLER])(portObj.cbArg, 0);
- }
- else {
- /*
- * Walk through each data bit and start bit
- * and fill with idle.
- */
- for (bitCnt = 0; bitCnt < UARTHW_MCBSP_TxPKTBITS; bitCnt++) {
- *buffer++ = 0xFFFF;
- }
- }
- }