Purpose:
After completing this lab, you will have an understanding of how to configure and add the Harmony Universal Serial Bus (USB) Library for Mass Storage Device (MSD) class using MPLAB® Harmony 3 Configurator (MHC).
Overview:
This lab extends audio_player_lab2 by adding Secure Digital (SD) card reader functionality. The audio_player_lab3 application shows how to edit the contents of an SD card. The PIC32 Multimedia Expansion Board II (MEB II) is connected to a USB host, (typically a PC) and after a successful enumeration, the SD card is presented as a mass storage drive on the PC allowing you to add or delete contents.
You will add a new task to handle the USB device events for the SD card reader. Apart from registering a USB device layer events handler, the application need not intervene in the functionality of the Mass Storage Device (MSD) Function Driver since the MSD Function Driver does not provide any application callable functions.
You will also add a task to handle button (switch S1 on the MEB II) press events. Pressing switch S1 will allow you to switch between the SD card Player mode and the SD card Reader mode. By default, the SD card Player mode is selected and the application will read and play the tone.txt file (if present) on the SD card. When switch S1 is pressed, the device will act as an SD card reader allowing you to connect to the PC and load files (tone.txt for this lab) to the SD card.
For Lab 3, you will be able to play audio data saved in a tone.txt file by loading it through the USB interface. For subsequent labs, you will be able to play WAV files by loading them to the SD card using the USB interface.
Lab Source Files and Solutions:
If you haven't already, download the lab source files and solutions.
This project has been verified to work with the following versions of software tools:
MPLAB X IDE v5.25
MPLAB XC32 Compiler v2.30
MPLAB Harmony v3.3.2
DEV_PACKS v3.5.0
CORE v3.5.0
CSP v3.5.0
BSP v3.5.0
AUDIO v3.4.0
USB v3.3.0
As the tools are regularly updated, there may be occasional issues while using newer versions. If that is the case, we recommend using the same version as specified in the project.
The archived versions of our tools can be found below:
MPLAB Harmony
MPLAB X IDE and XC32 Compiler
Note: Multiple versions of all these tools can co-exist on the same computer.
Procedure:
This lab builds off the work you performed in the previous lab. If you did not perform SD card Audio Player Lab 2, please start Lab 3 using the Lab 2 solution project (found under the firmware folder). Verify that it works as expected before continuing with this lab.
All steps must be completed before you will be ready to build, download, and run the application.
Lab Index
Step 1: Copy source files and rename project for Lab 3
Create a new folder, audio_player_lab3, under
apps/training/solutions/dev/audio_player.
At this point, we suggest you close any open projects from previous labs. This will avoid confusion since you will be opening the project with the same name as the previous lab before renaming it for this lab.
Copy the firmware folder from
apps/training/solutions/dev/audio_player/audio_player_lab2
to the newly created folder (audio_player_lab3).
Rename the project from audio_player_lab2 to "audio_player_lab3", because by the end of this session the lab will have audio_player_lab3 functionality. Open audio_player_lab2.
Under Projects, right click on audio_player_lab2 and select Rename…
In the popup window, rename the lab from audio_player_lab2 to "audio_player_lab3".
MPLAB X IDE renames the project. It closes the old project audio_player_lab2 and opens the renamed project audio_player_lab3.
Verify that the project builds properly after renaming. Click the
Clean and Build icon:
.
In the MPLAB X IDE Projects pane, right click on audio_player_lab3 and select Set as Main Project.
Open MHC. In MPLAB X IDE, click on Tools > Embedded > MPLAB Harmony 3 Configurator.
Step 2: Configure the USB Library
Select the MHC Project Graph tab. Remember, if you ever "lose” the MHC tool, you can find it here under Tools > Embedded > MPLAB Harmony 3 Configurator.
Add a USB Device Layer stack into your project from the Available Components window.
Expand the tree Libraries > USB > Device Stack and select the USB Device Layer.
At this point, you will be asked to auto activate some components required by the system. Select Yes for the USB High Speed Driver.
Your Project Graph should now resemble the screen shown below.
Attach a MSD Function Driver to your SD Card driver.
Right click on the green DRV_MEDIA attachment box. From the Satisfiers list, select MSD Function Driver.
Your Project Graph should now resemble the screen shown below.
Configure the USB device layer.
You can now click on the USB device layer component box to display the configuration options available for this component. Set Product ID Selection to msd_sdcard_demo2.
Configure the SD Card SPI Instance 0.
Click on SD Card (SPI) Instance 0 to display the configuration options.
Increase the Number of Clients value to 2.
Save the MHC configuration.
Step 3: Generate Harmony code
Expand the source file folders in the Projects pane. Notice that these are the files from Lab 2 that you copied to this directory.
Click on the Generate Code button as shown in the following figure. Notice the Merging Strategy option.
Note the new USB folders added to the lab.
Check for Harmony 3 issues in previous released versions.
In previously released versions of the Harmony 3 USB code (USB 3.3.0 and earlier), there were some issues that needed to be resolved in usb_device_init_data.c. The directory structure below shows the location of this file, which MHC generates.
In the usb_device_init_data.c source file, set the size of flashRowBackupBuffer (line 71) to "2048".
Also, In the source file usb_device_init_data.c make sure the function names are changed to "AsyncWrite" (line 110) and "EventHandlerSet" (line 112).
If you do need to modify these lines, the next time you generate code, you will see the following merge screen displayed. Just press the Close button.
Save all files and build the code. To do this, click on the
Clean and Build icon
and verify the project builds successfully.
At this point, you should be able to debug and step through the application. Effectively, you have a running MPLAB Harmony system. However, it is not yet ready to do anything. Next, you will develop your application state machine logic and make sure the system does what you want it to do. You’re ready to start implementing the application now.
Step 4: Include application-specific source files, add required code and build the project
Copy the source files into your project's Source Files folder:
app_sdcard_reader_task.c
app_sdcard_reader_task.h
app_button_press_task.c
app_button_press_task.h
Copy them from the following folder:
apps/training/solutions/audio_player/audio_player_lab3/dev_files
to this one:
apps/training/solutions/dev/audio_player/audio_player_lab3/firmware/src
Add the copied source files to your project.
Add app_sdcard_reader_task.c and app_button_press_task.c to the Source Files folder (in the MPLAB X IDE Projects pane) by right clicking and selecting Add Existing Items…
Add app_sdcard_reader_task.h and app_button_press_task.h to the Header Files folder by right clicking and selecting Add Existing Items…
The files under the project should look like this:
Open the app.c file and add the function prototypes for the SD card reader and button press tasks.
Add the initialization routines for the SD card reader and button press tasks.
Modify the APP_Tasks function to add the two newly added tasks, under the APP_STATE_SERVICE_TASKS state.
Add two functions that will set and get the current mode of the application. This will execute either the player functionality implemented by the APP_TONE_TEXTFILE_SDCARD_Tasks, or the SD card reader functionality implemented by the APP_SDCARD_READER_Tasks.
Now, open the app.h file and add the following enumeration. This will be used to manage the application modes.
Next, modify the APP_DATA structure to include the application's mode related information.
You also need to expose the set and get mode functions to other tasks. Include the following declarations in the app.h file.
Finally, open app_tone_textfile_sdcard.c and add the following include file and condition. This will ensure the APP_TONE_TEXTFILE_SDCARD_Tasks function runs only when the audio playback mode is selected.
Note: You must also add the closing bracket for the if condition.
Save all the files before closing.
Now, you are ready to build the code. Click the
Clean and Build icon and verify that the project builds successfully.
Step5: Review the Application code
Application File: app_tone_textfile_sdcard.c
This file remains the same as in audio_player_lab2, except for the condition added above, which makes sure that APP_TONE_TEXTFILE_SDCARD_Tasks runs only when the application is in Audio Player mode.
Application File: app_tone_textfile_sdcard.h
This file remains same as in audio_player_lab2.
Application File: app_sdcard_reader_task.h
Open file app_sdcard_reader_task.h. This file defines application enums, data, and Application Programming Interfaces (APIs).
The enumeration below defines the states of the SD card reader task.
Only two states are needed as the entire functionality is handled by the USB MSD class driver.
The SD card reader data structure holds information on the USB device handle, current state of the task and whether the USB interface is detached or not.
Application File: app_sdcard_reader_task.c
Open the app_sdcard_reader_task.c file. This file contains the SD card reader task initialization routine and the SD card task function.
The APP_SDCARD_READER_Initialize routine initializes the task to a known state.
The APP_USBDeviceEventHandler function notifies the application of USB MSD events.
The APP_SDCARD_READER_Tasks function opens the USB device and registers the USB device layer event handler. After this, the task enters the run state. From here on, the USB MSD driver handles all the events and there is really nothing that the application needs to handle for USB SD card read/write functionality.
The APP_SDCARD_READER_AttachDevice and APP_SDCARD_READER_DetachDevice functions attach and detach the USB device respectively.
Application File: app_button_press_task.h
Open the app_button_press_task.h file. This file defines the enums, data, and APIs related to the button press task.
The APP_BUTTON_PRESS_TASK_STATE enum helps maintain the states of the button task.
The APP_BUTTON_PRESS_TASK_DATA data structure holds the button task's state and button de-bounce related data.
Application File: app_button_press_task.c
Open the app_button_press_task.c file. This file initializes and runs the button press task.
The Press Task button uses the system timer service to implement de-bouncing. When the user presses the button, while the application is in Player mode, it suspends the audio streaming and un-mounts the file system. It then attaches the USB device and switches to the SD Card Reader mode. Similarly, when the user presses the button, while the application is in the SD Card Reader mode, the USB device is first detached, the tone text file SD card task is initialized and the application mode is switched back to SD Card Playback mode.
Step 6: Debug your Application
Congratulations! You’re done. You are ready to debug your third application.
Before you program and run the application, delete the tone.txt file on the micro SD card. You will load the tone.txt file using the newly added SD card reader functionality.
Make sure that the micro SD card is inserted into the micro SD card slot (J8) on the MEB II.
Connect a USB cable from the micro USB connector (J4) on the PIC32MZEF Starter Kit board to the PC.
Connect a headphone to the HP Out connector on the MEB II.
Before you start the debugger, you may want to set a breakpoint in the application file in app_button_press_task.c to verify that the application reads the button press and switches to the appropriate mode.
Debug your application! Click the
Debug Main Project icon.
The application boots in the SD Card Player mode. You will not be able to hear the tone as the tone.txt file was already deleted from the micro SD card.
Next, you will load the tone.txt file to the SD card from the PC. Press the switch S1 on the MEB II. Verify that the breakpoint is hit and the application mode is changed to SD Card Reader mode.
Remove all breakpoints, press the F5 key and allow the application to run.
Wait for the PC to enumerate the USB MSD. Verify that the device appears as a Removable Storage Device. On a Windows machine, do this by clicking on the My Computer (or Computer) icon. Click on the drive and copy the tone.txt file.
Once the tone.txt file is copied, press the S1 button to go back to the Player mode. Plug your earphones in and you should be able to listen to the tone!
Results
You should be able to view and edit the contents of the micro SD card by connecting the device to the USB host (PC). You will also be able to switch between the audio player functionality and the SD card reader functionality through the press of a button.
Analysis
In this lab, you added USB MSD support using MHC. You also demonstrated how MHC is capable of handling multiple clients that access the same SD card media. At the application layer, you added a new task (state machine) to handle a button press event to allow the users to switch between the audio player and SD card reader modes.
Conclusions
You added USB SD card reader support, thereby bringing your application one step closer to a full-fledged audio player. The lab demonstrates how easily you can add USB MSD class functionality to your applications. It also shows that there is little to no application overhead when it comes to handling MSD class events, as all these events are handled by the USB library. Going forward, you may want to add USB host functionality to the device to read a file (e.g., tone.txt or audio files) stored on a thumb-drive.