The two DMA controllers can be used to quickly transfer data between two peripherals (or memory) without any CPU interaction.
Not all combinations of peripherals are possible: available DMA connections.
EN | 0 | Stream disabled (reset state) | |
1 | Stream enabled (reset state) | ||
CHSEL | xxx | Channel nr selected (0..7) | |
CIR | 0 | Circular mode disabled (reset state) | |
1 | Circular mode enabled | ||
DIR | 00 | Direction peripheral to memory (reset state) | |
01 | Direction memory to peripheral | ||
10 | Direction memory to memory | ||
11 | reserved | ||
PSIZE* | 00 | Peripheral size 8 bit (reset state) | |
01 | Peripheral size 16 bit | ||
10 | Peripheral size 32 bit | ||
11 | reserved | ||
MSIZE* | 00 | Memory size 8 bit (reset state) | |
01 | Memory size 16 bit | ||
10 | Memory size 32 bit | ||
11 | reserved |
* Only writeable if EN = '0'
The code snippet below shows how to configure and use the DMA controller.
#include "reg_stm32f4xx.h" RCC->AHBENR[0] |= (0x1 << 22u); /* Enable DMA2 clock */ /* Configure DMA2 controller. */ DMA2->STREAM[0].CR |= (2u << 25u); /* Setup channel. */ DMA2->STREAM[0].CR |= (0x0 << 6u); /* Setup direction. */ DMA2->STREAM[0].CR |= (0x1 << 8u); /* Setup circular mode. */ DMA2->STREAM[0].NDTR |= 1u; /* Setup nr of transfers. */ /* Setup source and destination. */ DMA2->STREAM[0].PAR |= (uint32_t) &(ADC3->DR); DMA2->STREAM[0].M0AR |= (uint32_t) &(TIM3->CCR[0]); /* Setup buffer size. */ DMA2->STREAM[0].CR |= (0x1 << 11u); /* PSIZE */ DMA2->STREAM[0].CR |= (0x1 << 13u); /* MSIZE */ /* Start DMA transfer. */ DMA2->STREAM[0].CR |= (0x1 << 0u);