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

📄 uarthw_c54xx_mcbsp.c

📁 DSP串口的UART程序
💻 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_c54xx_mcbsp.c ========
 */
 
#include <std.h>

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

#include <csl.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 MCBSP_Handle hMcbsp;
static DMA_Handle hDmaRx;
static DMA_Handle hDmaTx;

static UARTHW_MCBSP_Params defaultParams = {
    MCBSP_PORT1,        /* mcbspId */
    DMA_CHA4,           /* dmaRxId */
    DMA_CHA5,           /* dmaTxId */
    100000000,          /* mcbspClkIn (100MHz) */
    115200,             /* baud rate */
    UARTHW_MCBSP_INTR_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);
    }

    rxId = DMA_getEventId(hDmaRx);
    txId = DMA_getEventId(hDmaTx);
    
    hwiAttrs.intrMask = params->intrMask.rxIntrMask;
    hwiAttrs.arg = NULL;
    HWI_dispatchPlug(rxId, (Fxn)UARTHW_MCBSP_dmaRxIsr, &hwiAttrs);
    hwiAttrs.intrMask = params->intrMask.txIntrMask;
    HWI_dispatchPlug(txId, (Fxn)UARTHW_MCBSP_dmaTxIsr, &hwiAttrs);

    IRQ_enable(rxId);
    IRQ_enable(txId);

    enable(txBuf);

    return (IOM_COMPLETED);
}

/*
 *  ======== setupDma =======
 */
static Int setupDma(MdUns *rxBuf, MdUns *txBuf, UARTHW_MCBSP_Params *params)
{
    /*
     * I am using the stack extensively during initialization as I dont 
     * require these structures after initialization.
     */
    Uns dmaTxSynEvt, dmaRxSynEvt;
    DMA_AdrPtr dmaTxDest, dmaRxSrc;
   
    DMA_GblConfig dmaGblCfg = {
        0x00,   /*  Breakpoint Emulation Behavior (FREE)  */
        NULL,   /* Source Program Page Address Register(DMSRCP)-Symbolic */
        NULL,   /* Destination Program Page Address Register(DMDSTP)-Symbolic */
        0x0000, /*  Element Address Index Register 0 (DMIDX0)  */
        0x0000, /*  Frame Address Index Register 0 (DMFRI0)  */
        0x0000, /*  Element Address Index Register 1 (DMIDX1)  */
        0x0000, /*  Frame Address Index Register 1 (DMFRI1)  */
        NULL,   /*  Global Source Address Reload Register (DMGSA)-Symbolic  */
        NULL,   /* Global Destination Address Reload Register(DMGDA)-Symbolic */
        0x0000, /*  Global Element Count Reload Register (DMGCR)  */
        0x0000  /*  Global Frame Count Reload Register (DMGFR)  */
    };
         
    DMA_Config dmaTxCfg = {
        0x0001,         /*  Channel Priority (0x0000 or 0x0001)  */
        DMA_DMMCR_RMK(
            DMA_DMMCR_AUTOINIT_OFF,
            DMA_DMMCR_DINM_ON,
            DMA_DMMCR_IMOD_HALF_AND_FULL,
            DMA_DMMCR_CTMOD_ABU,
            DMA_DMMCR_SIND_POSTINC,
            DMA_DMMCR_DMS_DATA,
            DMA_DMMCR_DIND_NOMOD,
            DMA_DMMCR_DMD_DATA
        ),              /* Transfer Mode Control Register (DMMCR) */
        DMA_DMSFC_RMK(
            0,
            DMA_DMSFC_DBLW_OFF,
            DMA_DMSFC_FRAMECNT_OF(0)
        ),              /* Sync Event and Frame Count Register (DMSFC) */
        (DMA_AdrPtr)0,  /* Source Address Register (DMSRC) - Symbolic */
        (DMA_AdrPtr)0,  /* Destination Address Register (DMDST) - Symbolic */
        2 * UARTHW_MCBSP_TxPKTBITS     /* Element Count Register (DMCTR) */
    };
        
    DMA_Config dmaRxCfg = {
        0x0001,         /* Channel Priority (0x0000 or 0x0001) */
        DMA_DMMCR_RMK(
            DMA_DMMCR_AUTOINIT_OFF,
            DMA_DMMCR_DINM_ON,
            DMA_DMMCR_IMOD_HALF_AND_FULL,
            DMA_DMMCR_CTMOD_ABU,
            DMA_DMMCR_SIND_NOMOD,
            DMA_DMMCR_DMS_DATA,
            DMA_DMMCR_DIND_POSTINC,
            DMA_DMMCR_DMD_DATA
        ),              /* Transfer Mode Control Register (DMMCR) */
        DMA_DMSFC_RMK(
             0,
             DMA_DMSFC_DBLW_OFF,
             DMA_DMSFC_FRAMECNT_OF(0)
        ),              /* Sync Event and Frame Count Register (DMSFC) */
        (DMA_AdrPtr)0,  /* Source Address Register (DMSRC) - Symbolic */
        (DMA_AdrPtr)0,  /* Destination Address Register (DMDST) - Symbolic */
        2 * UARTHW_MCBSP_RxPKTBITS     /*  Element Count Register (DMCTR) */
    };

    if (params->mcbspId == MCBSP_PORT1) {
        dmaRxSynEvt = DMA_DMSFC_DSYN_REVT1;
        dmaTxSynEvt = DMA_DMSFC_DSYN_XEVT1;
        dmaTxDest = (DMA_AdrPtr)MCBSP_ADDR(DXR11); 
        dmaRxSrc  = (DMA_AdrPtr)MCBSP_ADDR(DRR11);
    }
    else {
        dmaRxSynEvt = DMA_DMSFC_DSYN_REVT0;
        dmaTxSynEvt = DMA_DMSFC_DSYN_XEVT0;
        dmaTxDest = (DMA_AdrPtr)MCBSP_ADDR(DXR10); 
        dmaRxSrc  = (DMA_AdrPtr)MCBSP_ADDR(DRR10);
    }
     
    hDmaRx = DMA_open(params->dmaRxId, DMA_OPEN_RESET);
    hDmaTx = DMA_open(params->dmaTxId, DMA_OPEN_RESET);

    if (hDmaTx == INV || hDmaRx == INV) {
        return (IOM_EBADIO);
    }

    dmaTxCfg.dmsrc = (DMA_AdrPtr)(&txBuf[1]);
    dmaTxCfg.dmdst = dmaTxDest;
    dmaTxCfg.dmsfc = _DMA_DMSFC_DSYN_MK(dmaTxSynEvt);
         
    DMA_config(hDmaTx, &dmaTxCfg);
         
    dmaRxCfg.dmdst = (DMA_AdrPtr)(&rxBuf[0]);
    dmaRxCfg.dmsrc = dmaRxSrc;
    dmaRxCfg.dmsfc = _DMA_DMSFC_DSYN_MK(dmaRxSynEvt);

    DMA_config(hDmaRx, &dmaRxCfg);

    DMA_globalConfig(0x0FFFF, &dmaGblCfg);

    /* Set value of Global Index Register, DMIDX0 */
    DMA_RSET(DMIDX0, 0);
    DMA_RSET(DMIDX1, 0);

    /* Set FREE bit in DMPREC to enable free run on DMA */
    DMA_FSET(DMPREC, 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)
{
    /*
     * I am using the stack extensively during initialization as I dont 
     * require these structures after initialization.
     */
    Uns clkdv;

    MCBSP_Config mcbspCfg = {
        MCBSP_SPCR1_RMK(
            MCBSP_SPCR1_DLB_OFF,
            MCBSP_SPCR1_RJUST_DEFAULT,
            MCBSP_SPCR1_CLKSTP_DISABLE,
            MCBSP_SPCR1_DXENA_DEFAULT,
            MCBSP_SPCR1_RINTM_RRDY,
            MCBSP_SPCR1_RRST_DISABLE
        ),                                       /* SPCR1 */ 
        MCBSP_SPCR2_RMK(
            MCBSP_SPCR2_FREE_NO,
            MCBSP_SPCR2_SOFT_YES,
            MCBSP_SPCR2_FRST_DEFAULT,
            MCBSP_SPCR2_GRST_DEFAULT,
            MCBSP_SPCR2_XINTM_XRDY,
            MCBSP_SPCR2_XSYNCERR_NO
        ),                                     /* SPCR2 */ 
        MCBSP_RCR1_RMK(
            MCBSP_RCR1_RFRLEN1_OF(
                UARTHW_MCBSP_DATABITS + UARTHW_MCBSP_PARITYBITS),
            MCBSP_RCR1_RWDLEN1_16BIT
        ),                                     /* RCR1 */
        MCBSP_RCR2_RMK(
            MCBSP_RCR2_RPHASE_DUAL,
            MCBSP_RCR2_RFRLEN2_OF(UARTHW_MCBSP_RxHSTOPBITS - 1),
            MCBSP_RCR2_RWDLEN2_8BIT,
            MCBSP_RCR2_RCOMPAND_MSB,
            MCBSP_RCR2_RFIG_NO,
            MCBSP_RCR2_RDATDLY_1BIT
        ),                                     /* RCR2 */
        MCBSP_XCR1_RMK(
            MCBSP_XCR1_XFRLEN1_OF(
                UARTHW_MCBSP_DATABITS + UARTHW_MCBSP_PARITYBITS),
            MCBSP_XCR1_XWDLEN1_16BIT
        ),                                     /* XCR1 */
        MCBSP_XCR2_RMK(
            MCBSP_XCR2_XPHASE_DUAL,
            MCBSP_XCR2_XFRLEN2_OF(UARTHW_MCBSP_TxHSTOPBITS - 1),
            MCBSP_XCR2_XWDLEN2_8BIT,
            MCBSP_XCR2_XCOMPAND_MSB,
            MCBSP_XCR2_XFIG_YES,
            MCBSP_XCR2_XDATDLY_0BIT
        ),                                     /* XCR2 */
        MCBSP_SRGR1_RMK(
            MCBSP_SRGR1_FWID_OF(0),
            MCBSP_SRGR1_CLKGDV_OF(1)
        ),                                     /* SRGR1 */
        MCBSP_SRGR2_RMK( 
            MCBSP_SRGR2_GSYNC_FREE,
            MCBSP_SRGR2_CLKSP_RISING,
            MCBSP_SRGR2_CLKSM_INTERNAL,
            MCBSP_SRGR2_FSGM_DXR2XSR,
            0
        ),                          
        0x0000u,                               /* MCR1 */
        0x0000u,                               /* MCR2 */
        MCBSP_PCR_RMK(
            MCBSP_PCR_XIOEN_SP,
            MCBSP_PCR_RIOEN_SP,
            MCBSP_PCR_FSXM_INTERNAL,
            MCBSP_PCR_FSRM_EXTERNAL,
            MCBSP_PCR_CLKXM_OUTPUT,
            MCBSP_PCR_CLKRM_OUTPUT,
            MCBSP_PCR_FSXP_ACTIVELOW,
            MCBSP_PCR_FSRP_ACTIVELOW,
            MCBSP_PCR_CLKXP_RISING,
            MCBSP_PCR_CLKRP_FALLING
        ),                                     /* PCR   */
        0x0000u,                               /* RCERA */
        0x0000u,                               /* RCERB */
        0x0000u,                               /* XCERA */
        0x0000u,                               /* XCERB */
    };

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

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

    /*
     * 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 = clkdv;
    
    MCBSP_config(hMcbsp, &mcbspCfg);

    return (IOM_COMPLETED);
}

/*
 *  ======== enable ========
 *  This function is used to enable the McBSP and start DMA
 */
static void enable(MdUns *txBuf)
{
    /* Take MCBSP receive and transmit out of reset */
    MCBSP_start(hMcbsp, MCBSP_RCV_START | MCBSP_XMIT_START, 0xFFFF);

    /* Prime MCBSP DXR */
    while (!MCBSP_xrdy(hMcbsp)) {
        ;
    }
    MCBSP_write(hMcbsp, txBuf[0]);
  
    DMA_start(hDmaTx);
    DMA_start(hDmaRx);
  
    /* Start the MCBSP and Sample Rate Generator */
    MCBSP_start(hMcbsp, MCBSP_SRGR_START, 0xFFFF);
}

⌨️ 快捷键说明

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