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.
↗ github.com/Prateek2174/saiWhat'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/SLOTRregisters directly. - Designed to feed off a DMA stream so the CPU isn't in the audio sample loop.
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