您好, 这问题困扰我很久了
目前需要利用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 buffersInitiate_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);// loopfor (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/moduleI2S_Edma_Close();//Verify src/dst buffers after transferprintf("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) | #endif0;// 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) | #endif0;// 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 generatormcbspRegs->SPCR |= (CSL_MCBSP_SPCR_FRST_FSG << CSL_MCBSP_SPCR_FRST_SHIFT); //Enable FRSTfor (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 InitializationCSL_edma3Init(NULL);// EDMA Module OpenhModule = 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 readyparamHandle0= CSL_edma3GetParamHandle(hChannel37, CSL_EDMA3_CHA_37, &EdmaStat);paramHandle1= CSL_edma3GetParamHandle(hChannel36, CSL_EDMA3_CHA_36, &EdmaStat);// transmitterparamSetup.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));elseparamSetup.srcAddr = (Uint32)(srcBuf);paramSetup.dstAddr= (Uint32)&(mcbspRegs->DXR);paramSetup.linkBcntrld = CSL_EDMA3_LINKBCNTRLD_MAKE(CSL_EDMA3_LINK_NULL, 0);CSL_edma3ParamSetup(paramHandle0, ¶mSetup);// receiverparamSetup.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));elseparamSetup.dstAddr = (Uint32)dstBuf;paramSetup.linkBcntrld = CSL_EDMA3_LINKBCNTRLD_MAKE(CSL_EDMA3_LINK_NULL, 0);CSL_edma3ParamSetup(paramHandle1, ¶mSetup); }
Allen35065:
附件是mcbsp的例子,不是C6657上的,但是EDMA3和MCBSP模块是一样的,你可以参考对比一下。
Lin Jia-Hung:
回复 Allen35065:
Hi Allen:
我使用的是mcbsp_edma的例子, 想请问
1. 在范例中在mcbsp的设定, 都是使用CSL_mcbsp的function
在C6657的PDK内没有这些function
所以就直接设定McBSP参数, 同先前提问中的I2S_McBSP_Setup
这样是否可行
2. EDMA部分, 依原先C6454的设定,修改成C6657
C6657的mcbps在event 36及event 37
故修改了regionAccess.draeh = 0xffff
#define CSL_EDMA3_CHA_REVT0 36
#define CSL_EDMA3_CHA_XEVT0 37
但结果都无法进入中断, 请帮忙看问题发生在什么地方, 谢谢.
完整程序
程序如下
void mcbsp_edma_setup (void ) {CSL_McbspRegs *mcbspRegs = (CSL_McbspRegs *)CSL_Mcbsp0_CFG_DATA_REGS;CSL_Edma3ParamHandlehParamBasic;CSL_Edma3ParamHandlehParamBasic1;CSL_Edma3ParamSetupmyParamSetup;CSL_Edma3ParamSetupmyParamSetup1;CSL_Edma3ChannelObjChObj, ChObj1;CSL_Edma3ChannelAttrchParam;CSL_Edma3ContextedmaContext;CSL_Edma3ObjedmaObj;CSL_Edma3QueryInfoinfo;CSL_Edma3CmdIntrregionIntr;CSL_Edma3CmdDraeregionAccess;Uint32i, j;CSL_BitMask16ctrlMask;for (i = 0, j = 1; i < DATATX_COUNT; i++, j++) {srcBuff[i] = j;dstBuff[i] = 0;}/* Intc Module Initialization */intcContext.eventhandlerRecord = EventHandler;intcContext.numEvtEntries = 10;CSL_intcInit(&intcContext);/* Enable NMIs */CSL_intcGlobalNmiEnable();/* Enable Global Interrupts */intStat = CSL_intcGlobalEnable(&state);/* Opening a handle for the Event edma */vectId = CSL_INTC_VECTID_4;hIntcEdma = CSL_intcOpen(&intcObjEdma, CSL_INTC0_CPU_3_2_EDMA3CCINT0,//CSL_INTC_EVENTID_EDMA3CC_INT0,&vectId, &status);/* Edma Module Initialization */CSL_edma3Init(&edmaContext);/* Edma Module Level Open */hModule = CSL_edma3Open(&edmaObj, CSL_TPCC_2/*CSL_EDMA3*/, NULL, &status);/* Query Module Info */CSL_edma3GetHwStatus(hModule,CSL_EDMA3_QUERY_INFO, &info);/********************************Setup for Tx******************************//* Setup the DRAE Masks */regionAccess.region = CSL_EDMA3_REGION_GLOBAL;//CSL_EDMA3_REGION_0;regionAccess.drae= 0;regionAccess.draeh= 0xFFFF;CSL_edma3HwControl(hModule, CSL_EDMA3_CMD_DMAREGION_ENABLE, ®ionAccess);/* Open transmit channel */chParam.regionNum = CSL_EDMA3_REGION_GLOBAL;//CSL_EDMA3_REGION_0;chParam.chaNum = CSL_EDMA3_CHA_XEVT0;hChannel37 = CSL_edma3ChannelOpen(&ChObj,CSL_TPCC_2,//CSL_EDMA3,&chParam,&status);/* Channel setup */hParamBasic = CSL_edma3GetParamHandle(hChannel37, CSL_EDMA3_CHA_XEVT0, &status);/* param setup */myParamSetup.option = CSL_EDMA3_OPT_MAKE(CSL_EDMA3_ITCCH_DIS, \CSL_EDMA3_TCCH_DIS, \CSL_EDMA3_ITCINT_DIS, \CSL_EDMA3_TCINT_EN, \CSL_EDMA3_CHA_XEVT0, \CSL_EDMA3_TCC_NORMAL, \CSL_EDMA3_FIFOWIDTH_32BIT, \CSL_EDMA3_STATIC_DIS, \CSL_EDMA3_SYNC_A, \CSL_EDMA3_ADDRMODE_INCR,\CSL_EDMA3_ADDRMODE_INCR \);myParamSetup.srcAddr = (Uint32)srcBuff;myParamSetup.dstAddr = (Uint32)CSL_MCBSP_0_TX_EDMA_REGS;myParamSetup.aCntbCnt = CSL_EDMA3_CNT_MAKE(4, 16);myParamSetup.srcDstBidx = CSL_EDMA3_BIDX_MAKE(4, 0);myParamSetup.linkBcntrld = CSL_EDMA3_LINKBCNTRLD_MAKE(CSL_EDMA3_LINK_NULL, 1);myParamSetup.srcDstCidx = CSL_EDMA3_CIDX_MAKE(0, 0);myParamSetup.cCnt = 1;CSL_edma3HwChannelSetupParam(hChannel37, CSL_EDMA3_CHA_XEVT0);CSL_edma3HwChannelSetupQue(hChannel37, CSL_EDMA3_QUE_1);CSL_edma3ParamSetup(hParamBasic, &myParamSetup);CSL_edma3HwChannelControl(hChannel37, CSL_EDMA3_CMD_CHANNEL_DISABLE, NULL);CSL_edma3HwChannelControl(hChannel37, CSL_EDMA3_CMD_CHANNEL_CLEAR, NULL);/* clear the error registers */chErrClear.missed = TRUE;chErrClear.secEvt = TRUE;CSL_edma3HwChannelControl(hChannel37, CSL_EDMA3_CMD_CHANNEL_CLEARERR, &chErrClear);CSL_edma3HwChannelControl(hChannel37, CSL_EDMA3_CMD_CHANNEL_ENABLE, NULL);/********************************Setup for Rx******************************//* Open Receive channel */chParam.regionNum = CSL_EDMA3_REGION_GLOBAL;//CSL_EDMA3_REGION_0;chParam.chaNum = CSL_EDMA3_CHA_REVT0;hChannel36 = CSL_edma3ChannelOpen(&ChObj1,CSL_TPCC_2,//CSL_EDMA3,&chParam,&status);/* Channel Setup */hParamBasic1 = CSL_edma3GetParamHandle(hChannel36, CSL_EDMA3_CHA_REVT0, &status);/* Param Setup */myParamSetup1.option = CSL_EDMA3_OPT_MAKE(FALSE,FALSE,FALSE,TRUE,\CSL_EDMA3_CHA_REVT0, \CSL_EDMA3_TCC_NORMAL, \CSL_EDMA3_FIFOWIDTH_32BIT, \CSL_EDMA3_STATIC_DIS, \CSL_EDMA3_SYNC_A, \CSL_EDMA3_ADDRMODE_INCR, \CSL_EDMA3_ADDRMODE_INCR \);myParamSetup1.srcAddr = (Uint32)CSL_MCBSP_0_RX_EDMA_REGS;myParamSetup1.dstAddr = (Uint32)dstBuff;myParamSetup1.aCntbCnt = CSL_EDMA3_CNT_MAKE(4, 16);myParamSetup1.srcDstBidx = CSL_EDMA3_BIDX_MAKE(0, 4);myParamSetup1.linkBcntrld = CSL_EDMA3_LINKBCNTRLD_MAKE(CSL_EDMA3_LINK_NULL, 1);myParamSetup1.srcDstCidx = CSL_EDMA3_CIDX_MAKE(0, 0);myParamSetup1.cCnt = 1;CSL_edma3HwChannelSetupParam(hChannel36, CSL_EDMA3_CHA_REVT0);CSL_edma3HwChannelSetupQue(hChannel36, CSL_EDMA3_QUE_1);CSL_edma3ParamSetup(hParamBasic1, &myParamSetup1);EventRecord.handler = &eventEdmaHandler;EventRecord.arg = (void*)(hModule);CSL_intcPlugEventHandler(hIntcEdma, &EventRecord);/* Enabling event edma*/CSL_intcHwControl(hIntcEdma, CSL_INTC_CMD_EVTENABLE, NULL);/* Hook up the EDMA Event with an ISR */EdmaEventHook(CSL_EDMA3_CHA_XEVT0, txmyIsr);EdmaEventHook(CSL_EDMA3_CHA_REVT0, rxmyIsr);/* Enable the interrupts */regionIntr.region = CSL_EDMA3_REGION_GLOBAL;//CSL_EDMA3_REGION_0;//regionIntr.intr= (1 << CSL_EDMA3_CHA_XEVT0) | (1 << CSL_EDMA3_CHA_REVT0);//regionIntr.intrh= 0;regionIntr.intr= 0;//(1 << CSL_EDMA3_CHA_XEVT0) | (1 << CSL_EDMA3_CHA_REVT0);regionIntr.intrh= (1 << 4) | (1 << 5);CSL_edma3HwControl(hModule, CSL_EDMA3_CMD_INTR_ENABLE, ®ionIntr);/* Disable cahnnels and clear the EDMA event registers */CSL_edma3HwChannelControl(hChannel36, CSL_EDMA3_CMD_CHANNEL_DISABLE, NULL);CSL_edma3HwChannelControl(hChannel36, CSL_EDMA3_CMD_CHANNEL_CLEAR, NULL);/* clear the error registers */chErrClear.missed = TRUE;chErrClear.secEvt = TRUE;CSL_edma3HwChannelControl(hChannel36, CSL_EDMA3_CMD_CHANNEL_CLEARERR, &chErrClear);/* Enable the receive channel */CSL_edma3HwChannelControl(hChannel36, CSL_EDMA3_CMD_CHANNEL_ENABLE, NULL);/* Enable MCBSP transmit and receive */ #if 0ctrlMask = CSL_MCBSP_CTRL_TX_ENABLE | CSL_MCBSP_CTRL_RX_ENABLE;CSL_mcbspHwControl(hMcbsp, CSL_MCBSP_CMD_RESET_CONTROL, &ctrlMask); #endif //if (!(mcbspRegs->SPCR & CSL_MCBSP_SPCR_XEMPTY_MASK))// Feed DXR if XSR is empty. //mcbspRegs->DXR = 0xaa55;WAIT_FOR_1_CLK;/* wait for Transmit complete Interrupt */while (!intFlag);/* wait for Transmit complete Interrupt */while (!rxintFlag);/* Disable cahnnels and clear the EDMA event registers */CSL_edma3HwChannelControl(hChannel36, CSL_EDMA3_CMD_CHANNEL_DISABLE, NULL);CSL_edma3HwChannelControl(hChannel37, CSL_EDMA3_CMD_CHANNEL_DISABLE, NULL);CSL_edma3HwChannelControl(hChannel36, CSL_EDMA3_CMD_CHANNEL_CLEAR, NULL);CSL_edma3HwChannelControl(hChannel37, CSL_EDMA3_CMD_CHANNEL_CLEAR, NULL);/* clear the error registers */chErrClear.missed = TRUE;chErrClear.secEvt = TRUE;CSL_edma3HwChannelControl(hChannel36, CSL_EDMA3_CMD_CHANNEL_CLEARERR, &chErrClear);CSL_edma3HwChannelControl(hChannel37, CSL_EDMA3_CMD_CHANNEL_CLEARERR, &chErrClear);CSL_edma3ChannelClose(hChannel36);CSL_edma3ChannelClose(hChannel37);CSL_edma3Close(hModule);CSL_intcClose(hIntcEdma); }
sheep stone:
回复 Lin Jia-Hung:
请问你的问题解决了吗,最近一直在做这个,好久了都没搞定
Lin Jia-Hung:
回复 sheep stone:
很抱歉这问题摆放了很久
我最终没有找到解决方法, 项目只好停摆了.