DMA

DMA has 2 instances, one in HCPU and one in LCPU, both supporting memory-to-memory, memory-to-peripheral, peripheral-to-memory, and peripheral-to-peripheral transfers.

Main Features

  • 8 independent configurable channels

  • Each channel’s DMA request can select 1 from 16 hardware requests, or be triggered by software

  • Each channel supports 4 priority levels, with same priority resolved by channel number

  • Supports memory-to-memory, memory-to-peripheral, peripheral-to-memory, peripheral-to-peripheral transfers

  • Source and destination addresses independently support single byte/double byte/4-byte access, and both can independently select whether address auto-increment

  • Supports circular buffer mode, automatically restarts after single transfer completion

  • Each channel supports 3 event flags - transfer complete, half transfer, transfer error, each can independently generate interrupt requests

  • Single configuration maximum transfer unit count is 65536, each unit is single byte/double byte/4-byte transfer according to different configurations

DMAC Corresponding Peripheral Request ID

req_sel

DMAC1

DMAC2

0

mpi1

usart4_tx

1

mpi2

usart4_rx

2

/

usart5_tx

3

i2c4

usart5_rx

4

usart1_tx

/

5

usart1_rx

/

6

usart2_tx

btim3

7

usart2_rx

btim4

8

gptim1_update

/

9

gptim1_trigger

/

10

gptim1_cc1

/

11

gptim1_cc2

/

12

gptim1_cc3

/

13

gptim1_cc4

/

14

btim1

/

15

btim2

/

16

atim1_update

/

17

atim1_trigger

/

18

atim1_cc1

/

19

atim1_cc2

/

20

atim1_cc3

/

21

atim1_cc4

/

22

i2c1

/

23

i2c2

/

24

i2c3

/

25

atim1_com

/

26

usart3_tx

/

27

usart3_rx

/

28

spi1_tx

/

29

spi1_rx

/

30

spi2_tx

/

31

spi2_rx

/

32

i2s1_tx

/

33

i2s1_rx

/

34

/

/

35

/

/

36

pdm1_rx_l

/

37

pdm1_rx_r

/

38

gpadc

/

39

adc0

/

40

adc1

/

41

dac0

/

42

dac1

/

43

gptim2_update

/

44

gptim2_trigger

/

45

gptim2_cc1

/

46

audprc_tx_out_ch1

/

47

audprc_tx_out_ch0

/

48

audprc_tx_ch3

/

49

audprc_tx_ch2

/

50

audprc_tx_ch1

/

51

audprc_tx_ch0

/

52

audprc_rx_ch1

/

53

audprc_rx_ch0

/

54

gptim2_cc2

/

55

gptim2_cc3

/

56

gptim2_cc4

/

57

sdmmc1

/

58

/

/

59

/

/

60

/

/

61

/

/

62

/

/

63

/

/

DMA Example 1

Memory-to-memory 4-byte transfer 4096 bytes.


    DMA_HandleTypeDef hdma;
    HAL_StatusTypeDef err;

    uint32_t SrcAddress = 0x10000000;
    uint32_t DstAddress = 0x20000000;
    uint32_t Counts     = 1024;  //Transfer unit is word, so Counts= 4096 / 4
    
    /* Init DMA configure*/
    hdma.Instance                 = DMA1_Channel6;
    hdma.Init.Request             = 0;                     //Request id is useless while memory to memory, just set to 0
    hdma.Init.Direction           = DMA_MEMORY_TO_MEMORY;
    hdma.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
    hdma.Init.MemDataAlignment    = DMA_MDATAALIGN_WORD;
    hdma.Init.PeriphInc           = DMA_PINC_ENABLE;
    hdma.Init.MemInc              = DMA_MINC_ENABLE;
    hdma.Init.Mode                = DMA_NORMAL;
    hdma.Init.Priority            = DMA_PRIORITY_MEDIUM;

    hdma.XferHalfCpltCallback = DMA_Xfer_Half_Callback_Func;
    hdma.XferCpltCallback     = DMA_Xfer_Complete_Callback_Func;
    hdma.XferErrorCallback    = DMA_Xfer_Error_Callback_Func;

    err = HAL_DMA_Init(&hdma);
    if (err != HAL_OK)
        return err;

    err = HAL_DMA_Start_IT(hadc->DMA_Handle, SrcAddress, DstAddress, Counts);
    if (err != HAL_OK)
        return err;

DMA Example 2

ADC module-to-memory 4-byte transfer 4096 bytes.


    DMA_HandleTypeDef hdma;
    HAL_StatusTypeDef err;

    uint32_t SrcAddress = 0x10000000;
    uint32_t DstAddress = 0x20000000;
    uint32_t Counts     = 1024;  //Transfer unit is word, so Counts= 4096 / 4
    
    /* Init DMA configure*/
    hdma.Instance                 = DMA1_Channel6;
    hdma.Init.Request             = DMA_REQUEST_12;
    hdma.Init.Direction           = DMA_PERIPH_TO_MEMORY;
    hdma.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
    hdma.Init.MemDataAlignment    = DMA_MDATAALIGN_WORD;
    hdma.Init.PeriphInc           = DMA_PINC_DISABLE;      //Peripheral address NOT auto-increment
    hdma.Init.MemInc              = DMA_MINC_ENABLE;
    hdma.Init.Mode                = DMA_NORMAL;
    hdma.Init.Priority            = DMA_PRIORITY_MEDIUM;

    hdma.XferHalfCpltCallback = DMA_Xfer_Half_Callback_Func;
    hdma.XferCpltCallback     = DMA_Xfer_Complete_Callback_Func;
    hdma.XferErrorCallback    = DMA_Xfer_Error_Callback_Func;

    err = HAL_DMA_Init(&hdma);
    if (err != HAL_OK)
        return err;

    err = HAL_DMA_Start_IT(hadc->DMA_Handle, SrcAddress, DstAddress, Counts);
    if (err != HAL_OK)
        return err;

DMA Example 3

Memory-to-FLASH1 module 1-byte transfer 4096 bytes.


    DMA_HandleTypeDef hdma;
    HAL_StatusTypeDef err;

    uint32_t SrcAddress = 0x20000000;
    uint32_t DstAddress = hflash->Instance->DR;
    uint32_t Counts = 4096;  //Transfer unit is byte, so Counts= 4096 / 1
    
    /* Init DMA configure*/
    hdma.Instance                 = DMA1_Channel6;
    hdma.Init.Request             = DMA_REQUEST_0;
    hdma.Init.Direction           = DMA_MEMORY_TO_PERIPH;
    hdma.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
    hdma.Init.MemDataAlignment    = DMA_MDATAALIGN_BYTE;
    hdma.Init.PeriphInc           = DMA_PINC_DISABLE;      //Peripheral address NOT auto-increment
    hdma.Init.MemInc              = DMA_MINC_ENABLE;
    hdma.Init.Mode                = DMA_NORMAL;
    hdma.Init.Priority            = DMA_PRIORITY_MEDIUM;

    hdma.XferHalfCpltCallback = DMA_Xfer_Half_Callback_Func;
    hdma.XferCpltCallback = DMA_Xfer_Complete_Callback_Func;
    hdma.XferErrorCallback = DMA_Xfer_Error_Callback_Func;

    err = HAL_DMA_Init(&hdma);
    if (err != HAL_OK)
        return err;

    err = HAL_DMA_Start_IT(hadc->DMA_Handle, SrcAddress, DstAddress, Counts);
    if (err != HAL_OK)
        return err;

API Reference

bf0_hal_crc.h