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.

[6416T] DMA controller does not interrupt DSP after transfer completes

Normal 0 false false false EN-US X-NONE X-NONE MicrosoftInternetExplorer4

Hello,

We are seeing a condition in which 2 QDMA transfers are submitted to the EDMA controller, they both transfer all of their data, but only one of them interrupts the DSP indicating it is finished. These transfers are submitted such that the second is submitted while the first transfer is still in process.  The first transfer to complete always interrupts the DSP to indicate it is finished, but the second transfer to complete never interrupts the DSP. When these two transfers happen independently (not overlapping in time), they both finish and interrupt the DSP as programmed, but we've found this race condition where if the two transfers line up over top of each other, the second one to finish does not interrupt the DSP.

Both transfers are to/from the EMIF bus.  We have verified that the transfers complete by looking at the EMIF signals on a logic analyzer.

To reproduce:

Case 1

Submit transfer 'A' to the EDMA controller.  While it is transferring data, submit transfer 'B' at a equal or lower priority.  Transfer A finishes and interrupts the DSP, then transfer B starts and finishes, but does not interrupt the DSP.

Case 2

Submit transfer 'B' to the EDMA controller.  While it is transferring data, submit transfer 'A' at a higher priority.  Transfer B starts, then transfer A takes over because it has higher priority.  Transfer A then finishes and interrupts the DSP.  Transfer B finishes, but never interrupts the DSP.

Any thoughts on what might cause this?

Thanks for your help!
Jeff

  • The first thing that comes to mind is whether you are using the same TCC for both transfers or a different TCC?  If you're using the same TCC and the transfers complete close together then your interrupt will not have time to clear the IPR bit prior to the next interrupt firing in which case you would effectively lose one.

    Can you try a 3rd case which is similar to case 1 except that transfer B is at a higher priority?  In this case we expect transfer B to complete first.  So the question is, does the first completed transfer always generate the interrupt or does 'A' always generate the interrupt (for some reason)?

     

  • Brad - thanks for your reply.

    We are using different TCC's for the two transfers.  One is 3 and the other is 4.

    As for your 3rd case - B finishes first and generates an interrupt.  A does not generate an interrupt.

    We were looking at our interrupt handling, and it appears that we may have found the problem.  We have the EDMAISR that gets called when the EDMA controller finishes a transfer.  This ISR calls EDMA_IntDispatcher (the CSL function) and then does an IRQ_clear on the EDMA interrupt flag.  We think that there could be a race condition where the first transfer completes and the ISR is called, and then the next transfer completes very quickly after it (it is a short transfer).  This second transfer may finish after the dispatcher is finished processing the first transfer, or it finishes prior to the dispatcher and the dispatcher generates another EDMA interrupt.  Then when we clear the EDMA interrupt flag, we lose the interrupt for the second transfer.  Does that make sense?  We moved the EDMA interrupt flag clearing to BEFORE the dispatcher call, and it appears to be working fine now.  We havent tested extensively, but the particular test case that caused a problem before is looking ok.  Does that sound like a valid fix?

    Thanks,
    Jeff

  • JTM said:
    This ISR calls EDMA_IntDispatcher (the CSL function) and then does an IRQ_clear on the EDMA interrupt flag.

    You should not be doing IRQ_clear at all.  This is handled automatically in hardware.  Upon acceptance of the interrupt the corresponding flag in the CPU's IFR register is automatically cleared.  Basically you are making yourself lose an interrupt.  The right answer is to get rid of that code altogether.  Moving the call to before EDMA_intDispatcher did the trick because it just so happens that upon clearing an EDMA CIPR bit that will cause the CPU IFR to be re-asserted so you get lucky.  Bottom line is that you don't need to do IRQ_clear at all in any ISR...

    If you haven't looked at this thread you might find this helpful too:

    Problem getting isr callback for tcc for QEDMA

    Best regards,
    Brad