Showing results for 
Search instead for 
Did you mean: 

STM32G4 SAI Data Processing in I2S Mode

Associate II

Dear STM Community,

I've configured the SAI on my Nucleo-G474RE board by setting the protocol to "I2S Standard" and data size to 24 bits to communicate with an external 24 bit ADC. Further, the SAI works together with the DMA to fill the buffers. Here, I use the corresponding HAL function:

#define BUF_SIZE 512
uint32_t adc_buf[BUF_SIZE]; // raw adc buffer?
float32_f adc_buf_L_f32[BUF_SIZE/2]; // retrieved samples for left channel
HAL_SAI_Receive_DMA(&hsai_BlockA1, (uint8_t*) adc_buf, BUF_SIZE);

Do I need to mask the 32 bit values in the buffer to get the actual 24 bit encoded PCM data sent by the ADC via I2S or does the HAL library handle this for me? Here is my buffer processing callback function for the first half as an example:

void HAL_SAI_RxHalfCpltCallback(SAI_HandleTypeDef *hsai)
	uint32_t tmp;
	for (int i = 0; i < BUF_SIZE / 4; ++i)
		tmp = (adc_buf[i * 2] & 0x7FFFFF80) >> 7;
		adc_buf_L_f32[i] = (float32_t)((int32_t)tmp / 8388608.0f);

Here is the data format sent by the ADC from the Cirrus Logic document for the CS5343:



If properly configured, SAI performs the one-bit-shift in I2S protocol for you, read the SAI chapter in RM.

Also note, that ADCs (and CODECs generally) usually work in two's complement, i.e. you need to sign-extend the value after right-shift. Casting to signed integer.won't do.

The most illustrative thing to do is feed the ADC first quiet (ground) then an easily recognizable pattern (I recommend sawtooth), and observe the actual data "manually" in debugger, as they go through your computations.


Associate II

Hey, thanks for your reply. I've checked it and apparently CubeMX sets this parameter for shifting the data automatically depending on the configured protocol.

And also thanks for the hint regarding the sign extension. How could I forget it? I will adapt my code and check it with a sawtooth signal. That makes totally sense for testing.

Associate II

Ok, for others finding this thread through the search engine or whatever, the data is already processed by the HAL driver and can be used without further processing directly. Not even a single shift operation!

Chief II

As Jan already said, the processing is done by SAI hardware, not the HAL driver!

Associate II

You are right. When receiving, the bits are ignored by the SAI hardware depending on the start position set by FBOFF and/or if the data size is smaller than the slot size.