00001 /* ---------------------------------------------------------------------------- */ 00002 /* Atmel Microcontroller Software Support */ 00003 /* SAM Software Package License */ 00004 /* ---------------------------------------------------------------------------- */ 00005 /* Copyright (c) 2015, Atmel Corporation */ 00006 /* */ 00007 /* All rights reserved. */ 00008 /* */ 00009 /* Redistribution and use in source and binary forms, with or without */ 00010 /* modification, are permitted provided that the following condition is met: */ 00011 /* */ 00012 /* - Redistributions of source code must retain the above copyright notice, */ 00013 /* this list of conditions and the disclaimer below. */ 00014 /* */ 00015 /* Atmel's name may not be used to endorse or promote products derived from */ 00016 /* this software without specific prior written permission. */ 00017 /* */ 00018 /* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR */ 00019 /* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF */ 00020 /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE */ 00021 /* DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT, */ 00022 /* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT */ 00023 /* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, */ 00024 /* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF */ 00025 /* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING */ 00026 /* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, */ 00027 /* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ 00028 /* ---------------------------------------------------------------------------- */ 00029 /** \file */ 00030 00031 /** \addtogroup usbd_aud_fun 00032 *@{ 00033 */ 00034 00035 /*------------------------------------------------------------------------------ 00036 * Headers 00037 *------------------------------------------------------------------------------*/ 00038 00039 #include <USBLib_Trace.h> 00040 00041 #include <AUDDFunction.h> 00042 #include <AUDDSpeakerPhone.h> 00043 00044 #include <AUDRequests.h> 00045 00046 #include "USBD.h" 00047 #include <USBD_HAL.h> 00048 #include <USBDDriver.h> 00049 00050 /*---------------------------------------------------------------------------- 00051 * Internal types 00052 *----------------------------------------------------------------------------*/ 00053 00054 /** 00055 * \brief Audio speaker driver struct. 00056 */ 00057 typedef struct _AUDDFunction { 00058 /** Speaker & Phone function */ 00059 AUDDSpeakerPhone drv; 00060 /** Stream instance for speaker */ 00061 AUDDStream speaker; 00062 /** Stream instance for microphone */ 00063 AUDDStream mic; 00064 } AUDDFunction; 00065 00066 /*---------------------------------------------------------------------------- 00067 * Internal variables 00068 *----------------------------------------------------------------------------*/ 00069 00070 /** Global USB audio function driver instance. */ 00071 static AUDDFunction auddFunction; 00072 00073 /*---------------------------------------------------------------------------- 00074 * Internal functions 00075 *----------------------------------------------------------------------------*/ 00076 00077 /** 00078 * Callback triggerred after the mute or volume status of the channel has been 00079 * changed. 00080 * \param ec Event code. 00081 * \param channel Channel number. 00082 * \param pArg Pointer to AUDDStream instance. 00083 */ 00084 static void AUDDFunction_EventCallback(uint32_t ec, 00085 uint8_t channel, 00086 AUDDStream *pArg) 00087 { 00088 AUDDFunction *pAudf = &auddFunction; 00089 uint8_t mic = ((uint32_t)pArg == (uint32_t)(&pAudf->mic)); 00090 00091 if (ec == AUDD_EC_MuteChanged) { 00092 if (NULL != (void *)AUDDFunction_MuteChanged) 00093 AUDDFunction_MuteChanged(mic, channel, pArg->bmMute); 00094 } else if (ec == AUDD_EC_VolumeChanged) { 00095 /* Not supported now */ 00096 } 00097 } 00098 00099 /*--------------------------------------------------------------------------- 00100 * Exported functions 00101 *---------------------------------------------------------------------------*/ 00102 00103 /** 00104 * Initializes an USB audio speaker device driver, as well as the underlying 00105 * USB controller. 00106 */ 00107 void AUDDFunction_Initialize(USBDDriver *pUsbd, uint8_t bInterface) 00108 { 00109 AUDDFunction *pAudf = &auddFunction; 00110 AUDDSpeakerPhone *pDrv = &pAudf->drv; 00111 AUDDStream *pSpk = &pAudf->speaker; 00112 AUDDStream *pMic = &pAudf->mic; 00113 00114 bInterface = bInterface; 00115 00116 /* 0: Speaker */ 00117 AUDDSpeakerPhone_InitializeStream( 00118 pSpk, AUDDFunction_MaxNumSpeakerChannels, 0, 00119 (AUDDStreamEventCallback)AUDDFunction_EventCallback, 00120 (void *)pSpk); 00121 /* 1: Mic */ 00122 AUDDSpeakerPhone_InitializeStream( 00123 pMic, AUDDFunction_MaxNumMicrophoneChannels, 0, 00124 (AUDDStreamEventCallback)AUDDFunction_EventCallback, 00125 (void *)pMic); 00126 /* Audio Driver initialize */ 00127 AUDDSpeakerPhone_Initialize(pDrv, pUsbd, pSpk, pMic); 00128 00129 } 00130 00131 /** 00132 * Configure function with expected descriptors and start functionality. 00133 * Usually invoked when device is configured. 00134 * \pDescriptors Pointer to the descriptors for function configure. 00135 * \wLength Length of descriptors in number of bytes. 00136 */ 00137 void AUDDFunction_Configure(USBGenericDescriptor *pDescriptors, 00138 uint16_t wLength) 00139 { 00140 AUDDFunction *pAudf = &auddFunction; 00141 AUDDSpeakerPhone *pDrv = &pAudf->drv; 00142 AUDDSpeakerPhone_ParseInterfaces(pDrv, pDescriptors, wLength); 00143 } 00144 00145 /** 00146 * Invoked whenever the active setting of an interface is changed by the 00147 * host. Changes the status of the third LED accordingly. 00148 * \param interface Interface number. 00149 * \param setting Newly active setting. 00150 */ 00151 void AUDDFunction_InterfaceSettingChangedHandler(uint8_t interface, 00152 uint8_t setting) 00153 { 00154 AUDDFunction *pAudf = &auddFunction; 00155 AUDDSpeakerPhone *pDrv = &pAudf->drv; 00156 00157 if (setting == 0) AUDDSpeakerPhone_CloseStream(pDrv, interface); 00158 00159 if (NULL != (void *)AUDDFunction_StreamSettingChanged) { 00160 uint8_t mic = (interface == pDrv->pMicrophone->bAsInterface); 00161 AUDDFunction_StreamSettingChanged(mic, setting); 00162 } 00163 } 00164 00165 /** 00166 * Handles AUDIO-specific USB requests sent by the host 00167 * \param request Pointer to a USBGenericRequest instance. 00168 * \return USBRC_SUCCESS if request is handled. 00169 */ 00170 uint32_t AUDDFunction_RequestHandler( 00171 const USBGenericRequest *request) 00172 { 00173 AUDDFunction *pAudf = &auddFunction; 00174 AUDDSpeakerPhone *pDrv = &pAudf->drv; 00175 return AUDDSpeakerPhone_RequestHandler(pDrv, request); 00176 } 00177 00178 /** 00179 * Reads incoming audio data sent by the USB host into the provided buffer. 00180 * When the transfer is complete, an optional callback function is invoked. 00181 * \param buffer Pointer to the data storage buffer. 00182 * \param length Size of the buffer in bytes. 00183 * \param callback Optional callback function. 00184 * \param argument Optional argument to the callback function. 00185 * \return <USBD_STATUS_SUCCESS> if the transfer is started successfully; 00186 * otherwise an error code. 00187 */ 00188 uint8_t AUDDFunction_Read(void *buffer, 00189 uint32_t length, 00190 TransferCallback callback, 00191 void *argument) 00192 { 00193 AUDDFunction *pAudf = &auddFunction; 00194 AUDDSpeakerPhone *pDrv = &pAudf->drv; 00195 return AUDDSpeakerPhone_Read(pDrv, buffer, length, callback, argument); 00196 } 00197 00198 /** 00199 * Initialize Frame List for sending audio data. 00200 * 00201 * \param pListInit Pointer to the allocated list for audio write. 00202 * \param pDmaInit Pointer to the allocated DMA descriptors for autio write 00203 * (if DMA supported). 00204 * \param listSize Circular list size. 00205 * \param delaySize Start transfer after delaySize frames filled in. 00206 * \param callback Optional callback function for transfer. 00207 * \param argument Optional callback argument. 00208 * \return USBD_STATUS_SUCCESS if setup successfully; otherwise an error code. 00209 */ 00210 uint8_t AUDDFunction_SetupWrite(void *pListInit, 00211 void *pDmaInit, 00212 uint16_t listSize, 00213 uint16_t delaySize, 00214 TransferCallback callback, 00215 void *argument) 00216 { 00217 AUDDFunction *pAudf = &auddFunction; 00218 AUDDSpeakerPhone *pDrv = &pAudf->drv; 00219 return AUDDSpeakerPhone_SetupWrite(pDrv, 00220 pListInit, pDmaInit, listSize, delaySize, 00221 callback, argument); 00222 } 00223 00224 /** 00225 * Add frame buffer to audio sending list. 00226 * \buffer Pointer to data frame to send. 00227 * \length Frame size in bytes. 00228 * \return USBD_STATUS_SUCCESS if the transfer is started successfully; 00229 * otherwise an error code. 00230 */ 00231 uint8_t AUDDFunction_Write(void *buffer, uint16_t length) 00232 { 00233 AUDDFunction *pAudf = &auddFunction; 00234 AUDDSpeakerPhone *pDrv = &pAudf->drv; 00235 return AUDDSpeakerPhone_Write(pDrv, buffer, length); 00236 } 00237 00238 /**@}*/ 00239