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 00030 /** \file 00031 * \addtogroup usbd_audio_speaker 00032 *@{ 00033 */ 00034 00035 /*------------------------------------------------------------------------------ 00036 * Headers 00037 *------------------------------------------------------------------------------*/ 00038 00039 #include <AUDDSpeakerDriver.h> 00040 00041 #include <AUDDSpeakerPhone.h> 00042 00043 #include <USBLib_Trace.h> 00044 00045 #include <AUDRequests.h> 00046 00047 #include "USBD.h" 00048 #include <USBD_HAL.h> 00049 #include <USBDDriver.h> 00050 00051 /*---------------------------------------------------------------------------- 00052 * Internal types 00053 *----------------------------------------------------------------------------*/ 00054 00055 /** 00056 * \brief Audio speaker driver struct. 00057 */ 00058 typedef struct _AUDDSpeakerDriver { 00059 /** Speaker & Phone function */ 00060 AUDDSpeakerPhone fun; 00061 /** Stream instance for speaker */ 00062 AUDDStream speaker; 00063 /** Array for storing the current setting of each interface */ 00064 uint8_t bAltInterfaces[AUDDSpeakerDriver_NUMINTERFACES]; 00065 } AUDDSpeakerDriver; 00066 00067 /*---------------------------------------------------------------------------- 00068 * Internal variables 00069 *----------------------------------------------------------------------------*/ 00070 00071 /** Global USB audio speaker driver instance. */ 00072 static AUDDSpeakerDriver auddSpeakerDriver; 00073 00074 /*---------------------------------------------------------------------------- 00075 * Dummy callbacks 00076 *----------------------------------------------------------------------------*/ 00077 00078 /*---------------------------------------------------------------------------- 00079 * Internal functions 00080 *----------------------------------------------------------------------------*/ 00081 00082 /** 00083 * Callback triggerred after the mute or volume status of the channel has been 00084 * changed. 00085 * \param ec Event code. 00086 * \param channel Channel number. 00087 * \param pArg Pointer to AUDDStream instance. 00088 */ 00089 static void AUDDSpeaker_EventCallback(uint32_t ec, 00090 uint8_t channel, 00091 AUDDStream *pArg) 00092 { 00093 if (ec == AUDD_EC_MuteChanged) { 00094 if ((void *)AUDDSpeakerDriver_MuteChanged != NULL) 00095 AUDDSpeakerDriver_MuteChanged(channel, pArg->bmMute); 00096 } else if (ec == AUDD_EC_VolumeChanged) { 00097 /* Not supported now */ 00098 } 00099 } 00100 00101 /*---------------------------------------------------------------------------- 00102 * Exported functions 00103 *----------------------------------------------------------------------------*/ 00104 00105 /** 00106 * Initializes an USB audio speaker device driver, as well as the underlying 00107 * USB controller. 00108 */ 00109 void AUDDSpeakerDriver_Initialize(const USBDDriverDescriptors *pDescriptors) 00110 { 00111 AUDDSpeakerDriver *pAudd = &auddSpeakerDriver; 00112 AUDDSpeakerPhone *pAudf = &pAudd->fun; 00113 AUDDStream *pAuds = &pAudd->speaker; 00114 USBDDriver *pUsbd = USBD_GetDriver(); 00115 00116 AUDDSpeakerPhone_InitializeStream( 00117 pAuds, AUDDSpeakerDriver_NUMCHANNELS, 0, 00118 (AUDDStreamEventCallback)AUDDSpeaker_EventCallback, pAuds); 00119 00120 AUDDSpeakerPhone_Initialize( 00121 pAudf, pUsbd, pAuds, 0); 00122 00123 /* Initialize the USB driver */ 00124 USBDDriver_Initialize(pUsbd, 00125 pDescriptors, 00126 pAudd->bAltInterfaces); 00127 USBD_Init(); 00128 } 00129 00130 /** 00131 * Invoked whenever the active configuration of device is changed by the 00132 * host. 00133 * \param cfgnum Configuration number. 00134 */ 00135 void AUDDSpeakerDriver_ConfigurationChangeHandler(uint8_t cfgnum) 00136 { 00137 AUDDSpeakerDriver *pAudd = &auddSpeakerDriver; 00138 AUDDSpeakerPhone *pAudf = &pAudd->fun; 00139 const USBDDriverDescriptors *pDescriptors = pAudf->pUsbd->pDescriptors; 00140 USBConfigurationDescriptor *pDesc; 00141 00142 if (cfgnum > 0) { 00143 00144 /* Parse endpoints for data & notification */ 00145 if (USBD_HAL_IsHighSpeed() && pDescriptors->pHsConfiguration) 00146 pDesc = (USBConfigurationDescriptor *)pDescriptors->pHsConfiguration; 00147 else 00148 pDesc = (USBConfigurationDescriptor *)pDescriptors->pFsConfiguration; 00149 00150 AUDDSpeakerPhone_ParseInterfaces(pAudf, 00151 (USBGenericDescriptor *)pDesc, 00152 pDesc->wTotalLength); 00153 } 00154 } 00155 00156 /** 00157 * Invoked whenever the active setting of an interface is changed by the 00158 * host. Changes the status of the third LED accordingly. 00159 * \param interface Interface number. 00160 * \param setting Newly active setting. 00161 */ 00162 void AUDDSpeakerDriver_InterfaceSettingChangedHandler(uint8_t interface, 00163 uint8_t setting) 00164 { 00165 AUDDSpeakerDriver *pSpeakerd = &auddSpeakerDriver; 00166 AUDDSpeakerPhone *pAudf = &pSpeakerd->fun; 00167 00168 if (setting == 0) 00169 AUDDSpeakerPhone_CloseStream(pAudf, interface); 00170 00171 if (NULL != (void *)AUDDSpeakerDriver_StreamSettingChanged) 00172 AUDDSpeakerDriver_StreamSettingChanged(setting); 00173 } 00174 00175 /** 00176 * Handles audio-specific USB requests sent by the host, and forwards 00177 * standard ones to the USB device driver. 00178 * \param request Pointer to a USBGenericRequest instance. 00179 */ 00180 void AUDDSpeakerDriver_RequestHandler(const USBGenericRequest *request) 00181 { 00182 AUDDSpeakerDriver *pAudd = &auddSpeakerDriver; 00183 AUDDSpeakerPhone *pAudf = &pAudd->fun; 00184 USBDDriver *pUsbd = pAudf->pUsbd; 00185 00186 TRACE_INFO_WP("NewReq "); 00187 00188 /* Handle Audio Class requests */ 00189 if (AUDDSpeakerPhone_RequestHandler(pAudf, request) == USBRC_SUCCESS) 00190 return; 00191 00192 /* Handle STD requests */ 00193 if (USBGenericRequest_GetType(request) == USBGenericRequest_STANDARD) 00194 00195 USBDDriver_RequestHandler(pUsbd, request); 00196 /* Unsupported request */ 00197 else { 00198 00199 TRACE_WARNING( 00200 "AUDDSpeakerDriver_RequestHandler: Unsupported request (%d,%x)\n\r", 00201 USBGenericRequest_GetType(request), 00202 USBGenericRequest_GetRequest(request)); 00203 USBD_Stall(0); 00204 } 00205 } 00206 00207 /** 00208 * Reads incoming audio data sent by the USB host into the provided 00209 * buffer. When the transfer is complete, an optional callback function is 00210 * invoked. 00211 * \param buffer Pointer to the data storage buffer. 00212 * \param length Size of the buffer in bytes. 00213 * \param callback Optional callback function. 00214 * \param argument Optional argument to the callback function. 00215 * \return USBD_STATUS_SUCCESS if the transfer is started successfully; 00216 * otherwise an error code. 00217 */ 00218 uint8_t AUDDSpeakerDriver_Read(void *buffer, 00219 uint32_t length, 00220 TransferCallback callback, 00221 void *argument) 00222 { 00223 AUDDSpeakerDriver *pAudd = &auddSpeakerDriver; 00224 AUDDSpeakerPhone *pAudf = &pAudd->fun; 00225 return USBD_Read(pAudf->pSpeaker->bEndpointOut, 00226 buffer, length, 00227 callback, argument); 00228 } 00229 00230 /**@}*/