|
|
Purpose of this page is to give the user a basic understanding of how to use DMA. For further details study the reference manual [RM0090](https://www.st.com/resource/en/reference_manual/dm00031020-stm32f405415-stm32f407417-stm32f427437-and-stm32f429439-advanced-armbased-32bit-mcus-stmicroelectronics.pdf) on which the contens of this page are derived from.
|
|
|
The examples shown can be found [here](https://git.skywarder.eu/alberto.nidasio/skyward-dma-examples).
|
|
|
|
|
|
> :warning: This document applies to the whole stm32f4 family
|
|
|
Complete code examples for SPI and internal ADC can be found [here](https://git.skywarder.eu/alberto.nidasio/skyward-dma-examples).
|
|
|
|
|
|
## Introduction
|
|
|
:warning: This document applies to the whole stm32f4 family
|
|
|
|
|
|
# Introduction
|
|
|
|
|
|
Direct memory access (DMA) is used in order to provide high-speed data transfer between peripherals and memory and between memory and memory. Data can be quickly moved by DMA **without any CPU action**. This keeps CPU resources free for other operations.
|
|
|
|
|
|
The stm32f4 family has two DMA controllers (each with 8 streams) for a total of 16 possible configurations.
|
|
|
|
|
|
Each stream can be configured for memory-to-peripheral, peripheral-to-memoy or memory-to-memory transfers.
|
|
|
|
|
|
The peripherals that supports DMA are: SPI, I2S, SAI, I2C, ADC, DAC, UART, USART, timers and cryptographics processor.
|
|
|
|
|
|
A DMA transfer is characterized by the following properties:
|
|
|
|
|
|
- **DMA stream/channel**
|
|
|
Each DMA controller has 8 streams each of which can be configured between 8 channels.
|
|
|
<p>
|
|
|
<details>
|
|
|
<summary>DMA request mapping</summary>
|
|
|
<div align="center">
|
|
|
<img src="uploads/cf205e19878133a7c9b37b8ebbc86313/dma1_request_mapping.png" height="250"/><br/>
|
|
|
<i>DMA1 request mapping</i>
|
|
|
</div><br>
|
|
|
<div align="center">
|
|
|
<img src="uploads/af255b35c46b2cb231b7b388f3ce1c2a/dma2_request_mapping.png" height="250"/><br/>
|
|
|
<i>DMA2 request mapping</i>
|
|
|
</div>
|
|
|
</details>
|
|
|
</p>
|
|
|
|
|
|
- **Source and destination addresses**
|
|
|
A DMA transfer is defined by a source address and a destination address. Both the source and destination should be in the AHB or APB memory ranges and should be aligned to transfer size.
|
|
|
|
|
|
- **Transfer mode**
|
|
|
DMA is capable of performing three different transfer modes:
|
|
|
- Peripheral to memory
|
|
|
- **Transfer mode**:
|
|
|
- Memory to peripheral
|
|
|
- Peripheral to memory
|
|
|
- Memory to memory (only DMA2)
|
|
|
|
|
|
- **Transfer size** (only when DMA is the flow controller)
|
|
|
The transfer size is defined by the DMA_SxNDTR register value and by the peripheral side data width.
|
|
|
|
|
|
- **Source/destination address incrementing**
|
|
|
It is possible to configure the DMA to automatically increment the source and/or destination address after each data transfer.
|
|
|
|
|
|
- **Source and destination data width**
|
|
|
Data width for source and destination can be defined as:
|
|
|
- **Transfer size**: number of data items defined by the DMA_SxNDTR register value
|
|
|
- **Address incrementation**: tt is possible to configure the DMA to automatically increment the source and/or destination address after each data item transfer.
|
|
|
- **Data width**:
|
|
|
- Byte (8 bits)
|
|
|
- Half-word (16 bits)
|
|
|
- Word (32 bits)
|
|
|
|
|
|
- **Transfer type**
|
|
|
- Circular mode: the Circular mode is available to handle circular buffers and continuous data flows (the DMA_SxNDTR register is then reloaded automatically with the previously programmed value).
|
|
|
- **Transfer type**:
|
|
|
- Circular mode: available to handle circular buffers and continuous data flows (the DMA_SxNDTR register is reloaded automatically with the previously programmed value).
|
|
|
- Normal mode: once the DMA_SxNDTR register reaches zero, the stream is disabled (the EN bit in the DMA_SxCR register is then equal to 0).
|
|
|
|
|
|
## DMA configuration procedure
|
|
|
Each DMA stream implements also a 4 word (16 byte) FIFO which can be used to buffer data. By default the stream functions in direct mode, hence the fifo is used with a threshold of 0.
|
|
|
|
|
|
<p>
|
|
|
<details>
|
|
|
<summary>DMA request mapping</summary>
|
|
|
<div align="center">
|
|
|
<img src="uploads/cf205e19878133a7c9b37b8ebbc86313/dma1_request_mapping.png" height="250"/><br/>
|
|
|
<i>DMA1 request mapping</i>
|
|
|
</div><br>
|
|
|
<div align="center">
|
|
|
<img src="uploads/af255b35c46b2cb231b7b388f3ce1c2a/dma2_request_mapping.png" height="250"/><br/>
|
|
|
<i>DMA2 request mapping</i>
|
|
|
</div>
|
|
|
</details>
|
|
|
</p>
|
|
|
|
|
|
## Memory to peripheral mode
|
|
|
|
|
|
When this mode is enabled (by setting the EN bit in the DMA_SxCR register), the stream **immediately fills the FIFO** to ensure an immediate data transfer as soon as a DMA request is triggered by a peripheral. This require that the data are already available in the source address.
|
|
|
|
|
|
Each time a peripheral request occurs, the contents of the FIFO are drained and stored into the destination. When the level of the FIFO is lower than or equal to the predefined thresholdd level, the FIFO is fully reloaded with data from memory. As said, in direct mode the memory is access for each data item.
|
|
|
|
|
|
The transfer stops once the DMA_SxNDTR register reaches zero or when the EN bit in the DMA_SxCR register is cleared by software.
|
|
|
|
|
|
## Peripheral to memory mode
|
|
|
|
|
|
When this mode is enabled, each time a peripheral requests occurs, the stream initiates a transfer from the source to fill the FIFO. When the threshold level of the FIFO is reached, the contents of the FIFO are drained and stored into the destination.
|
|
|
|
|
|
The transfer stops once the DMA_SxNDTR register reaches zero or when the EN bit in the DMA_SxCR register is cleared by software.
|
|
|
|
|
|
# DMA configuration procedure
|
|
|
|
|
|
In order to setup a DMA stream correctly you need to follow this procedure:
|
|
|
1. **Disable the stream before changing the configuration**
|
|
|
This is done by resetting the EN bit in the DMA_SxCR register and read it back to confirm that there is no ongoing stream operation
|
|
|
This is done by resetting the EN bit in the DMA_SxCR register and reading it back to confirm that there is no ongoing stream operation
|
|
|
2. **Configure the stream**
|
|
|
3. **Enable the stream**
|
|
|
4. **Enable the peripheral used** (DMA request enable bit in the peripheral control register) |
|
|
\ No newline at end of file |
|
|
4. **Enable the peripheral used** (DMA request enable bit in the peripheral control register)
|
|
|
|
|
|
# SPI communication using DMA
|
|
|
|
|
|
SPI can be configured to transmit and/or receive data using DMA.
|
|
|
|
|
|
A DMA access is requested when the enble bit in the SPI_CR2 register is enabled.
|
|
|
- In transmission a DMA request is issued **each time TXE is set to 1**. The DMA then writes to the SPI_DR register (this clears TXE).
|
|
|
- In reception a DMA request is issued **each time RXNE is set to 1**. The DMA then reads the SPI_DR register (this clears RXNE).
|
|
|
|
|
|
The BSY flag can be monitored to ensure that the SPI communication is complete. |
|
|
\ No newline at end of file |