Skip to main content
Explorer
December 14, 2021
Question

Are there any examples of a UART transmit with DMA for a STM32MP1?

  • December 14, 2021
  • 4 replies
  • 8284 views

In a normal M4 like the STM32F466RE the MX program does most of the setup for transmitting the UART with DMA when you configure.

However there is NO DMA option when setting up the UART for the STM32MP157.

I dump internal information to a UART so I can see what is going wrong. The UART is operating at 2Mb (2,000,000 baud or bits per second) While that is good at getting the data out, it is too much of a drain on the processor going in and out of interrupts that fast.

That is what DMA is for. It operates in the background and is not noticed by my processor.

The DMA is different with the STM32MP1, some help with the configuring it with a UART for transmit would be helpful.

    This topic has been closed for replies.

    4 replies

    Technical Moderator
    December 14, 2021

    Hi @KiptonM​ ,

    With STM32CubeMX, if UART is assigned to Cortex-M4, you could assign DMA2 streams to it and got most code ready to use.

    I think your question is for Linux side.

    As I'm not expert, I dig into ST MPU wiki and found the following information which could help setting tty with DMA:

    https://wiki.st.com/stm32mpu/wiki/Serial_TTY_device_tree_configuration

    https://github.com/STMicroelectronics/linux/blob/v5.10-stm32mp/Documentation/devicetree/bindings/serial/st,stm32-uart.yaml

    Regards.

    KiptonMAuthor
    Explorer
    December 14, 2021

    Actually my question is on the M4 side. Not the Linux A7 side.

    So I went to DMA2 assigned it to M4

    Then i added USART3_TX

    The rest of the parameters I left to default.

    HAL_UART_Transmit_DMA(&huart3, (uint8_t *)tcbuffer1, strlen((char *)str));

    Does not work.

    Technical Moderator
    December 16, 2021

    Hi,

    Have you enabled "USART3 global interrupt' in CubeMX ?

    See attached a quick and dirty example out of CubeMX with few lines added to start the TX.

    Regards.

    In order to give better visibility on the answered topics, please click on 'Select as Best' on the reply which solved your issue or answered your question. See also 'Best Answers'

    KiptonMAuthor
    Explorer
    December 17, 2021

    The code looks almost identical except my does not output to the serial port.

    The only difference I could see is that your version generated a Stream1 for RX I am guessing

    static void MX_DMA_Init(void)
    {
     
     /* DMA controller clock enable */
     __HAL_RCC_DMAMUX_CLK_ENABLE();
     __HAL_RCC_DMA2_CLK_ENABLE();
     
     /* DMA interrupt init */
     /* DMA2_Stream0_IRQn interrupt configuration */
     HAL_NVIC_SetPriority(DMA2_Stream0_IRQn, 0, 0);
     HAL_NVIC_EnableIRQ(DMA2_Stream0_IRQn);
     /* DMA2_Stream1_IRQn interrupt configuration */
     HAL_NVIC_SetPriority(DMA2_Stream1_IRQn, 0, 0);
     HAL_NVIC_EnableIRQ(DMA2_Stream1_IRQn);
     
    }

    and mine did not because I was not expecting anything coming in on USART3

    /**
     * Enable DMA controller clock
     */
    static void MX_DMA_Init(void)
    {
     
     /* DMA controller clock enable */
     __HAL_RCC_DMAMUX_CLK_ENABLE();
     __HAL_RCC_DMA2_CLK_ENABLE();
     
     /* DMA interrupt init */
     /* DMA2_Stream0_IRQn interrupt configuration */
     HAL_NVIC_SetPriority(DMA2_Stream0_IRQn, 0, 0);
     HAL_NVIC_EnableIRQ(DMA2_Stream0_IRQn);
     
    }

    Here is the screen shot with the Interrupt set.

    KiptonMAuthor
    Explorer
    December 17, 2021

    Here is the screen shot of the Parameter setup

    My code worked on the STM32F446RE Nucleo board.

    Thanks for the help.

    Technical Moderator
    December 17, 2021

    Hi @KiptonM​,

    how did you test your M4 code ? using Engineering mode or Production mode ?

    In Production mode, as peripheral root clock init is done by Linux, your Device Tree matters.

    I tested (In engineering mode with latest CubeIDE) and still work when removed DMA stream1 on RX.

    Regards.