This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
您好, 这问题困扰我很久了
目前需要利用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); }
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_Edma3ParamHandle hParamBasic; CSL_Edma3ParamHandle hParamBasic1; CSL_Edma3ParamSetup myParamSetup; CSL_Edma3ParamSetup myParamSetup1; CSL_Edma3ChannelObj ChObj, ChObj1; CSL_Edma3ChannelAttr chParam; CSL_Edma3Context edmaContext; CSL_Edma3Obj edmaObj; CSL_Edma3QueryInfo info; CSL_Edma3CmdIntr regionIntr; CSL_Edma3CmdDrae regionAccess; Uint32 i, j; CSL_BitMask16 ctrlMask; 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 0 ctrlMask = 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); }