Course contentsShow
← Embedded Systems & Computer Architecture
Lesson 402 of 9365. Communication Protocols and Data TransferFree lesson

Handling DMA Interrupts and Completion Signaling

Develop interrupt service routines to handle transfer completion, error conditions, and half-transfer events without CPU polling.

In this lesson, you will learn how to transition from inefficient CPU polling to event-driven DMA operations by utilizing interrupts to handle data transfer status.

Moving Beyond Polling

Previously, we discussed configuring DMA channels and descriptors to offload data movement from the CPU. However, if the CPU sits in a while loop constantly checking a "transfer complete" flag, you waste the very cycles you bought with DMA. Instead, we use Interrupt Service Routines (ISRs) to let the hardware signal the CPU only when attention is required.

Defining DMA Events

A DMA controller typically triggers interrupts for three distinct scenarios:

  1. Transfer Complete: The DMA has moved the final byte/word defined in your descriptor. This is your cue to process the received data or trigger the next transmission.
  2. Half-Transfer: Useful for circular buffers. This interrupt triggers when the DMA is halfway through a block, allowing you to process the first half of the data while the DMA continues filling the second half.
  3. Transfer Error: Triggered by bus contention or invalid memory access. This is critical for system safety and debugging.

The Interrupt Service Routine

When an interrupt fires, the CPU jumps to your ISR. Your job is to read the DMA Status Register to identify which event occurred and clear the interrupt flag so the controller can trigger again later.

void DMA1_Channel1_IRQHandler(void) {
    // 1. Check for Transfer Complete
    if (DMA_GetITStatus(DMA1_IT_TC1)) {
        DMA_ClearITPendingBit(DMA1_IT_TC1);
        NotifyApplication("Data Transfer Done");
    }
    // 2. Check for Error
    else if (DMA_GetITStatus(DMA1_IT_TE1)) {
        DMA_ClearITPendingBit(DMA1_IT_TE1);
        HandleBusError();
    }
}

By clearing the flag within the ISR, you ensure the DMA controller can continue operating without getting stuck in a permanent interrupt state. This event-driven approach keeps your system responsive and ensures the CPU is only interrupted when a specific milestone or failure occurs, maximizing overall system efficiency.

Key Takeaway: Using DMA interrupts transforms your system from a wasteful polling architecture into an efficient, event-driven model where the CPU only acts when a transfer is finished, partially complete, or in error.