STM32 Audio Codec ?

When working on my projects with STM32 MCUs, one common challenge I frequently encounter is the need to produce sound reliably and with sufficient quality. Initially, I relied on PWM to generate pseudo-analog signals to drive speakers. However, not satisfied with the sound quality, eventually I turned my attention to audio codecs that can produce high-quality sound without requiring much computational power. The audio codec is an IC that incorporates DAC, speaker amplifiers, and a Digital Signal Processing Unit. The primary goal of the audio codec is to produce sound based on the streamed digital audio data. It has other many functionalities, including volume control and ramp transitions. 

In this article, I aim to provide comprehensive guidance on generating sound using the STM32F4 Discovery board, which comes with the CS43L22 audio codec. Leveraging STM32CubeMX for peripheral configuration and the HAL API for library development, I will show the configuration of necessary peripherals and the library I developed in detail.

To stream stereo audio, the commonly used interface is I2S (Inter-IC sound, not confused by I2C).  This interface has a Bit clock (SCK), Word Select (WS), Serial Data (SD), and an optional Mater Clock Line (MCLK). Other details of the interface can be found following the article on Wikipedia. In addition, there is another Interface (Usually I2C) to configure the functioning of the audio codec. So, the next part of the article is to explain how to configure these peripherals. 

STM32 I2S and I2C Configuration for CS43L22

As usual, we start our project by configuring the necessary peripherals, I2C, and I2S interface in our case. I2C is needed to control the Audio codec, whereas I2S will allow us to stream audio data.  As you see from the schematic of the board, I2S3 and I2C1 are connected to the audio codec. In addition, we have PD4 that controls the Reset pin of the audio codec. Considering all these connections, we use CubeMx to configure the necessary pins and peripherals.

STM32F4 schematic
STM32F4 schematic

 

I2C1 configuration is quite straightforward. As shown in the Figure below, I just enable it and use default parameters. 

STM32 I2C configuration
STM32 I2C configuration

For I2S, we have to specify some additional parameters. The audio frequency I specified is 48 kHz, Data and Frame format is 16 Bits data on 16 Bits Frame. You can check other configurations in the picture below. Also, it is vital to enable the Master Clock Output.

STM32 I2S Configuration
STM32 I2S Configuration

In addition, we need to enable DMA. In the configuration I specified circular mode, meaning that DMA will keep streaming a buffer continuously. 

STM32 I2S DMA configuration
STM32 I2S DMA configuration

Also, do not forget to enable DMA Interrupts

STM32 I2S DMA Interrupt enable
STM32 I2S DMA Interrupt enable

Finally, as I said, we have a PD4 pin connected to the reset pin of the audio codec. I specify this pin as GPIO Out in the project and give a meaningful name. Later, we will use this pin to enable the audio codec.

Finally, we can save the file to generate the code. 

STM32 CS43L22 Audio Codec HAL library

Once we configured all the peripherals, we can start writing code to initialize the audio codec and stream audio data. However, explaining every detail of the audio codec is time-consuming and cumbersome. Therefore, I attached the header and source files to this article and I am going to go through the main points of the library.

The code snippet below is the header file of the library. There, I defined the I2C address of the audio codec and the addresses of the registers. In addition, we need I2C1 and I2S3 handlers. To access them I defined them again using the extern keyword and redefined them with different names. 

Other than that, we have prototypes of functions and numeric typedef to define different states of the audio codec. 

#ifndef INC_CS43L22_H_
#define INC_CS43L22_H_

#include "main.h"

// I2C address...
Read more »