Step 7: Review the Application code
Application File: app_usb_audio_task.h
Open file app_usb_audio_task.h (in the MPLAB X IDE "Projects" pane under the Header Files/app folder). This file defines application states, data and APIs.
Important states, definitions and variables used by the USB audio task are explained below.
Application states corresponding to the state machine described previously in the "Overview" section are as follows.
The meaning of these states will be explained when the USB audio state machine implementation is discussed.
The audio CODEC related data is maintained in the APP_USB_AUDIO_CODEC structure.
- handle: Holds the handle to the audio CODEC driver.
- writeBufHandle1: Holds the handle to the audio buffer pointed by txbufferObject1
- writeBufHandle2: Holds the handle to the audio buffer pointed by txbufferObject2
- bufferHandler: Points to the audio CODEC buffer event handler.
- context: Holds the context value.
- txbufferObject1: Holds the pointer to the audio CODEC buffer queue 0.
- txbufferObject2: Holds the pointer to the audio CODEC buffer queue 1.
- bufferSize: Holds the size of the CODEC buffer.
- iswriteBufHandleAvailable1: Indicates whether txBufferObject1 is available (free) or in use.
- iswriteBufHandleAvailable2: Indicates whether txBufferObject2 is available (free) or in use.
The enumeration APP_USB_AUDIO_ALTERNATE_SETTINGS helps to manage the alternate settings supported by this application. This application supports only a 48 KHz sampling rate.
The enumeration APP_USB_AUDIO_CONTROLS defines the audio controls supported by this application. This application supports mute control.
The USB application data structure is as follows.
Here are the descriptions of some important structure members:
- state holds the USB state machine’s current state.
- usbDevHandle holds the USB device handle returned by a call to USB_DEVICE_Open().
- isConfigured indicates whether the USB host has configured the device or not.
- isReadComplete1 and isReadComplete2 indicate whether the buffers corresponding to USB buffer handles readTransferHandle1 and readTransferHandle2 have been read from the USB host or not.
- readTransferHandle1 and readTransferHandle2 are USB read buffer handles returned by a call to USB_DEVICE_AUDIO_Read() function.
- activeInterfaceAlternateSetting holds active value of USB Audio Streaming Interface Alternate setting.
- dacMute holds current value of Audio Control Mute settings. A true value indicates that audio is currently muted.
- currentAudioControl indicates which Audio Control Transfer is currently in progress.
- codec holds the audio CODEC related data.
This is the declaration for the USB device layer events handler. It notifies the application of various USB Device Layer events (e.g., enumeration).
This is the declaration for the USB audio function driver. It notifies the application of various USB Audio Class (Function Driver) related events.
Application File: app_usb_audio_task.c
Open file app_usb_audio_task.c (in the MPLAB X IDE "Projects" pane under the Source Files/app folder). This file contains the application state machine and implements the APIs.
The function APP_USB_AUDIO_DeviceEventHandler handles the USB Device Layer events (e.g., USB reset, configured etc…).
The function APP_USB_AUDIO_DeviceAudioEventHandler handles the USB Audio Class (Function Driver) events (e.g., alternate interface settings received, control events, read/write complete etc…).
The function APP_USB_AUDIO_Initialize sets up the default state of APP_USB_AUDIO_Tasks, and initializes the variables for the CODEC driver, USB read buffer related variables along with other variables. This function is called only once after power on.
The function APP_USB_AUDIO_Tasks implements the task’s state machine as shown in Figure 1.1 in the "Lab Overview" section.
The state machine states are described as follows:
- Opens the USB device and registers a call back with the Device layer to receive notifications
- Next state: APP_USB_AUDIO_STATE_CODEC_OPEN
- Opens the CODEC driver and sets the audio CODEC sampling rate to 48 kHz
- Next state: APP_USB_AUDIO_STATE_CODEC_SET_BUFFER_HANDLER
- Registers a buffer event handler with the CODEC driver.
- Next state: APP_USB_AUDIO_STATE_WAIT_FOR_CONFIGURATION
- Waits for the USB host to configure the USB device
- Next state: APP_USB_AUDIO_STATE_IDLE
- Waits for the USB host events
- When the user starts playing audio on the USB host (typically a PC), the USB host passes (alternate) interface settings to the USB device requesting it to change to alternate setting for the requested USB interface. The USB audio function driver call back notifies the application through USB_DEVICE_AUDIO_EVENT_INTERFACE_SETTING_CHANGED event and the USB state machine’s state is changed to APP_USB_AUDIO_STATE_USB_INTERFACE_ALTERNATE_SETTING_RCVD state.
- Checks if the alternate settings request is to play a 48 kHz audio
- If yes, the state machine proceeds to APP_USB_AUDIO_STATE_SUBMIT_INITIAL_READ_REQUEST
- Requests audio data from the USB host by a call to USB_DEVICE_AUDIO_Read() function
- Next state: APP_USB_AUDIO_STATE_PROCESS_DATA
- Waits for the requested audio data to be available from the USB host. When the audio data is available, the USB audio function driver call back function notifies the application through USB_DEVICE_AUDIO_EVENT_READ_COMPLETE event. The received audio data is then passed to the audio CODEC for playing by a call to DRV_CODEC_BufferAddWrite() function, and more audio data is requested from the USB host. The cycle repeats.
In addition to handling of audio data streams, the state machine also handles audio control requests from the USB host. The USB function driver call back notifies the control type to the application through USB_DEVICE_AUDIO_EVENT_CONTROL_SET_CUR event followed by USB_DEVICE_AUDIO_EVENT_CONTROL_TRANSFER_DATA_RECEIVED event which provides data for the control type. The application handles audio mute control requests from the USB host by muting/un-muting the audio CODEC driver in the APP_USB_AUDIO_STATE_MUTE_AUDIO_PLAYBACK state.
The functions APP_USB_AUDIO_MuteOn turns ON mute on the audio CODEC and APP_USB_AUDIO_MuteOff turns OFF mute on the audio CODEC.
The functions APP_USB_AUDIO_VolumeGet and APP_USB_AUDIO_VolumeSet, respectively gets and sets volume level for the audio CODEC.
The CODEC buffer event handler APP_USB_AUDIO_BufferEventHandler updates flags to let the application know that the audio buffer transfer is complete.
Application File: app_display _task.h
Open file app_ display _task.h. This file defines application enums, data and APIs.
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, a handle to system timer for implementing de-bouncing for volume slider and a flag to indicate whether the display has been initialized or not.
Application File: app_display _task.c
Open file app_display_task.c. This file contains the display task initialization and task functions.
The function APP_DISPAY_Initialize initializes the variables to default values.
The function APP_DISPLAY_Tasks performs the following tasks:
- Once the display screen has been drawn by the gfx library state machine, it sets the default volume level in the volume slider.
- 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 un-mute. Also, the audio CODEC is updated with the new volume level. Note that the volume slider has a de-bounce logic implemented by registering a call back with the system timer service. This avoids having multiple I2C transactions to the audio CODEC for volume changes.
The function _APP_DISPLAY_HandleMuteOn handles the volume mute event by setting the level of the volume slider object to zero and then disabling the volume slider object.
The function _APP_DISPLAY_HandleMuteOff reverses the action by setting the level of the volume slider object to its previous position and then enabling the volume slider object.
The function _APP_DISPLAY_HandleVolumeIncreaseDecrease scales the level of volume slider object to the volume level of audio CODEC.