Library 56- Extend SPI with DMA for STM32F4xx

As said in one post before, here is SPI DMA library for STM32F4 devices. Instead of onl TX functionality (as in USART DMA library) SPI DMA extension library enables DMA for TX and RX modes at the same time, to receive and transmit data over DMA.

Library supports up to 6 SPIs (max number in STM32F4 devices). It can work in 3 main modes:

  • Send data to slave device, receive data from slave device
  • Send data to slave device, don’t care for received data from slave device
  • Send dummy byte(s) to slave, receive data from slave device

DMA does not make any interrupts after it ends, user will have to check this by itself. There are also functions for that to allow easy check if DMA and SPI are done.

Library

Features

  • Enables DMA feature for TM SPI library
  • Can transmit, send only or receive only data via SPI and DMA
  • Works for all possible SPIs in STM32F4 devices
  • Supports changeable stream and channel settings

Dependencies

  • CMSIS
    • STM32F4xx
    • STM32F4xx DMA
  • TM
    • TM SPI
    • TM DMA
    • defines.h

Stream and channel settings

STM32F4xx devices have 2 DMA controllers. Each DMA controller has 8 DMA streams where each stream has 8 DMA channels for different peripherals available.

To get all available DMA peripherals, you should take a STM32F4xx Reference manual (1700+ pages) and take a look at DMA section. There are all available streams and channels for different peripheral.

This library uses only USART TX DMA. Default DMA streams and channels are in table below:

SPIx DMA DMA TX Stream DMA TX Channel DMA RX Stream DMA RX Channel
SPI1 DMA2 DMA Stream 3 DMA Channel 3 DMA Stream 2 DMA Channel 3
SPI2 DMA1 DMA Stream 4 DMA Channel 0 DMA Stream 3 DMA Channel 0
SPI3 DMA1 DMA Stream 5 DMA Channel 0 DMA Stream 0 DMA Channel 0
SPI4 DMA2 DMA Stream 1 DMA Channel 4 DMA Stream 0 DMA Channel 4
SPI5 DMA2 DMA Stream 6 DMA Channel 7 DMA Stream 5 DMA Channel 7
SPI6 DMA2 DMA Stream 5 DMA Channel 1 DMA Stream 6 DMA Channel 0

Some SPIs uses also different streams and channels. This can be handy if you have 2 peripherals on the same stream and DMA and you want to enable DMA for both. You can’t do that because only one channel on specific stream can be used at a time. For that purpose, someking of “remapping” was enabled which allows you to select custom Stream and Channel for specific SPI if it is available. Always look for STM32F4xx Reference manual for that settings.

Functions

Example

Example was tested using Nucleo-F411 board. Using SPI1, I connected MOSI and MISO pins together to simulate data from slave.

I split example into three parts:

  • In first part, I fill TX_Buffer and sent data over SPI. Because MOSI and MISO pins are connected together, I expected the same result in RX_Buffer after DMA finishes transmission. Image 1 proves successfull result.
    SPI RX Buffer after DMA transmission

    SPI RX Buffer after DMA transmission

    SPI DMA TX Buffer set

    SPI DMA TX Buffer set

  • In second part I sent data over SPI with DMA, but I set RX_Buffer to NULL, which means that I don’t to receive any data from DMA slave, only sent data. RX_Buffer is the same as it was at the end of part one.
  • Last part was to test receive method via SPI. I set TX_Buffer to NULL. In this case, DMA will send all zeros over SPI to slave, just to enable SPI clock for it. Because I had MOSI and MISO pins together, all zeros are received in RX_Buffer.

    SPI zeros sent over SPI DMA

    SPI zeros sent over SPI DMA

Project is available on my Github, download library below.

tilz0R

Owner of this site. Application engineer, currently employed by STMicroelectronics. Exploring latest technologies and owner of different libraries posted on Github.

You may also like...

Read before commenting!

Before you make a new comment, make sure you agree with things listed below:

  • - Read post to make sure if it is already posted what you are asking for,
  • - Make sure you have the latest version of libraries used in your project,
  • - Make a clean and grammatically correct written message,
  • - Report as many details as possible, including what have you done so far,
  • - Do NOT post any code here. Use Pastebin,
  • - Do NOT post any error codes here. Use Pastebin,
  • - Specify STM32Fxxx family and used Discovery/EVAL/Nucleo or custom made board,
  • - Make sure your clock is set correct for PLL,
  • - If you are using my HAL drivers, please check this post how to start.
Comment will be deleted on breaking these rules without notification!