⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 uarthw_c55xx_mcbsp.c

📁 MSP430与dsp接口技术1,编辑环境C语言,我运行过,好
💻 C
字号:
/*
 *  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.11.00.00 11-04-03 (ddk-b13)" */
/*
 *  ======== uarthw_c55xx_mcbsp.c ========
 */
 
#include <std.h>

#include <hwi.h>
#include <iom.h>

#include <csl_mcbsp.h>
#include <csl_irq.h>
#include <csl_dma.h>

#include <uarthw_mcbsp.h>

static Int setupDma(MdUns *rxBuf, MdUns *txBuf, UARTHW_MCBSP_Params *params);
static Int setupMcbsp(UARTHW_MCBSP_Params *params);
static void enable(MdUns *txBuf);
static void rxIsr(void);
static void txIsr(void);

static MCBSP_Handle hMcbsp;
static DMA_Handle hDmaRx;
static DMA_Handle hDmaTx;  

UARTHW_MCBSP_Params defaultParams = {
    MCBSP_PORT0,        /* mcbspId */
    DMA_CHA4,           /* dmaRxId */
    DMA_CHA5,           /* dmaTxId */

    200000000,          /* mcbspClkIn (200MHz)*/
    115200,              /* baud rate */
    {
        {
                UARTHW_MCBSP_IER_MASK_DEFAULT,
                UARTHW_MCBSP_IER_MASK_DEFAULT
        },
        {
                UARTHW_MCBSP_IER_MASK_DEFAULT,
                UARTHW_MCBSP_IER_MASK_DEFAULT
        }
    }
};

/*
 *  ======== UARTHW_MCBSP_start ========
 */
Int UARTHW_MCBSP_start(MdUns *rxBuf, MdUns *txBuf, 
                        UARTHW_MCBSP_Params *params)
{
    Int status;
    Int rxId, txId;
    HWI_Attrs hwiAttrs;

    if (params == NULL) {
        params = &defaultParams;
    }

    status = setupMcbsp(params);
    if (status < 0) {
       return (status);
    }

    status = setupDma(rxBuf, txBuf, params);
    if (status < 0) {
       return (status);
    }

    /* Obtain Interrupt IDs for Tx and Rx DMAs */
    rxId = DMA_getEventId(hDmaRx);
    txId = DMA_getEventId(hDmaTx);

    /* plug in the ISR */
    hwiAttrs.ier0mask = params->intrMask.rxIerMask[0];
    hwiAttrs.ier1mask = params->intrMask.rxIerMask[1];
    hwiAttrs.arg = NULL;
    HWI_dispatchPlug(rxId, (Fxn)rxIsr, &hwiAttrs);
    hwiAttrs.ier0mask = params->intrMask.txIerMask[0];
    hwiAttrs.ier1mask = params->intrMask.txIerMask[1];
    HWI_dispatchPlug(txId, (Fxn)txIsr, &hwiAttrs);

    IRQ_enable(rxId);
    IRQ_enable(txId);

    enable(txBuf);

    return (IOM_COMPLETED);
}

/*
 *      ======== setupDma =======
 */

static Int setupDma(MdUns *rxBuf, MdUns *txBuf, UARTHW_MCBSP_Params *params)
{
    Uns dmaTxSynEvt, dmaRxSynEvt;
    Uint32 dmaTxDest, dmaRxSrc;
    LgUns tempAdd;
    
    DMA_Config dmaTxCfg;                /* Tx Config Structure */
    DMA_Config dmaRxCfg;                /* Rx Config Structure */
    
    DMA_FSET(DMAGCR,FREE,0);

    hDmaRx = DMA_open(params->dmaRxId,DMA_OPEN_RESET);
    hDmaTx = DMA_open(params->dmaTxId,DMA_OPEN_RESET);

    
    //Initialize structures
    DMA_getConfig(hDmaRx, &dmaRxCfg);
    DMA_getConfig(hDmaTx, &dmaTxCfg);

    
    //Tx Side DMA specific configuration
    dmaTxCfg.dmacsdp = 
        DMA_FMK(DMACSDP,DST,DMA_DMACSDP_DST_PERIPH)             |
        DMA_FMK(DMACSDP,SRC,DMA_DMACSDP_SRC_DARAM)              |
        DMA_FMK(DMACSDP,DATATYPE,DMA_DMACSDP_DATATYPE_16BIT)    ;
        
    dmaTxCfg.dmaccr = 
        DMA_FMK(DMACCR,DSTAMODE,DMA_DMACCR_DSTAMODE_CONST)      |
        DMA_FMK(DMACCR,SRCAMODE,DMA_DMACCR_SRCAMODE_POSTINC)    |
        DMA_FMK(DMACCR,ENDPROG,DMA_DMACCR_ENDPROG_OFF)          |
        DMA_FMK(DMACCR,REPEAT,DMA_DMACCR_REPEAT_ON)             |
        DMA_FMK(DMACCR,AUTOINIT,DMA_DMACCR_AUTOINIT_ON)         |
        DMA_FMK(DMACCR,EN,DMA_DMACCR_EN_STOP)                   |
        DMA_FMK(DMACCR,PRIO,DMA_DMACCR_PRIO_HI)                 |
        DMA_FMK(DMACCR,FS,DMA_DMACCR_FS_DISABLE)                ;

                
    dmaTxCfg.dmacicr =
        DMA_FMK(DMACICR,HALFIE,DMA_DMACICR_HALFIE_ON)           |
        DMA_FMK(DMACICR,FRAMEIE,DMA_DMACICR_FRAMEIE_ON)         ;


    dmaTxCfg.dmacfi = 0x0000;
    dmaTxCfg.dmacei = 0x0000;
    dmaTxCfg.dmacen = 2 * UARTHW_MCBSP_TxPKTBITS;
    dmaTxCfg.dmacfn = 1;
    
    
    /* Rx Side DMA specific configuration */
    dmaRxCfg.dmacsdp = 
        DMA_FMK(DMACSDP,DST,DMA_DMACSDP_DST_DARAM)              |
        DMA_FMK(DMACSDP,SRC,DMA_DMACSDP_SRC_PERIPH)             |
        DMA_FMK(DMACSDP,DATATYPE,DMA_DMACSDP_DATATYPE_16BIT)    ;
        
    dmaRxCfg.dmaccr = 
        DMA_FMK(DMACCR,DSTAMODE,DMA_DMACCR_DSTAMODE_POSTINC)    |
        DMA_FMK(DMACCR,SRCAMODE,DMA_DMACCR_SRCAMODE_CONST)      |       
        DMA_FMK(DMACCR,ENDPROG,DMA_DMACCR_ENDPROG_OFF)          |
        DMA_FMK(DMACCR,REPEAT,DMA_DMACCR_REPEAT_ON)             |
        DMA_FMK(DMACCR,AUTOINIT,DMA_DMACCR_AUTOINIT_ON)         |
        DMA_FMK(DMACCR,EN,DMA_DMACCR_EN_STOP)                   |
        DMA_FMK(DMACCR,PRIO,DMA_DMACCR_PRIO_HI)                 |
        DMA_FMK(DMACCR,FS,DMA_DMACCR_FS_DISABLE)                ;
                
    dmaRxCfg.dmacicr = 
        DMA_FMK(DMACICR,HALFIE,DMA_DMACICR_HALFIE_ON)           |
        DMA_FMK(DMACICR,FRAMEIE,DMA_DMACICR_FRAMEIE_ON)         ;

    
    dmaRxCfg.dmacfi = 0x0;
    dmaRxCfg.dmacei = 0x0;
    dmaRxCfg.dmacen = 2 * UARTHW_MCBSP_RxPKTBITS;
    dmaRxCfg.dmacfn = 1;
    
    
    //Check to see which MCBSP port is being used
    if (params->mcbspId == MCBSP_PORT2) {
        dmaRxSynEvt = DMA_DMACCR_SYNC_REVT2;
        dmaTxSynEvt = DMA_DMACCR_SYNC_XEVT2;
        dmaTxDest = MCBSP_ADDR(DXR12) << 1;
        dmaRxSrc  = MCBSP_ADDR(DRR12) << 1;
    }
    else if (params->mcbspId == MCBSP_PORT1) {
        dmaRxSynEvt = DMA_DMACCR_SYNC_REVT1;
        dmaTxSynEvt = DMA_DMACCR_SYNC_XEVT1;
        dmaTxDest = MCBSP_ADDR(DXR11) << 1;
        dmaRxSrc  = MCBSP_ADDR(DRR11) << 1;
    }
    else {
        dmaRxSynEvt = DMA_DMACCR_SYNC_REVT0;
        dmaTxSynEvt = DMA_DMACCR_SYNC_XEVT0;
        dmaTxDest = MCBSP_ADDR(DXR10) << 1;
        dmaRxSrc  = MCBSP_ADDR(DRR10) << 1;
    }
    
    
    if (hDmaTx == INV || hDmaRx == INV) {
        return (IOM_EBADIO);
    }
    
    /* Setup Tx Side addresses based on MCBSP port */
    dmaTxCfg.dmacdsal = (DMA_AdrPtr)(dmaTxDest & 0xFFFF);
    dmaTxCfg.dmacdsau = ((dmaTxDest >> 15) & 0xFFFF);
        
    /* Need '<< 1' for byte addressing */
    tempAdd = (LgUns)(&txBuf[0]) << 1;

    dmaTxCfg.dmacssal = (DMA_AdrPtr)(tempAdd & 0xFFFF);
    dmaTxCfg.dmacssau = ((tempAdd >> 15) & 0xFFFF);
    
    dmaTxCfg.dmaccr |=
        DMA_FMK(DMACCR,SYNC,dmaTxSynEvt);
        
    DMA_config(hDmaTx,&dmaTxCfg);
    
    /* Setup Rx Side addresses based on MCBSP port */
    dmaRxCfg.dmacssal = (DMA_AdrPtr)(dmaRxSrc & 0xFFFF);
    dmaRxCfg.dmacssau = ((dmaRxSrc >> 15) & 0xFFFF);
        
    /* Need '<< 1' for byte addressing */
    tempAdd = (LgUns)(&rxBuf[0]) << 1;

    dmaRxCfg.dmacdsal = (DMA_AdrPtr)(tempAdd & 0xFFFF);
    dmaRxCfg.dmacdsau = ((tempAdd >> 15) & 0xFFFF);
    
    dmaRxCfg.dmaccr |=
        DMA_FMK(DMACCR,SYNC,dmaRxSynEvt);
    
    DMA_config(hDmaRx,&dmaRxCfg);
    
    
    /* Configure DMA to be free running */
    DMA_FSET(DMAGCR,FREE,1);
    
    return(IOM_COMPLETED);    
}

/*
 *  ======== setupMcbsp ========
 *  This function is used to setup the McBSP port chosen with the initial
 *  settings based on parity, stopbits, databits,baudrates chosen.
 */

static Int setupMcbsp(UARTHW_MCBSP_Params *params)
{
    Uns          clkdv;
    MCBSP_Config mcbspCfg;                      /*MCBSP Config Structure*/

    hMcbsp  = MCBSP_open(params->mcbspId, MCBSP_OPEN_RESET);

    if (hMcbsp == INV) {
        return (IOM_EBADIO);
    }

    /* Initialize MCBSP Structure */
    MCBSP_getConfig(hMcbsp, &mcbspCfg);

    /* Setup MCBSP Regs */
    mcbspCfg.pcr = 
        MCBSP_FMK(PCR,XIOEN,MCBSP_PCR_XIOEN_SP)                         |
        MCBSP_FMK(PCR,RIOEN,MCBSP_PCR_RIOEN_SP)                         |
        MCBSP_FMK(PCR,FSXM,MCBSP_PCR_FSXM_INTERNAL)                     | 
        MCBSP_FMK(PCR,FSRM,MCBSP_PCR_FSRM_EXTERNAL)                     | 
        MCBSP_FMK(PCR,CLKXM,MCBSP_PCR_CLKXM_OUTPUT)                     |
        MCBSP_FMK(PCR,CLKRM,MCBSP_PCR_CLKRM_OUTPUT)                     |
        MCBSP_FMK(PCR,DXSTAT,MCBSP_PCR_DXSTAT_0)                        |
        MCBSP_FMK(PCR,FSXP,MCBSP_PCR_FSXP_ACTIVELOW)                    |
        MCBSP_FMK(PCR,FSRP,MCBSP_PCR_FSRP_ACTIVELOW)                    | 
        MCBSP_FMK(PCR,CLKXP,MCBSP_PCR_CLKXP_RISING)                     |
        MCBSP_FMK(PCR,CLKRP,MCBSP_PCR_CLKRP_FALLING)                    ;

    /*
     * Here we compute the bit rate of the McBSP.  Each UART bit is
     * represented by 16 McBSP bits.
     */
    clkdv = (Uns)(params->mcbspClkIn / (params->baud * 16));

    /* clkdv is max 8-bits long, so make sure we didn't overflow ... */
    if (clkdv > 0xff) {
        return (IOM_EBADARGS);
    }

    mcbspCfg.srgr1 = 
        MCBSP_FMK(SRGR1,CLKGDV,MCBSP_SRGR1_CLKGDV_OF(clkdv))    |       
        MCBSP_FMK(SRGR1,FWID,MCBSP_SRGR1_FWID_OF(0))                    ;

    mcbspCfg.srgr2 = 
        MCBSP_FMK(SRGR2,GSYNC,MCBSP_SRGR2_GSYNC_FREE)                   |
        MCBSP_FMK(SRGR2,CLKSP,MCBSP_SRGR2_CLKSP_RISING)                 |
        MCBSP_FMK(SRGR2,CLKSM,MCBSP_SRGR2_CLKSM_INTERNAL)               |
        MCBSP_FMK(SRGR2,FSGM,MCBSP_SRGR2_FSGM_DXR2XSR)                  ;

        
    //Want DUAL Phase to account for Half stop bits
    mcbspCfg.xcr1 =
        MCBSP_FMK(XCR1,XFRLEN1,MCBSP_XCR1_XFRLEN1_OF(8))                |
        MCBSP_FMK(XCR1,XWDLEN1,MCBSP_XCR1_XWDLEN1_16BIT)                ;

    mcbspCfg.xcr2 =
        MCBSP_FMK(XCR2,XPHASE,MCBSP_XCR2_XPHASE_DUAL)                   |
        MCBSP_FMK(XCR2,XFRLEN2,MCBSP_XCR2_XFRLEN2_OF(1))                |
        MCBSP_FMK(XCR2,XWDLEN2,MCBSP_XCR2_XWDLEN2_8BIT)                 |
        MCBSP_FMK(XCR2,XCOMPAND,MCBSP_XCR2_XCOMPAND_MSB)                |
        MCBSP_FMK(XCR2,XFIG,MCBSP_XCR2_XFIG_NO)                         |
        MCBSP_FMK(XCR2,XDATDLY,MCBSP_XCR2_XDATDLY_0BIT)                 ;

    mcbspCfg.rcr1 =
        MCBSP_FMK(RCR1,RFRLEN1,MCBSP_RCR1_RFRLEN1_OF(8))                |
        MCBSP_FMK(RCR1,RWDLEN1,MCBSP_RCR1_RWDLEN1_16BIT)                ;

    mcbspCfg.rcr2 =
        MCBSP_FMK(RCR2,RPHASE,MCBSP_RCR2_RPHASE_DUAL)                   |
        MCBSP_FMK(RCR2,RFRLEN2,MCBSP_RCR2_RFRLEN2_OF(0))                |
        MCBSP_FMK(RCR2,RWDLEN2,MCBSP_RCR2_RWDLEN2_8BIT)                 |
        MCBSP_FMK(RCR2,RCOMPAND,MCBSP_RCR2_RCOMPAND_MSB)                |
        MCBSP_FMK(RCR2,RFIG,MCBSP_RCR2_RFIG_NO)                         |
        MCBSP_FMK(RCR2,RDATDLY,MCBSP_RCR2_RDATDLY_1BIT)                 ;

    mcbspCfg.spcr1 =
        MCBSP_FMK(SPCR1,DLB,MCBSP_SPCR1_DLB_OFF)                        |
        MCBSP_FMK(SPCR1,RJUST,MCBSP_SPCR1_RJUST_RZF)                    |
        MCBSP_FMK(SPCR1,CLKSTP,MCBSP_SPCR1_CLKSTP_DISABLE)              |
        MCBSP_FMK(SPCR1,DXENA,MCBSP_SPCR1_DEFAULT)                      |
        MCBSP_FMK(SPCR1,RINTM,MCBSP_SPCR1_RINTM_RRDY)                   |
        MCBSP_FMK(SPCR1,RRST,MCBSP_SPCR1_RRST_DISABLE)                  ;

    mcbspCfg.spcr2 =
        MCBSP_FMK(SPCR2,FREE,MCBSP_SPCR2_FREE_NO)                       |
        MCBSP_FMK(SPCR2,SOFT,MCBSP_SPCR2_SOFT_YES)                      |
        MCBSP_FMK(SPCR2,FRST,MCBSP_SPCR2_DEFAULT)                       |
        MCBSP_FMK(SPCR2,GRST,MCBSP_SPCR2_DEFAULT)                       |
        MCBSP_FMK(SPCR2,XINTM, MCBSP_SPCR2_XINTM_XRDY)                  |
        MCBSP_FMK(SPCR2,XSYNCERR,MCBSP_SPCR2_XSYNCERR_NO)               ;
        
    /* Assign structure to handle */
    MCBSP_config(hMcbsp, &mcbspCfg);

    return (IOM_COMPLETED);
}

/*
 *  ======== enable ========
 *  This function is used to enable the McBSP and start DMA
 */
static void enable(MdUns *txBuf)
{
    /* Start transmit and receive DMA channels */
    DMA_start(hDmaTx);
    DMA_start(hDmaRx);
        
    /* Start the MCBSP and Sample Rate Generator */
    MCBSP_start(hMcbsp, MCBSP_SRGR_START, 0xFFFF);
    
    /* Take MCBSP receive and transmit out of reset */
    MCBSP_start(hMcbsp, MCBSP_XMIT_START | MCBSP_RCV_START, 0xFFFF);
}

/*
 *  ======== rxIsr ========
 *  This function will clear the DMA CSR and call the upper layer ISR
 */
static void rxIsr(void)
{
    volatile Uns temp;
     
    temp = DMA_RGETH(hDmaRx, DMACSR);   /* DMA_RGET clears interrupt flag */

    UARTHW_MCBSP_dmaRxIsr();            /* Calling the upper layer ISR */
}

/*
 *  ======== txIsr ========
 *  This function will clear the DMA CSR and call the upper layer ISR
 */
static void txIsr(void)
{
    volatile Uns temp;
     
    temp = DMA_RGETH(hDmaTx, DMACSR);   /* DMA_RGET clears interrupt flag*/

    UARTHW_MCBSP_dmaTxIsr();            /* Calling the upper layer ISR */
}


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -