5 years, 5 months ago.

Using DMA to transmit UART on the STM32F7xx

I want to use the DMA to transmit 512 bytes using the UART peripheral and have the following code:

    DMA_HandleTypeDef _dma;

    //DMA controller clock enable 
    __DMA1_CLK_ENABLE();
  
    //Peripheral DMA init
    _dma.Instance = DMA1_Stream4;
    _dma.Init.Channel = DMA_CHANNEL_4;
    _dma.Init.Direction = DMA_MEMORY_TO_PERIPH;
    _dma.Init.PeriphInc = DMA_PINC_DISABLE;
    _dma.Init.MemInc = DMA_MINC_DISABLE;
    _dma.Init.PeriphDataAlignment = DMA_MDATAALIGN_BYTE;
    _dma.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
    _dma.Init.Mode = DMA_NORMAL;
    _dma.Init.Priority = DMA_PRIORITY_HIGH;
    _dma.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
    
    HAL_DMA_Init(&_dma);

I have three questions regarding the usage and initialization:

  1. How can I define i) the memory and ii) peripheral base address, and iii) the number of bytes that have to be transferred?
  2. Each time the UARTx_TDR transmits a byte it can generate an interrupt. How can I instruct the DMA that it should send the next byte if this interrupt has been generated, or how can I instruct the DMA to look at a specific bit in the UARTx_ISR register?
  3. After transmitting 512 bytes, I want the CPU to know to load 512 new bytes into the memory before re-enabling the DMA. How can I set up an interrupt that is executed after transmitting 512 bytes?

1 Answer

5 years, 5 months ago.

Hi Alex,

Mbed doesn't have DMA support built into the OS, so you will have to drop down to the HAL layer provided by the vendor as you're doing. We aren't intimately familiar with the STM32, but we found some good documentation in the STM32 Application Note 4031 titled "Using the STM32F2, STM32F4 and STM32F7 Series DMA controller". We suggest you read this AN.

To answer your questions: 1) The source, destination and transfer size are defined as parameters in the DMA start function:

2) This DMA supports interrupting the CPU when half the data length or the full data length have been trasmitted, not every byte. The benefit of using the DMA is to off-load the CPU of moving data, so using a small transfer size of 1-2 bytes would be unusual.

3) Please check the top of the source file for setting up the interrupt:

We haven't been able to find any Mbed-based STM32 DMA examples, but you can probably find some general DMA examples on the ST website (perhaps using the same HAL).

The HAL layer is maintained by ST, so if you encounter any issues trying to program the DMA, please raise a GitHub issue:

Regards,

Ralph, Team Mbed