case 07 · Personal · 2025

SAI audio driver

A Serial Audio Interface (SAI) driver for the STM32 NUCLEO-F446RE. I²S-style audio out of an MCU, configured and streamed in plain C.

C STM32F446RE SAI / I²S audio DMA
github.com/Prateek2174/sai

What's in it

A standalone sai.c / sai.h pair that initializes the SAI peripheral on the F446RE — clock setup, frame format, slot configuration, and the master clock divider — and streams audio data through it. The host application in main.c wires it up to a sample buffer.

Why bother

The SAI block on the F4 is one of the more configurable peripherals — you can run I²S, PCM, AC'97, or custom framing out of the same registers. The HAL driver hides all of that behind a struct. Writing it from the reference manual forces you to understand what each field actually does, which pays off the first time the codec doesn't lock and you have to read the bit-clock with a scope.

Notes

  • Configurable as master or slave; transmit or receive.
  • Frame and slot widths set from the SAI FRCR / SLOTR registers directly.
  • Designed to feed off a DMA stream so the CPU isn't in the audio sample loop.
Core/Src/sai.c C



void sai_mode_config(SAI_Block_TypeDef *sai, uint8_t mode){

	sai->CR1 &= ~SAI_xCR1_MODE_Msk;
	sai->CR1 |= (SAI_xCR1_MODE_Msk & (mode << SAI_xCR1_MODE_Pos));
}


void sai_audioblock_on(SAI_Block_TypeDef *sai){

	if(!(sai->CR1 & SAI_xCR1_SAIEN)){

		sai->CR1 |= SAI_xCR1_SAIEN;
	}
}


void sai_audioblock_off(SAI_Block_TypeDef *sai){

	sai->CR1 &= ~SAI_xCR1_SAIEN;
	while(sai->CR1 & SAI_xCR1_SAIEN);
}
MCU
STM32F446RE (NUCLEO board)
Peripheral
SAI1 / SAI2
Protocols
I²S, PCM (configurable)
Build
STM32CubeIDE, HAL-light

What's next

  • Codec bring-up — wire up a CS43L22 or PCM5102 and bring it up over I²C to go from raw I²S signals to audible output
  • DMA double-buffering — use ping-pong DMA buffers so the CPU can fill one buffer while the SAI drains the other; eliminates glitches at buffer boundaries
  • Audio effects — once DMA streaming is solid, implement a basic FIR filter or biquad EQ running on the M4's DSP instructions (SIMD, MAC in the FPU)
  • Full-duplex — configure SAI block A as transmitter and block B as receiver simultaneously for real-time audio passthrough and processing