
In this thirteenth part, section 1 of board support package, we shall develop the header for DMA in order to configure it later with different modes.
In this guide, we shall cover the following:
- Developing the header file.
1. Developing the header file:
We start off by creating new header file with name of dma_bsp.h
Within the header guard, include the following:
#include "stm32f4xx.h" #include "stdint.h"
We need STM32F4xx header to access the registers.
Also, stdint to handle variable type.
We shall define two macros to enable clock access to either DMA1 or DMA2:
#define __BSP_DMA1__CLOCK_ENABLE() RCC->AHB1ENR|=RCC_AHB1ENR_DMA1EN; #define __BSP_DMA2__CLOCK_ENABLE() RCC->AHB1ENR|=RCC_AHB1ENR_DMA2EN;
Since STM32F411 has two DMAs and each DMA has 7 streams, we shall define them as following:
typedef enum
{
dma1stream0=0,
dma1stream1,
dma1stream2,
dma1stream3,
dma1stream4,
dma1stream5,
dma1stream6,
dma1stream7,
dma2stream0,
dma2stream1,
dma2stream2,
dma2stream3,
dma2stream4,
dma2stream5,
dma2stream6,
dma2stream7,
};
This will be handy when enabling the interrupt in NVIC.
With each DMA Stream, you can use one of the 8 channels, we can define these channels as following:

typedef enum
{
Channel0=0,
Channel1,
Channel2,
Channel3,
Channel4,
Channel5,
Channel6,
Channel7
}DMA_Stream_ChannelTypedef;
Within DMA, you can control both, the memory and peripheral burst mode as following:
typedef enum
{
singleTransfer=0,
INCR4,
INCR8,
INCR16,
}DMA_Stream_BurstTypedef;
You can either use single or double buffer mode for data management:
typedef enum
{
singleBuffer=0,
doubleBuffer,
}DMA_StreamDoubleBufferTypedef;Also, the priority of the stream as following:
typedef enum
{
low=0,
medium,
high,
very_high
}DMA_StreamPriorityTypedef;Also, control the peripheral increment offset:
typedef enum
{
Psize=0,
wordSize,
}DMA_StreamPrephIncSizeTypedef;Memory and peripheral size as following:
typedef enum
{
byte=0,
halfWord,
word
}DMA_SizeTypedef;Use fixed or increment mode:
typedef enum
{
fixedMode=0,
incMode=1
}DMA_IncModeTypedef;
Use circular mode or not:
typedef enum
{
singleTransfer=0,
Circular=1
}DMA_CricularTypedef;Direction of the DMA:
typedef enum
{
peripheral2Memory=0,
memory2Peripheral,
memory2Memory
}DMA_DirectionTypedef;To choose either the DMA or the peripheral is the controller:
typedef enum
{
DMAController=0,
peripheralController,
}DMAPeripheralControlTypedef;For the interrupt functionality:
typedef enum
{
InterruptDisabled=0,
InterruptEnbaled=1,
TransferComplet=1,
HalfTransfer=1,
TransferError=1,
DirectModeError=1
}DMA_InterruptTypedef;
Data structure to handle DMA configuration:
typedef struct
{
uint8_t DMA_Channel;
uint8_t PeripheralBurstMode;
uint8_t MemoryBurstMode;
uint8_t DoubleBuffer;
uint8_t Priority;
uint8_t PeripheralIncSize;
uint8_t MemorySize;
uint8_t PerpheralSize;
uint8_t MemoryIncMode;
uint8_t PeripheralIncMode;
uint8_t CircularMode;
uint8_t Direction;
uint8_t PeripheralController;
uint8_t InterruptEnable;
uint8_t dmaStream;
uint8_t TransferCompleteInterrupt;
uint8_t HalfTransferInterrupt;
uint8_t TransferErrorInterrupt;
uint8_t DirectModeErrorInterrupt;
}DMA_ConfigTypedef;In next section, we shall develop DMA driver to move data from one memory location to another using memory to memory mode.
Stay tuned.
Add Comment