DMA (Direct Memory Access)
Introduction
DMA (Direct Memory Access) is exactly what it sounds, it is a peripheral that has direct access, or control, of a processor's memory bus. DMA enables more efficient use of interrupts, increases data throughput, and offloads some of the work the work the processor would have otherwise had to do. DMA can provide high-speed data transfer between peripherals and memory as well as memory to memory without any actions from the CPU, freeing up CPU resources for other operations
How DMA Works
When talking about DMA, we usually talk about a DMA transfer, which is the act of the peripheral transferring some data from one point to another.
In a typical DMA transfer, some event (such as an incoming data signal from a UART) notifies a separate device called the DMA controller that data needs to be transferred to memory. The DMA controller then asserts a DMA request signal to the CPU, asking its permission to use the bus. The CPU completes its current bus activity, stops driving the bus, and returns a DMA acknowledge signal to the DMA controller. The DMA controller then reads and writes one or more memory bytes, driving the address, data, and control signals as if it were itself the CPU. When the transfer is complete, the DMA controller stops driving the bus and deasserts the DMA request signal. The CPU can then remove its DMA acknowledge signal and resume control of the bus.
Typically, when we want to enable a DMA transfer there are 3 pieces of information that must be known. The source address, the destination address and the amount of data to be transferred. The source address is the address where the data will originate from, the destination address is where the data is going to be transferred, and the number of bytes to be transferred is, well, self explanatory . After each transfer of data, the amount of data to be transferred is decremented, this is how the DMA peripheral keeps track of how much data to transfer.
Types of DMA Transfers and Modes
Types of DMA Transfers
As mentioned before, DMA can support different types of transfers. On our STM32s, they support peripheral to memory, memory to peripheral, and peripheral to peripheral transfers.
Peripheral to Memory and Memory to Peripheral
A peripheral to memory transfer consists of data being transferred from a peripheral to some place in memory. For example, when incoming data coming from UART (the peripheral) is received, that data can be transferred using DMA directly to a memory buffer (the memory) to store its contents. Memory to peripheral is the exact same thing but the other way around. If we want to send some data sitting in a buffer through UART, we can use DMA transfers to transfer that data from the buffer to the UART.
Peripheral to Peripheral
A peripheral to peripheral transfer consists of data being transferred from one peripheral to another. An example of when this could be used is when you are using an ADC to take measurements from a sensor and you want to transmit that data through SPI to another board to store that information. You can use a DMA transfer going from peripheral (ADC) to peripheral (SPI) to make that happen.
DMA Modes
There are 2 DMA modes that our STM32s use, circular mode and Memory to memory mode.
Circular Mode
Circular mode is available to handle circular buffers and continuous data flows (e.g. ADC scan mode). When circular mode is activated, the number of data to be transferred is automatically reloaded with the initial value programmed during the channel configuration phase, and the DMA requests continue to be served.
Memory to Memory Mode
The DMA channels can also work without being triggered by a request from a peripheral. This mode is called Memory to Memory mode.
In memory to memory mode, the channel initiates transfers as soon as it is enabled by software. The transfer stops once the total number of bytes to be transferred reaches zero. Memory to Memory mode may not be used at the same time as Circular mode.
Why Use DMA?
You may be asking yourself, “this seems like unnecessary work, why can’t I just do everything without DMA transfers?” In most cases, you would be correct. Many applications don’t require the use of the DMA and having the CPU do all the work is fine But, in cases where large amounts of data need to be transferred, or a constant amount of data needs to be transferred at a high rate, instead of having the CPU do that, you can offload that work to the DMA peripheral.
Further Information
This document only covers a brief explanation of DMA, what it can do, how it does it, and the different types of transfers and modes. What this document does not go over is the direct implementation of DMA for STM32 using HAL and a lot of the nitty gritty details. If you would like to gain more information on DMA, please refer to the DMA section in the data sheets and this webpage that goes over DMA in an STM32 board.