cancel
Showing results for 
Search instead for 
Did you mean: 

I2S weird bit shift problem

baator025
Associate II

Hi,

I'm getting a problem in my project, where I tried to create a loopback between I2S3 and I2S4 on STM32F411 Disco.
It seems that only the least significant bit of 16-bit packets is somehow shifted to the next packet. The rest of the transmission is intact.
For example - I send {0x0001 0x0000 0x0000 0x0000} and I get {0x0000 0x0000 0x0001 0x0000}, but if I send {0xFFFE 0x0000 0x0000 0x0000}, I will receive {0x0000 0x0000 0x0000 0xFFFE}.
Packets order reversal is expected, but during analysis pay attention what happens with the least significant bit. Another example: transmitting {0x8001 0x0000 0x0000 0x0000} will end up with receiving {0x0000 0x0000 0x0001 0x8000} (I'd expect {0x0000 0x0000 0x000 0x8001}).
What is also interesting, readouts from logic analyzer seem to be correct.

I am not using HAL, I am configuring registers manually. I2S4 is configured as master receiver and uses DMA. I2S3 is configured as slave transmitter and I tried "feeding" it both with polling and interrupts. I always fill transmitter's buffer before initializing receiver with the first packet.

Since I've written my own abstraction layer, attaching code here may be difficult. Therefore I am uploading the link to repo: https://github.com/baator025/I2S_loopback . The most recent branch is rtos_integration.

I'd really appreciate help, because I've run out of ideas long ago.

Thanks,
Bartosz

27 REPLIES 27

Thanks, that did it! No more bit shift.

First I noticed that my implementation used APB1 for first I2S channel and APB2 for second one. There would be nothing wrong with that aside from that I set two different prescalers. After I fixed it, I noticed improvement, but some of the bits were still shifted.
After that I configured OSPEEDR and it seems that it fixed the problem.

Thanks again for the help. I'll remember to look for erratas, when I start working with a new MCU.

I found another solution to the problem, but thanks anyway. :)

You're not wrong about PDMs, it's different protocol/interface. However, I2S can be used for capturing the data. 
Take a look at this document: AN5027 

Regarding PDM2PCM lib - I described my problem here . Long story short- after calling PDM_Filter_setConfig, MCU goes into hard fault. I'd appreciate if you could take a look at this.

Cool, great - well done!

Let me look into your PDM Mic issue (even I do not use it as same MCU).
Have you debugged why HardFault_Handler was called?

BTW: I am not sure if a SPI as I2S (which works), can be used for PDM.
I assume: PDM works only with a SAI interface (configured for PDM). Or: you use the FSDM interface.

Let me look...

> I assume: PDM works only with a SAI interface (configured for PDM).

Why?

PDM is just a clocked stream of bits. SPI is just a clocked stream of bits, either; and so is basically I2S (that's why it's one interface). You need to filter it, but SAI won't do that either; and while HW filter is more comfortable/efficient, SW is viable in many cases, too.

SAI which supports PDM has one advantage, though, it supports stereo PDM in the both-edges mode. But that can be worked around with SPI/I2S, one timer, one extra pin, and a bit of thinking, too. And not all SAI support that mode, and not all STM32 have SAI at all.

JW

You are right, sorry: yes, with SPI as I2S it should be possible to connect a PDM MIC (but just in mono mode):

chrome-extension://efaihttps://www.st.com/resource/en/application_note/an5027-interfacing-pdm-digital-microphones-using-stm32-mcus-and-mpus-stmicroelectronics.pdf 

Just to bear in mind: the I2S clock for a PDM MIC is way faster as for a regular PCM I2S. And this frequency has to be configured properly in relation to the decimation factor used.