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.

DMA Channel goes into error state after each transfer




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], &paramSetup);

    //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;
}

  • Hi,

    Did you refer any CSL based EDMA code provided by TI? Is this your own code?
    I can suggest you if you are begineer for EDMA, To get more detailed info,refer the EDMA user guide and search at TI wiki page as well E2E forum.

    EDMA3 LLD based DMA and QDMA example codes are avilable at:
    edma3_lld_xx_xx_xx_xx\examples\edma3_driver\evm6678\sample_app
    edma3_lld_xx_xx_xx_xx\packages\ti\sdo\edma3\drv

    If you are looking CSL based EDMA tranfer test code, please check at PDK as per below path,
    pdk_C6678_x_x_x_x\packages\ti\csl\example\edma
    pdk_C6678_x_x_x_x\packages\ti\csl\src\ip\edma

  • Hi Pubesh,

    Of course this code is based on the CSL examples shipped as port of the PDK.

    Instead of general pointers to documentation, I would be grateful if someone could take a look at how the posted code configures the paramset ad whether there is something going wrong. Also an explanation why I need to re-enable the channel all the time would be very helpful.

    Thank you in advance and best regards, Clemens

  • Clemens,

    I could not find the right sequence of your own code for transfer using a QDMA channel
    You can find the steps to implement for transfer using QDMA.

    • Initializes and Opens the EDMA module.
    • Sets up the Module and gets the module setup values.
    • Enables the DMA and QDMA regions.
    • Opens the specified QDMA channel 'channelNum'.
    • PING uses PARAM Entry 1 & PONG uses PARAM Entry 2.
    • Configures the PARAM Blocks.
    • Enables the channel.
    • Initiates the QDMA Transfer by setting the Trigger Word.
    • Poll on the IPR bit & Clear the pending bit.
    • Compares the transfered data & Closes EDMA module.

    Already it is implement in the CSL based edma test code.

  • Hi Pubesh,

    I give up on trying to get a sane answer. Thanks anyway.

    Best regards.

  • Hi,

    Do you need any further follow-up? Is there any progress on your side. 

  • Hi Pubesh,

    Thanks, the question has been answered on another thread which was originally about dma throughput.

    Regards, Clemens