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