cancel
Showing results for 
Search instead for 
Did you mean: 

Simple UART1 DMA dosent work generated with latest STM32CUBEMX 5.4.0 and STM32F0 1.11.0

TaipeiViking
Associate II

Help!

Generating a minimum configuration with UART1 in DMA mode.

The blocking version if(1) works, but with if(0) the DMA version nothing comes out.

Configuration file for CubeMX attached.

What am i missing??

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */
    /* USER CODE BEGIN 3 */
		static uint16_t usLEDfwTimer=0;
		static uint8_t ucByte[]="A";
 
		if(++usLEDfwTimer>=50000) //around 10 times per second
		{
			usLEDfwTimer=0;
			if(1)
			{ 
					HAL_StatusTypeDef sU=HAL_UART_Transmit(&huart1,(uint8_t*)&ucByte[0], 1,1);	//this works ! 
			}else
				{ 
					HAL_StatusTypeDef sU=HAL_UART_Transmit_DMA(&huart1,(uint8_t*)&ucByte[0], 1);	//dosent work
			}
			if(ucByte[0]>'Z')ucByte[0]='A';else ucByte[0]++;
		}
  }
  /* USER CODE END 3 */

5 REPLIES 5
TaipeiViking
Associate II

Solved: The STM32Cube generates the following lines:

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_USART1_UART_Init();
  MX_DMA_Init();

This simple example works simply by changing the orders of the init-calls to:

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_DMA_Init();
  MX_USART1_UART_Init();

.... so that the DMA init is called before the UART init.

Saw this reported before and thought it would have been fixed in the Cube by now.

So, to make the fix work so that it will be preserved across code generations by the cube,

initializing the DMA as part of the /* USER CODE worked l... here is the fix:

  /* USER CODE BEGIN SysInit */
  MX_DMA_Init();
 
  /* USER CODE END SysInit */
 
  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_USART1_UART_Init();
  MX_DMA_Init();

Note that the DMA is initialized twice, but it still works, and is preserved when generating code from the Cube.

Lastly note that the UART interrupts MUST be enabled... see below...

0690X00000AtPpdQAF.png

Like & Enjoy!

Pavel A.
Evangelist III

Do you understand that HAL_UART_Transmit is synchronous, unlike _IT and _DMA variants which are asynchronous?

The _IT and _DMA variants return immediately after starting the transfer, and will call completion callback later.

Or, you can check the huart1 struct for completion.

-- pa

Please don't confuse "synchronicity" with blocking/non-blocking functions, specially when discussing UARTS!

The root cause of this issue (if you step through the code in the debugger) is that the MX_DMA_Init(); must be called BEFORE MX_USARTx_UART_Init();

So, it should be fixed in the CubeMX so that the init-functions gets called in the right order. The same issue has been reported in for other peripherals, (ADC, etc.) so the workaround is to call MX_DMA_Init(); within /* USER CODE .. because it then gets preserved through subsequent builds in CubeMX.

Piranha
Chief II