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

📄 uarthw_c6x1x_mcbsp.c

📁 DM642的串口驱动源码
💻 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_c6x1x_mcbsp.c ========
 */
 
#include <std.h>

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

#undef _INLINE          /* for debug so CSL functions are not inline'd */

#if defined(_62_)
#define CHIP_6711
#elif defined(_64_)
#define CHIP_6416
#endif

#include <csl.h>
#include <csl_irq.h>
#include <csl_edma.h>
#include <csl_mcbsp.h>

#include <uarthw_mcbsp.h>

#if defined(_62_)
#define MCBSPID         MCBSP_DEV1      // dsk6711 - DEV1
#define MCBSPCLKIN      75000000        // dsk6711 - 75MHz
#elif defined (_64_)
#define MCBSPID         MCBSP_DEV2      // teb6416 - DEV2
#define MCBSPCLKIN      125000000       // teb6416 - 125MHz
#endif

static UARTHW_MCBSP_Params defaultParams = {
    MCBSPID,            /* mcbspId */
    0,                  /* dmaRxId (ignored for 6x) */
    0,                  /* dmaTxId (ignored for 6x) */
    MCBSPCLKIN,         /* mcbspClkIn (in MHz) */
    115200,             /* baud rate */
    UARTHW_MCBSP_INTR_MASK_DEFAULT
};

static EDMA_Handle hEdmaTx;
static EDMA_Handle hEdmaRx;
static MCBSP_Handle hMcbsp;

static void enable(void);

/*
 *  ======== UARTHW_MCBSP_start ========
 */
Int UARTHW_MCBSP_start(MdUns *rxBuf, MdUns *txBuf,
                        UARTHW_MCBSP_Params *params)
{
    Uns         clkdv;

    EDMA_Handle edmaRxPing;     /* Handles */
    EDMA_Handle edmaRxPong;
    EDMA_Handle edmaTxPing;
    EDMA_Handle edmaTxPong;

    MCBSP_Config mcbspCfg;      /* Config Structures */
    EDMA_Config edmaRxCfg;
    EDMA_Config edmaTxCfg;

    Int rxTcc, txTcc;           /* TCC ids */ 

    HWI_Attrs hwiAttrs;

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

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

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

    hEdmaRx = EDMA_open(MCBSP_getRcvEventId(hMcbsp), EDMA_OPEN_RESET);
    hEdmaTx = EDMA_open(MCBSP_getXmtEventId(hMcbsp), EDMA_OPEN_RESET);

    if (hEdmaRx == EDMA_HINV || hEdmaTx == EDMA_HINV) {
        /* no attempt to close McBSP since we will SYS_abort() anyway */
        return (IOM_EBADIO);
    }

    // Memory Space Allocation
    edmaRxPing = EDMA_allocTable(-1);
    edmaRxPong = EDMA_allocTable(-1);
    edmaTxPing = EDMA_allocTable(-1);
    edmaTxPong = EDMA_allocTable(-1);

    // EDMA Transfert Complete Code Allocation
    rxTcc = EDMA_intAlloc(-1);
    txTcc = EDMA_intAlloc(-1);

    EDMA_getConfig(hEdmaRx, &edmaRxCfg);
    EDMA_getConfig(hEdmaTx, &edmaTxCfg);
        
    // Rx Side EDMA specific configuration
    edmaRxCfg.opt |= 
        EDMA_FMK(OPT,PRI,EDMA_OPT_PRI_HIGH) |
        EDMA_FMK(OPT,ESIZE,EDMA_OPT_ESIZE_16BIT) |
        EDMA_FMK(OPT,2DS,EDMA_OPT_2DS_NO) |
        EDMA_FMK(OPT,SUM,EDMA_OPT_SUM_NONE) |
        EDMA_FMK(OPT,2DD,EDMA_OPT_2DD_NO) |
        EDMA_FMK(OPT,DUM,EDMA_OPT_DUM_INC) |
        EDMA_FMK(OPT,TCINT,EDMA_OPT_TCINT_YES) |
        EDMA_FMK(OPT,LINK,EDMA_OPT_LINK_YES) |
        EDMA_FMK(OPT,FS,EDMA_OPT_FS_NO);
        
    // Tx Side EDMA specific configuration
    edmaTxCfg.opt |=
        EDMA_FMK(OPT,PRI,EDMA_OPT_PRI_HIGH) |                   
        EDMA_FMK(OPT,ESIZE,EDMA_OPT_ESIZE_16BIT) |
        EDMA_FMK(OPT,2DS,EDMA_OPT_2DS_NO) |             
        EDMA_FMK(OPT,SUM,EDMA_OPT_SUM_INC) |
        EDMA_FMK(OPT,2DD,EDMA_OPT_2DD_NO) |                     
        EDMA_FMK(OPT,DUM,EDMA_OPT_DUM_NONE) |
        EDMA_FMK(OPT,TCINT,EDMA_OPT_TCINT_YES) |                
        EDMA_FMK(OPT,LINK,EDMA_OPT_LINK_YES) |
        EDMA_FMK(OPT,FS,EDMA_OPT_FS_NO);

    MCBSP_getConfig(hMcbsp, &mcbspCfg);

    // McBSP Config 
    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,CLKSSTAT,MCBSP_PCR_CLKSSTAT_0) |
        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.srgr |= 
        MCBSP_FMK(SRGR,GSYNC,MCBSP_SRGR_GSYNC_FREE) |
        MCBSP_FMK(SRGR,CLKSP,MCBSP_SRGR_CLKSP_RISING) |
        MCBSP_FMK(SRGR,CLKSM,MCBSP_SRGR_CLKSM_INTERNAL) |
        MCBSP_FMK(SRGR,FSGM,MCBSP_SRGR_FSGM_DXR2XSR) |
        MCBSP_FMK(SRGR,CLKGDV,MCBSP_SRGR_CLKGDV_OF(clkdv));

    mcbspCfg.xcr |=
        MCBSP_FMK(XCR,XPHASE,MCBSP_XCR_XPHASE_DUAL) |
        MCBSP_FMK(XCR,XFRLEN2,MCBSP_XCR_XFRLEN2_OF(
                UARTHW_MCBSP_TxHSTOPBITS - 1)) |
        MCBSP_FMK(XCR,XWDLEN2,MCBSP_XCR_XWDLEN2_8BIT) |
        MCBSP_FMK(XCR,XCOMPAND,MCBSP_XCR_XCOMPAND_MSB) |
        MCBSP_FMK(XCR,XFIG,MCBSP_XCR_XFIG_YES) |
        MCBSP_FMK(XCR,XDATDLY,MCBSP_XCR_XDATDLY_0BIT) |
        MCBSP_FMK(XCR,XFRLEN1,MCBSP_XCR_XFRLEN1_OF(
                UARTHW_MCBSP_DATABITS + UARTHW_MCBSP_PARITYBITS)) |
        MCBSP_FMK(XCR,XWDLEN1,MCBSP_XCR_XWDLEN1_16BIT) |
        MCBSP_FMK(XCR,XWDREVRS,MCBSP_XCR_XWDREVRS_DISABLE);

    mcbspCfg.rcr |=
        MCBSP_FMK(RCR,RPHASE,MCBSP_RCR_RPHASE_DUAL) |
        MCBSP_FMK(RCR,RFRLEN2,MCBSP_RCR_RFRLEN2_OF(
                UARTHW_MCBSP_RxHSTOPBITS - 1)) |
        MCBSP_FMK(RCR,RWDLEN2,MCBSP_RCR_RWDLEN2_8BIT) |
        MCBSP_FMK(RCR,RCOMPAND,MCBSP_RCR_RCOMPAND_MSB) |
        MCBSP_FMK(RCR,RFIG,MCBSP_RCR_RFIG_YES) |
        MCBSP_FMK(RCR,RDATDLY,MCBSP_RCR_RDATDLY_1BIT) |
        MCBSP_FMK(RCR,RFRLEN1,MCBSP_RCR_RFRLEN1_OF(
                UARTHW_MCBSP_DATABITS + UARTHW_MCBSP_PARITYBITS)) |
        MCBSP_FMK(RCR,RWDLEN1,MCBSP_RCR_RWDLEN1_16BIT) |
        MCBSP_FMK(RCR,RWDREVRS,MCBSP_RCR_RWDREVRS_DISABLE);

    mcbspCfg.spcr |=
        MCBSP_FMK(SPCR,FREE,MCBSP_SPCR_FREE_NO) |
        MCBSP_FMK(SPCR,SOFT,MCBSP_SPCR_SOFT_YES) |
        MCBSP_FMK(SPCR,FRST,MCBSP_SPCR_FRST_YES) |
        MCBSP_FMK(SPCR,GRST,MCBSP_SPCR_GRST_YES) |
        MCBSP_FMK(SPCR,XINTM,MCBSP_SPCR_XINTM_XRDY) |
        MCBSP_FMK(SPCR,XSYNCERR,MCBSP_SPCR_XSYNCERR_NO) |
        MCBSP_FMK(SPCR,DLB,MCBSP_SPCR_DLB_OFF) |
        MCBSP_FMK(SPCR,RJUST,MCBSP_SPCR_RJUST_RZF) |
        MCBSP_FMK(SPCR,CLKSTP,MCBSP_SPCR_CLKSTP_DISABLE) |
        MCBSP_FMK(SPCR,DXENA,MCBSP_SPCR_DXENA_OFF) | 
        MCBSP_FMK(SPCR,RINTM,MCBSP_SPCR_RINTM_EOS);     

    MCBSP_config(hMcbsp, &mcbspCfg);

    // RX Side
    edmaRxCfg.src = MCBSP_getRcvAddr(hMcbsp);
    edmaRxCfg.idx = 0x00000000; // IDX reset / CSL bug
    edmaRxCfg.cnt = UARTHW_MCBSP_RxPKTBITS;
    edmaRxCfg.opt = edmaRxCfg.opt | EDMA_FMK(OPT, TCC, rxTcc);
        
    // - Ping Buffer
    edmaRxCfg.dst = (Uint32)rxBuf;
    edmaRxCfg.rld = (edmaRxCfg.rld & 0xFFFF0000) | (EDMA_RLD_RMK(0,edmaRxPong));
    EDMA_config(hEdmaRx, &edmaRxCfg);
    EDMA_config(edmaRxPing, &edmaRxCfg);
    
    // - Pong Buffer
    edmaRxCfg.dst = (Uint32)(rxBuf + UARTHW_MCBSP_RxPKTBITS);
    edmaRxCfg.rld = (edmaRxCfg.rld & 0xFFFF0000) | (EDMA_RLD_RMK(0,edmaRxPing));
    EDMA_config(edmaRxPong, &edmaRxCfg);

    // TX Side
    edmaTxCfg.dst = MCBSP_getXmtAddr(hMcbsp);
    edmaTxCfg.idx = 0x00000000; // IDX reset / CSL bug
    edmaTxCfg.cnt = UARTHW_MCBSP_TxPKTBITS;
    edmaTxCfg.opt = edmaTxCfg.opt | EDMA_FMK(OPT, TCC, txTcc);  

    // - Ping Buffer
    edmaTxCfg.src = (Uint32)txBuf ;
    edmaTxCfg.rld = (edmaTxCfg.rld & 0xFFFF0000) | (EDMA_RLD_RMK(0,edmaTxPong));
    EDMA_config(hEdmaTx, &edmaTxCfg);
    EDMA_config(edmaTxPing, &edmaTxCfg);
    
    // - Pong Buffer
    edmaTxCfg.src = (Uint32)(txBuf + UARTHW_MCBSP_TxPKTBITS);
    edmaTxCfg.rld = (edmaTxCfg.rld & 0xFFFF0000) | (EDMA_RLD_RMK(0,edmaTxPing));
    EDMA_config(edmaTxPong, &edmaTxCfg);        
        
    // Disable any previous machine state
    // - McBSP disable
    MCBSP_FSETSH(hMcbsp,SPCR,RRST,YES);
    MCBSP_FSETSH(hMcbsp,SPCR,XRST,YES);

    // - EDMA disable
    EDMA_disableChannel(hEdmaTx);
    EDMA_disableChannel(hEdmaRx);
    EDMA_clearChannel(hEdmaTx);
    EDMA_clearChannel(hEdmaRx);
        
    // Enable EDMA channel interrupt to CPU (CIER)
    EDMA_intClear(rxTcc);
    EDMA_intClear(txTcc);
    EDMA_intEnable(rxTcc);
    EDMA_intEnable(txTcc);
                                
    // Start Sample Rate Generator: set /GRST = 1 
    MCBSP_enableSrgr(hMcbsp);
                
    // Enable Frame Sync Generator for McBSP: set /FRST = 1
    MCBSP_enableFsync(hMcbsp);

    /*
     * The EDMA interrupt dispatcher will be called by the
     * BIOS HWI interrupt dispatcher.
     */
    hwiAttrs.intrMask = params->intrMask;
    hwiAttrs.ccMask   = IRQ_CCMASK_NONE;
    hwiAttrs.arg      = NULL;
    HWI_dispatchPlug(IRQ_EVT_EDMAINT, (Fxn)EDMA_intDispatcher, -1, &hwiAttrs);

    EDMA_intHook(rxTcc, (EDMA_IntHandler)UARTHW_MCBSP_dmaRxIsr);
    EDMA_intHook(txTcc, (EDMA_IntHandler)UARTHW_MCBSP_dmaTxIsr);

    // Enable EDMA-CPU interrupt (+clear any previous)
    IRQ_clear(IRQ_EVT_EDMAINT);
    IRQ_enable(IRQ_EVT_EDMAINT);

    enable();

    return (IOM_COMPLETED);
}

/*
 *  ======== enable ========
 */
static Void enable(Void)
{
    // Enable Rx Event EDMA channel
    EDMA_enableChannel(hEdmaRx);

    // Enable Tx Event EDMA channel
    EDMA_enableChannel(hEdmaTx);

    // Enable MCBSP
    MCBSP_enableRcv(hMcbsp);

    // Enable MCBSP
    MCBSP_enableXmt(hMcbsp);
}

⌨️ 快捷键说明

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