cancel
Showing results for 
Search instead for 
Did you mean: 

Wrong initialization sequence with CubeMX in CubeIDE when Using I2S with DMA

Benjamin Brammer
Senior II

Hello,

I have come over this bug per coincidence:

I am doing an evaluation project with the STM32F407G-DISC1 Board and want to utilize the DMA together with the I2S to feed the Audio data to the CS43L22 DAC.

Since interrupt driven I2S transmit HAL functions work fine, I was really suprised that the DMA related functions did not work. An I neither got any error report nor was there a MCLK visible on the oscilloscope.

Through my interent research I stumbled over the following video from Tripplikit Electronics:

https://www.youtube.com/watch?v=ToRk2lOhydo&ab_channel=TripplikitElectronics

He had the same problematic as I do observe and found the reason for the not working DMA.

It is because of the intialization order when the peripherals get initalized via HAL. The following code snippets show the problem.

If you program STMCubeMX in CubeIDE to use DMA together with the I2S (SPI3 peripheral) the following initialization sequence is created:

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();
 
  /* USER CODE BEGIN Init */
 
  /* USER CODE END Init */
 
  /* Configure the system clock */
  SystemClock_Config();
 
  /* USER CODE BEGIN SysInit */
 
  /* USER CODE END SysInit */
 
  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_I2C1_Init();
  MX_I2S3_Init();
  MX_SPI1_Init();
  MX_DMA_Init();
  MX_USB_HOST_Init();
  /* USER CODE BEGIN 2 */

with MX_DMA_Init() the DMA clock gets enabled. But without the DMA clock, no register write to the DMA registers gets acknowledged. So the correct sequence should be the following:

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();
 
  /* USER CODE BEGIN Init */
 
  /* USER CODE END Init */
 
  /* Configure the system clock */
  SystemClock_Config();
 
  /* USER CODE BEGIN SysInit */
 
  /* USER CODE END SysInit */
 
  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_I2C1_Init();
  MX_DMA_Init();
  MX_I2S3_Init();
  MX_SPI1_Init();
  MX_USB_HOST_Init();
  /* USER CODE BEGIN 2 */

This did resolve the problem.

Please correct this in your new CubeMX/CubeIDE release.

Thanks!

kidn regards

Benjamin

2 REPLIES 2
VOj.1
Associate

Hi, I had the same issue, I found this post after I solved it myself, here is the stackoverflow post just as a cross reference: https://stackoverflow.com/questions/70558087/stm32-spi-ll-dma-transmit/70559815#70559815

Hello @VOj.1​ ,

Thank you for having reported.

Actually you're right, when DMA is used, the MX_DMA_Init shall always be called before any other HAL_***_Init (where *** is any peripheral with a HW dependency on DMA init code).

A regression was detected in the previous STM32CubeMX version 6.3.0 (STM32CubeIDE Version: 1.7.0 generating a wrong order of initialization functions, and it seems to be corrected for some use cases.

For example, starting a project from scratch and configuring I2S and DMA in one shot (without switching to Project Manager view before configuring I2S DMA request), MX_DMA_Init Function call will be in its correct position.

With this being said, this misbehavior has been already reported internally to be fixed as soon as possible.

Meanwhile, you can make sure that the initialization functions are correctly ordered through Project Manager view > Advanced Settings tab:

0693W00000HnoBFQAZ.png 

Hope this clarifies the situation.

Khouloud.