Step 9: Review the Application Code
Application File: app.h
Open the app.h file and review the code. This file is generated by MPLAB® Harmony Configurator (MHC) when you click the "Generate Code" button. It enumerates the application states and creates a structure to hold application data.
Application File: app.c
Open the app.c file and review the code. This file is generated by MHC when you click the "Generate Code" button.
- Allows the application to initialize various tasks and application related data. The thumb drive audio and display tasks are also initialized in this function.
- Implements the application state machine. It is called periodically from the SYS_Tasks function.
Application File: app_thumb_drive_audio_task.h
This file defines application states, data and APIs, related to USB host task and player tasks.
The states related to the thumb drive audio state machine (APP_THUMB_DRIVE_AUDIO_Tasks, shown in this image) are enumerated as shown in this image.
The states related to the audio player state machine (shown in this image) are enumerated as shown in this image.
The data structure for the thumb drive audio state machine is shown below.
- state holds the application state, and the variable codec holds CODEC related variables.
- player holds audio player related data.
- thumbDriveEventCallback holds the call back functions registered by other tasks that need event notifications from the app_thumb_drive_audio_task task.
- deviceIsConnected indicates whether the flash drive is connected or disconnected.
The data structure for the audio player state machine is shown below.
- fileHandle holds the handle to the audio file currently being played.
- fileStatus holds the file status for the current audio file, returned by a call to SYS_FS_FileStat().
- state holds the state of the audio player state machine
- buffer holds the buffer related information that is used by the decoder and the audio CODEC. The buffer members are as follows:
- buffer holds the decoded audio data.
- inUse A buffer is marked to be in use when the buffer is queued for playing with the CODEC.
- decoded A buffer is marked as decoded when the buffer contains the decoded audio data (output of decoder).
- writeHandler holds the buffer handle returned by a call to DRV_CODEC_BufferAddWrite().
- bufferSize indicates the number of decoded audio data elements available in the buffer.
- currentSongIdx, nextSongIdx and previousSongIdx point to index of the current song, next song and previous song respectively in the global buffer that contains path information of all the audio files.
- totalAudioFiles holds the total number of WAV audio files found on the SD card.
- nBytesRead holds the actual number of bytes read from the file; returned by a call to SYS_FS_FileRead().
- currentFilesize holds the total size of the current audio file pointed by the fileHandle.
- readIdx and wrriteIdx are used to index into the buffer containing audio data for the audio CODEC. writeIdx points to the index till the decoded audio data is available in the buffer. readIdx points to the index till the audio data is queued to the audio CODEC.
- decodeDataSize holds the number of data bytes decoded by the decoder; returned by a call to DECODER_Decode().
Application File: app_thumb_drive_audio_task.c
This file implements the thumb drive audio state machine.
- The APP_THUMB_DRIVE_AUDIO_Tasks state machine starts in this state where it sets an handler to receive File System Events and an handler to receive USB Host Layer Events. The Host Layer provides events when a connected device requires more current than can be provided or when a unsupported device was attached. The File System Events handler receives file system mount/un-mount events. After this, the USB bus is enabled which starts the process of detacting attached devices and enumerating them.
- In this state, the task waits for the USB bust to be enabled. Once enabled the state machine moves to the APP_THUMB_DRIVE_AUDIO_STATE_WAIT_FOR_DEVICE_ATTACH state.
- The state machine waits for a USB device to get attached. This is indicated to the application layer by the File System call back (registered previously) event SYS_FS_EVENT_MOUNT.
- The state machine then moves to the APP_THUMB_DRIVE_AUDIO_STATE_DEVICE_CONNECTED state, from which it moves to APP_THUMB_DRIVE_AUDIO_STATE_CODEC_OPEN state.
- The state machine opens the audio CODEC. Once opened, the state machine moves to the APP_THUMB_DRIVE_AUDIO_STATE_CODEC_SET_BUFFER_HANDLER state.
- The state machine sets the CODEC buffer events handler and moves to the APP_THUMB_DRIVE_AUDIO_STATE_RUNNING state.
- Calls APP_THUMB_DRIVE_AUDIO_Card_Tasks function that traverses through all the directories on the thumb drive and saves the path of all WAV files found to AppThumbDriveFilesTable.
- Selects the first WAV file from the AppThumbDriveFilesTable
- Calls the APP_THUMB_DRIVE_AUDIO_Card_OpenTrack function to open it for playing.
- Checks if any buffer is available.
- If yes, it reads the current audio file by a call to APP_THUMB_DRIVE_AUDIO_Card_FillBuffer function and then passes the read data to APP_THUMB_DRIVE_AUDIO_Player_Decode function which decodes the WAV formatted data read from the file.
- If none of the decoded buffers are in use, it queues the decoded buffer to the CODEC driver for playing by a call to DRV_CODEC_BufferAddWrite function, and marks it as “in Use”.
- The player state remains in APP_THUMB_DRIVE_AUDIO_PLAYER_STATE_RUNNING until the entire audio file is read (played) out.
- The CODEC driver calls this buffer event handler (registered with the CODEC by a call to DRV_CODEC_BufferEventHandlerSet function), upon completion of each queued buffer to the audio CODEC.
- The application checks if a decoded buffer is ready and if yes, then it queues the decoded buffer for playing with the audio CODEC by a call to DRV_CODEC_BufferAddWrite function.
Once the audio file is completely read out or if the decoder output is zero (nothing to decode), the player state is changed to APP_THUMB_DRIVE_AUDIO_PLAYER_STATE_TRACK_CHANGE, where it first waits for the already queued audio buffers to the CODEC driver to complete; after which it selects the next audio file from the AppThumbDriveFilesTable, and opens the it for playing and the player state machine changes back to APP_THUMB_DRIVE_AUDIO_PLAYER_STATE_RUNNING. This process continues and the audio files are continuously played in a circular manner from the AppThumbDriveFilesTable, one after the other.
Application File: app_display_task.h
This file defines application states, data and APIs, related to the display task.
The volume mute enumerator helps manage the current audio activity and act on a trigger to change from Mute On/Off or volume increase and decrease.
The Display data structure holds the volume/mute information, the id of the current track being played and a handle to system timer for implementing de-bouncing for the volume slider.
APP_DISPLAY_MSG_ID enumerator manages various messages that are displayed on the UI. These messages are based on the events received from the thumb-drive audio task.
APP_DISPLAY_MSG_INFO holds the message ID and the corresponding message text that is displayed corresponding to various events received from the thumb-drive audio task.
Application File: app_display_task.c
The function APP_DISPAY_Initialize sets up the default value for the volume/mute variable as not changed. It also registers a handler with the thumb-drive audio task to receive thumb-drive audio task related events.
The function APP_DISPLAY_Tasks performs the following tasks:
Once the display screen has been drawn by the graphics library state machine, it initializes the listbox object with tracks from the thumb-drive whenever the tracks list is updated by the thumb-drive audio task. It also sets the default volume level in the volume slider. If no tracks are available, the volume slider and scroll-up/down buttons are disabled.
It handles events notified by the thumb-drive audio task. Based on the events received, the display task updates the appropriate text message on the UI. The events can be thumb-drive connected/disconnected, no audio files found in the thumb-drive, thumb-drive not found etc.
It handles the volume and mute control. The user can increase or decrease the volume through the volume slider. For mute control, the volume slider is disabled or enabled based on whether the volume is mute or unmute. Also, the audio CODEC is updated with the new volume level. Note that the volume slider has de-bounce logic implemented by registering a callback with the system timer service. This avoids having multiple I2C transactions to the audio CODEC for volume changes.
It updates the list box object with the current audio track being played. The audio files are played one after the other from the thumb-drive, and hence, when the current audio track changes, the list box object’s focus is updated to reflect the current (changed) track being played.
System Configuration File: system_config.h
This file defines the application specific configuration macros.
- The macros DECODER_MAX_INPUT_BUFFER_SIZE and DECODER_MAX_OUTPUT_BUFFER_SIZE define the size of input and output buffers.
- The macro APP_THUMB_DRIVE_AUDIO_CODEC_WRITE_QUEUE_SIZE defines the size of the CODEC driver buffer queue.
- The macro APP_THUMB_DRIVE_AUDIO_CARD_MAX_DIRS defines the maximum directories that will be scanned for the audio files.
- The macro APP_THUMB_DRIVE_AUDIO_CARD_MAX_FILES defines the maximum files that will be saved.