Hi,
I am using non-Q DMA channels on C6678.
The code to access it was initially written for QDMA channels, but ported to DMA channels later.
Although it worked fine with QDMA channels, with DMA channels after each transfer the channel goes into error state (bit in secondary event register goes high)
and the channel can't be triggered until I clear the flag and re-enable it again.
Despite this works, when stepping through my code using the debugger, even those measures don't seem to help every time and while debugging unrelated issues I often get stuck waiting for a DMA transfer to finish.
I would be really grateful if somebody could take a look at the code below - most likely it is just an overlook difference between DMA and QDMA I didn't think about.
Thank you in advance, Clemens
void queueQDMACopy2D(uint32_t type, void *src, void *dst, uint16_t srcStride, uint16_t dstStride, uint16_t lineLength, uint16_t lineCnt) {
// Clear secondary event register, which always flags - reason unknown
edmaHandle->regs->TPCC_SECR = 1 << channelNum;
CSL_Edma3ParamSetup paramSetup;
paramSetup.option = CSL_EDMA3_OPT_MAKE(CSL_EDMA3_ITCCH_DIS, \
CSL_EDMA3_TCCH_DIS, \
CSL_EDMA3_ITCINT_DIS, \
CSL_EDMA3_TCINT_EN,\
tcc,\
CSL_EDMA3_TCC_NORMAL,\
CSL_EDMA3_FIFOWIDTH_NONE, \
CSL_EDMA3_STATIC_DIS, \
CSL_EDMA3_SYNC_AB, \
CSL_EDMA3_ADDRMODE_INCR, \
CSL_EDMA3_ADDRMODE_INCR);
paramSetup.srcAddr = localToGlobalAdress((Uint32) src);
paramSetup.aCntbCnt = CSL_EDMA3_CNT_MAKE(lineLength, lineCnt);
paramSetup.dstAddr = localToGlobalAdress((Uint32) dst);
paramSetup.srcDstBidx = CSL_EDMA3_BIDX_MAKE(srcStride, dstStride);
paramSetup.linkBcntrld = CSL_EDMA3_LINKBCNTRLD_MAKE(0xFFFFu, 0);
paramSetup.srcDstCidx = CSL_EDMA3_CIDX_MAKE(0,1);
paramSetup.cCnt = 1;
// routine which writes to config space in 32-bit quantitiess
setupParam(&edmaHandle->regs->PARAMSET[paramStartOffset], ¶mSetup);
//required each time
CSL_edma3HwChannelControl(channelHandle, CSL_EDMA3_CMD_CHANNEL_ENABLE, NULL);
CSL_edma3HwChannelControl(channelHandle, CSL_EDMA3_CMD_CHANNEL_SET, NULL);
}
void wait() {
while(!(edmaHandle->regs->TPCC_IPR & (1 << tcc)));
// Clear secondary events (channel error flag for dummy transfer used to terminate link)
//edmaHandle->regs->TPCC_SECR = 1 << channelNum;
// Clear pending interrupt flag
edmaHandle->regs->TPCC_ICR = 1 << tcc;
}