uarthw_mcbsp.c
上传用户:dahaojd
上传日期:2008-01-29
资源大小:14357k
文件大小:9k
源码类别:

DSP编程

开发平台:

C/C++

  1. /*
  2.  *  Copyright 2003 by Texas Instruments Incorporated.
  3.  *  All rights reserved. Property of Texas Instruments Incorporated.
  4.  *  Restricted rights to use, duplicate or disclose this code are
  5.  *  granted through contract.
  6.  *  
  7.  */
  8. /* "@(#) DDK 1.10.00.23 07-02-03 (ddk-b12)" */
  9. /*
  10.  *  ======== uarthw_mcbsp.c ========
  11.  */
  12.  
  13. #include <std.h>
  14. #include <iom.h>
  15. #include <uarthw.h>
  16. #include <uarthw_mcbsp.h>
  17. #define LSRREG                  (portObj.LSRVAL)
  18. #define THRREG                  (portObj.THRVAL)
  19. #define LSRCLEARRXFULLMASK      0xFE
  20. #define LSRCLEARTXEMPTYMASK     0xDF
  21. #define LSRCLEARRXFEMASK        0xF7
  22. #define LSRSETTXEMPTYMASK       0x20
  23. #define LSRSETRXFULLMASK        0x01
  24. #define LSRSETRXFEMASK          0x08
  25. #define CURRENTTXOFFSET         portObj.txOffset
  26. #define CURRENTRXOFFSET         portObj.rxOffset
  27. static void processTx(MdUns *buffer);
  28. static void processRx(MdUns *buffer);
  29. typedef struct UARTHW_Obj {
  30.     Byte        THRVAL;
  31.     Byte        LSRVAL;
  32.     MdUns *     txBuffer;
  33.     MdUns *     rxBuffer;
  34.     Uns         txOffset;
  35.     Uns         rxOffset;
  36.     Bool        breakOn;
  37.     Ptr         cbArg;
  38.     UARTHW_Tcallback *cbFxns;
  39. } UARTHW_Obj;
  40. /*
  41.  *  This driver only supports a single UART.
  42.  */
  43. static UARTHW_Obj  portObj;
  44. #if defined(_54_) || defined(_55_)
  45. /* rxBuffer and txBuffer must be aligned for the DMA to work correctly */
  46. #pragma DATA_ALIGN(rxBuffer, 32)
  47. #pragma DATA_ALIGN(txBuffer, 32)
  48. #endif
  49. /*
  50.  * CACHE issue on c6x1x!  For 6x1x these buffers need to be in on-chip
  51.  * memory (cache needs to be split) or cache needs to be disabled. You can
  52.  * do this by setting 3-way cache, defining a new on-chip memory section
  53.  * and placing .bss in on-chip memory.  This probably needs to be a 
  54.  * parameter so that 6x version can do correct cache management.
  55.  */
  56. static MdUns rxBuffer[UARTHW_MCBSP_MAXBITS * 2];
  57. static MdUns txBuffer[UARTHW_MCBSP_MAXBITS * 2];
  58. /*
  59.  *  ======== UARTHW_open ========
  60.  *  This function is used to attach to the software UART.
  61.  *  Typically this function plugs the UART interrupt vector with
  62.  *  the internal driver supplied isr routine.
  63.  */
  64. UARTHW_Handle UARTHW_open(Int uartId, Ptr attrs, Ptr cbArg, UARTHW_Tcallback 
  65.         *cbFxns)
  66. {
  67.     Uns  i;
  68.  
  69.     if (uartId != 0) {
  70.         return (NULL);
  71.     }
  72.     /* save the callback functions and argument */
  73.     portObj.cbFxns = cbFxns;
  74.     portObj.cbArg = cbArg;
  75.     
  76.     /* Initialize the uart parameters given by the app */
  77.     portObj.txBuffer  = txBuffer;
  78.     portObj.rxBuffer  = rxBuffer;
  79.     portObj.breakOn   = FALSE;
  80.     /* Initialize the Rx and Tx buffers to all 0xFFFF */ 
  81.     for (i = 0; i < UARTHW_MCBSP_MAXBITS * 2; i++) {
  82.         portObj.txBuffer[i] = portObj.rxBuffer[i] = 0xFFFF;
  83.     }
  84.     /* set the initial offsets */
  85.     CURRENTRXOFFSET = 0;
  86.     CURRENTTXOFFSET = 0;
  87.     
  88.     /* Enable the device */
  89.     LSRREG = 0x20;      
  90.     THRREG = 0x00;
  91.         
  92.     /* start the MCBSP/DMA ping-pong buffering and ISRs ... */
  93.     UARTHW_MCBSP_start(portObj.rxBuffer, portObj.txBuffer, attrs);
  94.     return (&portObj);
  95. }
  96. /*
  97.  *  ======== UARTHW_disableRx ========
  98.  *  This is an empty function for the McBSP implementation since this 
  99.  *  implementation does not support flow control.
  100.  */
  101. void UARTHW_disableRx(UARTHW_Handle hUart)
  102. {
  103. }
  104. /*
  105.  *  ======== UARTHW_enableRx ========
  106.  *  This is an empty function for the McBSP implementation since this 
  107.  *  implementation does not support flow control.
  108.  */
  109. void UARTHW_enableRx(UARTHW_Handle hUart)
  110. {
  111. }
  112. /*
  113.  *  ======== UARTHW_getModemStatus ========
  114.  *  This function is not implemented by the simulated McBSP UART driver.
  115.  */
  116. Int UARTHW_getModemStatus(UARTHW_Handle hUart, Char *pmodemStatus)
  117. {
  118.     *pmodemStatus = 0;
  119.    
  120.     return (IOM_ENOTIMPL);
  121. }
  122. /*
  123.  *  ======== UARTHW_resetDevice ========
  124.  *  This function is used to reset the UART.
  125.  *  Currently this is a dummy function.
  126.  */
  127. void UARTHW_resetDevice(UARTHW_Handle hUart)
  128. {
  129. }
  130. /*
  131.  *  ======== UARTHW_setBreak ========
  132.  *  This function is used to set the break on/off for the simulated UART  
  133.  */
  134. Int UARTHW_setBreak(UARTHW_Handle hUart, Int bBreak)
  135. {
  136.     portObj.breakOn = (Bool)bBreak; 
  137.    
  138.     if (!bBreak) {
  139.         (*(portObj.cbFxns)[UARTHW_TXEMPTY_STATUSHANDLER])(portObj.cbArg, 0);
  140.     }
  141.     return (IOM_COMPLETED);
  142. }
  143. /*
  144.  *  ======== UARTHW_setDTR ========
  145.  *  This function is not implemented by the simulated McBSP UART driver.
  146.  */
  147. Int UARTHW_setDTR(UARTHW_Handle hUart, Int dtrval)
  148. {
  149.     return (IOM_ENOTIMPL);
  150. }
  151. /*
  152.  *  ======== UARTHW_setRTS ========
  153.  *  This function is not implemented by the simulated McBSP UART driver.
  154.  */
  155. Int UARTHW_setRTS(UARTHW_Handle hUart, Int rtsval)
  156. {
  157.     return (IOM_ENOTIMPL);
  158. }
  159. /*
  160.  *  ======== UARTHW_writeChar ========
  161.  *
  162.  *  This function is used to write a character to the transmit register 
  163.  */
  164. void UARTHW_writeChar(UARTHW_Handle hUart, Char c)
  165. {
  166.     THRREG = c;
  167.     LSRREG = LSRREG & LSRCLEARTXEMPTYMASK; 
  168. }
  169. /*
  170.  *  ======== UARTHW_txEmpty ========
  171.  *
  172.  *  This function is used to get the transmit buffer empty condition 
  173.  */
  174. Int UARTHW_txEmpty(UARTHW_Handle hUart)
  175. {
  176.     return (LSRREG & 0x20);
  177. }
  178. /*
  179.  *  -------- support functions --------
  180.  */
  181. /*
  182.  *  ======== decodeBit ========
  183.  *
  184.  *  This function decoded the received character by testing the     
  185.  *  center 4 bits of the baud. A majority rule is used for the      
  186.  *  decoding
  187.  */
  188. static Bool decodeBit(Uns value)
  189. {
  190.     /* Test middle 4 bits in received raw data */
  191.     value = ((value >> 6) & 0x0F );
  192.     if ((value == 7) || (value > 10)) {
  193.         return (1);
  194.     }
  195.     else {
  196.         return (0);
  197.     }
  198. }
  199. /* 
  200.  *  ======== UARTHW_MCBSP_dmaRxIsr ========
  201.  *
  202.  *  This is the interrupt service handler used by the DSK 5402
  203.  *  McBSP driver for the receive channel.
  204.  */
  205. Void UARTHW_MCBSP_dmaRxIsr(void)
  206. {
  207.      MdUns *bufp;
  208.      bufp = &(portObj.rxBuffer[CURRENTRXOFFSET]);
  209.      CURRENTRXOFFSET = CURRENTRXOFFSET ^ UARTHW_MCBSP_RxPKTBITS;
  210.      processRx(bufp);
  211. }
  212. /* 
  213.  *  ======== UARTHW_MCBSP_dmaTxIsr ========
  214.  *
  215.  *  This is the interrupt service handler used by the DSK 5402
  216.  *  McBSP driver for the transmit channel
  217.  */
  218. Void UARTHW_MCBSP_dmaTxIsr(Void)
  219. {
  220.      MdUns *bufp;
  221.      bufp = &(portObj.txBuffer[CURRENTTXOFFSET]);
  222.      CURRENTTXOFFSET = CURRENTTXOFFSET ^ UARTHW_MCBSP_TxPKTBITS;
  223.      processTx(bufp);
  224. }
  225. /*
  226.  *  ======== processRx ========
  227.  *  Process Reception function : Reception of a buffer from the 
  228.  *  McBSP and reformat it to get the associated character value 
  229.  */
  230. static void processRx(MdUns *buffer)
  231. {
  232.     Uns rawData = 0;
  233.     Bool bitValue;
  234.     Uns bitCnt;
  235.     Int rxchar = 0;
  236.     /*
  237.      *  Point to start of data in dma buffer 
  238.      *  skip the start bit
  239.      */
  240.     rawData = *buffer++;
  241.     /* get the value of the majority of the bits */
  242.     bitValue = decodeBit(rawData);
  243.         
  244.     /*The start bit should be zero */
  245.     if (bitValue != 0) {
  246.         LSRREG = LSRREG | LSRSETRXFEMASK;
  247.         (*(portObj.cbFxns)[UARTHW_LINE_STATUSHANDLER])(portObj.cbArg, LSRREG);
  248.         LSRREG = LSRREG & LSRCLEARRXFEMASK;
  249.     }
  250.         
  251.     /* Walk through each data bit */
  252.     for (bitCnt = 0; bitCnt < UARTHW_MCBSP_DATABITS; bitCnt++) {
  253.         /* read raw bit (word) from dma buffer */
  254.         rawData = *buffer++;
  255.         /* get the value of the majority of the bits */
  256.         bitValue = decodeBit(rawData);
  257.                         
  258.         /* put received bit into proper place */
  259.         rxchar += bitValue << bitCnt;
  260.     }
  261.                  
  262.     (*(portObj.cbFxns)[UARTHW_RXFULL_STATUSHANDLER])(portObj.cbArg, rxchar);
  263. }
  264. /*
  265.  *  ======== processTx ========
  266.  *
  267.  *  Process transmission function : this function is filling the
  268.  *  xmitbuffer with appropriate data or 0xFFFF if idle mode.
  269.  */
  270. static void processTx(MdUns *buffer)
  271. {
  272.     Uns bitCnt;
  273.                         
  274.     /* Check if break is on . Note that this code can be further optimized */
  275.     if (portObj.breakOn) {
  276.         for (bitCnt = 0; bitCnt < UARTHW_MCBSP_TxPKTBITS; bitCnt++) {
  277.             *buffer++ = 0x0000;
  278.         }
  279.         return;                                 
  280.     }                                   
  281.     /*
  282.      * If new char waiting to be sent
  283.      */
  284.     if (!UARTHW_txEmpty(&portObj)) {
  285.         /* Mark output Fifo as empty */
  286.         LSRREG = LSRREG | LSRSETTXEMPTYMASK; 
  287.         /* Set start bit in buffer */
  288.         *buffer++ = 0x0000;
  289.         /* Walk through each data bit */
  290.         for (bitCnt = 0; bitCnt < UARTHW_MCBSP_DATABITS; bitCnt++) {
  291.             /* determine state of bit and set dma buffer value */
  292.             if ((THRREG >> bitCnt & 0x1) == 1 ) {
  293.                 *buffer++ = 0xFFFF;
  294.             }
  295.             else {
  296.                 *buffer++ = 0x0000;
  297.             }
  298.         }
  299.                     
  300.         (*(portObj.cbFxns)[UARTHW_TXEMPTY_STATUSHANDLER])(portObj.cbArg, 0);
  301.     } 
  302.     else {
  303.         /* 
  304.          * Walk through each data bit and start bit 
  305.          * and fill with idle.
  306.          */
  307.         for (bitCnt = 0; bitCnt < UARTHW_MCBSP_TxPKTBITS; bitCnt++) {
  308.             *buffer++ = 0xFFFF;
  309.         }
  310.     } 
  311. }