如下所示的程序:
// **************************************************************************************
EDMA3_DRV_Result edmaInitiateXferDoubleChain(const void *dst, const void *src, const int aCnt,const int bCnt, const int cCnt, const int srcBIdx,const int destBIdx, const int srcCIdx,const int destCIdx, const int chCnt)
{EDMA3_DRV_PaRAMRegs paramSet, *gParamSet;uint32_t addr;EDMA3_DRV_Result edmaResult = EDMA3_DRV_SOK;signed char *srcBuf, *dstBuf;volatile int coreCnt = determineProcId();int bIndex; //, cIndex;if((chCnt<0) || (chCnt>2) || ((chCnt&1) != 0)){
System_printf("DMA channel (%d) not valid", chCnt);
System_abort("\n");}if(bCnt * cCnt > MAX_PARAMS-1){
System_printf("Can't handle bCnt(%d)*cCnt(%); max allowed is %d", bCnt, cCnt, MAX_PARAMS-1);
System_abort("\n");}srcBuf = (signed char*) getGlobalAddr((signed char *) src);dstBuf = (signed char*) getGlobalAddr((signed char *) dst);// set paramSetparamSet.srcAddr = (unsigned int) srcBuf;paramSet.destAddr = (unsigned int) dstBuf;paramSet.aCnt= aCnt;paramSet.bCnt= 1;paramSet.cCnt= 1;paramSet.srcBIdx = 0;paramSet.destBIdx = 0;paramSet.srcCIdx = 0;paramSet.destCIdx = 0;paramSet.bCntReload = 0;paramSet.linkAddr= 0xFFFFu;paramSet.opt = 0x00000000u;// enable final TCC chaining; only one transferparamSet.opt |= (1 << OPT_TCCHEN_SHIFT);// set TCC to chained channelparamSet.opt |= ((gEdmaXfer[coreCnt][chCnt+1].tcc << OPT_TCC_SHIFT) & OPT_TCC_MASK);gParamSet = &globalParamSet[(coreCnt*(EDMA_CHANNELS>>1)+(chCnt>>1))*MAX_PARAMS];// now write the paramsets to be used by the first of the doubly chained channelsfor(bIndex = 0; bIndex <= bCnt; bIndex++){
// table of paramSet
gParamSet[bIndex] = paramSet;
// update src and dst address;
paramSet.srcAddr += srcBIdx;
paramSet.destAddr += destBIdx;
if(bIndex == (bCnt-1)) // last in the set
{
// set to be a dummy transfer
paramSet.aCnt = 1;
paramSet.bCnt = 0;
paramSet.cCnt = 0;
// disable chaining
paramSet.opt &= ~(1 << OPT_TCCHEN_SHIFT);
}}// ensure gParamSet is written to cacheCache_wbInv(gParamSet, (bCnt+1)*sizeof(EDMA3_DRV_PaRAMRegs), Cache_Type_ALLD, 1);// set paramSet; src is global param set; dst is chained PARAMset;// src increment is size of PARAMset and dst address is always the sameparamSet.srcAddr = (uint32_t) getGlobalAddr((signed char *) &gParamSet[0]);EDMA3_DRV_getPaRAMPhyAddr(gHEdma[coreCnt/4], gEdmaXfer[coreCnt][chCnt].chId, &addr);paramSet.destAddr = (uint32_t) getGlobalAddr((signed char *) addr);paramSet.aCnt= sizeof(EDMA3_DRV_PaRAMRegs);paramSet.bCnt= bCnt+1;paramSet.cCnt= 1;paramSet.srcBIdx = sizeof(EDMA3_DRV_PaRAMRegs);paramSet.destBIdx = 0;paramSet.srcCIdx = 0;paramSet.destCIdx = 0;paramSet.bCntReload = 0;paramSet.linkAddr= 0xFFFFu;paramSet.opt = 0x00000000u;// both intermediate and final chaining enabledparamSet.opt |= (1 << OPT_TCCHEN_SHIFT);paramSet.opt |= (1 << OPT_ITCCHEN_SHIFT);// final interrupt enabledparamSet.opt |= (1 << OPT_TCINTEN_SHIFT);// set TCC to chained channelparamSet.opt |= ((gEdmaXfer[coreCnt][chCnt].tcc << OPT_TCC_SHIFT) & OPT_TCC_MASK);/* Now, write the PaRAM Set to the second of the doubly chained channels */edmaResult = EDMA3_DRV_setPaRAM(gHEdma[coreCnt/4], gEdmaXfer[coreCnt][chCnt+1].chId, (EDMA3_DRV_PaRAMRegs *) ¶mSet);// start transfer on the second of the doubly chained channelsif(edmaResult == EDMA3_DRV_SOK){edmaResult = EDMA3_DRV_enableTransfer (gHEdma[coreCnt/4],gEdmaXfer[coreCnt][chCnt+1].chId,EDMA3_DRV_TRIG_MODE_MANUAL);}return(edmaResult);
} // edmaInitiateXferDoubleChain
应该是乒乓模式, 但是我看不懂,希望可以得到解释,困在这里好多天了
Allen35065:
双缓的方式即
EDMA->BufferA 触发EDMA->BufferB触发EDMA->BufferA
三缓或者更多缓就是上述循环的简单增加。
TI中文支持网