2025-03-25 2:26 AM
Hi
I am working on project that receive several I2S streams from MEMS microphones. I found that "audio level" from second microphones pair had higher level then from other. After some analysis and SD lines swapping i found that I2S data received by second I2S is multiplied by 2 factor (binary shifted).
I built minimal system with on STM32F411CEUx (Black Pill board) to reproduce it.
I configured:
* I2S1: Half-Duplex Master Receive
* I2S2: Half-Duplex Slave Receive
* I2S4: Half-Duplex Slave Transmit
All I2S has same other configuration values:
* I2S Philips
* 32 Bits Data on 32 Bits Frame
* 16 KHz
GPIO pins connected that way:
/*
I2S1 GPIO I2S2 GPIO I2S4 GPIO
============== =============== ================
PA4 -> I2S1_WS <=> PB10 -> I2S2_CK <=> PA1 -> I2S4_SD
PA5 -> I2S1_CK <=> PB15 -> I2S2_SD <=> PB12 -> I2S4_WS
PA7 -> I2S1_SD <=> PB9 -> I2S2_WS <=> PB13 -> I2S4_CK
*/
I also set a maximal speed for all I2S pins:
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
I use STM32Cube FW_F4 V1.28.1
All I2S configured with Circular DMA
I2S4 used to transmit data:
static const uint32_t demo[4] = {
0xBADC0FFE,
0xE0DDF00D,
0xBADC0FFE,
0xE0DDF00D
}
[...]
HAL_I2S_Transmit_DMA(&hi2s4, (uint16_t*)demo, 2);
I2S1 and I2S2 used to receive data:
static int32_t i2s_buffer_1[4 * I2S_DMA_BUF_LENGTH] __attribute__((__aligned__(16))) = {0};
static int32_t i2s_buffer_2[4 * I2S_DMA_BUF_LENGTH] __attribute__((__aligned__(16))) = {0};
[..]
HAL_I2S_RegisterCallback(&hi2s1, HAL_I2S_RX_HALF_COMPLETE_CB_ID, i2s_dma_cb_half_1);
HAL_I2S_RegisterCallback(&hi2s1, HAL_I2S_RX_COMPLETE_CB_ID, i2s_dma_cb_full_1);
HAL_I2S_RegisterCallback(&hi2s2, HAL_I2S_RX_HALF_COMPLETE_CB_ID, i2s_dma_cb_half_2);
HAL_I2S_RegisterCallback(&hi2s2, HAL_I2S_RX_COMPLETE_CB_ID, i2s_dma_cb_full_2);
HAL_I2S_Receive_DMA(&hi2s1, (uint16_t*)i2s_buffer_1, I2S_DMA_BUF_LENGTH);
HAL_I2S_Receive_DMA(&hi2s2, (uint16_t*)i2s_buffer_2, I2S_DMA_BUF_LENGTH);
In ideal case i expect that i2s buffers and source buffers should be the same, but it not.
Datas in i2s receiving buffers shifted (rotated):
/*
demo[0] 0xbadc0ffe | 101110101101110000001111 11111110
i2s_buffer_1[0] 0xfebadd0f | 11111110 101110101101110100001111
i2s_buffer_2[0] 0xebadd0ff | 1110 101110101101110100001111 1111
^
demo[1] 0xe0ddf00d | 111000001101110111110000 00001101
i2s_buffer_1[1] 0x0de0dcf0 | 00001101 111000001101110011110000
i2s_buffer_2[1] 0xde0dcf00 | 1101 111000001101110011110000 0000
*/
I already checked:
- I2S weird bit shift problem : https://community.st.com/t5/stm32-mcus-products/i2s-weird-bit-shift-problem/td-p/757051/page/2
- STM32F42xx SPI errata handling with 70pF load : https://community.st.com/t5/stm32-mcus-products/stm32f42xx-spi-errata-handling-with-70pf-load/td-p/243053
- https://www.st.com/resource/en/errata_sheet/es0287-stm32f411xcxe-device-errata-stmicroelectronics.pdf
But none of solutions works.
I also did a check with osciliscope and found no suspected signal deviations
Test output pattern 0xAAAAAAAA (SD and CK lines)
Test output pattern 0xAAAAAAAA (SD and WS lines)
Test output pattern 0xAAAAAAAA (SD and WS lines)
WS fall and CK:
WS rise and CK:
It looks like delayed WS latch
Anybody seen that before?
P.S.
APB1 periferal clock 48MHz
APB2 periferal clock 96MHz / 48MHz
Clock configuration:
2025-03-25 3:55 AM
Do you observe the In I2S Slave mode, the WS level must be set by the external master when enabling the I2S erratum?
I don't know if there's any provision in Cube/HAL for this erratum, but I doubt there is. I don't use Cube.
JW
2025-03-25 3:58 AM
Hi,
>Anybody seen that before?
Maybe...
I had DAC connected on I2S , on F411 ; as long as i was running it with 16b data, 2ch , all fine.
But then going to 32b sample size, i never got clean signal - or lets say reliable; something looked "puzzled" in the data, like data shifted or hi-lo nibble puzzled; then after some power cycles it was suddenly ok - so my settings correct, but next power cycle again wrong. So i decided: useless, with 32b data words.
And switched to H743 , on SAI with I2S mode, all perfect, also with 32b data.
So on F411 - try to use 16b words, at double frequency, should be same with pd micro signals.
2025-03-25 11:21 AM
@waclawek.jan wrote:Do you observe the In I2S Slave mode, the WS level must be set by the external master when enabling the I2S erratum?
i seen that:
but i have no idea how to implement it...
2025-03-25 11:27 AM
>> So on F411 - try to use 16b words, at double frequency, should be same with pd micro signals.
i seen it with 16 bits samples.
>> And switched to H743 , on SAI with I2S mode, all perfect, also with 32b data.
thanks for hint