5.4 DMA Guide

This chapter describes the file layout and the 12 public functions of the DMA driver in the N32G033 standard peripheral library, together with the single example (FLASH_RAM). Read the “DMA” chapter of the user manual for request remapping, transfer direction, and memory-to-memory mode, and the errata sheet for known chip issues.

5.4.1 Related files

Relative path Purpose
firmware/n32g033_std_periph_driver/inc/n32g033_dma.h Defines the DMA_InitType structure and the macros for transfer direction, address increment, data width, priority, and request remapping, and declares 12 public functions in one contiguous block
firmware/n32g033_std_periph_driver/src/n32g033_dma.c Implements those 12 functions: channel reset and initialization, enable and transfer counting, interrupt and flag handling, and request remapping
projects/n32g033_EVAL/examples/DMA/ DMA example root directory, with 1 example: FLASH_RAM
projects/n32g033_EVAL/examples/DMA/FLASH_RAM/ Project layout of this example: MDK-ARM/, EWARM/, inc/, src/, and readme.txt
projects/n32g033_EVAL/bsp/ Board support files shared by the examples: the serial log interface in log.h

5.4.2 API reference

Search API12 functions

The following 12 public functions are listed in the declaration order of n32g033_dma.h in 1 group; each entry gives a summary and the original comment above the function in n32g033_dma.c.

Reset, initialization, and transfer control

DMA_DeInit, DMA_Init, DMA_StructInit, DMA_EnableChannel, DMA_ConfigInt, DMA_SetCurrDataCounter, DMA_GetCurrDataCounter, DMA_GetFlagStatus, DMA_ClearFlag, DMA_GetIntStatus, DMA_ClrIntPendingBit, DMA_RequestRemap

void DMA_DeInit(DMA_ChannelType* DMAChx)Reset CHCFG, TXNUM, PADDR, MADDR, INTCLR registers of DMA Channel x to their default reset values.
Source comment
name    DMA_DeInit.
fun     Reset CHCFG, TXNUM, PADDR, MADDR, INTCLR registers of DMA Channel x
        to their default reset values.
param   DMAChx (The input parameters must be the following values):
          - DMA_CH1
          - DMA_CH2
          - DMA_CH3
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.
Source comment
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):
          - DMA_CH1
          - DMA_CH2
          - DMA_CH3
param   DMA_InitParam (The input parameters must be the following values):
          - PeriphAddr
            -0x00000000~0xFFFFFFFF
          - MemAddr
            -0x00000000~0xFFFFFFFF
          - Direction
            - DMA_DIR_PERIPH_DST
            - DMA_DIR_PERIPH_SRC
          - BufSize
            -0x0000~0xFFFF
          - PeriphInc
            - DMA_PERIPH_INC_ENABLE
            - DMA_PERIPH_INC_DISABLE
          - DMA_MemoryInc
            - DMA_MEM_INC_ENABLE
            - DMA_MEM_INC_DISABLE
          - PeriphDataSize
            - DMA_PERIPH_DATA_SIZE_BYTE
            - DMA_PERIPH_DATA_SIZE_HALFWORD
            - DMA_PERIPH_DATA_SIZE_WORD
          - MemDataSize
            - DMA_MemoryDataSize_Byte
            - DMA_MemoryDataSize_HalfWord
            - DMA_MemoryDataSize_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
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.
Source comment
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.
Source comment
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):
          - DMA_CH1
          - DMA_CH2
          - DMA_CH3
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.
Source comment
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):
          - DMA_CH1
          - DMA_CH2
          - DMA_CH3
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.
Source comment
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):
          - DMA_CH1
          - DMA_CH2
          - DMA_CH3
param   DataNumber(The input parameters must be the following values) :
          - 0~0xFFFF
return  none
note    This function can only be used when the DMAChx is disabled.
uint16_t DMA_GetCurrDataCounter(const DMA_ChannelType* DMAChx)Get the current number of remaining data for DMA Channel x.
Source comment
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):
          - DMA_CH1
          - DMA_CH2
          - DMA_CH3
return  Returns the number of bytes remaining to be transferred.
FlagStatus DMA_GetFlagStatus(uint32_t DMAFlag, const 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.
Source comment
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
param   DMAy (The input parameters must be the following values):
          - DMA
return  SET or RESET.
void DMA_ClearFlag(uint32_t DMAFlag, 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.
Source comment
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
param   DMAy (The input parameters must be the following values):
          - DMA
return  none.
INTStatus DMA_GetIntStatus(uint32_t DMA_IT, const 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.
Source comment
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   DMA_IT (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
param   DMAy (The input parameters must be the following values):
          - DMA
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 DMA_IT, 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.
Source comment
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   DMA_IT (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
param   DMAy (The input parameters must be the following values):
          - DMA
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, const DMA_Module* DMAy, 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.
Source comment
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_UART1_TX
          - DMA_REMAP_UART1_RX
          - DMA_REMAP_UART2_TX
          - DMA_REMAP_UART2_RX
          - DMA_REMAP_UART3_TX
          - DMA_REMAP_UART3_RX
          - DMA_REMAP_SPI1_TX
          - DMA_REMAP_SPI1_RX
          - DMA_REMAP_SPI2_TX
          - DMA_REMAP_SPI2_RX
          - DMA_REMAP_I2C1_TX
          - DMA_REMAP_I2C1_RX
          - DMA_REMAP_I2C2_TX
          - DMA_REMAP_I2C2_RX
          - DMA_REMAP_TIM1_CH1
          - DMA_REMAP_TIM1_CH2
          - DMA_REMAP_TIM1_CH3
          - DMA_REMAP_TIM1_CH4
          - DMA_REMAP_TIM1_COM
          - DMA_REMAP_TIM1_UP
          - DMA_REMAP_TIM1_TRIG
          - DMA_REMAP_TIM3_CH1
          - DMA_REMAP_TIM3_CH2
          - DMA_REMAP_TIM3_CH3
          - DMA_REMAP_TIM3_CH4
          - DMA_REMAP_TIM3_UP
          - DMA_REMAP_TIM3_TRIG
          - DMA_REMAP_TIM4_CH1
          - DMA_REMAP_TIM4_CH2
          - DMA_REMAP_TIM4_CH3
          - DMA_REMAP_TIM4_UP
          - DMA_REMAP_TIM4_TRIG
          - DMA_REMAP_TIM6_UP
          - DMA_REMAP_RESERVED
param   DMAy (The input parameters must be the following values):
          - DMA
param   DMAChx (The input parameters must be the following values):
          - DMA_CH1
          - DMA_CH2
          - DMA_CH3
param  Cmd:(The input parameters must be the following values)
            - ENABLE
            - DISABLE
return  none.

5.4.3 Demo descriptions

This section describes the single DMA example: FLASH_RAM moves a constant array from FLASH into RAM in memory-to-memory mode and checks the result.

5.4.3.1 FLASH_RAM Memory-to-memory transfer

Example directory: projects/n32g033_EVAL/examples/DMA/FLASH_RAM/

Enable the DMA clock and the channel interrupt→Configure the source address, destination address, and transfer length→Start the memory-to-memory transfer→The transfer-complete interrupt reads the remaining count and clears the flag→Print the verification result over the serial port

Item Source analysis
Function Moves the FLASH constant array SRC_Const_Buffer into the RAM array DST_Buffer with DMA in memory-to-memory mode, then compares the two with memcmp and prints the result over the serial port.
Source files src/main.c holds main, RCC_Configuration, and NVIC_Configuration;
DMA_IRQ_HANDLER in src/n32g033_it.c reads the remaining count and clears the interrupt flag;
inc/main.h and inc/n32g033_it.h give the declarations;
readme.txt gives the test steps;
the project files are in MDK-ARM/ and EWARM/.
Key configuration Channel: DMA_CH1;
source is the FLASH constant array SRC_Const_Buffer and destination is the RAM array DST_Buffer;
transfer direction DMA_DIR_PERIPH_SRC, memory-to-memory enabled, word data width;
both addresses increment, normal mode, high priority;
transfer-complete interrupt enabled, the request source remapped to the reserved item.
Program and data path main -> RCC_Configuration enables the DMA clock on the AHB bus -> NVIC_Configuration enables the DMA interrupt -> DMA_DeInit, DMA_StructInit, and DMA_Init configure the channel -> DMA_RequestRemap maps the reserved request -> DMA_ConfigInt enables the transfer-complete interrupt -> DMA_EnableChannel starts the transfer -> wait for the remaining count to reach zero -> memcmp verifies the data and the result is printed.
Main APIs DMA_DeInit, DMA_StructInit, DMA_Init, DMA_RequestRemap, DMA_ConfigInt, DMA_GetCurrDataCounter, DMA_EnableChannel, DMA_GetIntStatus, DMA_ClrIntPendingBit
Verification The hardware is the N32G033K8Q7-1_STB V1.0 evaluation board, with UART TX on PA9 and RX on PA10 at 115200 baud;
after downloading, resetting, and running, the serial port prints DMA Flash to RAM passed, which means the transfer and the check succeeded.
Use note The system clock is 64 MHz;
memory-to-memory mode uses no peripheral request, so the example remaps the request source to the reserved item, otherwise the request would land on UART1_TX.
Core-code walkthrough and porting

The example moves data between FLASH and RAM in DMA memory-to-memory mode and checks that both sides match afterwards.

Data path: RCC_Configuration enables the DMA clock → NVIC_Configuration enables the DMA interrupt → DMA_Init sets the source address, destination address, and transfer length → DMA_EnableChannel starts the transfer → the transfer-complete interrupt reads the remaining count and clears the flag → memcmp verifies the data

1. Enable the clock and the interrupt together. DMA sits on the AHB bus, so its clock must be enabled first and the channel interrupt routed into the NVIC, otherwise the transfer-complete event never reaches the handler.

src/main.csrc/main.c · RCC_Configuration
void RCC_Configuration(void)
{
    /* Enable DMA clock */
    RCC_EnableAHBPeriphClk(RCC_AHB_PERIPH_DMA, ENABLE);
}
src/main.csrc/main.c · NVIC_Configuration
    NVIC_InitType NVIC_InitStructure;

    /* Enable DMA IRQ Channel */
    NVIC_InitStructure.NVIC_IRQChannel                   = DMA_IRQN;
    NVIC_InitStructure.NVIC_IRQChannelPriority           = 0;
    NVIC_InitStructure.NVIC_IRQChannelCmd                = ENABLE;
    NVIC_Init(&NVIC_InitStructure);

Change the interrupt number when you use another DMA channel; the DMA clock bit is on the AHB bus rather than the APB bus, so the wrong bus keeps the channel from working.

2. Give the addresses and transfer parameters in one structure. After DMA_StructInit fills the defaults, the structure sets the source and destination addresses, the transfer direction, the data width, and the memory-to-memory mode.

src/main.csrc/main.c · main
    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.DMA_MemoryInc  = DMA_MEM_INC_ENABLE;
    DMA_InitStructure.PeriphDataSize = DMA_PERIPH_DATA_SIZE_WORD;
    DMA_InitStructure.MemDataSize    = DMA_MemoryDataSize_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);

Direction set to DMA_DIR_PERIPH_SRC treats PeriphAddr as the data source; in memory-to-memory mode both addresses may increment.

3. Remap the request and read the initial value before starting. Memory-to-memory mode recommends remapping the request source to the reserved item, after which the transfer-complete interrupt is enabled and the start count is read before the channel is enabled.

src/main.csrc/main.c · main
    /* In memory-to-memory mode, it is recommended to set an reserved
    peripheral request source in the system, otherwise the request
    will be mapped to the UART1_TX. */
    DMA_RequestRemap(DMA_REMAP_RESERVED, DMA, DMA_CHANNEL_USED, ENABLE);

    /* Enable DMA Channel Transfer Complete interrupt */
    DMA_ConfigInt(DMA_CHANNEL_USED, DMA_INT_TXC, ENABLE);

    /* Get Current Data Counter value before transfer begins */
    CurrDataCounterBegin = DMA_GetCurrDataCounter(DMA_CHANNEL_USED);

    /* Enable DMA Channel transfer */
    DMA_EnableChannel(DMA_CHANNEL_USED, ENABLE);

    /* Wait the end of transmission */
    while (CurrDataCounterEnd != 0)
    {
    }

The while loop that waits for the remaining count to reach zero is how the example synchronizes; in real code a flag or interrupt is a more robust way to detect the end.

4. The handler reads back the remaining count and clears the flag, the main flow checks the data. DMA_IRQ_HANDLER reads the remaining data count and clears the global interrupt flag on transfer completion, and the main flow then compares source and destination with memcmp.

src/n32g033_it.csrc/n32g033_it.c · DMA_IRQ_HANDLER
void DMA_IRQ_HANDLER(void)
{
    /* Test on DMA channel Transfer Complete interrupt */
    if (DMA_GetIntStatus(DMA_IT_FLAG_TC, DMA))
    {
        /* Get Current Data Counter value after complete transfer */
        CurrDataCounterEnd = DMA_GetCurrDataCounter(DMA_CHANNEL_USED);
        /* Clear DMA channel Half Transfer, Transfer Complete and Global interrupt pending bits */
        DMA_ClrIntPendingBit(DMA_IT_FLAG_GL, DMA);
    }
}
src/main.csrc/main.c · main
    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 comment above DMA_IRQ_HANDLER keeps the name SysTick_Handler, which differs from the actual function name; read the function definition as authoritative.

Corresponding source files: src/main.c, src/n32g033_it.c, firmware/n32g033_std_periph_driver/inc/n32g033_dma.h

5.4.4 Notes and troubleshooting

Scenario Check & action Source
Memory-to-memory mode The DMA chapter of the user manual states that this mode uses no peripheral request and needs the request source remapped;
map the request source to the reserved item as the manual describes, so the request does not land on UART1_TX.
User manual
Number of data items The DMA chapter of the user manual states that the transfer count must be set before the channel is enabled and that DMA_SetCurrDataCounter may only be called while the channel is off;
disable the channel before changing the transfer length.
User manual
Interrupt and flag clearing The DMA chapter of the user manual states that the global interrupt status is the logical OR of transfer complete, half transfer, and transfer error;
clearing the three interrupt states also clears the global interrupt state.
User manual
Peripheral clock bus The DMA chapter of the user manual states that DMA uses the AHB clock;
confirm the AHB peripheral bit is the one selected when enabling the clock.
User manual

Errata sheet V1.0.0 (2025.9.25) covers revision A silicon and lists no DMA entries.

Nations Technologies DevKit Docs

Datasheets, SDK, driver APIs and demo guides for Nations Technologies MCU development kits, organized by chip series.

© 2026 Nations Technologies Inc. All rights reserved.粤ICP备11069485号This site uses cookie-free anonymous analytics.