Direct Memory Access

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.




Features


Configuration Registers

DMA_SxCR - Stream X configuration register




EN0Stream disabled (reset state)
1Stream enabled (reset state)
CHSELxxxChannel nr selected (0..7)
CIR0Circular mode disabled (reset state)
1Circular mode enabled
DIR00Direction peripheral to memory (reset state)
01Direction memory to peripheral
10Direction memory to memory
11reserved
PSIZE*00Peripheral size 8 bit (reset state)
01Peripheral size 16 bit
10Peripheral size 32 bit
11reserved
MSIZE*00Memory size 8 bit (reset state)
01Memory size 16 bit
10Memory size 32 bit
11reserved

* Only writeable if EN = '0'

DMA_SxPAR - Stream X peripheral address register




NDTxxxNumber of data items to be transfered.

DMA_SxM0AR - Stream X memory 0 address register




M0AxxxBase address of memory 0.

DMA_SxM1AR - Stream X memory 1 address register




M1AxxxBase address of memory 1.

DMA_SxNDTR - Stream X number of data register




NDTxxxNumber of data items to be transfered.

Programming Example

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);