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

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.11.00.00 11-04-03 (ddk-b13)" */
  9. /*
  10.  *  ======== uarthw_evmdm642.c ========
  11.  */
  12.  
  13. #include <std.h>
  14. #define CHIP_DM642      1
  15. #include <hwi.h>
  16. #include <iom.h>
  17. #include <csl.h>
  18. #include <csl_irq.h>
  19. #include <evmdm642.h>
  20. #include <evmdm642_osd.h>
  21. #include <uarthw.h>
  22. #include <uarthw_evmdm642.h>
  23. #include <uarthw_evmdm642hal.h>
  24. #define RBRREG(regset)  regset->uart[0]
  25. #define THRREG(regset)  regset->uart[0]
  26. #define DLLREG(regset)  regset->uart[0]
  27. #define DLHREG(regset)  regset->uart[1]
  28. #define IERREG(regset)  regset->uart[1]
  29. #define FCRREG(regset)  regset->uart[2]
  30. #define EFRREG(regset)  regset->uart[2]
  31. #define IIRREG(regset)  regset->uart[2]
  32. #define LCRREG(regset)  regset->uart[3]
  33. #define MCRREG(regset)  regset->uart[4]
  34. #define XON1REG(regset) regset->uart[4]
  35. #define LSRREG(regset)  regset->uart[5]
  36. #define XON2REG(regset) regset->uart[5]
  37. #define MSRREG(regset)  regset->uart[6]
  38. #define XOF1REG(regset) regset->uart[6]
  39. #define TCRREG(regset)  regset->uart[6]
  40. #define SPRREG(regset)  regset->uart[7]
  41. #define XOF2REG(regset) regset->uart[7]
  42. #define TLRREG(regset)  regset->uart[7]
  43. #define FRDYREG(regset) regset->uart[7]
  44. #define getLineStatus(regset)           (LSRREG(regset))
  45. #define getModemControlReg(regset)      (MCRREG(regset))
  46. #define setModemControlReg(regset, c)   MCRREG(regset) = (c)
  47. #define getLineControlReg(regset)       (LCRREG(regset))
  48. #define setLineControlReg(regset, c)    LCRREG(regset) = (c)
  49. #define disableRx(regset)               (IERREG(regset) &= ~UART_IER_RXDATAEN)
  50. #define disableTx(regset)               (IERREG(regset) &= ~UART_IER_THREMPEN)
  51. #define enableRx(regset)                (IERREG(regset) |= UART_IER_RXDATAEN)
  52. #define enableTx(regset)                (IERREG(regset) |= UART_IER_THREMPEN)
  53. #ifdef _DEBUG
  54. #define getInt(regset)                  (IIRREG(regset) & 0x3f)
  55. #else
  56. #define getInt(regset)                  (IIRREG(regset) & 0x0f)
  57. #endif /* _DEBUG */
  58. #define NUMPORTS                        2
  59. #define NOINTPENDING                    0x01
  60. #define IDENTIFYINT(id)                 ((id >> 1) & 0x03)
  61. #define MCRDTRMASK                      0xFE
  62. #define MCRRTSMASK                      0xFD
  63. #define LCRBRKMASK                      0xBF
  64. #define AFERTSCTSMASK                   0xDD
  65. #define AFERTSCTSFLW                    0x22
  66. #define AFECTSFLW                       0x20
  67. #define AFEDISFLW                       0x00
  68. #define LCRBREAKPOS                     6
  69. #define MCRRTSPOS                       1
  70. typedef struct UartRegs {
  71.     volatile Byte uart[8];
  72. } UartRegs;
  73. static void setupFlowParams(UARTHW_Handle hUart, Uns flowParam);
  74. static void uartIsr(Ptr cbArg);
  75. static Int uartRxFull(UartRegs * regs);
  76. static UARTHW_EVMDM642_Params defaultParams = { 
  77.     UARTHW_EVMDM642_FLOW_NONE,                  
  78.     UARTHW_EVMDM642_DISABLE_PARITY,             
  79.     UARTHW_EVMDM642_WORD8,                      
  80.     UARTHW_EVMDM642_STOP1,                      
  81.     UARTHW_EVMDM642_BAUD_115200                 
  82. };
  83. typedef struct UARTHW_Obj {
  84.     Int uartId;                         /* UART port ID */
  85.     Int rxDisabled;                     /* disabled flag */
  86.     UartRegs * regs;                    /* base pointer to reg set */
  87.     UARTHW_EVMDM642_Params *params;
  88.     UARTHW_Tcallback * cbFxns;
  89.     Ptr cbArg;
  90. } UARTHW_Obj;
  91. UARTHW_Obj portObj[NUMPORTS];
  92. #ifdef _DEBUG
  93. struct {
  94.         Int errInts;
  95.         Int mdmInts;
  96.         Int rhrInts;
  97.         Int thrInts;
  98.         Int rtoInts;
  99.         Int rxCnt;
  100.         Int rxXoff;
  101.         Int rtsCts;
  102. } intStats[NUMPORTS] =
  103. {
  104.         {0, 0, 0, 0, 0, 0, 0, 0},
  105.         {0, 0, 0, 0, 0, 0, 0, 0}
  106. };
  107. #endif /* _DEBUG */
  108. /*
  109.  *  ======== UARTHW_open ========
  110.  *
  111.  *  This function is used to attach to the UART.
  112.  *  Typically this function plugs the UART interrupt vector with
  113.  *  the internal driver supplied isr routine.
  114.  *  Initializes the UART, UART flow parameters and UART communication parameters
  115.  *
  116.  */
  117. UARTHW_Handle UARTHW_open(Int uartId, Ptr params, Ptr cbArg, UARTHW_Tcallback *cbFxns)
  118. {
  119.     volatile Char c;
  120.         UartRegs *regs;
  121.     UARTHW_EVMDM642_Params *uartParams = (UARTHW_EVMDM642_Params *)params;
  122.     UARTHW_Handle  port;
  123.     if (uartId >= NUMPORTS) {
  124.         return (NULL);                  // invalid UART id
  125.     }
  126.     port = &portObj[uartId];
  127.     
  128.     port->uartId = uartId;
  129.     regs = port->regs = (UartRegs *) (EVMDM642_CPLD_BASE + (uartId * sizeof(UartRegs)));
  130.     /* 
  131.      * Initialize the isrhandler to the one given by
  132.      * generic uart.
  133.      */
  134.     port->cbFxns = cbFxns;
  135.     port->cbArg = cbArg;
  136.        
  137.     EVMDM642_OSD_init();
  138.     if (uartId == 0) {
  139.         EVMDM642_OSD_intHook(UARTA_IRQ, uartIsr, port);
  140.     } 
  141.     else {
  142.         EVMDM642_OSD_intHook(UARTB_IRQ, uartIsr, port);
  143.     }
  144.     /* 
  145.      * Use the default attributes if one is not given
  146.      */
  147.     if (uartParams == NULL) {
  148.         uartParams = &defaultParams;
  149.     }
  150.     /*
  151.      * Set EFR registers
  152.      */
  153.     LCRREG(regs) = 0xBF;                /* address secondary register set */
  154.     EFRREG(regs) = 
  155.     UART_EFR_AUTOCTS | UART_EFR_AUTORTS | UART_EFR_ENHFUNCEN; /* enable enhanced functions */
  156.     LCRREG(regs) = 0x00;                /* back to primary register set */
  157.     MCRREG(regs) = 0x00;
  158.     MCRREG(regs) = UART_MCR_IRQENOP | UART_MCR_FIFORDYEN; /* enable IRQ and FIF rdy register */
  159.     IERREG(regs) = 0x00;                /* set interrupt enable register */
  160.     FCRREG(regs) = 0x00;                /* set FIFO control */
  161.     /*
  162.      * Set up baud rate and other comm parameters
  163.      */
  164.     LCRREG(regs) = UART_LCR_DLTCHEN; /* enable divisor */
  165.     DLLREG(regs) = uartParams->baud;
  166.     DLHREG(regs) = uartParams->baud >> 8;
  167.     LCRREG(regs) = uartParams->wordSize | (uartParams->stopBits << 2) |
  168.                 (uartParams->parity << 3);
  169.     FCRREG(regs) =                              /* FIFO control register */
  170.                 UART_FCR_RXTRG16 | UART_FCR_TXTRG32 | UART_FCR_DMAMODE |
  171.                 UART_FCR_RSTTXFIFO | UART_FCR_RSTRXFIFO | UART_FCR_FIFOEN;
  172.     IERREG(regs) =                              /* enable normal interrupts */
  173.                 UART_IER_MDMSTATEN | UART_IER_RXLSTATEN | UART_IER_THREMPEN |
  174.                 UART_IER_RXDATAEN;
  175.     LSRREG(regs);                               /* clear previous line status */
  176.     MSRREG(regs);                               /* modem status register */
  177.     MCRREG(regs);                               /* modem control register */
  178.     while (uartRxFull(regs)) { /* remove active characters */
  179.         c = RBRREG(regs);
  180.     }
  181.     port->params = uartParams;
  182.       
  183.     setupFlowParams(port, (uartParams->flowControl) & UARTHW_EVMDM642_HW_FLOW_MASK);
  184.     port->rxDisabled = 0;               /* indicate we're enabled now */
  185.     enableRx(regs);
  186.     enableTx(regs);
  187.   
  188.     return (port);
  189. }
  190. /*
  191.  *  ======== UARTHW_getModemStatus ========
  192.  *
  193.  *  This function is used to get the modem status for the UART. 
  194.  */
  195.  
  196. Int UARTHW_getModemStatus(UARTHW_Handle hUart, char *pmodemStatus)
  197. {
  198.     *pmodemStatus = MSRREG(hUart->regs);
  199.     return (IOM_COMPLETED);
  200. }
  201. /*
  202.  *  ======== UARTHW_resetDevice ========
  203.  *
  204.  *  This function is used to reset the UART 16c75x.
  205.  *  Ideally this function should clear the transmit and 
  206.  *  receive fifos if the fifos are being used.
  207.  */
  208. void UARTHW_resetDevice(UARTHW_Handle hUart)
  209. {
  210.     FCRREG(hUart->regs) =
  211.                 UART_FCR_RXTRG16 | UART_FCR_TXTRG32 | UART_FCR_DMAMODE |
  212.                 UART_FCR_RSTTXFIFO | UART_FCR_RSTRXFIFO | UART_FCR_FIFOEN;
  213. }
  214. /*
  215.  *  ======== UARTHW_setBreak ========
  216.  *
  217.  *  This function is used to set the break on/off for the UART 16c75x 
  218.  */
  219. Int UARTHW_setBreak(UARTHW_Handle hUart, Int bBreak)
  220. {
  221.     char lcrVal;
  222.     lcrVal = getLineControlReg(hUart->regs);
  223.     lcrVal = (lcrVal & LCRBRKMASK) | (bBreak << LCRBREAKPOS);
  224.     setLineControlReg(hUart->regs, lcrVal);
  225.    
  226.     return (IOM_COMPLETED);
  227. }
  228. /*
  229.  *  ======== UARTHW_setDTR ========
  230.  *
  231.  *  This function is used to set the DTR signal for the UART 16c75x 
  232.  */
  233. Int UARTHW_setDTR(UARTHW_Handle hUart, int dtrval)
  234. {
  235.     char mcrVal;
  236.     mcrVal = getModemControlReg(hUart->regs);
  237.     mcrVal = (mcrVal & MCRDTRMASK) | dtrval;
  238.     setModemControlReg(hUart->regs, mcrVal);
  239.     return (IOM_COMPLETED);
  240. }
  241. /*
  242.  *  ======== UARTHW_setRTS ========
  243.  *
  244.  *  This function is used to set the RTS signal for the UART 16c75x 
  245.  */
  246. Int UARTHW_setRTS(UARTHW_Handle hUart, int rtsval)
  247. {
  248.     char mcrVal;
  249.     mcrVal = getModemControlReg(hUart->regs);
  250.     mcrVal = (mcrVal & MCRRTSMASK) | (rtsval << MCRRTSPOS);
  251.     setModemControlReg(hUart->regs, mcrVal);
  252.     
  253.     return (IOM_COMPLETED);
  254. }
  255. /*
  256.  *  ======== UARTHW_txEmpty ========
  257.  *
  258.  *  This function is used to get the transmit buffer empty condition 
  259.  */
  260. Int UARTHW_txEmpty(UARTHW_Handle hUart)
  261. {
  262.     return (LSRREG(hUart->regs) & UART_LSR_THREMPTY);
  263. }
  264. /*
  265.  *  ======== UARTHW_writeChar ========
  266.  *
  267.  *  This function is used to write a character to the transmit register 
  268.  */
  269. void UARTHW_writeChar(UARTHW_Handle hUart, char c)
  270. {
  271.     THRREG(hUart->regs) = c;
  272. }
  273. /*
  274.  *  ======== UARTHW_enableRx ========
  275.  *  Enable the Rx Interrupt of the UART.
  276.  *
  277.  */
  278. void UARTHW_enableRx(UARTHW_Handle hUart)
  279. {
  280.     if (ATM_seti(&hUart->rxDisabled, 0)) {
  281.         enableRx(hUart->regs);
  282.     }
  283. }
  284. /*
  285.  *  ======== UARTHW_disableRx ========
  286.  *  Disable the Rx Interrupt of the UART.
  287.  *
  288.  */
  289. void UARTHW_disableRx(UARTHW_Handle hUart)
  290. {
  291.     int gie;
  292.     gie = IRQ_globalDisable();
  293.     disableRx(hUart->regs);
  294.     hUart->rxDisabled = 1;
  295.     IRQ_globalRestore(gie);
  296. }
  297. /*
  298.  *  ======== setupFlowParams ========
  299.  *
  300.  *  This function is used to setup the UART 16c75x flow paramaters
  301.  */
  302. static void setupFlowParams(UARTHW_Handle hUart, Uns flowParam)
  303. {
  304.     char mcrVal;
  305.  
  306.     mcrVal = getModemControlReg(hUart->regs);
  307.         mcrVal &= AFERTSCTSMASK;
  308.  
  309.     if (flowParam & UARTHW_EVMDM642_FLOW_AFE_RTSCTS) {
  310.         mcrVal |= AFERTSCTSFLW;
  311.     }
  312.     else if (flowParam & UARTHW_EVMDM642_FLOW_AFE_CTS) {
  313.         mcrVal |= AFECTSFLW;
  314.     }
  315.     else {
  316.         mcrVal |= AFEDISFLW;  
  317.     }
  318.     setModemControlReg(hUart->regs, mcrVal);                
  319. }
  320. /* 
  321.  *  ======== uartIsr ========
  322.  *
  323.  *  This is the interrupt service handler used by the EVMDM642
  324.  *  UART driver.
  325.  */
  326. static void uartIsr(Ptr portArg)
  327. {
  328.     Int                 id;
  329.     Int                 argval;
  330.     Int                 temp;
  331.     UARTHW_Handle       port = (UARTHW_Handle) portArg;
  332.     UARTHW_Tcallback    *callbacks = port->cbFxns;
  333.     Ptr                 cbArg = port->cbArg;
  334.     /*
  335.      * While loop here since 16C752/4 holds interrupt line high until
  336.      * all interrupt conditions are handled (2 or more may be pending
  337.      * at same time).  DM642 uses edge-triggered interrupts and would
  338.      * miss interrupts otherwise.
  339.      */
  340.     while (!((id = getInt(port->regs)) & NOINTPENDING)) {
  341.         switch (id) {
  342.             case UART_INT_MSR: /* Modem status interrupt -- read and dispatch */
  343. #ifdef _DEBUG
  344.                 intStats[port->uartId].mdmInts++;
  345. #endif /* _DEBUG */
  346.                 argval = MSRREG(port->regs);
  347.                 (*callbacks[UARTHW_MODEM_STATUSHANDLER])(cbArg, argval);
  348.                 break;
  349.             case UART_INT_THR:          /* Transmit handler */
  350. #ifdef _DEBUG
  351.                 intStats[port->uartId].thrInts++;
  352. #endif /* _DEBUG */
  353.                 /* NOTE:
  354.                  * This shouldn't be necessary, but sometimes the interrupt
  355.                  * comes in before the transmitter is really empty.  Still
  356.                  * working on this one
  357.                  */
  358.                 while (!(temp = UARTHW_txEmpty(port))) {
  359.                     asm(" NOP");
  360.                 }
  361.                 (*callbacks[UARTHW_TXEMPTY_STATUSHANDLER])(cbArg, temp);
  362.                 break;
  363.             case UART_INT_RHR:          /* Receive Handler */
  364.             case UART_INT_RXTO:         /* Receive time-out error */
  365. #ifdef _DEBUG
  366.                 if (id == UART_INT_RHR)
  367.                     intStats[port->uartId].rhrInts++;
  368.                 else
  369.                     intStats[port->uartId].rtoInts++;
  370. #endif /* _DEBUG */
  371.                 while ((!port->rxDisabled) && uartRxFull(port->regs)) {
  372. #ifdef _DEBUG
  373.                     intStats[port->uartId].rxCnt++;
  374. #endif /* _DEBUG */
  375.                     argval = RBRREG(port->regs);
  376.                     (*callbacks[UARTHW_RXFULL_STATUSHANDLER])(cbArg, argval); 
  377.                 }
  378.                 break;
  379.                 case UART_INT_RLSERR:   /* Receiver line status error */
  380. #ifdef _DEBUG
  381.                     intStats[port->uartId].errInts++;
  382. #endif /* _DEBUG */
  383.                     argval = LSRREG(port->regs);
  384.                     /*
  385.                      * Isolate parity/framing/overrun and data ready
  386.                      * Discard characters by reading the receiver buffer
  387.                      * ready register, and get the line status again
  388.                      */
  389.                     while ((argval & UART_LSR_ERRMASK) && (argval & UART_LSR_DATAIN)) {
  390.                         RBRREG(port->regs);
  391.                         argval = LSRREG(port->regs);
  392.                     }
  393.                     (*callbacks[UARTHW_LINE_STATUSHANDLER])(cbArg, argval);
  394.                     break;
  395. #ifdef _DEBUG
  396.                 case UART_INT_XOFF:     /* Xoff interrupt */
  397.                     intStats[port->uartId].rxXoff++;
  398.                     break;
  399.                 case UART_INT_CTSRTS:  /* RTS or CTS pin change to inactive */
  400.                     intStats[port->uartId].rtsCts++;
  401.                     break;
  402.                 default:
  403.                     while (1) {
  404.                         /* should never get here ... */
  405.                         asm(" NOP");
  406.                     }
  407. #endif /* _DEBUG */
  408.         }
  409.     }
  410. }
  411. /*
  412.  * ======== uartRxFull ========
  413. * * 
  414.  * This function is used to get the Receive Buffer Full condition 
  415.  */
  416. static Int uartRxFull(UartRegs *regs)
  417. {
  418.     return (LSRREG(regs) & UART_LSR_DATAIN);
  419. }