Skip to main content
evenlund
Associate III
November 9, 2020
Question

Does the Nucleo STM32G431 have a bug with the I2S (receive)?

  • November 9, 2020
  • 12 replies
  • 2676 views

I am using the latest versions of STM32CubeIDE and updated firmware for STM32G431. I am trying to setup the Nucleo STM32G431 with I2S master for a microphone with DMA in circular mode, very similar to what "YetANotherElectronicsChannel" did in this video (just omitting the transmit part): https://www.youtube.com/watch?v=lNBrGOk0XzE.

I have made this work fine with the Nucleo F446RE, but when using the G431 only the HAL_I2S_RxHalfCpltCallback seems to be started. Moreover I get no data into the memory given to the DMA.

Is there a bug in the software? I see that the #if defined(SPI_I2S_SUPPORT) is grayed out in the stm32g4xx_hal_i2s.c file (contrary to what I have for F446RE), proably meaning that it is not defined earlier. I have tried commenting out the #if defined and #endif, but there seems to be no difference.

Has anywone set up the G431 successfully with I2S master receive and DMA?

This topic has been closed for replies.

12 replies

evenlund
evenlundAuthor
Associate III
November 17, 2020

I have now setup the I2S3 in the same manner like the I2S2 and the I2S3 is working perfectly in stereo, but the I2S3 behave in the exact same way with no data (0 value) saved to the variable that DMA should fill. I am starting to suspect that the DMA is not setup or working correctly. I have setup both I2S's exactly the same in STM32cubeide/cubemx with circular mode and data width of half word. I am showing the code for reading the buffers below. Any clue of what is wrong?

void HAL_I2S_RxHalfCpltCallback(I2S_HandleTypeDef *hi2s){
	if (hi2s->Instance==SPI2)
	{
		lsample1=(int)(rxBuf1[0]<<16|rxBuf1[1]);
		rsample1=(int)(rxBuf1[2]<<16|rxBuf1[3]);
		//HAL_GPIO_TogglePin(LD2_GPIO_Port, LD2_Pin);
	}
	else
	{
		lsample2=(int)(rxBuf2[0]<<16|rxBuf2[1]);
		rsample2=(int)(rxBuf2[2]<<16|rxBuf2[3]);
		//HAL_GPIO_TogglePin(LD2_GPIO_Port, LD2_Pin);
	}
}
 
void HAL_I2S_RxCpltCallback(I2S_HandleTypeDef *hi2s){
	if (hi2s->Instance==SPI2)
	{
		lsample1=(int)(rxBuf1[4]<<16|rxBuf1[5]);
		rsample1=(int)(rxBuf1[6]<<16|rxBuf1[7]);
		//HAL_GPIO_TogglePin(LD2_GPIO_Port, LD2_Pin);
	}
	else
	{
		lsample2=(int)(rxBuf2[4]<<16|rxBuf2[5]);
		rsample2=(int)(rxBuf2[6]<<16|rxBuf2[7]);
		//HAL_GPIO_TogglePin(LD2_GPIO_Port, LD2_Pin);
	}
}

waclawek.jan
Super User
November 17, 2020

Debug as usually - read out and check/post SPI/I2S, relevant DMAMUX, DMA and GPIO registers' content. Cube is open source.

JW

evenlund
evenlundAuthor
Associate III
November 17, 2020

I appreciate you trying to help me! Unfortunately I find it difficult to being seen/get help or get an overview of other users questions too on this forum. And I don't think there is a way to reach out to ST directly to ask questions that may be related to bugs for a particular MCU.

I have at my best efforts tried to look into register settings during debugging, but I am unsure what are correct settings to get things running. Are there any overviews for the order of how the I2S should be set up with DMA and the corresponding register settings? My way of trying to spot such errors is either to compare registers between two different MCUs (one working) or, for this case, comparing on the registers for a functional and a non-functional I2S. So far I see no differences.

waclawek.jan
Super User
November 17, 2020

> comparing on the registers for a functional and a non-functional I2S.

Sounds like a good approach.

> So far I see no differences.

Okay, so show them.

JW

evenlund
evenlundAuthor
Associate III
November 18, 2020

I don't get much out of observing these registers except for that the SPI2 DR register is never changing from 0, the SPI used by the I2S with a problem.

I start the I2S reception with

 HAL_I2S_Receive_DMA(&hi2s2, rxBuf1, 4);
 HAL_I2S_Receive_DMA(&hi2s3, rxBuf2, 4);

Have a go at what you think is the problem - here are some screenshots:

After MX_I2S*_inits:

SPIs

0693W000005BmZ1QAK.pngDMAMUX

0693W000005BmaiQAC.pngDMA1

0693W000005BmcZQAS.png 

After first RxHalfCpltCallback:

SPIs

0693W000005BmeVQAS.pngDMA1 (DMAMUX is unchanged)

0693W000005BmfYQAS.pnghist data structures

0693W000005BmXZQA0.pngLater RxHalfCpltCallback:

0693W000005BmheQAC.png0693W000005BmiNQAS.pngIn RxCpltCallback:

0693W000005Bmj6QAC.png0693W000005BmhpQAC.png 

Piranha
Principal III
November 18, 2020

"Testing shows the presence, not the absence of bugs." /Edsger Dijkstra/

Take a note that such issues can happen because of this:

https://community.st.com/s/question/0D50X0000C5Tns8SQC/bug-stm32-hal-driver-lock-mechanism-is-not-interrupt-safe

And yes - that means that almost the whole HAL library is flawed and unreliable.

evenlund
evenlundAuthor
Associate III
November 18, 2020

I appreciate you pointing me to this post. Do you suggest I change the code directly with your suggested code (first post) or will I have to wait for a full rewrite of the HAL library ;) ? Will this possibly fix my problem?

Even though there is some hate towards the HAL library I think that it beats manually setting register bitfields in the correct order, having to carefully read the full 600 page manual before you can do anything practical with the MCU. I also like that you can reuse setups and code between different MCU families. I think there is a reason for arduinos popularity beyond price and functionality.

waclawek.jan
Super User
November 18, 2020

You haven't shown us the respective GPIO registers' content. DR being stuck at 0 - while everything otherwise indicates I2S and DMA running OK - sounds much like data pin for the given I2S not being set in GPIO.

As for interrupts appear to be missing, try a much slower I2S clock, that could perhaps reveal if it's the bloated Cube code or something else.

JW

evenlund
evenlundAuthor
Associate III
November 19, 2020

Thank you for your insight!

Here are the GPIO registers just after the I2S init:

0693W000005BunfQAC.png0693W000005BunpQAC.png0693W000005Buo9QAC.png 

In the first RxCpltCallback only these registers changes:0693W000005BuoOQAS.png0693W000005BuoxQAC.png 

In successive callbacks only the IDR registers of GPIOA, GPIOB and GPIOF changes. Crossing fingers that there is a simple fix.

waclawek.jan
Super User
November 21, 2020

Appears OK.

So, you have set I2S CK and WS to PF0/PF1? Do you see those two clicks on those pins, observed by oscilloscope or LA?

Isn't HSE enabled in RCC?

JW

evenlund
evenlundAuthor
Associate III
November 23, 2020

That is correct - I use I2S2 on PF0 and PF1. I will see if I can get an oscilloscope that is able to observe the clicks. I assume that this will happen at 1/150e6 s as the I2S clock is 150 MHz. I have been experimenting with setting the clock really low, but have not seen any change.

No, the HSE cannot be enabled when using I2S2. Do I have to cut traces to the crystal on the Nucleo STM32G431 to make it work?