2024-09-28 06:11 PM - edited 2024-09-28 06:17 PM
Board: STM32 Nucleo-F411RE
I am trying to get audio from I2S MEMS microphone (SPH0645). According to datasheet here -
https://www.knowles.com/docs/default-source/default-document-library/sph0645lm4h-1-datasheet.pdf
Basically I am supposed to get a 32-bit, where the first 24-bit is needed, last 8-bits should be ignored.
According to this, I have set the I2S pins as Half Duplex Master, with following settings -
The DMA settings is given below -
Here as the frame size is 32-bits, I have set data width as 'word'.
My code is like this (ignoring the init functions) -
#define BUFF_SIZE 200
volatile uint32_t i2s_rxData[BUFF_SIZE];
volatile uint32_t i2s_RxSmpl;
int main(void) {
HAL_I2S_Receive_DMA(&hi2s2, (uint32_t *)i2s_rxData, BUFF_SIZE);
while (1) {
}
}
Now, my expectation was that each entry on data buffer would be a 32-bit number, but it seems I get 16-bit each entry. In debug mode, this is how the DMA buffer looks like.
The pattern is, 2 numbers 16-bit numbers, ending with two zeros. I dont know exactly why it behaves like this.
So, I considered each 4 buffer entry as 1 audio data and did the needed bit shifting -
void HAL_I2S_RxCpltCallback(I2S_HandleTypeDef *hi2s){
HAL_I2S_DMAPause(hi2s);
uint16_t n1 = 0;
uint16_t n2 = 0;
uint32_t decoded = 0;
for (int i = 0; i < BUFF_SIZE; i = i+4) {
decoded = 0;
decoded = i2s_rxData[i]; // Take 1st element of every 4th entry
decoded = decoded << 16; // Left shift it
decoded |= i2s_rxData[i+1]; // put the next number LSB 16-bit
decoded = decoded >> 8; // Get 24 bits on data by shifting 8-bits right
aduio_dataBuff[i/4] = decoded; // Append it to Audio buffer
}
// See plot of Audio Buffer at trace timeline @ Debug Mode
for (int i = 0; i < BUFF_SIZE/4; i++) {
if (aduio_dataBuff[i] != 0)
x = aduio_dataBuff[i];
}
HAL_I2S_DMAResume(hi2s);
}
This does work, however, I am not getting perfect audio signal after post processing unless I ignore the zeros in processed audio buffer.
Processed Audio with zeros ignored -
Without Zero Ignored -
This means, clearly there is something I am not doing right.
I have tried changing *Data and Data Frame format* on I2S settings and also Data Width from DMA request settings, but I am no sure where it's not going perfect.
Can anyone please guide me toward right direction? I just spend quite a bit time on this and want to get this right. Thanks.
2024-11-20 06:07 AM
Late response, but did you try 24-bits data (on a 32 bits frame)?