📄 uarthw_c54xx_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_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 + -