📄 uarthw_c6x1x_mcbsp.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 + -