您好, 这问题困扰我很久了
目前需要利用McBSP来控制I2S ADC
首先, 使用Loop-back模式来测试McBSP
若以McBSP Register来测试, 可以正确的完成测试。
但以实际使用, 是需要利用EDMA或Interrupt来完成
PDK所提供的范例是需要RTOS来执行
目前的计划是不打算使用TI的RTOS
先前有使用SPI的EDMA来控制SPI
故将SPI EDMA改写成McBSP EDMA
TX是给已知的数值, 利用loop-back模式
来测试RX是否正确
此执行结果只能执行一次正确的EDMA
其他重复执行EDMA控制, 结果均为0
完整程序如下:

请各位先进帮我看是哪里错误
或我忽略掉那个重点
若有相关资料也可以提供, 谢谢
撷取部分程序内容
main
void main (void)
{
volatile Uint32 failFlag = FALSE;
int i;
int success = 0;
// Initiate src/dst buffers
Initiate_Buffers(TEST_ACNT, TEST_BCNT, TEST_CCNT, TEST_ACNT, TEST_ACNT, TEST_ACNT*TEST_BCNT,
TEST_ACNT*TEST_BCNT, (Uint32)srcBuf, (Uint32)dstBuf, CSL_EDMA3_SYNC_A);
I2S_McBSP_Setup();
I2S_Edma_Open((Uint32)srcBuf, (Uint32)dstBuf);
// loop
for (i=0; i<10; i++)
{
Initiate_Buffers(TEST_ACNT, TEST_BCNT, TEST_CCNT, TEST_ACNT, TEST_ACNT, TEST_ACNT*TEST_BCNT,
TEST_ACNT*TEST_BCNT, (Uint32)srcBuf, (Uint32)dstBuf, CSL_EDMA3_SYNC_A);
I2S_Transfer((Uint32)srcBuf, (Uint32)dstBuf, BUF_SIZE);
failFlag = Verify_Transfer(TEST_ACNT, TEST_BCNT, TEST_CCNT, TEST_ACNT, TEST_ACNT, TEST_ACNT*TEST_BCNT,
TEST_ACNT*TEST_BCNT, (Uint32)srcBuf, (Uint32)dstBuf, CSL_EDMA3_SYNC_A);
if (failFlag == TRUE)
success++;
}
//Close EDMA channels/module
I2S_Edma_Close();
//Verify src/dst buffers after transfer
printf("success = %d\n", success);
printf("end of test\n");
}
I2S_McBSP_Setup
void I2S_McBSP_Setup (void)
{
int i;
CSL_McbspRegs *mcbspRegs = (CSL_McbspRegs *)CSL_Mcbsp0_CFG_DATA_REGS;
// 1. Place the McBSP in reset by clearing the XRST, RRST, FRST, and GRST bits to 0 in SPCR.
mcbspRegs->SRGR = 0;
// 2 Set the CLKXM, CLKRM, FSXM, FSRM, CLKXP, and CLKRP bits to 1 in the pin control register (PCR).
mcbspRegs->PCR = (CSL_MCBSP_PCR_FSXM_INTERNAL<<CSL_MCBSP_PCR_FSXM_SHIFT) |
(CSL_MCBSP_PCR_FSRM_INTERNAL<<CSL_MCBSP_PCR_FSRM_SHIFT) |
(CSL_MCBSP_PCR_CLKXM_OUTPUT<<CSL_MCBSP_PCR_CLKXM_SHIFT) |
(CSL_MCBSP_PCR_CLKRM_OUTPUT<<CSL_MCBSP_PCR_CLKRM_SHIFT) |
(CSL_MCBSP_PCR_CLKXP_FALLING<<CSL_MCBSP_PCR_CLKXP_SHIFT)|
(CSL_MCBSP_PCR_CLKRP_RISING<<CSL_MCBSP_PCR_CLKRP_SHIFT)|
0;
mcbspRegs->SPCR =
#ifdef ENABLE_I2S_LOOPBACK
(CSL_MCBSP_SPCR_DLB_ENABLE<<CSL_MCBSP_SPCR_DLB_SHIFT) |
#endif
0;
// 2. McBSP clocks and frames to internal clock source
// 2a Set the CLKSM and FSGM bits to 1 in the sample rate generator register (SRGR).
mcbspRegs->SRGR = (CSL_MCBSP_SRGR_GSYNC_FREE<<CSL_MCBSP_SRGR_GSYNC_SHIFT)|
(CSL_MCBSP_SRGR_FSGM_FSG<<CSL_MCBSP_SRGR_FSGM_SHIFT) |
(31<<CSL_MCBSP_SRGR_FPER_SHIFT) |
(15<<CSL_MCBSP_SRGR_FWID_SHIFT) |
#ifdef ENABLE_INTERNAL_CLOCK
// internal setting
(CSL_MCBSP_SRGR_CLKSM_INTERNAL<<CSL_MCBSP_SRGR_CLKSM_SHIFT) |
(16<<CSL_MCBSP_SRGR_CLKGDV_SHIFT) |
#else
// external setting
(7<<CSL_MCBSP_SRGR_CLKGDV_SHIFT) |
#endif
0;
// 2b Set the CLKXM, CLKRM, FSXM, and FSRM bits to 1 in the pin control register (PCR).
mcbspRegs->RCR = (CSL_MCBSP_RCR_RPHASE_DUAL_FRM<<CSL_MCBSP_RCR_RPHASE_SHIFT)|
(CSL_MCBSP_RCR_RWDLEN2_16BIT<<CSL_MCBSP_RCR_RWDLEN2_SHIFT) |
(CSL_MCBSP_RCR_RFIG_NO<<CSL_MCBSP_RCR_RFIG_SHIFT)|
(CSL_MCBSP_RCR_RDATDLY_1BIT<<CSL_MCBSP_RCR_RDATDLY_SHIFT) |
(CSL_MCBSP_RCR_RWDLEN1_16BIT<<CSL_MCBSP_RCR_RWDLEN1_SHIFT) |
0;
mcbspRegs->XCR = (CSL_MCBSP_XCR_XPHASE_DUAL_FRM<<CSL_MCBSP_XCR_XPHASE_SHIFT)|
(CSL_MCBSP_XCR_XWDLEN2_16BIT<<CSL_MCBSP_XCR_XWDLEN2_SHIFT) |
(CSL_MCBSP_XCR_XFIG_NO<<CSL_MCBSP_XCR_XFIG_SHIFT)|
(CSL_MCBSP_XCR_XDATDLY_1BIT<<CSL_MCBSP_XCR_XDATDLY_SHIFT) |
(CSL_MCBSP_XCR_XWDLEN1_16BIT<<CSL_MCBSP_XCR_XWDLEN1_SHIFT) |
0;
// 2c Clear the SCLKME bit to 0 in PCR.
for (i = 0; i < 100; i++) {
asm (" nop");
}
// 3 Bring the McBSP out of reset by setting the XRST, RRST, and GRST bits to 1 in SPCR.
mcbspRegs->SPCR |= (CSL_MCBSP_SPCR_GRST_CLKG << CSL_MCBSP_SPCR_GRST_SHIFT) |
(CSL_MCBSP_SPCR_XRST_ENABLE << CSL_MCBSP_SPCR_XRST_SHIFT) |
(CSL_MCBSP_SPCR_RRST_ENABLE << CSL_MCBSP_SPCR_RRST_SHIFT);
//11. start internal frame sync generator
mcbspRegs->SPCR |= (CSL_MCBSP_SPCR_FRST_FSG << CSL_MCBSP_SPCR_FRST_SHIFT); //Enable FRST
for (i = 0; i < 2; i++) {
asm (" nop");
}
//10.
if (!(mcbspRegs->SPCR & CSL_MCBSP_SPCR_XEMPTY_MASK)) // Feed DXR if XSR is empty.
mcbspRegs->DXR = 0xaa55;
// while((mcbspRegs->SPCR & (1<<18)));
// while(!(mcbspRegs->SPCR & 0x00000100));
}
I2S_Edma_Open
void I2S_Edma_Open (Uint32 srcBuf, Uint32 dstBuf)
{
// EDMA Module Initialization
CSL_edma3Init(NULL);
// EDMA Module Open
hModule = CSL_edma3Open(&moduleObj, CSL_TPCC_2, NULL, &EdmaStat);
// McBSP_0 transmit Channel Open - Channel 37 for Tx (MCBSP0_XEVT)
chParam.regionNum = CSL_EDMA3_REGION_GLOBAL;
chSetup.que = CSL_EDMA3_QUE_0;
chParam.chaNum = CSL_EDMA3_CHA_37;
hChannel37 = CSL_edma3ChannelOpen(&ChObj0, CSL_TPCC_2, &chParam, &EdmaStat);
chSetup.paramNum = chParam.chaNum; //CSL_EDMA3_CHA_37;
CSL_edma3HwChannelSetupParam(hChannel37, chSetup.paramNum);
// McBSP_0 receive Channel Open - Channel 36 for Rx (MCBSP0_REVT)
chParam.regionNum = CSL_EDMA3_REGION_GLOBAL;
chSetup.que = CSL_EDMA3_QUE_0;
chParam.chaNum = CSL_EDMA3_CHA_36;
hChannel36 = CSL_edma3ChannelOpen(&ChObj1, CSL_TPCC_2, &chParam, &EdmaStat);
chSetup.paramNum = chParam.chaNum; //CSL_EDMA3_CHA_36;
CSL_edma3HwChannelSetupParam(hChannel36, chSetup.paramNum);
}
I2S_Edma_Setup_Params
void I2S_Edma_Setup_Params (Uint32 srcBuf, Uint32 dstBuf, Uint32 Size)
{
CSL_McbspRegs *mcbspRegs = (CSL_McbspRegs *)CSL_Mcbsp0_CFG_DATA_REGS;
// Clear Event of DMA3CC (Evt36, Evt37)
EDMA3CC_SECRH = 0x00000030;
// Parameter Handle Open
// Open all the handles and keep them ready
paramHandle0 = CSL_edma3GetParamHandle(hChannel37, CSL_EDMA3_CHA_37, &EdmaStat);
paramHandle1 = CSL_edma3GetParamHandle(hChannel36, CSL_EDMA3_CHA_36, &EdmaStat);
// transmitter
paramSetup.aCntbCnt = CSL_EDMA3_CNT_MAKE(TEST_ACNT, (TEST_BCNT));
paramSetup.srcDstBidx = CSL_EDMA3_BIDX_MAKE(TEST_ACNT, 0);
paramSetup.srcDstCidx = CSL_EDMA3_CIDX_MAKE(0, 0);
paramSetup.cCnt = TEST_CCNT;
paramSetup.option = CSL_EDMA3_OPT_MAKE(FALSE, FALSE, FALSE, TRUE, CSL_EDMA3_CHA_37,
CSL_EDMA3_TCC_NORMAL, CSL_EDMA3_FIFOWIDTH_NONE, FALSE,
CSL_EDMA3_SYNC_A, CSL_EDMA3_ADDRMODE_INCR, CSL_EDMA3_ADDRMODE_INCR);
if( ((Uint32)srcBuf & 0xFFF00000) == 0x00800000)
paramSetup.srcAddr = (Uint32)(global_address((Uint32)srcBuf));
else
paramSetup.srcAddr = (Uint32)(srcBuf);
paramSetup.dstAddr = (Uint32)&(mcbspRegs->DXR);
paramSetup.linkBcntrld = CSL_EDMA3_LINKBCNTRLD_MAKE(CSL_EDMA3_LINK_NULL, 0);
CSL_edma3ParamSetup(paramHandle0, ¶mSetup);
// receiver
paramSetup.aCntbCnt = CSL_EDMA3_CNT_MAKE(TEST_ACNT, TEST_BCNT);
paramSetup.srcDstBidx = CSL_EDMA3_BIDX_MAKE(0, TEST_ACNT);
paramSetup.srcDstCidx = CSL_EDMA3_CIDX_MAKE(0, 0);
paramSetup.cCnt = TEST_CCNT;
paramSetup.option = CSL_EDMA3_OPT_MAKE(FALSE, FALSE, FALSE, TRUE, CSL_EDMA3_CHA_36,
CSL_EDMA3_TCC_NORMAL, CSL_EDMA3_FIFOWIDTH_NONE, FALSE,
CSL_EDMA3_SYNC_A, CSL_EDMA3_ADDRMODE_INCR, CSL_EDMA3_ADDRMODE_INCR);
paramSetup.srcAddr = (Uint32)&(mcbspRegs->DRR);
if( ((Uint32)dstBuf & 0xFFF00000) == 0x00800000)
paramSetup.dstAddr = (Uint32)(global_address((Uint32)dstBuf));
else
paramSetup.dstAddr = (Uint32)dstBuf;
paramSetup.linkBcntrld = CSL_EDMA3_LINKBCNTRLD_MAKE(CSL_EDMA3_LINK_NULL, 0);
CSL_edma3ParamSetup(paramHandle1, ¶mSetup);
}
