WavePlayer using STM32 Discovery

This tutorial will cover how to make WavePlayer using STM32 Discovery board. This player will be able to play the wave files from the USB device. The peripherals that we are going to use are as follows: I2S (Inter IC Sound), I2C, FATFS and USB HOST


The code Works alright for F4 Discovery board. You will get some error with PLLI2SN. Just comment those 2 lines and it will be fine.

CubeMX Setup

Below is the picture of the schematics of the Discovery board that I am using for this project. I will setup all the peripherals according to their connection with the CS43L22 IC

I2C Peripheral

First of all I am setting the I2C Peripheral as shown below

Here I needed to change the default SDA pin (PB7) to PB9, since that’s the one connected to the IC

I2S peripheral

After I2C, its time to setup the I2S peripheral

Make sure you select all the pins as shown in the schematics

  • PC12 -> I2S3_SD
  • PC10 -> I2S3_CK
  • PC7 -> I2S3_MCK
  • PA4 -> I2S3_WS

Here we also need to enable the DMA as shown below

DMA is selected in circular mode, and Data Width is Half width since we will be dealing with 16 bits.


Next we need to enable the USB HOST, so that we can read the audio files from the USB

Also make sure you activate the VBUS, as the USB devices mostly don’t have the Power supply, and that’s why HOST is responsible to provide the required power to such devices.

Next, select the USB_HOST and select the class as Mass Storage Class. Leave everything here to default.

And now we need to enable the voltage supply to the VBUS pin. To do that you need to look at the user manual for your board. I am using STM32F4 discovery board, and it have the following diagram for the USB

As you can see above, the VBUS is powered from the PC0 pin. But PC0 is connected to the EN Pin, which is an active Low pin. This means in order to supply the voltage to the VBUS, we must Pull down the PC0 Pin, or basically Set it LOW.

Also enable the PC0 in the Platform Settings as shown above

FAT File System

Now we will setup the FAT File System

Select the USB Disk Mode, and leave everything to default here. I have enabled the use of Long Filename just in case if I have files with long names

And finally I am using PA0 as the external interrupt key. This is to control the operations in Player like NEXT, PREVIOUS, PAUSE, RESUME etc

Some Insight into the CODE

We need to copy the respective library files into the src, and the inc folders. The final image of these libraries is shown below

The underlined files are the libraries that you need to include in your project. You can download them at the end of this post

First of all we need to include the header files in our main file. We will be using functions only from waveplayer.h and File_Handling.h files

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */

#include "waveplayer.h"
#include "File_Handling.h"

/* USER CODE END Includes */

Next, we will define the functions to check the USB state, and the AUDIO state

extern ApplicationTypeDef Appli_state;
extern AUDIO_PLAYBACK_StateTypeDef AudioState;

int IsFinished = 0;

ApplicationTypeDef Appli_state is the already defined in usb_host.c file, and that’s why we need to declare it as an extern. USB can have the following states


AUDIO_PLAYBACK_StateTypeDef AudioState is defined in the waveplayer.c file, and it have the following states


Other then these, I have also define a variable IsFinished to check if the AUDIO playback is stopped.

Now we will write an external interrupt callback for the button

void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
	if (GPIO_Pin == GPIO_PIN_0)
//		AudioState = AUDIO_STATE_NEXT;
		if (AudioState == AUDIO_STATE_PLAY)
			AudioState = AUDIO_STATE_PAUSE;

		if (AudioState == AUDIO_STATE_WAIT)

Here we can control what the button will do. In the code above, the button is programmed to PAUSE, and RESUME the audio

Our main code will be written inside the while loop

  while (1)

    /* USER CODE BEGIN 3 */

    if (Appli_state == APPLICATION_READY)

    	while (!IsFinished)

    		if (AudioState == AUDIO_STATE_STOP)
    			IsFinished = 1;


In the code above, first we will continuously check if the USB is ready for communication. Once it is ready

  • Mount the USB
  • Start the Audio Player. The parameter is the index of the track (song) that you want to start playing with
  • AUDIO_PLAYER_Process will keep processing the AUDIO until it is stopped. It takes the parameter “isLoop“, which means do you want the loop the AUDIO ? If set TRUE, the 1st track will play after the last track, or in case of FALSE, the player will stop after the last track
  • If the AUDIO state is STOP, the IsFinished will be set to 1, and the processing will STOP


Check out the VIDEO Below


You can buy me a coffee Sensor by clicking DONATE OR Just click DOWNLOAD to download the code

Notify of
Oldest Most Voted
Inline Feedbacks
View all comments