🛠 Lecture audio sur le codec CS43L22 : I2S, classe D et les limitations du BSP

STM32F4DISCOVERY (STM32F407VGT6 Discovery kit) · intermediaire · Schéma : chaîne audio de la STM32F4DISCOVERY — MCU STM32F407 sortant en I2S3 vers le codec CS43L22 (DAC + ampli classe D), piloté en I2C1 (adresse 0x94, reset PD4), avec sortie casque et connecteur haut-parleur ; encart sur les limitations : stéréo 16 bits uniquement, bruit sous 48 kHz.

Objective

The STM32F4DISCOVERY was marketed by ST as the board "for easily developing audio applications." The hardware is real: a CS43L22 codec (stereo DAC + class D amplifier for the speaker), a headphone jack, a speaker connector, and a digital microphone — all driven by the STM32F407VGT6. This tutorial plays a sound via the CubeF4 BSP and, more importantly, addresses its documented limitations, which explain 90% of disappointments.

Hardware Architecture

BSP Limitations (Source: Known Limitations section)

  1. 16-bit stereo only: A mono file must be duplicated across both channels.
  2. Noise at low sampling rates: Low-quality files produce a "high and uncomfortable noise level" on the class D speaker — increase the rate to above 48 kHz.
  3. Possible I2C corruption: Communication with the CS43L22 can be corrupted if interrupted by user interrupt routines — keep ISRs short or mask interrupts around codec accesses.
  4. Volume and mute are handled by codec registers (BSP_AUDIO_OUT_SetVolume, ..._SetMute), not by the MCU.
  5. Initialization fails if the ID read over I2C1 does not match: check the PD4 reset line before compiling.

Code Skeleton

#include "stm32f4_discovery.h"
#include "stm32f4_discovery_audio.h"

/* Buffer stereo 16 bits, 48 kHz mini pour eviter le bruit classe D */
static int16_t audioBuffer[2 * 480];   /* 10 ms de sine 440 Hz */

int main(void)
{
  HAL_Init;
  SystemClock_Config;               /* 168 MHz */

  /* Init codec : I2C1 addr 0x94, reset PD4, verif CS43L22_ID */
  BSP_AUDIO_OUT_Init(AUDIO_FREQUENCY_48K, 70);  /* volume 70 */
  BSP_AUDIO_OUT_SetAudioFrameFilter(CODEC);

  FillSine(audioBuffer, 480, 440, 48000);       /* a ecrire : stereo 16b */
  BSP_AUDIO_OUT_Play((uint16_t *)audioBuffer,
                     sizeof(audioBuffer));       /* DMA I2S circulaire */

  while (BSP_AUDIO_OUT_Playing) { }           /* attente fin */
  BSP_AUDIO_OUT_Stop(CODEC_DURING);
}

Procedure

  1. Open the CubeF4 audio demo (Projects/STM32F4-Discovery/) as a reference for I2S pinout.
  2. Prepare your samples in 16-bit stereo, ≥ 48 kHz — convert with ffmpeg if needed (-ac 2 -ar 48000 -sample_fmt s16).
  3. Feed the buffer in circular mode via DMA and reload it in the half-transfer callback (HalfTransfer) for a continuous stream.
  4. Set the volume with BSP_AUDIO_OUT_SetVolume; the headphone output and the speaker connector share the same DAC.

Expected Verification

A clean 440 Hz tone comes out of the speaker (or headphones). If you hear an unpleasant hissing sound, your sampling rate is too low — this is limitation #2, not a hardware defect. If the codec fails to initialize (invalid CS43L22_ID), check the PD4 reset line and address 0x94 on I2C1 with a logic analyzer.

Common Errors

Other tutorials for this board

Code examples for this board

← Back to the board 🛠 All tutorials