3

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

Knee Caps
  • 181
  • 2
  • 9
  • Somehow, this code does work: https://github.com/MYaqoobEmbedded/STM32-Tutorials/blob/master/Tutorial%2040%20-%20UART%20DMA/UART_DMA_main.c – Knee Caps Oct 23 '19 at 21:49

3 Answers3

15

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!!!

Knee Caps
  • 181
  • 2
  • 9
  • 1
    Interrestingly, it is only a problem when using CubeMX integrated in STM32CUBEIDE. Stand alon CubeMX works great. – Knee Caps Oct 23 '19 at 23:14
  • 1
    Thanks, same problem here. Saved me some debugging time. – Raphael Oct 06 '21 at 13:06
  • It looks like a bug in the integrated STM32CUBEIDE or I am missing something. I get a grey MX_DMA_Init line and I am not able to step it up so that it remains above USART2. I had to click in "Do Not Generate Function Call" and call it myself in user code before the USART2 initialization. – Marcelo Roberto Jimenez May 29 '22 at 03:31
  • +1 I was upset that this bug had cost me over an hour of my life debugging. Exasperated, I turned to my colleague and ranted about this problem. Turns out an issue he's been trying to figure out for over a day is caused by the same problem! – MichaelK Jun 10 '22 at 19:08
  • Lost 1/2 day to find this issue. Is this a problem with CUBE MX? – paulojfonseca Jul 15 '22 at 09:36
3

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.

0

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.