In this lesson, you will learn how to use hardware flow control signals to ensure your DMA engine only moves data when a peripheral is actually ready to send or receive it.
The Problem of Blind Transfers
When you perform a memory-to-memory transfer, the DMA controller operates as fast as the system bus allows. However, when moving data between memory and a peripheral (like an ADC or a UART), the peripheral often operates at a different speed. If the DMA blindly pushes data, you might experience "buffer underruns" (sending data that isn't ready) or "buffer overruns" (overwriting data that hasn't been read yet).
Hardware Flow Control (DREQ and DACK)
To solve this, we use dedicated hardware signaling: the DMA Request (DREQ) and DMA Acknowledge (DACK) lines.
- DREQ: The peripheral asserts this signal to the DMA controller whenever it needs service. For an input peripheral (like a UART receiver), it asserts DREQ when a new byte arrives in its internal register.
- DACK: Once the DMA controller begins the transfer, it asserts the DACK signal. This tells the peripheral, "I am now reading your data," allowing the peripheral to clear its status flag or prepare the next piece of data.
By relying on these physical lines, the DMA engine stays perfectly synchronized with the peripheral's internal state machine, rather than relying on software polling or timers.
Conceptual Configuration
When setting up the DMA channel, you must configure it for "Peripheral Mode" rather than "Memory-to-Memory" mode. In this mode, the DMA remains idle until the hardware request line is pulled active:
// Pseudo-configuration of a Peripheral-to-Memory DMA channel
dma_channel_config.mode = PERIPHERAL_REQUEST_MODE;
dma_channel_config.request_line = UART_RX_READY; // Maps to hardware pin
dma_channel_config.flow_control = HARDWARE_DACK; // Enable handshake signals
dma_init(DMA_CHANNEL_1, &dma_channel_config);
By binding the transfer logic to these signal lines, you offload the timing management from the CPU to the hardware, ensuring reliable data flow even under high system load.
Key Takeaway: Synchronizing DMA via DREQ/DACK signals creates a hardware-level handshake that prevents data loss and ensures that memory transfers are always paced by the actual readiness of the peripheral.