🛠 Lecture audio sur le codec CS43L22 : I2S, classe D et les limitations du BSP
Objectif
La STM32F4DISCOVERY a été vendue par ST comme la carte « pour développer des applications audio facilement ». L'équipement est réel : un codec CS43L22 (DAC stéréo + amplificateur classe D pour haut-parleur), une prise casque, un connecteur haut-parleur, et un micro numérique — le tout piloté par le STM32F407VGT6. Ce tutoriel joue un son via le BSP CubeF4 et surtout ses limitations documentées, qui expliquent 90 % des déceptions.
Architecture matérielle
- Contrôle : I2C1, adresse device 0x94, broche reset PD4 ; le BSP vérifie la présence du codec en lisant
CS43L22_ID. - Flux audio : l'I2S envoie les échantillons 16 bits stéréo vers le CS43L22 ; la lecture (playback) dans le BSP CubeF4 passe par I2S3, la capture micro PDM par I2S2.
- Exemples officiels :
Projects/STM32F4-Discovery/dans STM32CubeF4 (démos audio play/record).
Les limitations du BSP (source : section Known Limitations)
- Stéréo 16 bits uniquement : un fichier mono doit être dupliqué sur les deux canaux.
- Bruit à faible fréquence d'échantillonnage : les fichiers de mauvaise qualité produisent un « niveau de bruit élevé et inconfortable » sur le haut-parleur classe D — remontez à plus de 48 kHz.
- Corruption I2C possible : la communication avec le CS43L22 peut être corrompue si elle est interrompue par des routines d'interruption utilisateur — gardez les ISR courtes ou masquez les interruptions autour des accès codec.
- Le volume et la mute passent par des registres du codec (
BSP_AUDIO_OUT_SetVolume,..._SetMute), pas par le MCU. - L'initialisation échoue si l'ID lu sur I2C1 ne correspond pas : vérifiez le reset PD4 avant de compiler.
Squelette de code
#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 écrire : 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);
}
Démarche
- Ouvrez la démo audio de CubeF4 (
Projects/STM32F4-Discovery/) comme référence de brochage I2S. - Préparez vos échantillons en stéréo 16 bits, ≥ 48 kHz — convertissez avec ffmpeg si besoin (
-ac 2 -ar 48000 -sample_fmt s16). - Alimentez le buffer en circulaire via DMA et rechargez-le dans la callback de transfert à moitié plein (
HalfTransfer) pour un flux continu. - Réglez le volume avec
BSP_AUDIO_OUT_SetVolume; la sortie casque et le connecteur haut-parleur partagent le même DAC.
Vérification attendue
Un 440 Hz propre sort du haut-parleur (ou du casque). Si vous entendez un sifflement désagréable, votre fréquence d'échantillonnage est trop basse — c'est la limitation n°2, pas un défaut matériel. Si le codec n'initialise pas (CS43L22_ID invalide), vérifiez la ligne reset PD4 et l'adresse 0x94 sur I2C1 avec un analyseur logique.
Erreurs fréquentes
- Jouer du mono sans le dupliquer : le BSP n'accepte que la stéréo 16 bits (limitations 4 et 5 du BSP).
- Faire des appels
BSP_AUDIO_OUT_*dans une ISR longue : le BSP avertit que l'I2C du codec peut être corrompu par les interruptions utilisateur. - Confondre le micro MP45DT02 (PDM, capture sur I2S2) avec le codec de lecture : deux périphériques distincts, deux initialisations distinctes.
- Utiliser PC7 (MCLK du codec) comme broche libre : elle est engagée sur l'horloge audio tant que le codec vit.
Autres tutoriels pour cette carte
- Premier téléversement sur la STM32F4DISCOVERY avec l'Arduino STM32duino
- Zephyr RTOS sur la STM32F4DISCOVERY : west build et west flash
- MicroPython sur la STM32F4DISCOVERY : REPL interactif et pilotage des LED
- STM32Cube HAL et BSP officiel : LED, bouton et accéléromètre avec détection automatique
- USB OTG FS sur le port micro-AB : se faire passer pour un périphérique classe CDC
- Acquérir le micro PDM MP45DT02 : I2S2, filtre PDM-vers-PCM et contraintes de sortie