Hello,
I am trying to get I2S and DMA working on my stm32wb55 microcontroller using platformio and the arduino framework. I want to read data from an INMP441 (or similar). I did try to use the STCube IDE (or MX) to configure I2S and DMA using tutorials from the internet but this also did not work. The tutorials are all made for other ST-microcontrollers though.
I either have a problem setting up the DMA, SAI (for I2S) or the DMA interrupt. I do not really have any idea where my problem lies. Trying to just port the code from STCube to platformio is also not straight forward, since some variables are unknown by the platformio core. But as I mentioned before, with the STCube it also does not seem to be working.
Does anyone here have any experience with the STM32WB55 and the SAI of this Microcontroller in particular? I am using the WeAct STM32WB55CGU6 for testing.
Thanks a lot for helping me out here.
You should be able to equivalently import a STM32Cube project to be built by PlatformIO. Do you have the full STM32Cube project for that?
Problems with linking interrupt functions are mostly two things: Not specifying C linkage for the handler functions when doing it from .cpp code (extern "C" void SomeInterrupt_Handler()
) or, defining the interrupt handler in a library function without setting lib_archive = no
.
Hello Max,
thanks for your reply. Since I am not even able to get it to work using the STMCube, trying to import it is not my main concern yet.
Do you know how to get the I2S and DMA with interrupt to work on the STM32WB55 using STMCube?
While I haven’t tried it myself (I have other stm32 boards but not a stm32wb series one), the video
https://www.youtube.com/watch?v=ToRk2lOhydo
shows that the auto-generated CubeMX code has a bug in it, where the clock for the DMA perpiheral is not enabled at the time the I2S DMA is set up, and so it won’t work. The problem there is in the order of initialization: First, MX_DMA_Init()
must be called, then the MX_IS3_Init()
(or similiar). Or, the clock enable function for the DMA peripheral must be called manualyl before the I2S init.
The video also shows the general DMA setup, like doing half-word sized, memory to peripheral (it’s outputting a I2S stream in this case, not reading an I2S stream like your microphone, so yours would be peripheral to memory of course), with non-incrementing on the peripheral side and incrementing address on the memory side.
Of course, that video is very old by now, so it might have been resolved already.
But really, checking out the perpiherals view is crucial.
- is the clock tree setup correctly? Especially the SAI audio clocks.
- Are the clocks for DMA and I2S enabled during runtime? (check the RCC APB enable registers and similiar)
- Is the I2S enabled? (I2S control register)
- Under the same settings you told CubeMX to set it up?
- Is the DMA enabled? (DMA control registers?)
- Under which settings? Is the peripheral address right, the memory address, increment settings? Does it use the correct DMA stream meant for the peripheral?
- Are the DMA interrupts firing?
- use a logic analyzer to check the I2S pin activity, like WS, BCLK, DOUT, …
etc.
Hi,
so I found the issue. It was that the auto clock settings made by STCube were wrong. The Core clock was set to 4 MHz. I set it to 64 MHz, now it works.
Since then I have tried to port the code over to pio where I am using the Arduino Framework. Unfortunately I was not successful so far. Do you know how to properly port it over?