Failing to receive data from UART in DMA mode

Viewed 4429

I am trying to receive 8 bytes from my pc on my NUCLEO F446RE stm32 board. Transmitting to the pc works. The problem is, I am unable to receive data using DMA. I saw an example with almost the same code and it has worked for the person. If I use the interrupt mode (just change HAL_UART_Receive_DMA to HAL_UART_Receive_IT, it does work and the RX Complete callback is being called.

Here is the complete main.c. DMA is in circular mode.

main.c

https://pastebin.com/1W4BCjxB

3 Answers

I got it solved, it is actually ridiculous.

So, this is part of the code that CubeMX generates:

MX_GPIO_Init();
MX_USART2_UART_Init();
MX_DMA_Init();

If I order it as follows:

MX_GPIO_Init();
MX_DMA_Init();
MX_USART2_UART_Init();

It works!!!

I had the same problem. Here is the solution with using the CubeMX integrated view. In the CubeMX->Project Manager->Advanced Settings you can select the order of functions to be generated. I moved my MX_DMA_Init to the top to ensure that the DMA is ready before any other peripherals are initialised.

You haven't initialized the DMA variables as well as handler for the DMA interrupt. You will need to do something along these lines

Initialize DMA:

hdma_usart2_rx.Instance = DMA2_Stream1;
hdma_usart2_rx.Init.Channel = DMA_CHANNEL_2;
hdma_usart2_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
hdma_usart2_rx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_usart2_rx.Init.MemInc = DMA_MINC_DISABLE;
hdma_usart2_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_usart2_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_usart2_rx.Init.Mode = DMA_CIRCULAR;
hdma_usart2_rx.Init.Priority = DMA_PRIORITY_HIGH;
hdma_usart2_rx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
HAL_DMA_Init(&hdma_usart2_rx);
void DMA2_Stream2_IRQHandler(void)
{
    HAL_NVIC_ClearPendingIRQ(DMA2_Stream2_IRQn);
    HAL_DMA_IRQHandler(&hdma_usart1_rx);
}

HAL_UART_Receive_DMA only starts the DMA and does not handle the interrupt and the data transfer.

Related