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

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_c55xx_mcbsp.c ========
  11.  */
  12.  
  13. #include <std.h>
  14. #include <hwi.h>
  15. #include <iom.h>
  16. #include <csl_mcbsp.h>
  17. #include <csl_irq.h>
  18. #include <csl_dma.h>
  19. #include <uarthw_mcbsp.h>
  20. static Int setupDma(MdUns *rxBuf, MdUns *txBuf, UARTHW_MCBSP_Params *params);
  21. static Int setupMcbsp(UARTHW_MCBSP_Params *params);
  22. static void enable(MdUns *txBuf);
  23. static void rxIsr(void);
  24. static void txIsr(void);
  25. static MCBSP_Handle hMcbsp;
  26. static DMA_Handle hDmaRx;
  27. static DMA_Handle hDmaTx;  
  28. UARTHW_MCBSP_Params defaultParams = {
  29.     MCBSP_PORT0,        /* mcbspId */
  30.     DMA_CHA4,           /* dmaRxId */
  31.     DMA_CHA5,           /* dmaTxId */
  32.     200000000,          /* mcbspClkIn (200MHz)*/
  33.     115200,              /* baud rate */
  34.     {
  35.         {
  36.                 UARTHW_MCBSP_IER_MASK_DEFAULT,
  37.                 UARTHW_MCBSP_IER_MASK_DEFAULT
  38.         },
  39.         {
  40.                 UARTHW_MCBSP_IER_MASK_DEFAULT,
  41.                 UARTHW_MCBSP_IER_MASK_DEFAULT
  42.         }
  43.     }
  44. };
  45. /*
  46.  *  ======== UARTHW_MCBSP_start ========
  47.  */
  48. Int UARTHW_MCBSP_start(MdUns *rxBuf, MdUns *txBuf, 
  49.                         UARTHW_MCBSP_Params *params)
  50. {
  51.     Int status;
  52.     Int rxId, txId;
  53.     HWI_Attrs hwiAttrs;
  54.     if (params == NULL) {
  55.         params = &defaultParams;
  56.     }
  57.     status = setupMcbsp(params);
  58.     if (status < 0) {
  59.        return (status);
  60.     }
  61.     status = setupDma(rxBuf, txBuf, params);
  62.     if (status < 0) {
  63.        return (status);
  64.     }
  65.     /* Obtain Interrupt IDs for Tx and Rx DMAs */
  66.     rxId = DMA_getEventId(hDmaRx);
  67.     txId = DMA_getEventId(hDmaTx);
  68.     /* plug in the ISR */
  69.     hwiAttrs.ier0mask = params->intrMask.rxIerMask[0];
  70.     hwiAttrs.ier1mask = params->intrMask.rxIerMask[1];
  71.     hwiAttrs.arg = NULL;
  72.     HWI_dispatchPlug(rxId, (Fxn)rxIsr, &hwiAttrs);
  73.     hwiAttrs.ier0mask = params->intrMask.txIerMask[0];
  74.     hwiAttrs.ier1mask = params->intrMask.txIerMask[1];
  75.     HWI_dispatchPlug(txId, (Fxn)txIsr, &hwiAttrs);
  76.     IRQ_enable(rxId);
  77.     IRQ_enable(txId);
  78.     enable(txBuf);
  79.     return (IOM_COMPLETED);
  80. }
  81. /*
  82.  *      ======== setupDma =======
  83.  */
  84. static Int setupDma(MdUns *rxBuf, MdUns *txBuf, UARTHW_MCBSP_Params *params)
  85. {
  86.     Uns dmaTxSynEvt, dmaRxSynEvt;
  87.     Uint32 dmaTxDest, dmaRxSrc;
  88.     LgUns tempAdd;
  89.     
  90.     DMA_Config dmaTxCfg;                /* Tx Config Structure */
  91.     DMA_Config dmaRxCfg;                /* Rx Config Structure */
  92.     
  93.     DMA_FSET(DMAGCR,FREE,0);
  94.     hDmaRx = DMA_open(params->dmaRxId,DMA_OPEN_RESET);
  95.     hDmaTx = DMA_open(params->dmaTxId,DMA_OPEN_RESET);
  96.     
  97.     //Initialize structures
  98.     DMA_getConfig(hDmaRx, &dmaRxCfg);
  99.     DMA_getConfig(hDmaTx, &dmaTxCfg);
  100.     
  101.     //Tx Side DMA specific configuration
  102.     dmaTxCfg.dmacsdp = 
  103.         DMA_FMK(DMACSDP,DST,DMA_DMACSDP_DST_PERIPH)             |
  104.         DMA_FMK(DMACSDP,SRC,DMA_DMACSDP_SRC_DARAM)              |
  105.         DMA_FMK(DMACSDP,DATATYPE,DMA_DMACSDP_DATATYPE_16BIT)    ;
  106.         
  107.     dmaTxCfg.dmaccr = 
  108.         DMA_FMK(DMACCR,DSTAMODE,DMA_DMACCR_DSTAMODE_CONST)      |
  109.         DMA_FMK(DMACCR,SRCAMODE,DMA_DMACCR_SRCAMODE_POSTINC)    |
  110.         DMA_FMK(DMACCR,ENDPROG,DMA_DMACCR_ENDPROG_OFF)          |
  111.         DMA_FMK(DMACCR,REPEAT,DMA_DMACCR_REPEAT_ON)             |
  112.         DMA_FMK(DMACCR,AUTOINIT,DMA_DMACCR_AUTOINIT_ON)         |
  113.         DMA_FMK(DMACCR,EN,DMA_DMACCR_EN_STOP)                   |
  114.         DMA_FMK(DMACCR,PRIO,DMA_DMACCR_PRIO_HI)                 |
  115.         DMA_FMK(DMACCR,FS,DMA_DMACCR_FS_DISABLE)                ;
  116.                 
  117.     dmaTxCfg.dmacicr =
  118.         DMA_FMK(DMACICR,HALFIE,DMA_DMACICR_HALFIE_ON)           |
  119.         DMA_FMK(DMACICR,FRAMEIE,DMA_DMACICR_FRAMEIE_ON)         ;
  120.     dmaTxCfg.dmacfi = 0x0000;
  121.     dmaTxCfg.dmacei = 0x0000;
  122.     dmaTxCfg.dmacen = 2 * UARTHW_MCBSP_TxPKTBITS;
  123.     dmaTxCfg.dmacfn = 1;
  124.     
  125.     
  126.     /* Rx Side DMA specific configuration */
  127.     dmaRxCfg.dmacsdp = 
  128.         DMA_FMK(DMACSDP,DST,DMA_DMACSDP_DST_DARAM)              |
  129.         DMA_FMK(DMACSDP,SRC,DMA_DMACSDP_SRC_PERIPH)             |
  130.         DMA_FMK(DMACSDP,DATATYPE,DMA_DMACSDP_DATATYPE_16BIT)    ;
  131.         
  132.     dmaRxCfg.dmaccr = 
  133.         DMA_FMK(DMACCR,DSTAMODE,DMA_DMACCR_DSTAMODE_POSTINC)    |
  134.         DMA_FMK(DMACCR,SRCAMODE,DMA_DMACCR_SRCAMODE_CONST)      |       
  135.         DMA_FMK(DMACCR,ENDPROG,DMA_DMACCR_ENDPROG_OFF)          |
  136.         DMA_FMK(DMACCR,REPEAT,DMA_DMACCR_REPEAT_ON)             |
  137.         DMA_FMK(DMACCR,AUTOINIT,DMA_DMACCR_AUTOINIT_ON)         |
  138.         DMA_FMK(DMACCR,EN,DMA_DMACCR_EN_STOP)                   |
  139.         DMA_FMK(DMACCR,PRIO,DMA_DMACCR_PRIO_HI)                 |
  140.         DMA_FMK(DMACCR,FS,DMA_DMACCR_FS_DISABLE)                ;
  141.                 
  142.     dmaRxCfg.dmacicr = 
  143.         DMA_FMK(DMACICR,HALFIE,DMA_DMACICR_HALFIE_ON)           |
  144.         DMA_FMK(DMACICR,FRAMEIE,DMA_DMACICR_FRAMEIE_ON)         ;
  145.     
  146.     dmaRxCfg.dmacfi = 0x0;
  147.     dmaRxCfg.dmacei = 0x0;
  148.     dmaRxCfg.dmacen = 2 * UARTHW_MCBSP_RxPKTBITS;
  149.     dmaRxCfg.dmacfn = 1;
  150.     
  151.     
  152.     //Check to see which MCBSP port is being used
  153.     if (params->mcbspId == MCBSP_PORT2) {
  154.         dmaRxSynEvt = DMA_DMACCR_SYNC_REVT2;
  155.         dmaTxSynEvt = DMA_DMACCR_SYNC_XEVT2;
  156.         dmaTxDest = MCBSP_ADDR(DXR12) << 1;
  157.         dmaRxSrc  = MCBSP_ADDR(DRR12) << 1;
  158.     }
  159.     else if (params->mcbspId == MCBSP_PORT1) {
  160.         dmaRxSynEvt = DMA_DMACCR_SYNC_REVT1;
  161.         dmaTxSynEvt = DMA_DMACCR_SYNC_XEVT1;
  162.         dmaTxDest = MCBSP_ADDR(DXR11) << 1;
  163.         dmaRxSrc  = MCBSP_ADDR(DRR11) << 1;
  164.     }
  165.     else {
  166.         dmaRxSynEvt = DMA_DMACCR_SYNC_REVT0;
  167.         dmaTxSynEvt = DMA_DMACCR_SYNC_XEVT0;
  168.         dmaTxDest = MCBSP_ADDR(DXR10) << 1;
  169.         dmaRxSrc  = MCBSP_ADDR(DRR10) << 1;
  170.     }
  171.     
  172.     
  173.     if (hDmaTx == INV || hDmaRx == INV) {
  174.         return (IOM_EBADIO);
  175.     }
  176.     
  177.     /* Setup Tx Side addresses based on MCBSP port */
  178.     dmaTxCfg.dmacdsal = (DMA_AdrPtr)(dmaTxDest & 0xFFFF);
  179.     dmaTxCfg.dmacdsau = ((dmaTxDest >> 15) & 0xFFFF);
  180.         
  181.     /* Need '<< 1' for byte addressing */
  182.     tempAdd = (LgUns)(&txBuf[0]) << 1;
  183.     dmaTxCfg.dmacssal = (DMA_AdrPtr)(tempAdd & 0xFFFF);
  184.     dmaTxCfg.dmacssau = ((tempAdd >> 15) & 0xFFFF);
  185.     
  186.     dmaTxCfg.dmaccr |=
  187.         DMA_FMK(DMACCR,SYNC,dmaTxSynEvt);
  188.         
  189.     DMA_config(hDmaTx,&dmaTxCfg);
  190.     
  191.     /* Setup Rx Side addresses based on MCBSP port */
  192.     dmaRxCfg.dmacssal = (DMA_AdrPtr)(dmaRxSrc & 0xFFFF);
  193.     dmaRxCfg.dmacssau = ((dmaRxSrc >> 15) & 0xFFFF);
  194.         
  195.     /* Need '<< 1' for byte addressing */
  196.     tempAdd = (LgUns)(&rxBuf[0]) << 1;
  197.     dmaRxCfg.dmacdsal = (DMA_AdrPtr)(tempAdd & 0xFFFF);
  198.     dmaRxCfg.dmacdsau = ((tempAdd >> 15) & 0xFFFF);
  199.     
  200.     dmaRxCfg.dmaccr |=
  201.         DMA_FMK(DMACCR,SYNC,dmaRxSynEvt);
  202.     
  203.     DMA_config(hDmaRx,&dmaRxCfg);
  204.     
  205.     
  206.     /* Configure DMA to be free running */
  207.     DMA_FSET(DMAGCR,FREE,1);
  208.     
  209.     return(IOM_COMPLETED);    
  210. }
  211. /*
  212.  *  ======== setupMcbsp ========
  213.  *  This function is used to setup the McBSP port chosen with the initial
  214.  *  settings based on parity, stopbits, databits,baudrates chosen.
  215.  */
  216. static Int setupMcbsp(UARTHW_MCBSP_Params *params)
  217. {
  218.     Uns          clkdv;
  219.     MCBSP_Config mcbspCfg;                      /*MCBSP Config Structure*/
  220.     hMcbsp  = MCBSP_open(params->mcbspId, MCBSP_OPEN_RESET);
  221.     if (hMcbsp == INV) {
  222.         return (IOM_EBADIO);
  223.     }
  224.     /* Initialize MCBSP Structure */
  225.     MCBSP_getConfig(hMcbsp, &mcbspCfg);
  226.     /* Setup MCBSP Regs */
  227.     mcbspCfg.pcr = 
  228.         MCBSP_FMK(PCR,XIOEN,MCBSP_PCR_XIOEN_SP)                         |
  229.         MCBSP_FMK(PCR,RIOEN,MCBSP_PCR_RIOEN_SP)                         |
  230.         MCBSP_FMK(PCR,FSXM,MCBSP_PCR_FSXM_INTERNAL)                     | 
  231.         MCBSP_FMK(PCR,FSRM,MCBSP_PCR_FSRM_EXTERNAL)                     | 
  232.         MCBSP_FMK(PCR,CLKXM,MCBSP_PCR_CLKXM_OUTPUT)                     |
  233.         MCBSP_FMK(PCR,CLKRM,MCBSP_PCR_CLKRM_OUTPUT)                     |
  234.         MCBSP_FMK(PCR,DXSTAT,MCBSP_PCR_DXSTAT_0)                        |
  235.         MCBSP_FMK(PCR,FSXP,MCBSP_PCR_FSXP_ACTIVELOW)                    |
  236.         MCBSP_FMK(PCR,FSRP,MCBSP_PCR_FSRP_ACTIVELOW)                    | 
  237.         MCBSP_FMK(PCR,CLKXP,MCBSP_PCR_CLKXP_RISING)                     |
  238.         MCBSP_FMK(PCR,CLKRP,MCBSP_PCR_CLKRP_FALLING)                    ;
  239.     /*
  240.      * Here we compute the bit rate of the McBSP.  Each UART bit is
  241.      * represented by 16 McBSP bits.
  242.      */
  243.     clkdv = (Uns)(params->mcbspClkIn / (params->baud * 16));
  244.     /* clkdv is max 8-bits long, so make sure we didn't overflow ... */
  245.     if (clkdv > 0xff) {
  246.         return (IOM_EBADARGS);
  247.     }
  248.     mcbspCfg.srgr1 = 
  249.         MCBSP_FMK(SRGR1,CLKGDV,MCBSP_SRGR1_CLKGDV_OF(clkdv))    |       
  250.         MCBSP_FMK(SRGR1,FWID,MCBSP_SRGR1_FWID_OF(0))                    ;
  251.     mcbspCfg.srgr2 = 
  252.         MCBSP_FMK(SRGR2,GSYNC,MCBSP_SRGR2_GSYNC_FREE)                   |
  253.         MCBSP_FMK(SRGR2,CLKSP,MCBSP_SRGR2_CLKSP_RISING)                 |
  254.         MCBSP_FMK(SRGR2,CLKSM,MCBSP_SRGR2_CLKSM_INTERNAL)               |
  255.         MCBSP_FMK(SRGR2,FSGM,MCBSP_SRGR2_FSGM_DXR2XSR)                  ;
  256.         
  257.     //Want DUAL Phase to account for Half stop bits
  258.     mcbspCfg.xcr1 =
  259.         MCBSP_FMK(XCR1,XFRLEN1,MCBSP_XCR1_XFRLEN1_OF(8))                |
  260.         MCBSP_FMK(XCR1,XWDLEN1,MCBSP_XCR1_XWDLEN1_16BIT)                ;
  261.     mcbspCfg.xcr2 =
  262.         MCBSP_FMK(XCR2,XPHASE,MCBSP_XCR2_XPHASE_DUAL)                   |
  263.         MCBSP_FMK(XCR2,XFRLEN2,MCBSP_XCR2_XFRLEN2_OF(1))                |
  264.         MCBSP_FMK(XCR2,XWDLEN2,MCBSP_XCR2_XWDLEN2_8BIT)                 |
  265.         MCBSP_FMK(XCR2,XCOMPAND,MCBSP_XCR2_XCOMPAND_MSB)                |
  266.         MCBSP_FMK(XCR2,XFIG,MCBSP_XCR2_XFIG_NO)                         |
  267.         MCBSP_FMK(XCR2,XDATDLY,MCBSP_XCR2_XDATDLY_0BIT)                 ;
  268.     mcbspCfg.rcr1 =
  269.         MCBSP_FMK(RCR1,RFRLEN1,MCBSP_RCR1_RFRLEN1_OF(8))                |
  270.         MCBSP_FMK(RCR1,RWDLEN1,MCBSP_RCR1_RWDLEN1_16BIT)                ;
  271.     mcbspCfg.rcr2 =
  272.         MCBSP_FMK(RCR2,RPHASE,MCBSP_RCR2_RPHASE_DUAL)                   |
  273.         MCBSP_FMK(RCR2,RFRLEN2,MCBSP_RCR2_RFRLEN2_OF(0))                |
  274.         MCBSP_FMK(RCR2,RWDLEN2,MCBSP_RCR2_RWDLEN2_8BIT)                 |
  275.         MCBSP_FMK(RCR2,RCOMPAND,MCBSP_RCR2_RCOMPAND_MSB)                |
  276.         MCBSP_FMK(RCR2,RFIG,MCBSP_RCR2_RFIG_NO)                         |
  277.         MCBSP_FMK(RCR2,RDATDLY,MCBSP_RCR2_RDATDLY_1BIT)                 ;
  278.     mcbspCfg.spcr1 =
  279.         MCBSP_FMK(SPCR1,DLB,MCBSP_SPCR1_DLB_OFF)                        |
  280.         MCBSP_FMK(SPCR1,RJUST,MCBSP_SPCR1_RJUST_RZF)                    |
  281.         MCBSP_FMK(SPCR1,CLKSTP,MCBSP_SPCR1_CLKSTP_DISABLE)              |
  282.         MCBSP_FMK(SPCR1,DXENA,MCBSP_SPCR1_DEFAULT)                      |
  283.         MCBSP_FMK(SPCR1,RINTM,MCBSP_SPCR1_RINTM_RRDY)                   |
  284.         MCBSP_FMK(SPCR1,RRST,MCBSP_SPCR1_RRST_DISABLE)                  ;
  285.     mcbspCfg.spcr2 =
  286.         MCBSP_FMK(SPCR2,FREE,MCBSP_SPCR2_FREE_NO)                       |
  287.         MCBSP_FMK(SPCR2,SOFT,MCBSP_SPCR2_SOFT_YES)                      |
  288.         MCBSP_FMK(SPCR2,FRST,MCBSP_SPCR2_DEFAULT)                       |
  289.         MCBSP_FMK(SPCR2,GRST,MCBSP_SPCR2_DEFAULT)                       |
  290.         MCBSP_FMK(SPCR2,XINTM, MCBSP_SPCR2_XINTM_XRDY)                  |
  291.         MCBSP_FMK(SPCR2,XSYNCERR,MCBSP_SPCR2_XSYNCERR_NO)               ;
  292.         
  293.     /* Assign structure to handle */
  294.     MCBSP_config(hMcbsp, &mcbspCfg);
  295.     return (IOM_COMPLETED);
  296. }
  297. /*
  298.  *  ======== enable ========
  299.  *  This function is used to enable the McBSP and start DMA
  300.  */
  301. static void enable(MdUns *txBuf)
  302. {
  303.     /* Start transmit and receive DMA channels */
  304.     DMA_start(hDmaTx);
  305.     DMA_start(hDmaRx);
  306.         
  307.     /* Start the MCBSP and Sample Rate Generator */
  308.     MCBSP_start(hMcbsp, MCBSP_SRGR_START, 0xFFFF);
  309.     
  310.     /* Take MCBSP receive and transmit out of reset */
  311.     MCBSP_start(hMcbsp, MCBSP_XMIT_START | MCBSP_RCV_START, 0xFFFF);
  312. }
  313. /*
  314.  *  ======== rxIsr ========
  315.  *  This function will clear the DMA CSR and call the upper layer ISR
  316.  */
  317. static void rxIsr(void)
  318. {
  319.     volatile Uns temp;
  320.      
  321.     temp = DMA_RGETH(hDmaRx, DMACSR);   /* DMA_RGET clears interrupt flag */
  322.     UARTHW_MCBSP_dmaRxIsr();            /* Calling the upper layer ISR */
  323. }
  324. /*
  325.  *  ======== txIsr ========
  326.  *  This function will clear the DMA CSR and call the upper layer ISR
  327.  */
  328. static void txIsr(void)
  329. {
  330.     volatile Uns temp;
  331.      
  332.     temp = DMA_RGETH(hDmaTx, DMACSR);   /* DMA_RGET clears interrupt flag*/
  333.     UARTHW_MCBSP_dmaTxIsr();            /* Calling the upper layer ISR */
  334. }