5.7 DMA Guide
This chapter describes the file composition and 12 public functions of the DMA driver in the N32H49x standard peripheral library, together with the BURST and FLASH_RAM examples. DMA moves data between peripherals and memory or between memory and memory; for the channel priority, data width, burst length and request remapping, see the “DMA controller” chapter of the user manual.
5.7.1 Related files
| Relative path | Purpose |
|---|---|
firmware/n32h49x_std_periph_driver/inc/n32h49x_dma.h |
Defines the channel, data-width, burst and interrupt selection macros and the DMA_InitType structure, and declares the 12 public functions |
firmware/n32h49x_std_periph_driver/src/n32h49x_dma.c |
Implements the 12 functions above: channel reset and initialization, structure defaults, channel enable, interrupt and data-count setup, flag and interrupt status access, and request remapping |
projects/n32h49x_EVAL/examples/DMA/ |
DMA example root directory, containing the BURST and FLASH_RAM examples |
projects/n32h49x_EVAL/examples/DMA/BURST/ |
Project directory composition of this example: MDK-ARM/, EWARM/, inc/, src/, readme.txt |
projects/n32h49x_EVAL/bsp/ |
Common board files referenced by this example: the UART log function |
5.7.2 API reference
The following 12 public functions are listed in the declaration order of n32h49x_dma.h in 4 groups; each entry gives a summary and the original comment above the function in n32h49x_dma.c.
Reset and initialization
DMA_DeInit, DMA_Init, DMA_StructInit, DMA_EnableChannel
Interrupt and data count
DMA_ConfigInt, DMA_SetCurrDataCounter, DMA_GetCurrDataCounter
Flags and interrupt status
DMA_GetFlagStatus, DMA_ClearFlag, DMA_GetIntStatus, DMA_ClrIntPendingBit
Request remapping
DMA_RequestRemap
void DMA_DeInit(DMA_ChannelType* DMAChx)Reset CHCFG, TXNUM, PADDR, MADDR, INTCLR registers of DMA1/DMA2 Channel x to their default reset values.
name DMA_DeInit.
fun Reset CHCFG, TXNUM, PADDR, MADDR, INTCLR registers of DMA1/DMA2 Channel x
to their default reset values.
param DMAChx (The input parameters must be the following values):
- DMA1_CH1
- DMA1_CH2
- DMA1_CH3
- DMA1_CH4
- DMA1_CH5
- DMA1_CH6
- DMA1_CH7
- DMA1_CH8
- DMA2_CH1
- DMA2_CH2
- DMA2_CH3
- DMA2_CH4
- DMA2_CH5
- DMA2_CH6
- DMA2_CH7
- DMA2_CH8
return none
void DMA_Init(DMA_ChannelType* DMAChx, DMA_InitType* DMA_InitParam)Initializes the DMA Channel x by the structure parameter DMA_InitParam of type DMA_InitType. Includes configuration peripheral/memory address, transmission direction, address increment mode, data bit width, priority, etc.
name DMA_Init.
fun Initializes the DMA Channel x by the structure parameter
DMA_InitParam of type DMA_InitType. Includes configuration
peripheral/memory address, transmission direction, address
increment mode, data bit width, priority, etc.
param DMAChx (The input parameters must be the following values):
- DMA1_CH1
- DMA1_CH2
- DMA1_CH3
- DMA1_CH4
- DMA1_CH5
- DMA1_CH6
- DMA1_CH7
- DMA1_CH8
- DMA2_CH1
- DMA2_CH2
- DMA2_CH3
- DMA2_CH4
- DMA2_CH5
- DMA2_CH6
- DMA2_CH7
- DMA2_CH8
param DMA_InitParam (The input parameters must be the following values):
- PeriphAddr
- MemAddr
- Direction
- DMA_DIR_PERIPH_DST
- DMA_DIR_PERIPH_SRC
- BufSize
- PeriphInc
- DMA_PERIPH_INC_ENABLE
- DMA_PERIPH_INC_DISABLE
- MemoryInc
- DMA_MEM_INC_ENABLE
- DMA_MEM_INC_DISABLE
- PeriphDataSize
- DMA_PERIPH_DATA_WIDTH_BYTE
- DMA_PERIPH_DATA_WIDTH_HALFWORD
- DMA_PERIPH_DATA_WIDTH_WORD
- MemDataSize
- DMA_MEM_DATA_WIDTH_BYTE
- DMA_MEM_DATA_WIDTH_HALFWORD
- DMA_MEM_DATA_WIDTH_WORD
- CircularMode
- DMA_MODE_CIRCULAR
- DMA_MODE_NORMAL
- Priority
- DMA_PRIORITY_VERY_HIGH
- DMA_PRIORITY_HIGH
- DMA_PRIORITY_MEDIUM
- DMA_PRIORITY_LOW
- Mem2Mem
- DMA_M2M_ENABLE
- DMA_M2M_DISABLE
- BurstCmd
- DMA_BURST_ENABLE
- DMA_BURST_DISABLE
- BURST_MODE
- DMA_BURST_MODE_Almost
- DMA_BURST_MODE_Dynamic
- BURST_LEN
- DMA_BURST_LEN_single
- DMA_BURST_LEN_1
- DMA_BURST_LEN_2
- DMA_BURST_LEN_3
- DMA_BURST_LEN_4
- DMA_BURST_LEN_5
- DMA_BURST_LEN_6
- DMA_BURST_LEN_7
- DMA_BURST_LEN_8
return none
void DMA_StructInit(DMA_InitType* DMA_InitParam)Initializes the structure parameter of type DMA_InitType used to initialize DMA. This function is usually called before initializing a parameter of type DMA_InitType.
name DMA_StructInit.
fun Initializes the structure parameter of type DMA_InitType used to
initialize DMA. This function is usually called before initializing
a parameter of type DMA_InitType.
param DMA_InitParam :
- Pointer to the DMA_InitType structure which will be initialized.
return none
void DMA_EnableChannel(DMA_ChannelType* DMAChx, FunctionalState Cmd)DMA Channel x Channel enable. This function is called after DMA initialization is successful to start moving data.
name DMA_EnableChannel.
fun DMA Channel x Channel enable. This function is called after DMA
initialization is successful to start moving data.
param DMAChx (The input parameters must be the following values):
- DMA1_CH1
- DMA1_CH2
- DMA1_CH3
- DMA1_CH4
- DMA1_CH5
- DMA1_CH6
- DMA1_CH7
- DMA1_CH8
- DMA2_CH1
- DMA2_CH2
- DMA2_CH3
- DMA2_CH4
- DMA2_CH5
- DMA2_CH6
- DMA2_CH7
- DMA2_CH8
param Cmd:(The input parameters must be the following values)
- ENABLE
- DISABLE
return none
void DMA_ConfigInt(DMA_ChannelType* DMAChx, uint32_t DMAInt, FunctionalState Cmd)DMA Channel x interrupts enable. Before enabling a DMA channel, enabling transfer completion interrupt, half-transfer interrupt or transfer error interrupt will cause an interrupt when the corresponding event occurs.
name DMA_ConfigInt.
fun DMA Channel x interrupts enable. Before enabling a DMA channel,
enabling transfer completion interrupt, half-transfer interrupt
or transfer error interrupt will cause an interrupt when the
corresponding event occurs.
param DMAChx (The input parameters must be the following values):
- DMA1_CH1
- DMA1_CH2
- DMA1_CH3
- DMA1_CH4
- DMA1_CH5
- DMA1_CH6
- DMA1_CH7
- DMA1_CH8
- DMA2_CH1
- DMA2_CH2
- DMA2_CH3
- DMA2_CH4
- DMA2_CH5
- DMA2_CH6
- DMA2_CH7
- DMA2_CH8
param DMAInt (The input parameters must be the following values):
- DMA_INT_TXC
- DMA_INT_HTX
- DMA_INT_ERR
param Cmd (The input parameters must be the following values):
- ENABLE
- DISABLE
return none
void DMA_SetCurrDataCounter(DMA_ChannelType* DMAChx, uint16_t DataNumber)Set the current number of data transfers for DMA Channel x.
name DMA_SetCurrDataCounter.
fun Set the current number of data transfers for DMA Channel x.
param DMAChx (The input parameters must be the following values):
- DMA1_CH1
- DMA1_CH2
- DMA1_CH3
- DMA1_CH4
- DMA1_CH5
- DMA1_CH6
- DMA1_CH7
- DMA1_CH8
- DMA2_CH1
- DMA2_CH2
- DMA2_CH3
- DMA2_CH4
- DMA2_CH5
- DMA2_CH6
- DMA2_CH7
- DMA2_CH8
param DataNumber (The input parameters must be the following values):
- 1~0xFFFF
return none
note This function can only be used when the DMAChx is disabled.
uint16_t DMA_GetCurrDataCounter(DMA_ChannelType* DMAChx)Get the current number of remaining data for DMA Channel x.
name DMA_GetCurrDataCounter.
fun Get the current number of remaining data for DMA Channel x.
param DMAChx (The input parameters must be the following values):
- DMA1_CH1
- DMA1_CH2
- DMA1_CH3
- DMA1_CH4
- DMA1_CH5
- DMA1_CH6
- DMA1_CH7
- DMA1_CH8
- DMA2_CH1
- DMA2_CH2
- DMA2_CH3
- DMA2_CH4
- DMA2_CH5
- DMA2_CH6
- DMA2_CH7
- DMA2_CH8
return Returns the number of bytes remaining to be transferred.
FlagStatus DMA_GetFlagStatus(uint32_t DMAy_Flag, DMA_Module *DMAy)Get DMA Channel x flag status. Contains the global flag, transfer completion flag, half-transfer flag, and transfer error flag for the corresponding channel.
name DMA_GetFlagStatus.
fun Get DMA Channel x flag status. Contains the global flag, transfer
completion flag, half-transfer flag, and transfer error flag for
the corresponding channel.
param DMAFlag (The input parameters must be the following values):
- DMA_FLAG_GL1
- DMA_FLAG_TC1
- DMA_FLAG_HT1
- DMA_FLAG_TE1
- DMA_FLAG_GL2
- DMA_FLAG_TC2
- DMA_FLAG_HT2
- DMA_FLAG_TE2
- DMA_FLAG_GL3
- DMA_FLAG_TC3
- DMA_FLAG_HT3
- DMA_FLAG_TE3
- DMA_FLAG_GL4
- DMA_FLAG_TC4
- DMA_FLAG_HT4
- DMA_FLAG_TE4
- DMA_FLAG_GL5
- DMA_FLAG_TC5
- DMA_FLAG_HT5
- DMA_FLAG_TE5
- DMA_FLAG_GL6
- DMA_FLAG_TC6
- DMA_FLAG_HT6
- DMA_FLAG_TE6
- DMA_FLAG_GL7
- DMA_FLAG_TC7
- DMA_FLAG_HT7
- DMA_FLAG_TE7
- DMA_FLAG_GL8
- DMA_FLAG_TC8
- DMA_FLAG_HT8
- DMA_FLAG_TE8
param DMAy (The input parameters must be the following values):
- DMA1
- DMA2
return SET or RESET.
void DMA_ClearFlag(uint32_t DMAy_FLAG, DMA_Module *DMAy)Clear DMA Channel x flag status. Contains the global flag, transfer completion flag, half-transfer flag, and transfer error flag for the corresponding channel.
name DMA_ClearFlag.
fun Clear DMA Channel x flag status. Contains the global flag, transfer
completion flag, half-transfer flag, and transfer error flag for the
corresponding channel.
param DMAFlag (The input parameters must be the following values):
- DMA_FLAG_GL1
- DMA_FLAG_TC1
- DMA_FLAG_HT1
- DMA_FLAG_TE1
- DMA_FLAG_GL2
- DMA_FLAG_TC2
- DMA_FLAG_HT2
- DMA_FLAG_TE2
- DMA_FLAG_GL3
- DMA_FLAG_TC3
- DMA_FLAG_HT3
- DMA_FLAG_TE3
- DMA_FLAG_GL4
- DMA_FLAG_TC4
- DMA_FLAG_HT4
- DMA_FLAG_TE4
- DMA_FLAG_GL5
- DMA_FLAG_TC5
- DMA_FLAG_HT5
- DMA_FLAG_TE5
- DMA_FLAG_GL6
- DMA_FLAG_TC6
- DMA_FLAG_HT6
- DMA_FLAG_TE6
- DMA_FLAG_GL7
- DMA_FLAG_TC7
- DMA_FLAG_HT7
- DMA_FLAG_TE7
- DMA_FLAG_GL8
- DMA_FLAG_TC8
- DMA_FLAG_HT8
- DMA_FLAG_TE8
param DMAy (The input parameters must be the following values):
- DMA1
- DMA2
return none.
INTStatus DMA_GetIntStatus(uint32_t DMAy_Int, DMA_Module *DMAy)Get DMA Channel x interrupt status. Contains the global interrupt, transfer completion interrupt, half-transfer interrupt, and transfer error interrupt for the corresponding channel.
name DMA_GetIntStatus.
fun Get DMA Channel x interrupt status. Contains the global interrupt,
transfer completion interrupt, half-transfer interrupt, and transfer
error interrupt for the corresponding channel.
param DMAy_Int (The input parameters must be the following values):
- DMA_INT_GLB1
- DMA_INT_TXC1
- DMA_INT_HTX1
- DMA_INT_ERR1
- DMA_INT_GLB2
- DMA_INT_TXC2
- DMA_INT_HTX2
- DMA_INT_ERR2
- DMA_INT_GLB3
- DMA_INT_TXC3
- DMA_INT_HTX3
- DMA_INT_ERR3
- DMA_INT_GLB4
- DMA_INT_TXC4
- DMA_INT_HTX4
- DMA_INT_ERR4
- DMA_INT_GLB5
- DMA_INT_TXC5
- DMA_INT_HTX5
- DMA_INT_ERR5
- DMA_INT_GLB6
- DMA_INT_TXC6
- DMA_INT_HTX6
- DMA_INT_ERR6
- DMA_INT_GLB7
- DMA_INT_TXC7
- DMA_INT_HTX7
- DMA_INT_ERR7
- DMA_INT_GLB8
- DMA_INT_TXC8
- DMA_INT_HTX8
- DMA_INT_ERR8
param DMAy (The input parameters must be the following values):
- DMA1
- DMA2
return SET or RESET.
note Global interrupt status is the logic or generation of transfer completion
interrupt, half-transfer interrupt, transfer error interrupt.
void DMA_ClrIntPendingBit(uint32_t DMAy_Int, DMA_Module *DMAy)Clear DMA Channel x interrupt status bits. Contains the global interrupt, transfer completion interrupt, half-transfer interrupt, and transfer error interrupt for the corresponding channel.
name DMA_ClrIntPendingBit.
fun Clear DMA Channel x interrupt status bits. Contains the global interrupt,
transfer completion interrupt, half-transfer interrupt, and transfer
error interrupt for the corresponding channel.
param DMAy_Int (The input parameters must be the following values):
- DMA_INT_GLB1
- DMA_INT_TXC1
- DMA_INT_HTX1
- DMA_INT_ERR1
- DMA_INT_GLB2
- DMA_INT_TXC2
- DMA_INT_HTX2
- DMA_INT_ERR2
- DMA_INT_GLB3
- DMA_INT_TXC3
- DMA_INT_HTX3
- DMA_INT_ERR3
- DMA_INT_GLB4
- DMA_INT_TXC4
- DMA_INT_HTX4
- DMA_INT_ERR4
- DMA_INT_GLB5
- DMA_INT_TXC5
- DMA_INT_HTX5
- DMA_INT_ERR5
- DMA_INT_GLB6
- DMA_INT_TXC6
- DMA_INT_HTX6
- DMA_INT_ERR6
- DMA_INT_GLB7
- DMA_INT_TXC7
- DMA_INT_HTX7
- DMA_INT_ERR7
- DMA_INT_GLB8
- DMA_INT_TXC8
- DMA_INT_HTX8
- DMA_INT_ERR8
param DMAy (The input parameters must be the following values):
- DMA1
- DMA2
return none.
note Global interrupt state is the logic or generation of transfer completion
interrupt, half-transfer interrupt, transfer error interrupt. In fact,
after clearing the three interrupt states, the global interrupt state
will also be cleared.
void DMA_RequestRemap(uint32_t DMA_Remap, DMA_ChannelType* DMAChx, FunctionalState Cmd)Set DMA Channel x’s remap request. Channel request mapping is flexible, allowing users to map any DMA request to any DMA channel as needed. It is important to note that there can be only one DMA request per DMA channel at a time.
name DMA_RequestRemap.
fun Set DMA Channel x's remap request. Channel request mapping is flexible,
allowing users to map any DMA request to any DMA channel as needed. It
is important to note that there can be only one DMA request per DMA
channel at a time.
param DMA_Remap (The input parameters must be the following values):
- DMA_REMAP_ADC1
- DMA_REMAP_ADC2
- DMA_REMAP_ADC3
- DMA_REMAP_DSMU_FILT0
- DMA_REMAP_USART1_TX
- DMA_REMAP_USART1_RX
- DMA_REMAP_USART2_TX
- DMA_REMAP_USART2_RX
- DMA_REMAP_USART3_TX
- DMA_REMAP_USART3_RX
- DMA_REMAP_USART4_TX
- DMA_REMAP_USART4_RX
- DMA_REMAP_UART5_TX
- DMA_REMAP_UART5_RX
- DMA_REMAP_UART6_TX
- DMA_REMAP_UART6_RX
- DMA_REMAP_UART7_TX
- DMA_REMAP_UART7_RX
- DMA_REMAP_UART8_TX
- DMA_REMAP_UART8_RX
- DMA_REMAP_SPI1_TX
- DMA_REMAP_SPI1_RX
- DMA_REMAP_SPI2_I2S2_TX
- DMA_REMAP_SPI2_I2S2_RX
- DMA_REMAP_SPI3_I2S3_TX
- DMA_REMAP_SPI3_I2S3_RX
- DMA_REMAP_RES
- DMA_REMAP_DSMU_FILT1
- DMA_REMAP_SPI4_TX
- DMA_REMAP_SPI4_RX
- DMA_REMAP_SPI5_TX
- DMA_REMAP_SPI5_RX
- DMA_REMAP_SPI6_TX
- DMA_REMAP_SPI6_RX
- DMA_REMAP_XSPI_TX
- DMA_REMAP_XSPI_RX
- DMA_REMAP_I2C1_TX
- DMA_REMAP_I2C1_RX
- DMA_REMAP_I2C2_TX
- DMA_REMAP_I2C2_RX
- DMA_REMAP_I2C3_TX
- DMA_REMAP_I2C3_RX
- DMA_REMAP_I2C4_TX
- DMA_REMAP_I2C4_RX
- DMA_REMAP_SDIO
- DMA_REMAP_DAC1
- DMA_REMAP_DAC2
- DMA_REMAP_DSMU_FILT2
- DMA_REMAP_DSMU_FILT3
- DMA_REMAP_USART9_TX
- DMA_REMAP_USART9_RX
- DMA_REMAP_UART10_TX
- DMA_REMAP_UART10_RX
- DMA_REMAP_CORDIC_WR
- DMA_REMAP_CORDIC_RD
- DMA_REMAP_BTIM1_UP
- DMA_REMAP_BTIM2_UP
- DMA_REMAP_GTIM1_CH1
- DMA_REMAP_GTIM1_CH2
- DMA_REMAP_GTIM1_CH3
- DMA_REMAP_GTIM1_CH4
- DMA_REMAP_GTIM1_UP
- DMA_REMAP_GTIM1_TRIG
- DMA_REMAP_GTIM2_CH1
- DMA_REMAP_GTIM2_CH2
- DMA_REMAP_GTIM2_CH3
- DMA_REMAP_GTIM2_CH4
- DMA_REMAP_GTIM2_UP
- DMA_REMAP_GTIM2_TRIG
- DMA_REMAP_GTIM3_CH1
- DMA_REMAP_GTIM3_CH2
- DMA_REMAP_GTIM3_CH3
- DMA_REMAP_GTIM3_CH4
- DMA_REMAP_GTIM3_UP
- DMA_REMAP_GTIM3_TRIG
- DMA_REMAP_GTIM4_CH1
- DMA_REMAP_GTIM4_CH2
- DMA_REMAP_GTIM4_CH3
- DMA_REMAP_GTIM4_CH4
- DMA_REMAP_GTIM4_UP
- DMA_REMAP_GTIM4_TRIG
- DMA_REMAP_GTIM5_CH1
- DMA_REMAP_GTIM5_CH2
- DMA_REMAP_GTIM5_CH3
- DMA_REMAP_GTIM5_CH4
- DMA_REMAP_GTIM5_UP
- DMA_REMAP_GTIM5_TRIG
- DMA_REMAP_GTIM6_CH1
- DMA_REMAP_GTIM6_CH2
- DMA_REMAP_GTIM6_CH3
- DMA_REMAP_GTIM6_CH4
- DMA_REMAP_GTIM6_UP
- DMA_REMAP_GTIM6_TRIG
- DMA_REMAP_GTIM7_CH1
- DMA_REMAP_GTIM7_CH2
- DMA_REMAP_GTIM7_CH3
- DMA_REMAP_GTIM7_CH4
- DMA_REMAP_GTIM7_UP
- DMA_REMAP_GTIM7_TRIG
- DMA_REMAP_GTIM8_CH1
- DMA_REMAP_GTIM8_CH2
- DMA_REMAP_GTIM8_CH3
- DMA_REMAP_GTIM8_CH4
- DMA_REMAP_GTIM8_COM
- DMA_REMAP_GTIM8_UP
- DMA_REMAP_GTIM8_TRIG
- DMA_REMAP_GTIM9_CH1
- DMA_REMAP_GTIM9_CH2
- DMA_REMAP_GTIM9_CH3
- DMA_REMAP_GTIM9_CH4
- DMA_REMAP_GTIM9_COM
- DMA_REMAP_GTIM9_UP
- DMA_REMAP_GTIM9_TRIG
- DMA_REMAP_GTIM10_CH1
- DMA_REMAP_GTIM10_CH2
- DMA_REMAP_GTIM10_CH3
- DMA_REMAP_GTIM10_CH4
- DMA_REMAP_GTIM10_COM
- DMA_REMAP_GTIM10_UP
- DMA_REMAP_GTIM10_TRIG
- DMA_REMAP_ATIM1_CH1
- DMA_REMAP_ATIM1_CH2
- DMA_REMAP_ATIM1_CH3
- DMA_REMAP_ATIM1_CH4
- DMA_REMAP_ATIM1_COM
- DMA_REMAP_ATIM1_UP
- DMA_REMAP_ATIM1_TRIG
- DMA_REMAP_ATIM2_CH1
- DMA_REMAP_ATIM2_CH2
- DMA_REMAP_ATIM2_CH3
- DMA_REMAP_ATIM2_CH4
- DMA_REMAP_ATIM2_COM
- DMA_REMAP_ATIM2_UP
- DMA_REMAP_ATIM2_TRIG
- DMA_REMAP_ATIM3_CH1
- DMA_REMAP_ATIM3_CH2
- DMA_REMAP_ATIM3_CH3
- DMA_REMAP_ATIM3_CH4
- DMA_REMAP_ATIM3_COM
- DMA_REMAP_ATIM3_UP
- DMA_REMAP_ATIM3_TRIG
param DMAChx (The input parameters must be the following values):
- DMA1_CH1
- DMA1_CH2
- DMA1_CH3
- DMA1_CH4
- DMA1_CH5
- DMA1_CH6
- DMA1_CH7
- DMA1_CH8
- DMA2_CH1
- DMA2_CH2
- DMA2_CH3
- DMA2_CH4
- DMA2_CH5
- DMA2_CH6
- DMA2_CH7
- DMA2_CH8
param Cmd (The input parameters must be the following values):
- ENABLE
- DISABLE
return none.
5.7.3 Demo descriptions
This section describes the 2 DMA examples: BURST moves a constant array from memory to memory in burst mode, and FLASH_RAM performs the same memory-to-memory transfer in normal mode.
5.7.3.1 BURST burst memory-to-memory transfer
Example directory: projects/n32h49x_EVAL/examples/DMA/BURST/
Initialize the log and DMA1 clock→Configure DMA1_CH1 for a memory-to-memory burst transfer→Configure the reserved request mapping and enable the transfer complete interrupt→Enable the channel and wait for the interrupt to set the completion flag→Compare the source and destination buffers and print the result
| Item | Source analysis |
|---|---|
| Function | Uses DMA1_CH1 to move the constant array SRC_Const_Buffer into DST_Buffer in memory-to-memory mode with burst transfer enabled (almost mode, length 8);when the transfer completes the interrupt sets a flag, and main compares the two buffers and prints pass or fail. |
| Source files | src/main.c: main, RCC_Configuration, NVIC_Configuration, DMA_IRQ_HANDLER;inc/main.h: defines DMA_USED (DMA1), DMA_CHANNEL_USED (DMA1_CH1), BUFFER_SIZE and other macros;readme.txt: function, environment and usage notes;MDK-ARM/, EWARM/: Keil and IAR projects. |
| Key configuration | Clock: RCC_EnableAHBPeriphClk(RCC_AHB_PERIPHEN_DMA1, ENABLE);Channel: DMA1_CH1 with Direction set to DMA_DIR_PERIPH_SRC, Mem2Mem enabled, WORD width and both PeriphInc and MemoryInc enabled;Burst: BurstCmd enabled, BurstMode set to DMA_BURST_MODE_ALMOST and BurstLen set to DMA_BURST_LEN_8;Interrupt: DMA_INT_TXC1. |
| Program and data path | main first enables the DMA1 clock with RCC_Configuration and the channel interrupt with NVIC_Configuration;after clearing DST_Buffer it calls DMA_DeInit and DMA_StructInit, fills DMA_InitStructure and writes DMA1_CH1 with DMA_Init;DMA_RequestRemap configures the reserved request mapping, DMA_ConfigInt enables the transfer complete interrupt and DMA_EnableChannel starts the transfer;main waits for TransferCompleteFlag and then compares the buffers with memcmp and prints the conclusion. |
| Main APIs | DMA_DeInit, DMA_StructInit, DMA_Init, DMA_RequestRemap, DMA_ConfigInt, DMA_EnableChannel |
| Verification | The UART prints “DMA Burst transfer passed” when the source and destination buffers match; otherwise it prints “DMA Burst transfer failed”. |
| Use note | A memory-to-memory transfer must configure the reserved request mapping number DMA_REMAP_RES;TransferCompleteFlag is set in the interrupt service routine and the main loop uses it to detect the end of the transfer;the burst length is 8 and the burst mode is almost, which should be adjusted to the target channel when porting. |
Core-code walkthrough and porting
The example uses DMA1_CH1 to move a constant array from memory to memory in burst mode, then sets a flag from the interrupt and compares the buffer contents.
Data path: RCC_Configuration enables the DMA1 clock → NVIC_Configuration enables the channel interrupt → DMA_StructInit and DMA_Init configure the DMA1_CH1 burst transfer → DMA_RequestRemap configures the reserved request mapping and DMA_ConfigInt enables the transfer complete interrupt → DMA_EnableChannel starts the transfer and the interrupt sets TransferCompleteFlag → memcmp compares the buffers
1. Initialize the channel and fill the structure. main first resets the channel and fills the structure with defaults, sets the peripheral address, memory address, direction and burst parameters, and finally writes DMA1_CH1.
DMA_DeInit(DMA_CHANNEL_USED);
DMA_StructInit(&DMA_InitStructure);
DMA_InitStructure.PeriphAddr = (uint32_t)SRC_Const_Buffer;
DMA_InitStructure.MemAddr = (uint32_t)DST_Buffer;
DMA_InitStructure.Direction = DMA_DIR_PERIPH_SRC;
DMA_InitStructure.BufSize = BUFFER_SIZE;
DMA_InitStructure.PeriphInc = DMA_PERIPH_INC_ENABLE;
DMA_InitStructure.MemoryInc = DMA_MEM_INC_ENABLE;
DMA_InitStructure.PeriphDataSize = DMA_PERIPH_DATA_WIDTH_WORD;
DMA_InitStructure.MemDataSize = DMA_MEM_DATA_WIDTH_WORD;
DMA_InitStructure.CircularMode = DMA_MODE_NORMAL;
DMA_InitStructure.Priority = DMA_PRIORITY_HIGH;
DMA_InitStructure.Mem2Mem = DMA_M2M_ENABLE;
/* DMA BURST enable */
DMA_InitStructure.BurstCmd = DMA_BURST_ENABLE;
/* BURST mode is almost */
DMA_InitStructure.BurstMode = DMA_BURST_MODE_ALMOST;
/* BURST length */
DMA_InitStructure.BurstLen = DMA_BURST_LEN_8;
DMA_Init(DMA_CHANNEL_USED, &DMA_InitStructure);
A memory-to-memory transfer uses DMA_M2M_ENABLE with DMA_DIR_PERIPH_SRC, placing the source array on the peripheral address side, and enables increment on both sides.
2. Configure the reserved request mapping and enable the interrupt. Memory-to-memory mode needs the reserved request mapping number DMA_REMAP_RES; the transfer complete interrupt is then enabled and the channel started.
/* When operating in memory-to-memory mode, a reserved channel
request mapping number must be configured */
DMA_RequestRemap(DMA_REMAP_RES, DMA_CHANNEL_USED, ENABLE);
/* Enable DMA x Channel y Transfer Complete interrupt */
DMA_ConfigInt(DMA_CHANNEL_USED, DMA_IT_FLAG_TC, ENABLE);
/* Enable DMA x Channel y transfer */
DMA_EnableChannel(DMA_CHANNEL_USED, ENABLE);
The interrupt is enabled before the channel so that the first transfer completion is captured; DMA_IT_FLAG_TC is defined as DMA_INT_TXC1 in this example.
3. Wait for completion and compare the buffers. The main loop polls TransferCompleteFlag, and after the interrupt sets it the source and destination buffers are compared with memcmp.
/* Wait the end of transmission */
while (TransferCompleteFlag == 0)
{
}
/* Check if the transmitted and received data are equal */
if (memcmp(SRC_Const_Buffer, DST_Buffer, BUFFER_SIZE) == 0)
{
log_info("DMA Burst transfer passed\n");
}
else
{
log_error("DMA Burst transfer failed\n");
}
TransferCompleteFlag is declared __IO so the polling read is not optimized away, and the comparison length uses BUFFER_SIZE to match the actual transfer size.
4. Set the completion flag in the interrupt service routine. DMA_IRQ_HANDLER checks the transfer complete interrupt status, clears the pending bit and sets TransferCompleteFlag.
void DMA_IRQ_HANDLER(void)
{
/* Test on DMA channel Transfer Complete interrupt */
if (DMA_GetIntStatus(DMA_IT_FLAG_TC, DMA_USED))
{
/* Clear DMA channel Transfer Complete interrupt pending bits */
DMA_ClrIntPendingBit(DMA_IT_FLAG_TC, DMA_USED);
/* Set DMA transfer completion flag */
TransferCompleteFlag = 1;
}
}
The interrupt must test the status before clearing the pending bit of the channel; DMA_IRQ_HANDLER and DMA_USED are mapped to the real channel by macros in main.h.
Corresponding source files: src/main.c
5.7.3.2 FLASH_RAM normal memory-to-memory transfer
Example directory: projects/n32h49x_EVAL/examples/DMA/FLASH_RAM/
Initialize the log and DMA2 clock→Configure DMA2_CH8 for a normal memory-to-memory transfer→Configure the reserved request mapping and enable the transfer complete interrupt→Enable the channel and wait for the interrupt to set the completion flag→Compare the source and destination buffers and print the result
| Item | Source analysis |
|---|---|
| Function | Uses DMA2_CH8 to move the constant array SRC_Const_Buffer into DST_Buffer in memory-to-memory mode without burst transfer;when the transfer completes the interrupt sets a flag, and main compares the two buffers and prints pass or fail. |
| Source files | src/main.c: main, RCC_Configuration, NVIC_Configuration, DMA_IRQ_HANDLER;inc/main.h: defines DMA_USED (DMA2), DMA_CHANNEL_USED (DMA2_CH8), BUFFER_SIZE and other macros;readme.txt: function, environment and usage notes;MDK-ARM/, EWARM/: Keil and IAR projects. |
| Key configuration | Clock: RCC_EnableAHBPeriphClk(RCC_AHB_PERIPHEN_DMA2, ENABLE);Channel: DMA2_CH8 with Direction set to DMA_DIR_PERIPH_SRC, Mem2Mem enabled, WORD width and both PeriphInc and MemoryInc enabled;Interrupt: DMA_INT_TXC, normal mode without burst. |
| Program and data path | main enables the DMA2 clock and configures the DMA2_Channel8 interrupt;after clearing DST_Buffer it calls DMA_DeInit and DMA_StructInit, fills a normal-mode structure and writes DMA2_CH8 with DMA_Init;DMA_RequestRemap configures the reserved request mapping, DMA_ConfigInt enables the transfer complete interrupt and DMA_EnableChannel starts the transfer;it waits for TransferCompleteFlag and then compares the buffers with memcmp and prints the conclusion. |
| Main APIs | DMA_DeInit, DMA_StructInit, DMA_Init, DMA_RequestRemap, DMA_ConfigInt, DMA_EnableChannel |
| Verification | The UART prints “DMA Flash to RAM passed” when the source and destination buffers match; otherwise it prints “DMA Flash to RAM failed”. |
| Use note | Unlike the BURST example, burst is not enabled and the rest of the flow is the same; a memory-to-memory transfer also needs the reserved request mapping DMA_REMAP_RES;the channel and interrupt numbers come from the macros in main.h, which should be changed to the target channel when porting. |
Core-code walkthrough and porting
The example uses DMA2_CH8 to move a constant array from memory to memory in normal mode, then sets a flag from the interrupt and compares the buffer contents.
Data path: RCC_Configuration enables the DMA2 clock → NVIC_Configuration enables the DMA2_Channel8 interrupt → DMA_StructInit and DMA_Init configure the DMA2_CH8 normal transfer → DMA_RequestRemap configures the reserved request mapping and DMA_ConfigInt enables the transfer complete interrupt → DMA_EnableChannel starts the transfer and the interrupt sets TransferCompleteFlag → memcmp compares the buffers
1. Configure the channel transfer parameters. main configures DMA2_CH8 with the same fields as the BURST example, but does not set any burst parameter, keeping the default non-burst mode.
/* DMA x channel y configuration */
DMA_DeInit(DMA_CHANNEL_USED);
DMA_StructInit(&DMA_InitStructure);
DMA_InitStructure.PeriphAddr = (uint32_t)SRC_Const_Buffer;
DMA_InitStructure.MemAddr = (uint32_t)DST_Buffer;
DMA_InitStructure.Direction = DMA_DIR_PERIPH_SRC;
DMA_InitStructure.BufSize = BUFFER_SIZE;
DMA_InitStructure.PeriphInc = DMA_PERIPH_INC_ENABLE;
DMA_InitStructure.MemoryInc = DMA_MEM_INC_ENABLE;
DMA_InitStructure.PeriphDataSize = DMA_PERIPH_DATA_WIDTH_WORD;
DMA_InitStructure.MemDataSize = DMA_MEM_DATA_WIDTH_WORD;
DMA_InitStructure.CircularMode = DMA_MODE_NORMAL;
DMA_InitStructure.Priority = DMA_PRIORITY_HIGH;
DMA_InitStructure.Mem2Mem = DMA_M2M_ENABLE;
DMA_Init(DMA_CHANNEL_USED, &DMA_InitStructure);
DMA_StructInit first sets the burst function to its default disabled state, so no burst field needs to be written here.
2. Configure the request mapping, interrupt and start. As in the BURST example, the reserved mapping DMA_REMAP_RES is configured first, then the transfer complete interrupt is enabled and the channel started.
/* When operating in memory-to-memory mode, a reserved channel
request mapping number must be configured */
DMA_RequestRemap(DMA_REMAP_RES, DMA_CHANNEL_USED, ENABLE);
/* Enable DMA x Channel y Transfer Complete interrupt */
DMA_ConfigInt(DMA_CHANNEL_USED, DMA_INT_TXC, ENABLE);
/* Enable DMA x Channel y transfer */
DMA_EnableChannel(DMA_CHANNEL_USED, ENABLE);
Here the channel-independent interrupt selector macro DMA_INT_TXC is used directly, and the channel written by DMA_Init determines the actual channel.
3. Wait for completion and compare the buffers. The main loop polls TransferCompleteFlag, and after the interrupt sets it the source and destination buffers are compared with memcmp.
/* Wait the end of transmission */
while (TransferCompleteFlag == 0)
{
}
/* Check if the transmitted and received data are equal */
if (memcmp(SRC_Const_Buffer, DST_Buffer, BUFFER_SIZE) == 0)
{
log_info("DMA Flash to RAM passed\n");
}
else
{
log_error("DMA Flash to RAM failed\n");
}
The comparison length is again BUFFER_SIZE, matching BufSize in the structure, so that the whole transfer is verified.
4. Set the completion flag in the interrupt service routine. DMA_IRQ_HANDLER checks the transfer complete interrupt status, clears the pending bit and sets TransferCompleteFlag.
void DMA_IRQ_HANDLER(void)
{
/* Test on DMA channel Transfer Complete interrupt */
if (DMA_GetIntStatus(DMA_IT_FLAG_TC, DMA_USED))
{
/* Clear DMA channel Transfer Complete interrupt pending bits */
DMA_ClrIntPendingBit(DMA_IT_FLAG_TC, DMA_USED);
/* Set DMA transfer completion flag */
TransferCompleteFlag = 1;
}
}
This function is identical to the BURST example; the channel number likewise comes from the macros in main.h and should be changed together with the channel when porting.
Corresponding source files: src/main.c
5.7.4 Notes and troubleshooting
| Scenario | Check & action | Source |
|---|---|---|
| FLASH programming | Using DMA to program FLASH is not recommended, to avoid timing errors. | User manual |
| FLASH read | When using DMA to read FLASH, DCache must be disabled and re-enabled after the read completes. | User manual |
| Unique request source | Different channels must not use the same request source, otherwise when several channels are enabled only the higher-priority channel is triggered. | User manual |
| Memory-to-memory mapping | In memory-to-memory mode the DMA request mapping must be set to the reserved value. | User manual |
| Register write condition | The address and data-count registers can only be written while the channel is disabled, and DMA_TXNUMx becomes read-only once the channel is enabled. |
User manual |
| Configuration order | The channel registers must be configured before the channel is enabled, otherwise a permission error event may occur; follow the flow given in the user manual. |
User manual |
| Clear interrupts before enabling | When software provides the interrupt service, clear all interrupts of the channel before enabling it. | User manual |
| Disabling circular mode | To disable circular mode, write 0 to CHEN first to disable the channel, then write 0 to CIRC, because other bits cannot be modified while CHEN is 1. |
User manual |
| Address alignment | PSIZE and MSIZE determine the address increment step and the ignored low bits, for example 16-bit ignores bit 0 and 32-bit ignores bits 0 and 1. |
User manual |
| Transfer count | The transfer count ranges from 0 to 65535; when this register is 0, no data transfer occurs whether the channel is enabled or not. |
User manual |
| Transfer error | Access to a reserved address region causes a transfer error, and hardware automatically clears the channel enable bit and stops the channel. | User manual |