cancel
Showing results for 
Search instead for 
Did you mean: 

Circular DMA interrupts

BDoon.1
Associate II

I have a project that uses DMA in circular mode, and i've implemented the half and complete interrupts necessary to manage the transfer.  I'm using just 2 nodes, and I've noticed that I get a complete interrupt to start the transfer, and then the expected half-complete-half-complete-etc pattern I'd expect.  I've definitely enabled the HT interrupt, but i still always see the TC hit first to start the process.

What is that?  Is it a nuance of circular mode?

3 REPLIES 3
TDK
Guru

It should work how you expect. You're probably not handling the interrupt in time, or not enabling it in time, or some other race condition.

If you feel a post has answered your question, please click "Accept as Solution".
MM..1
Chief II

DMA TC isnt same as peripheral TC. DMA TC report you , that last pack (BYTE WORD DWORD) is sended to peripheral. In real use peripherals start for example sending this value same time, in other can place into FIFO exist many variants. But real traffic end is always delayed...

nouirakh
ST Employee

Hello @BDoon.1 

What you're observing is indeed a common behavior when using DMA in circular mode, especially when the DMA is first initialized and started.

When you first start the DMA transfer, the DMA controller may generate a transfer-complete (TC) interrupt immediately. This can happen due to the following reasons:

  1. Initial State: When the DMA is first enabled, it might consider the initial state as a "complete" state because it hasn't started transferring data yet. This can trigger the TC interrupt.

  2. Buffer Initialization: The DMA controller might be initializing the buffer pointers and other internal states, which can cause it to generate a TC interrupt as part of the setup process.

To handle the initial TC interrupt and ensure your application logic works correctly, you can implement a simple check in your interrupt service routine (ISR) to differentiate between the initial TC interrupt and subsequent ones.

 Example of how you might implement this in your code:

void DMA_IRQHandler(void) {
    if (DMA_GetITStatus(DMA1_Stream0, DMA_IT_TCIF0)) {
        // Transfer Complete Interrupt
        if (!initialTCHandled) {
            // Handle the initial TC interrupt
            initialTCHandled = true;
        } else {
            // Handle subsequent TC interrupts
            // Your TC interrupt handling code here
        }
        DMA_ClearITPendingBit(DMA1_Stream0, DMA_IT_TCIF0);
    }