 Hello and welcome to the STM32L4 MOOC online training. My name is André Barata and this is the dedicated session for the DFSTM peripheral. DFSTM stands for Digital Filter for Sigma Delta Modulator and you can find the clear and detailed presentation on this peripheral on the theoretical slides posted down below. On this session we will solely focus on the practical aspects of implementing DFSTM on STM32QMX. In our hands-on we will demonstrate how to connect a single microphone and collect audio samples for this device. There is a microphone located on the bottom right corner of our L4 Discovery board as shown in the slides and it is connected through two wires to our microcontroller. The goal of this session is to learn how to connect our microphone physically, how to configure our DFSTM peripheral to convert the PDM signal to PCM signal, which is a type of data much easier to be transferred and processed by our microcontroller and how to generate and make use of the code generated by the STM32QMX. Let's start by explaining the physical connection of the microphone. On our L4 Discovery board there is an embedded microphone which is a MEMS based microphone and it's connected through two wires, audio clock and the audio data in. Those are respectively PA9 and PA7. PA7 is the line which transmits the data from the microphone to the microcontroller and PA9 delivers the clock source from DMCU to the microphone. The microphone needs a clock source from 1 MHz to 3.5 MHz to work properly. DFSTM role is to convert PDM format bitstream to PCM, which is a parallel data format with 24-bit resolution, much easier to be handled by the microcontroller. Our system is working at 80 MHz, the microphone input is clocked with 2 MHz and the output sampling frequency in PCM format will be 8 kHz. The maximum resolution of the output signal is 24 bits, being the rest of the 32 data which contains information about the channel configuration. As we just finished our theoretical presentation, let's now open STM32 Cubemix to start generating our code. With STM32 Cubemix open, our first step will be to click on New Project, we will type our part number STM32L476VG and then we will double click on the part number to start a new project. As you remember our microphone is connected to the microcontroller through the lines P7 and P9. To simplify the task of finding the correct pin, we may just type P7 which will alight the pin. We select it with the left button of the mouse and as we can see it is assigned to the DFSTM data in 2. So by going to the peripheral tree, we go to the DFSTM1 channel 2 and we will enable the mode DFSTM SPI channel 2 internal clock. So we will be using the internal clock provided by the MCU and the data will flow through the channel 2. P7 is assigned correctly, yet the clock line needs to be reassigned to the right pin. So by holding at the control key, we will relocate it to P9. This is just simply dragging it from its initial position to P9. On the clock configuration tab, by default we have 4 MHz MSI clock selected, but as we agreed to run this program at 80 MHz, we will need to change it. As you can see, we can't run it directly from MSI. Since for running at such high frequencies, we will need some PLL support. Fortunately, QBMX will handle all these changes for us. We just need to press OK and he will change everything to run with 80 MHz and this will happen through PLL. Let's have a look on the clock source for DFSTM. It is driven from the peripheral clock 2 as we were expecting. Let's go now to the biggest part of our configuration, which will happen on the configuration tab. On control session, we are going to select the DFSTM icon. And on the channel number 2, we should see the configuration SPI with rising edge and SPI clock should be internal SPI clock. No analog watchdog configuration will be preformed. More information about watchdog or any other parameter of the DFSTM can be found on the detailed theoretical presentation as they won't be covered during the hands-on session. We will press on apply and then we will go to the output clock window. In the output clock window, we will configure the clock source which goes to the microphone itself. As you recall, our system is running in 80 MHz and to achieve the 2 MHz for the microphone input clock, we need to set the divider to 40. This will be all for the clock parameters. And we will press apply to save the configuration. We have 4 filters available and they can be assigned to any given channel. In this session we will be using filter 0. We have 2 options when choosing which channels to be filtered. The regular channel selection or the injected channel selection. The difference between these 2 modes can be found on the theoretical slides once more. As we are just using one microphone, no switching between source signals is needed and we can just use the regular channel selection and assign it the filter to the channel too. We will select continuous mode as we want to have continuous conversions and the trigger to start conversion will be by software. The rest of the parameters will be handled after DMA configuration. The next step will be the configuration of the filter itself. The reason why we need filtering while using DFSTM is because we are converting the data from the PDM to PCM format, so over sampling needs to be considered. Here we can select the filter order. In our example we will be using sync3 filter type. Now we specify the output frequency. As we aim for 8kHz output frequency and our microphone is running at 2MHz we need to set FOSC to 250. So to wrap up 8kHz multiply by 250 will give us the 2MHz input clock source. The next parameter we will leave it as one. We will press apply to save the configuration and now let's go to the DMA configuration. With such high flow of information coming out of the DFSTM unit it is necessary to have support of the DMA to ensure smooth processing of the information. We will enable DMA from peripheral to memory and we will use standard priority as there are no other peripherals using DMA. Data length will be worth both sides and we will use memory increment. In mode we will use circular as we have continuous conversions of data on the buffer. We press apply and we will return to the filter zero configuration. We need to enable both fast mode and DMA mode. Fast mode is used as we just have one source of data, so there is no need to pre-fill the filter configuration each time. DMA mode is enabled as we are committing this filter to use DMA on its transfers. We will press apply and we just finish to configure the DFSTM peripheral for this specific application. As everything is configured we can just save and generate the code using system workbench for STM32 as our IDE. After the code is generated by STM32 Cubemix and our project is loaded on system workbench for STM32 we will open our main.c file stored inside of the source folder. On the main file you are supposed to see the initialization of all peripherals defined on STM32 Cubemix. In this specific case we can see the system clock configuration, DMA and the DFSTM unit which will be in focus on this session. As a first step we will initialize a buffer where we will store our data to be transferred through DMA. We start by defining a constant value which will be used as the length of the buffer. So we type define audio rack 1024. Then we proceed to initialize the buffer itself and it will be in 32 rack buff audio rack inside of the brackets. Although we are initializing a 32-bit long buffer it is important to note that each chunk of data stores 24 bits of significant audio data plus 8 less significant bits which are filled with data about the channel configuration. The next step will be to start the DFSTM peripheral using HAL functions. In this case HAL DFSTM filter regular start DMA. The four input parameters of this function are the handler to the DFSTM peripheral, the pointer to the buffer location and the size of the transfer. This function will start the acquisition of that in the DFSTM unit and as you recall in our configuration moment it will be triggered by software and mediated by DMA as the function's name suggests. We will proceed to compile and debug our code. On debug mode we will add to monitor our recorded buffer and if we would press resume and let it run for a while when we would pause we will see some value stored on it. If we would process and plot the data we would realize that the content does not look like an audio information and this is due to the fact that we did not treat our data and clear those 8 less significant bits from the PDM to PCM conversion. This is a common mistake when implementing DFSTM for the first time. As you might be guessing in the second part of our example we will implement a typical continuous reception of data where we will treat the data getting rid of those extra 8 bits. So let's start by creating an additional buffer which we will fill with treated audio content. We will initialize it just like we did before. So int, play buff with the same length. We also need to create two additional flags, one for complete and the other for half of complete reception of DMA transfers. When using DMA in circular buffer topology we will be able to make use of the recently transferred data, processed it and store it on the play buffer while in the second part of the DMA buffer is being filled in the meantime. So to make it clear whenever half of the buffer is completed we will treat this information while in the other half is being filled with data coming from the DFSTM unit. The DMA unit generates independent interrupts when reaching the complete and half complete size of the buffer. So to make use of this feature let's go to the STM32XXHALDFSTM.C file and we will copy the initialization of both interrupt service routines. Those can be found manually browsing the file or by simply pressing CTRL-F and search for the weak functions. We will copy them into the main file and we will set each flag inside of respective interrupt service routine. On the infinite loop we will proceed to check if any flag was set during the execution and in case if yes we will treat the content to be stored on the play buffer and logically clear the designated flag. To treat the content we just need to right shift the data 8 bits and this way we will get rid of the unnecessary data generated during the PDM to PCM conversion. We will apply this process to both halves of the buffer and then we will be ready to build and compile the project. We will start the application and add the play buffer to the monitor with expressions. If we would plot the data stored on it we would see a typical audio waveform. It is important to note that for this hands-on to be successful we need to apply an audible audio source so the microphone and DFSDME unit can clearly capture and convert the data. This will be all for this hands-on. Thank you for watching.