STM32 HAL with CubeMX: Tutorial 43 - WAV Player from USB Disk

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hello everyone this is muhammediye coupe and I am showing up again on YouTube to share with you an application that I have develop recently and that is how to play a WAV audio file from the USB Drive out to the audio headphones and as you know it's in 32 of for discovery features an audio codec that we can use to play an audio out and also you speed to plug in a USB Drive alright so I have to say that I had lots of fun preparing this video and this is the ultimate one moment let's share it together the very first thing we're going to do is to open cuba mix and set up our pen outs and then we're going to jump into a steamfitter cube ide to carry on the programming and for this tutorial i've created about 4 files it's two libraries and the audio cs4 three l22 that I've already shared previously on YouTube I've previously shown you how to play an analog passer through and a generic I 2's signal this time it will utilize that audio library to read our file from USB Drive and play out in the headphone okay so what you want to do is to go to access board selector okay now on its select our board so it's the stm32f4discovery you want to select it and set up the pin out I don't want to initialize to their default mood all right now the first thing I'm gonna do here is that I want to clear all the pan out and let me walk you through the user manual of the discovery board just to give you an idea of what are the sort of pins we need to set up for this tutorial so let's head to the user manual I'm gonna be using USB so if you navigate down tube 835 of the user manual that is the USB on-the-go of fast speed and here there is one required pin the I need to enable so PC zero is a GPIO pin that I need to enable this is the power switch on the switches power to USB and since we're gonna use USB in host mode which means we're gonna plug in an external device a USB Drive which require five volt power and that's what this PC zero does so in Cuba makes me want to set PC 0 2 GB are you enable it and set it to low because it's an active low enable signal and then wanna enable USB interface and that's ba-ba 11 and be a 12 in addition to the v bus on PA 9 so that's about the USB let's go ahead and set it up together and we're gonna come back again and look at the audio schematic alright so that's quite simple when i go pc 0 city to TBI 2 output and by default it is set to low so this is already low so now power should be enabled to our USB connector alright now next thing we do is to enable USB so if you head down to connectivity I believe and USB on-the-go FS it's a host mode and activate the bus and you can see PA 11 be at 12 and be 8 9 enabled so that's awesome and regarding parameter settings we're not gonna change anything on here okay and the next thing you want to do for USP is to head down to middleware way to enable USB host so USB host set it to mass storage horse to class because we read files from it's like a USB Drive okay parameter settings we're gonna leave everything as default the next thing we need to do is to enable a fat effects file system for it so using the USB disk okay and next next thing we need to do is for the audio library so let me head back to the to the user manual now on the user manual if I scroll down to the audio schematic or maybe scroll of instead let's have a look here we go so this is the audio schematic and you can see we've got a few pills here the very first one is the I squared C to communicate with the audio device and that's from pb6 and vp9 so back home cube X so we to set bb6 to I to see one serial clock and vp9 to I to see one data and on connectivity I squared C 1 we need to enable it in i2c mode and leave everything else as default state then we have BD 4 which is the reset burn this is used by the audio library to activate and deactivate the audio device it's like a hard reset and that's from BD 4 so when able BD 4 and 6 2 GPIO outbursts and then we need to enable the audio interface line so that's 1 I 2 is 3 I believe and those are PC severed PC to PC 12 and BA for all right so we're gonna enable it automatically and let's see if it's going to enable the correct bins right so we went ahead to multimedia and I to s3e to enable this as half duplex master unless enable indeed pc10 pc-12 BB na sorry PA for so let's double check again so we've got PC 10 for cereal o'clock pc-12 for serial data and ba for forward select are we going to need to enable master clock on PC 7 okay so will you head to this you can check master clock output and it is indeed on PC 7 and then the next few things want to do is when enabled LED zone on the steam discovery boards or PD 12 to PD 15 are the onboard LEDs I believe you are already quite familiar with this and PA 0 for the button I'll use button in my application to demonstrate how to play an audio pause and resume and stop it completely and so on we can use the push button for that right now we need to do quite a little bit of clock settings to set up correctly for i2 s so we went ahead to RCC first and enable the external oscillator and that is enable on P H 0 H 1 and not on a clock configuration we want to set this up I am using the external oscillator and I want to set the maximum clock speed of 1 6 8 megahertz another important one is the art I - s wait to feed at 1 megahertz because in my software i assume that PLL i2 s input is 1 megahertz and I accordingly change the prescaler and divider to achieve the correct i 2's clock alright so we're going to set this to 8 and multiply this by 2 so that we retain the same maximum clock speed there we go alright and I want to set this to I want to change this I've got an arrow here currently set to 50 which exceeds the limit so I'm gonna change the prescaler to 271 so that's something that gives me about and I set the divider to 8 I think 6 that gives me 4 to 5 megahertz so that's that's a good initial value but that doesn't matter as long as the inverse is 1 mega Hertz and this is a valid output it doesn't matter at this stage because I already change it in my software based on the wave file sampling frequency all right I hope that makes sense now we're gonna head back to I 2 s settings so on I - s let's see everything is ok so I'm as I am assuming 16 bits data frame and let's select the initial audio frequency - 44 kilo Hertz ok and that's pretty accurate that's 0.24% button software everything gets changed as I said and then I want to enable DMA for i2 s transmit buffer because we're gonna use deep a to transmit the audio buffer out to the headphone so on DMA of i2 s select s p i3 TX and now the reason why we have this VI here and not i2 is is that in esteem 32 s P I and I - as share the same data buffer and same hardware pretty much okay but sir but it's the same thing and for D may mood I wanna set to set it to circular and use a FIFO with a full threshold and the data with our half Ward because we're using 16-bit 16-bit on i2 s so that's a half Ward and full Ward is 32 bits on stm32 ok and that's pretty much everything these are all the things we need to do for I 2 s DMA alright and that's everything we need to do on pin configuration and now we're ready to generate a project so important manager give the project a name I will pull it Web Player tutorial and I want to select the right folder to store in so honest tour it at this very location yeah I think that's the correct location where I wanna store it and the idea I like to start with system work pin force T in 32 instead of Q by da because for some reason mark your body is not stable with this so I'll select system workbench you can select any IDE that works for you it doesn't make any difference okay but I'll be using cube IDE I'll export it to queue by DA and I wanna change the minimum heap size to 0 X 2000 and X because my application requires some dynamic memory allocation and we need to ensure it's sufficient and same thing for stack size and that's it and I believe this is the right firmware let me just double check this is the firmware I have no I want to use firmware 1.2 4.1 you can use any firmware you like it should work the same as long as to say recent firmware and a stable one ok now let's generate the code that says no I would have to change this so let's redo that again it will work there we go and I click yes I'm gonna wait for it to generate the source code alright and now we're gonna head to open folder and copy project path and I will open a steam 32 cube IDE I'm gonna use a cube IDE for this quality people now use cube ID and I like it to I used to use system workbench now I'm switching gradually to system 32 15 32 cube IDE it's a very very nice tool ok so heading to sniffing cube IDE click on file open projects from file system I'll give it the path of the project I'll click finish now it will have to do some convert to convert it to cube IDE format but that's fine because when I use cube IDE the raw format it seems to crash for me I'm not sure if I'm the only one having the issue but using it this way there's no problem at all it will work the same so let's wait for that to finish all right it finished exporting the project to cube IDE and now this is my way of player tutorial and you can see it's an empty main has to go only the set up by cube of X now let me let me build the project just to ensure things are ok and now what you want to do is that I'm connected these are the library files that I will share as part of this tutorial so this one the c is for 300 22 i've already developed this and i share it in a previous tutorial video I've just made slight modification to its regarding audio volume so I might updated there too and now and these are the new libraries that I've written this time written an audio i2s that controls I to s configuration like sampling frequency it starts DMA transfer and stop that and wealth player is responsible for WAV file format reading from USB disk and making all the required configuration for a WAV file we're gonna see that in detail in a bit so what you want to do I'm gonna share these down in the description of the video and I believe for this tutorial I'm not sure the entire get hub repository for this project to make things easier for people who do want to start from scratch but I highly recommend that you do start from qmx and do the things step by step because this way you're gonna learn and feel free to discover the libraries here and my main reference into developing these libraries are stm32 example service the examples they provide example of playing our file from USB disk to the audio headphone I'll have used that example to make a very a much simpler version of their libraries so that's my main reference into this tutorial alright now what you want to do is that you want to copy the audio folder into your into our Web Player tutorial project so I want to just copy it here okay and now I need to add a path to it and include it as part of the source folder you see it doesn't have the C sign which means compiler doesn't compile this folder so what you want to want to do now is to right-click on this and go to properties and on here and our C C++ general go to past and symbols and the first thing I will do is I want to add a path to this folder so click on add and add audio so that all the hitch file are a built in compiled and same thing on source location add a folder and add our audio and that's it now it should change and should have the C sign on it there we go as you can see here alright so now what we want to do is that our going to start including files into my main so as a step one I need to include my audio i2s and my Web Player at the same time my cs4 three l22 so I don't include all these hitch file into my main ok so let's do that and you can click control space - it's matically right that and the other one is my c is for three l21 l22 sorry and the web layout API okay and then if you can recall from our USB flashdrive tutorial we need to export the application state because we need it when we initialize USB and if we want to know whether USB Drive is connected successfully or disconnect or it is ready to be used and we do that by going to USB host and it's rather USB horse to see and there we see this variable application state so you want to copy this into our main as external so I'll put it here it's an external variable so that compiler can see it and add it to our main so that we can use it all right and then what you will do is that I'm going to set up my audio codec first so these are things like initializing the audio codec sitting volume and enabling right and left so let's do that and this is actually quite similar to my audio tutorial previously so first need to initialize the audio codec and I'm going to do that in bigger number two that's the ideal place for it after all peripheral initialization and this function require an IQs handle and the output mood and I want my mood to be i2 s and you can see that when you navigate to mood we have I to s or analog password in our cases and i2 s so let me copy that so the first one is I try to see handle is i2 c1 and the other one is mood alright so let me copy this this is i2 s and then we're set Warrior as I said at the very beginning of the video that I made a slight change to the volume to the suit volume API so what this does now is that this is from 0 to 255 0 corresponds to mute and 255 corresponds to maximum but trust me you don't wanna use 2 5 5 with a headphone it is super loud so I think you start with 150 is a good starting point and and then when enable right and left I'm just going to copy it over from my note it's way quicker so enable writing left basically means you enable both bright and lifts of the headphone okay so that's it that's all for the initialization of the audio library now let's initialize the i2s library now let me give you a brief description about this library and what it does so the audio I to s API library does things like playing starting the DMA the i2s DMA changing the system clocks the PLL of the i2s so that it matches with the wife while sampling frequency so so the magic it does is that it changes the I to is clock frequency to play different sampling frequency depending on the file that we read from USB Drive okay so that's what it does and we can use it to also start the codec so instead of starting each of them separately we can just call this play it will start the codec and also start iqs DMA transfer okay and I'll leave that with you you can look at it in details and you or that you're in your own time and find ways to perhaps improve it or make changes to it but this one pretty much you might not make more changes here okay so to initialize this I need to call its initialize function and pass in sorry I need to call this sit handle rather and passing the I to is handle that contains all the configuration of our r2 is okay so that's we're going to call it here and pass in a pointer to the only two is initialization handler okay and then what we're going to do next is to start developing our application the first thing I want to do is that I want to test my USB connect and disconnect functionality so to do that I will use the application state variable so this particular one if you can go there you can see that it has got all these in um state so I want to check if my USB is connected then I'm going to turn led on if it's disconnected I turn it off so that's the very beginning to ensure our USB is a USB library is working fine and then we're gonna move on and start implementing the Web Player functionality so if application state is if this one is equal to what's the state start physical the application start then I know my USB is plugged in and as being and it's being processed and opened and then else if state is equal to disconnect mean disk is just been unplugged so this is equal to disconnect then I want to turn LED back off so let me just copy over from my notes there we go so I sit green LED and I reset it we're Gnaeus be as unplugged so let's compile the code and look over into our esteem discovery board and just double check that things are actually walking on the USB side as we expect all right awesome we now know that our USP is working fine okay then next step we're going to do is that to mount our USB Drive into file system and we're gonna start implementing our Web Player now monic USB Drive has got a couple of web audio files that I stored at this file path though let me copy over from my notes so private variables I define this to where file 1 and the path is in audio directory and it's called Araki to do it we're okay so that's a very nice music then what we need to do next is that to check if application state is ready bush means that USB Drive is really to be used not just at the start state but in the ready state then I want to start implementing my application and I'll show you all the fun of playing our file so if application state is ready first thing I want to do is to mount my USB Drive to a file system and you do that with F mount and I all you want to do it once so let's do this so if mount and you need to pass in the FATA first variable and you will find it and we go to middleware ast I think third party fatty phase it's basically fat if I search you just navigate there and you'll find the variables that I can use as an extent so the first variable is for the first file system so let's use that and it needs a pointer to that I believe exactly and then the drive path and we're gonna mount it immediately or just do that on the go so let's do that so that will be our USB path you will find it in the fatty phase let me copy it and it expects a constant teach our type it's the same thing but let me typecast it just in case each our pointer and I pass in the USB path and then write zero here and I only want to do this once since application really will keep looping into my while loop by only one amount this D card once so I'll just add a boolean variable for simplicity and cool it is is the Kart mounted citizen itial e20 and i want to check for this condition in my application really so that's a very simple implementation you can do way better if you have an art or so things like that so if SD card is not yet mounted so if it's equal to zero then i will apply this code and I will set this variable to one so that doesn't interrogate here ok so that's step one and then starting with the fun now the way I want to implement a web layer in a very simplistic way I have only a single push button on the STM for discovery board and what I want to do is that when you first press the push button it starts playing the selected file and when you press it again it poses and resume so any press will be pause or resume if you hold the blue button while on the board state if you hold it for a half a second then it's gonna stop the folder and you can start again by pressing to play they owe to you again I hope that is not confusing are we gonna see this anyway right so step one is whenever my push button is pressed I'm gonna use a condition like this if hull TBR is a very simple been read if my PA 0 which is the blue post button is high then I want to sit the orange LED on and I want to wait for half a second just to allow a delay still a bit of delay without having to get this condition so often and then step one now we're gonna use our web player that's a fun bit so this is the web player library let me give you a quick walk through this library so what this does is that it has a web header which reads the first 40 bytes or 44 bytes of our web or file that we read from USB Drive and it specifies what are these parameters so that we can set our system accordingly things like sampling rate is very very important okay there we go now the first thing we need to do is to select the file so file select we're gonna call this file select simple function I've created this worth player in a very simple way you can get go through it if you want to make changes to it depending on your application but you'll will get to see that it's very very simple indeed so first thing we're gonna select the file that we're going to play hello I'm gonna play this file where file 1 I called it so when I pass a path to this file there ok that's it and then I want to start playing this file so I'm gonna call a function called play so this will just initiate the player it's not gonna play continuously so you need after you call this you need to call another function called a process so wealth process is the one that will continuously check if there's something to process in the wealth API and you can see the implementation of it is quite simple prayer if the state is normal then it's gonna swap buffers and or stop if it's at the end of the file or remain an idle state if there's nothing to process so into your while loop so that corresponds to placing this process into your while loop in your application to constantly monitor for something to process ok so I'm gonna call it here however I'm gonna call the process until the end of my file so I'm gonna put it into a while loop here there's a function called is finished so if the file is finished in the file so if it didn't reach the end of file it will keep in the while loop so if it's not and the file then carry on and continue processing the left file okay so this is the rank you in a call here and now while I'm in the infinite wire loop if my push button is pressed again I will implement pause and resume so I need to check for this condition again alright so if my push button is pressed while the file is playing then I want to either pause or resume so let me use a simple variable called toggle so I'll call it boys with you toggle so this will switch between either we toggle either we bows or resume based on the state of this variable so so I'm gonna whenever this button is pressed and I will toggle this variable I'll do an X or which will change the state from 0 to 1 or 1 to 0 accordingly now if this one is high then I want to boys if it's lower than I will resume okay so let me copy the code from my note is very very simple in do so those are engine called boys in my wife player I get here is so pause and resume when the one a button is pressed then I do a boys and then if it's pressed again then I will do a I'll do resume except while it's in the well let's not overcomplicate that let's make it very very simple now so this is what I said I'm gonna do it for you and I well praying the radial IDI back to Lord so this will light up the red LED whenever we pose and when your resume red LED goes off now an additional thing that I want to do is that before we resume if the button press wasn't assemble press if it's a hold then i will completely stop playing the file and we do that by doing something like this so I'm gonna put a delay here of half a second if we press the button more than half a second or maybe let's make it one second for simplicity if we press it for more than one second then it's going to stop the file so let me say so if after one second the button is still pressed then I want to stop instead of just throw instead of resuming and this only occur and while the music is in the pawza state okay there we go and that's that's it that's pretty much it this is our demo and then towards the very end of the condition so at the end of the while loop so when we finish doing that our to switch this led off there we go so when we exit that while loop the player wire loop I will turn the orange LED back off I'll put a short delay of one second so that we don't keep the button pressed mistakingly so what's gonna happen now is that when you press button that plays presenter game balls resume hold it it stops so press again it plays so let's demonstrate that then let me compile the call to load it to the board and we're gonna have a look at the board and we're gonna hear a very exciting music at the headphone all right excellent who have heard audio at the outpost and now before I finish off the video I want to make a few notes for you this demo is based on 16 bits bit resolution so what you want if you want to make sure all wife files you have will work is to use one of these wife converters I quite like this one audio data online convert so what you can do with this is that convert any file format to have and what you want to do is that you want to change bit resolution ensure that it's 16-bit so what this demo only 16 bits work otherwise if you want to play specific 24-bit files or 8 bits of 32 you want to make some changes to the iOS frame format so you know is one of these frame formats and also change DMA data width and your audio frame buffer so these are the kind of changes you want to make when I play other format but first for simplicity I kept it constant so just change any file you have to 16 bits resolution a WAV file and it will play out very nicely alright this brings me to the end of this video thank you so much if you enjoyed it don't forget to hit like and subscribe and stay tuned for the next videos thank you
Info
Channel: Mutex Embedded - Education
Views: 12,778
Rating: undefined out of 5
Keywords: STM32, Cortex-M4, Embedded-C
Id: QPmFvSFyIbs
Channel Id: undefined
Length: 35min 50sec (2150 seconds)
Published: Sat Apr 25 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.