Purpose
After completing this lab, you will have an understanding of configuring and adding multiple modules (SD card driver, Serial Peripheral Interface (SPI) driver, and Files System Service) using the MPLAB Harmony Configurator (MHC). You will also learn how to integrate these modules into the MPLAB Harmony project. This lab should start to show you the power of Harmony!
Overview
This lab adds to the previous one. The audio_player_lab2 application reads an audio text file from the PIC32 Multimedia Expansion Board II (MEB II) SD card and streams it over the PIC32 I²S interface to the audio CODEC. The audio file is saved as a .txt file with comma-separated left and right channel audio data. The audio_player_lab2 application demonstrates the configuration and integration of the additional modules to audio_player_lab1 using MHC, thereby extending its functionality.
The naming of functions and variables used in audio_player_lab1 has been changed from APP_TONE_LOOKUP_TABLE_ to APP_TONE_TEXTFILE_SDCARD_. Otherwise the basic application flow remains the same.
APP_TONE_TEXTFILE_SDCARD_Tasks() |
APP_TONE_TEXTFILE_SDCARD_Tasks() adds four new states to the audio_player_lab1 state machine. These states are related to mounting the file system on the SD card, opening and reading the audio text file, and parsing the text file before the audio data is passed to the audio CODEC.
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 MHC 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: that 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 complete SD card Audio Player Lab 1, please start Lab 2 using the Lab 1 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 2
Create a new folder (audio_player_lab2) under
apps/training/solutions/dev/audio_player.
At this point, we suggest closing any open project from the previous lab. This will prevent 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_lab1 to the newly created folder (audio_player_lab2).
Rename the project from audio_player_lab1 to "audio_player_lab2", because by the end of this session the lab will have audio_player_lab2 functionality. Open audio_player_lab1.
In the MPLAB X IDE Projects pane, right click on audio_player_lab1 and select Rename…
In the popup window, rename the lab from audio_player_lab1 to "audio_player_lab2". Make sure that the Also Rename Project Folder option is selected.
MPLAB X IDE renames the project. It closes the old project and opens the renamed project.
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_lab2 and select Set as Main Project
Open MHC. In the MPLAB X IDE click on Tools > Embedded > MPLAB Harmony 3 Configurator.
Step 2: With MHC, Configure SD Card Driver, SPI Driver, and File System
Select the MHC Project Graph tab. Remember, if you ever “lose” the MHC tool, you can find it under Tools > Embedded > MPLAB Harmony 3 Configurator.
Add a SD Card (SPI) driver into your project from the Available Components window.
Expand the Harmony > Drivers > SDCARD tree and select the SD Card (SPI) driver.
The SD Card (SPI) component block will be displayed in the Project Graph window as in the image below.
Highlight the component block by clicking on it. The available configuration setting will display in the Configuration Options window. For this project change the following:
- SD Card Speed (Hz) to 20,000,000
- Transfer Queue Size to 10
- Chip Select Pin to RB14
Attach a DRV_MEDIA to your SD Card driver.
Right click on the yellow DRV_MEDIA attachment box. From the Satisfiers list, select FILE SYSTEM.
Your Project Graph should now resemble the screen shown below.
Click on the FILE SYSTEM component box to display the configuration options available for this component. Set Maximum Simultaneous File Access to 2.
Attach a SPI peripheral (PLIB) to your SD Card driver.
Right click on the red diamond for the SPI Instance 0. From the Satisfiers list, select SPI2. This matches the hardware SPI peripheral that is routed to the SD Card controller on the MEB2 Expansion Card.
Your Project Graph should now resemble the screen shown below.
Click on the SPI2 peripheral to display the configuration options available for this component. Select Slave select SPI support is disabled and 2,000,000 Baud Rate.
Save the MHC configuration by clicking the Save button.
Step 3: Generate Harmony Code and Build Project
Expand the source file folders in the Projects pane. Notice that these are the files from Lab 1 that you copied to this directory.
Click on the Generate Code button as shown in the following figure. Notice the Merging Strategy option.
Let’s examine what was done after MHC generated the code:
The Source Files folder contains files related to your specific application. In the following steps you will add your application code to the existing app.c and app.h files. You will also add other application-specific source files to the project.
The Source Files/config/default folder contains customized Harmony Framework files. These files have been generated by MHC in response to your specific MHC selections.
MHC has added some new (with respect to the previous lab) folders to this lab. Under Source Files/config/default new files were added to the driver and peripheral folders; sdspi, and spi respectively. These folders include source files that implement the Harmony SD card, and SPI Drivers.
MHC also added the fs folder under the Source Files/config/default/system folder. MHC knows the Harmony SD card driver requires the File System Service library, so it added it to the project for you.
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 and Add Required Code
Copy the following source files into your project's source files folder:
app_tone_textfile_sdcard.c
app_tone_textfile_sdcard.h
Copy them from this folder:
apps/training/solutions/audio_player/audio_player_lab2/dev_files
to this one:
apps/training/solutions/dev/audio_player/audio_player_lab2/firmware/src
Add the copied source files to your project.
Add app_tone_textfile_sdcard.c to the Source Files/app folder (in the MPLAB X IDE Projects pane) by right clicking and selecting Add Existing Item…
Add app_tone_textfile_sdcard.h to the Header Files/app folder by right clicking and selecting Add Existing Item…
Remove the application files from audio_player_lab1:
app_tone_lookup_table.c
app_tone_lookup_table.h
Right click on these file names in the Projects pane, and select Remove From Project.
Since you are retaining the app.c and app.h files from audio_player_lab1, you need to change some of the function names to correspond with the newly included app_tone_textfile_sdcard.c file.
Open the file app.c and change the name of the function prototypes
Then change the name of this function from
APP_TONE_LOOKUP_TABLE_Initialize() to
"APP_TONE_TEXTFILE_SDCARD_Initialize()"
in function APP_Tasks as shown below.
Similarly, change the name of this function from
APP_TONE_LOOKUP_TABLE_Tasks() to
"APP_TONE_TEXTFILE_SDCARD_Tasks()"
in function APP_Tasks as shown below.
Save the file before closing.
Step 5: Review the Application Code
Application File: app_tone_textfile_sdcard.h
Open file app_tone_textfile_sdcard.h. This file defines application states, data, and APIs.
Application states corresponding to the state machine, described in the "Overview" section above, are as follows. Note the newly added states highlighted in the red box.
The application data structure is shown below.
- The variable state and CODEC are retained from audio_player_lab1. They hold the state of application and codec related variables respectively.
- audio_player_lab1 had the audio data saved in a global buffer, whereas audio_player_lab2 will read ASCII audio text data from a file saved in the SD card. This ASCII data needs to be parsed. The variable textParser holds the ASCII text data to be parsed (see APP_TONE_TEXTFILE_AUDIO_DATA_PARSER below).
- fileHandle holds the handle to a file opened by using the File System API call SYS_FS_FileOpen.
- fileSize holds the size of the opened file.
- currentFilePosition holds the current file position.
- buffer holds the ASCII data read from the tone.txt file. The buffer serves as an input to the audio data parser routine. It converts the comma-separated ASCII audio values to binary integer values.
- nElements holds the number of ASCII values present in the buffer that need to be parsed.
- The CODEC data structure will remain the same. It is included here for completeness.
APIs for initialization, task state machine, and buffer completion events are declared.
Application File: app_tone_textfile_sdcard.c
Open file app_tone_textfile_sdcard.c. This file contains the application state machine and implements the APIs.
The implementation of function APP_TONE_TEXTFILE_SDCARD_Initialize sets up the default state of APP_TONE_TEXTFILE_SDCARD_Tasks and initializes the variables for the CODEC driver, along with other variables.
The function APP_TONE_TEXTFILE_SDCARD_Tasks implements the task’s state machine as shown in the figure in the "Overview" section above.
As with audio_player_lab1, it starts in APP_TONE_TEXTFILE_SDCARD_STATE_CODEC_OPEN state and remains in it until it opens the CODEC driver and gets a valid driver handle.
The state APP_TONE_TEXTFILE_SDCARD_STATE_CODEC_SET_BUFFER_HANDLER registers a buffer event handler with the CODEC driver.
The state APP_TONE_TEXTFILE_SDCARD_STATE_CARD_MOUNT mounts the FAT file system to the SD card.
After the file system is successfully mounted, the state machine enters APP_TONE_TEXTFILE_SDCARD_STATE_CARD_CURRENT_DRIVE_SET state where it sets the current drive of the file system to the specified path and then opens the tone.txt audio file.
In the APP_TONE_TEXTFILE_SDCARD_STATE_READ_FILE_SIZE, the size of the opened file (tone.txt) is read.
The state APP_TONE_TEXTFILE_SDCARD_STATE_CARD_READ reads the ASCII audio data contained in the tone.txt file and passes the read buffer to the APP_TONE_TEXTFILE_SDCARD_Parse_Audio_Text_Data routine, which converts it to binary data and saves it in the buffer pointed by the CODEC variable.
The entire tone.txt file is read and converted in one shot, and the audio data buffer appToneTextFileSdcardToneBuffer is updated.
In state APP_TONE_TEXTFILE_SDCARD_STATE_CODEC_ADD_BUFFER, the application submits audio data buffers to the driver queue and enters into a waiting state (APP_TONE_TEXTFILE_SDCARD_STATE_CODEC_WAIT_FOR_BUFFER_COMPLETE) for the last submitted buffer to complete. The number of buffers queued is equal to queue_size-1 (i.e., two buffers).
The Direct Memory Access (DMA) transfers the last buffer and the CODEC calls the event handler when the buffer transmission is completed.
In the event handler APP_TONE_TEXTFILE_SDCARD_BufferEventHandler, the state of the task is changed from waiting to complete.
A new buffer is submitted from the state APP_TONE_TEXTFILE_SDCARD_STATE_CODEC_BUFFER_COMPLETE and the state machine goes to the waiting state again. The cycle of waiting <-> complete state continues.
Step 6: Debug Your Application
Congratulations! You’re done: you are ready to debug
your second application.
Before you program and run your application, you need to program the micro SD card with the audio text file.
Go to the dev_files folder of this lab
(apps/training/middleware/audio_player/audio_player_lab2/dev_files) and copy the tone.txt file into the micro SD card.
Insert the micro SD card into the micro SD card slot (J8) on the MEB II Board.
Before you start the debugger, set a breakpoint in the application file in app_tone_textfile_sdcard.c. Through this breakpoint you can observe that the APP_TONE_TEXTFILE_SDCARD_Tasks() is successfully able to open the CODEC driver.
Put a breakpoint in the APP_TONE_TEXTFILE_SDCARD_STATE_CARD_MOUNT state. Through this breakpoint you can observe that the file system was successfully mounted on the SD card.
Debug your application! Click the
Debug Main Project icon.
Single-step (by pressing the F7 key) to observe the flow of the application state machine.
Put a breakpoint in the buffer event handler. Hitting this breakpoint in the event handler indicates that the last submitted buffer is transferred to the CODEC.
Remove all breakpoints and press the F5 key and allow the application to run.
Connect headphones to the HP Out connector on the MEB II and you should hear a tone.
Results
As with audio_player_lab1, you should be able to hear a sine tone output through the headphone jack on the MEB II. There could be issues with the audio output if you did not configure the SD card driver or File System Service properly (the audio data is read from the text file stored in the SD card).
Analysis
You have successfully played a sine tone on the PIC32 microcontroller and heard the audio through the headphone on the development board. The sine tone produced is 16-bits, at a 48000 sampling rate. The tone was produced statically and stored in a text file on the SD card mounted on the board. The existing configuration from audio_player_lab1 was enhanced using MHC to configure the SD card driver and File System Service to access the audio text file stored on the SD card. The application state machine was enhanced to add new steps to read audio data from the text file.
Conclusions
In this lab, you have extended the audio_player_lab1 to add another level of complexity. Now you should be in a position to appreciate how easy it was to add new modules (driver/system service) to an existing application. This lab can also be used as a reference for dealing with File Systems and SD card memory management.