SAMV71 Xplained Ultra Software Package 1.5

AUDDStream.c

Go to the documentation of this file.
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  *  USB Audio Device Streaming interface with controls.
00032  *  (3 channels supported).
00033  */
00034 
00035 /** \addtogroup usbd_audio_speakerphone
00036  *@{
00037  */
00038 
00039 /*------------------------------------------------------------------------------
00040  *         Headers
00041  *------------------------------------------------------------------------------*/
00042 
00043 #include <AUDDSpeakerPhone.h>
00044 
00045 #include <USBDescriptors.h>
00046 #include <USBRequests.h>
00047 #include <AUDDescriptors.h>
00048 #include <AUDRequests.h>
00049 
00050 #include <USBD_HAL.h>
00051 
00052 #include <USBLib_Trace.h>
00053 
00054 /*------------------------------------------------------------------------------
00055  *         Types
00056  *------------------------------------------------------------------------------*/
00057 
00058 /** Parse data extention for descriptor parsing  */
00059 typedef struct _AUDDParseData {
00060     /** Pointer to AUDDSpeakerPhone instance */
00061     AUDDSpeakerPhone *pAudf;
00062     /** Pointer to found interface descriptor */
00063     USBInterfaceDescriptor *pIfDesc;
00064 
00065 } AUDDParseData;
00066 
00067 /** Transfer callback extention */
00068 typedef struct _AUDDXfrExt {
00069     /** Pointer to AUDDStream instance */
00070     AUDDStream *pStream;
00071     /** Buffer for USB device to get data from host */
00072     uint16_t    usbBuffer;
00073     /** Additional information: Entity */
00074     uint8_t     bEntity;
00075     /** Additional information: Channel */
00076     uint8_t     bCh;
00077 } AUDDXfrExt;
00078 
00079 /*------------------------------------------------------------------------------
00080  *         Internal Variable
00081  *------------------------------------------------------------------------------*/
00082 
00083 /** Transfer data extension */
00084 static AUDDXfrExt auddXfrData;
00085 
00086 /*------------------------------------------------------------------------------
00087  *         Internal Functions
00088  *------------------------------------------------------------------------------*/
00089 
00090 /**
00091  * Parse descriptors: Interface, ISO IN/OUT, Feature Unit IDs.
00092  * \param desc Pointer to descriptor list.
00093  * \param arg  Argument, pointer to AUDDParseData instance.
00094  */
00095 static uint32_t AUDDSpeakerPhone_Parse(USBGenericDescriptor *pDesc,
00096                                        AUDDParseData *pArg)
00097 {
00098     AUDDStream *pSpeaker = pArg->pAudf->pSpeaker;
00099     AUDDStream *pMic     = pArg->pAudf->pMicrophone;
00100     USBEndpointDescriptor *pEp = (USBEndpointDescriptor *)pDesc;
00101     uint8_t bSpeakerDone = 0, bMicDone = 0;
00102 
00103     /* Validate descriptor */
00104     if (pDesc->bLength == 0)
00105         return USBRC_PARAM_ERR;
00106 
00107     /* Log current interface */
00108     if (pDesc->bDescriptorType == USBGenericDescriptor_INTERFACE) {
00109         USBInterfaceDescriptor *pIf = (USBInterfaceDescriptor *)pDesc;
00110 
00111         /* AudioControl interface */
00112         if (pIf->bInterfaceClass ==
00113             AUDControlInterfaceDescriptor_CLASS
00114             && pIf->bInterfaceSubClass ==
00115             AUDControlInterfaceDescriptor_SUBCLASS) {
00116             pArg->pIfDesc = pIf;
00117 
00118             if (pSpeaker) pSpeaker->bAcInterface = pIf->bInterfaceNumber;
00119 
00120             if (pMic)     pMic->bAcInterface = pIf->bInterfaceNumber;
00121         }
00122         /* AudioStreaming interface with endpoint */
00123         else if (pIf->bInterfaceClass ==
00124                  AUDStreamingInterfaceDescriptor_CLASS
00125                  && pIf->bInterfaceSubClass ==
00126                  AUDStreamingInterfaceDescriptor_SUBCLASS)
00127             pArg->pIfDesc = pIf;
00128         /* Not Audio interface, force end */
00129         else if (pArg->pIfDesc)
00130             return USBRC_PARTIAL_DONE;
00131     }
00132 
00133     if (pArg->pIfDesc) {
00134         /* Find Control Interface */
00135         /* Find Entities */
00136         /* Find Streaming Interface & Endpoints */
00137         if (pDesc->bDescriptorType == USBGenericDescriptor_ENDPOINT
00138             && (pEp->bmAttributes & 0x3) == USBEndpointDescriptor_ISOCHRONOUS) {
00139             if (pEp->bEndpointAddress & 0x80
00140                 && pMic) {
00141                 pMic->bEndpointIn = pEp->bEndpointAddress & 0x7F;
00142                 pMic->bAsInterface = pArg->pIfDesc->bInterfaceNumber;
00143                 /* Fixed FU */
00144                 pMic->bFeatureUnitIn = AUDD_ID_MicrophoneFU;
00145             } else if (pSpeaker) {
00146                 pSpeaker->bEndpointOut = pEp->bEndpointAddress;
00147                 pSpeaker->bAsInterface = pArg->pIfDesc->bInterfaceNumber;
00148                 /* Fixed FU */
00149                 pSpeaker->bFeatureUnitOut = AUDD_ID_SpeakerFU;
00150             }
00151         }
00152     }
00153 
00154     if (pSpeaker) {
00155         if (pSpeaker->bAcInterface != 0xFF
00156             && pSpeaker->bAsInterface != 0xFF
00157             && pSpeaker->bFeatureUnitOut != 0xFF
00158             && pSpeaker->bEndpointOut != 0)
00159             bSpeakerDone = 1;
00160     } else    bSpeakerDone = 1;
00161 
00162     if (pMic) {
00163         if (pMic->bAcInterface != 0xFF
00164             && pMic->bAsInterface != 0xFF
00165             && pMic->bFeatureUnitIn != 0xFF
00166             && pMic->bEndpointIn != 0)
00167             bMicDone = 1;
00168     } else    bMicDone = 1;
00169 
00170     if (bSpeakerDone && bMicDone)
00171         return USBRC_FINISHED;
00172 
00173     return USBRC_SUCCESS;
00174 }
00175 
00176 /**
00177  * Callback triggered after the new mute status of a channel has been read.
00178  * Changes the mute status of the given channel accordingly.
00179  * \param pData Pointer to AUDDXfrExt (transfer extension data).
00180  */
00181 static void AUDD_MuteReceived(AUDDXfrExt *pData)
00182 {
00183     AUDDStream_ChangeMute(pData->pStream,
00184                           pData->bCh,
00185                           (uint8_t)pData->usbBuffer);
00186     USBD_Write(0, 0, 0, 0, 0);
00187 }
00188 
00189 /**
00190  * Callback triggered after the new volume status of a channel has been read.
00191  * Changes the volume status of the given channel accordingly.
00192  * \param pData Pointer to AUDDXfrExt (transfer extension data).
00193  */
00194 static void AUDD_VolumeReceived(AUDDXfrExt *pData)
00195 {
00196     AUDDStream_SetVolume(pData->pStream,
00197                          pData->bCh,
00198                          pData->usbBuffer);
00199     USBD_Write(0, 0, 0, 0, 0);
00200 }
00201 
00202 /**
00203  * Get Target AUDDStream for control
00204  * \param pAudf         Pointer to AUDDSpeakerPhone instance.
00205  * \param bAcInterface  Interface number
00206  * \param bEntity       Entity ID
00207  * \param bChannel      Channel number
00208  * \return Pointer to AUDDStream instance
00209  */
00210 static AUDDStream *AUDD_GetCtlStream(
00211     AUDDSpeakerPhone *pAudf,
00212     uint8_t bAcInterface,
00213     uint8_t bEntity,
00214     uint8_t bChannel)
00215 {
00216     AUDDStream *pAuds = 0;
00217 
00218     if (bEntity == pAudf->pSpeaker->bFeatureUnitOut
00219         || bEntity == pAudf->pSpeaker->bFeatureUnitIn)
00220         pAuds = pAudf->pSpeaker;
00221     else if (bEntity == pAudf->pMicrophone->bFeatureUnitIn
00222              || bEntity == pAudf->pMicrophone->bFeatureUnitOut)
00223         pAuds = pAudf->pMicrophone;
00224 
00225     if (pAuds != 0
00226         && bAcInterface == pAuds->bAcInterface
00227         && bChannel <= pAuds->bNumChannels)
00228         return pAuds;
00229 
00230     return 0;
00231 }
00232 
00233 /**
00234  * Handle the SET_CUR request.
00235  * \param pAudf Pointer to AUDDSpeakerPhone instance.
00236  * \param pReq  Pointer to USBGenericRequest instance.
00237  */
00238 static void AUDD_SetCUR(
00239     AUDDSpeakerPhone *pAudf,
00240     const USBGenericRequest *pReq)
00241 {
00242     uint8_t bIf     = AUDGenericRequest_GetInterface(pReq);
00243     uint8_t bEntity = AUDGenericRequest_GetEntity(pReq);
00244     uint8_t bLength = USBGenericRequest_GetLength(pReq);
00245     uint8_t bCh     = AUDFeatureUnitRequest_GetChannel(pReq);
00246     uint8_t bCtrl   = AUDFeatureUnitRequest_GetControl(pReq);
00247     uint8_t bSet = 1;
00248     AUDDStream *pAuds = AUDD_GetCtlStream(pAudf, bIf, bEntity, bCh);
00249     TransferCallback fCallback;
00250 
00251     TRACE_INFO_WP("sCUR ");
00252     TRACE_DEBUG("\b(E%d, CtlS%d, Ch%d, L%d) ", bEntity, bCtrl, bCh, bLength);
00253 
00254     /* Set Mute to AC, 1 byte */
00255     if (bCtrl == AUDFeatureUnitRequest_MUTE
00256         && bLength == 1
00257         && pAuds)
00258         fCallback = (TransferCallback) AUDD_MuteReceived;
00259     else if (bCtrl == AUDFeatureUnitRequest_VOLUME
00260              && bLength == 2
00261              && pAuds && pAuds->pwVolumes)
00262         fCallback = (TransferCallback) AUDD_VolumeReceived;
00263     else
00264         bSet = 0;
00265 
00266     if (bSet) {
00267 
00268         auddXfrData.pStream = pAuds;
00269         auddXfrData.bEntity = bEntity;
00270         auddXfrData.bCh     = bCh;
00271         USBD_Read(0,
00272                   &auddXfrData.usbBuffer,
00273                   bLength,
00274                   fCallback,
00275                   (void *) &auddXfrData);
00276     } else
00277 
00278         USBD_Stall(0);
00279 
00280 }
00281 
00282 /**
00283  * Handle the GET_CUR request.
00284  * \param pAudf Pointer to AUDDSpeakerPhone instance.
00285  * \param pReq  Pointer to USBGenericRequest instance.
00286  */
00287 static void AUDD_GetCUR(
00288     AUDDSpeakerPhone *pAudf,
00289     const USBGenericRequest *pReq)
00290 {
00291     uint8_t bIf     = AUDGenericRequest_GetInterface(pReq);
00292     uint8_t bEntity = AUDGenericRequest_GetEntity(pReq);
00293     uint8_t bLength = USBGenericRequest_GetLength(pReq);
00294     uint8_t bCh     = AUDFeatureUnitRequest_GetChannel(pReq);
00295     uint8_t bCtrl   = AUDFeatureUnitRequest_GetControl(pReq);
00296     uint8_t bGet = 1;
00297     AUDDStream *pAuds = AUDD_GetCtlStream(pAudf, bIf, bEntity, bCh);
00298 
00299     TRACE_INFO_WP("gCUR ");
00300     TRACE_INFO_WP("\b(E%d, CtlS%d, Ch%d, L%d) ", bEntity, bCtrl, bCh, bLength);
00301 
00302     /* Get Mute 1 byte */
00303     if (bCtrl == AUDFeatureUnitRequest_MUTE
00304         && bLength == 1
00305         && pAuds)
00306         auddXfrData.usbBuffer = ((pAuds->bmMute & (1 << bCh)) > 0);
00307     else if (bCtrl == AUDFeatureUnitRequest_VOLUME
00308              && bLength == 2
00309              && pAuds && pAuds->pwVolumes)
00310         auddXfrData.usbBuffer = pAuds->pwVolumes[bCh];
00311     else
00312         bGet = 0;
00313 
00314     if (bGet)
00315 
00316         USBD_Write(0, &auddXfrData.usbBuffer, bLength, 0, 0);
00317     else
00318 
00319         USBD_Stall(0);
00320 }
00321 
00322 /*------------------------------------------------------------------------------
00323  *         Exported Functions
00324  *------------------------------------------------------------------------------*/
00325 
00326 /**
00327  * Initialize AUDDStream instance.
00328  * Note the number of channels excludes the master control, so
00329  * actual volume array size should be (1 + numChannels).
00330  * \param pAuds Pointer to AUDDStream instance.
00331  * \param numChannels     Number of channels in the stream (<31).
00332  * \param wChannelVolumes Data array for channel volume values.
00333  * \param fCallback Callback function for stream events.
00334  * \param pArg      Pointer to event handler arguments.
00335  */
00336 void AUDDStream_Initialize(AUDDStream *pAuds,
00337                            uint8_t     numChannels,
00338                            uint16_t    wChannelVolumes[],
00339                            AUDDStreamEventCallback fCallback,
00340                            void *pArg)
00341 {
00342     pAuds->bAcInterface    = 0xFF;
00343     pAuds->bFeatureUnitOut = 0xFF;
00344     pAuds->bFeatureUnitIn  = 0xFF;
00345     pAuds->bAsInterface    = 0xFF;
00346     pAuds->bEndpointOut    = 0;
00347     pAuds->bEndpointIn     = 0;
00348 
00349     pAuds->bNumChannels   = numChannels;
00350     pAuds->bmMute         = 0;
00351     pAuds->pwVolumes      = wChannelVolumes;
00352 
00353     pAuds->fCallback = fCallback;
00354     pAuds->pArg      = pArg;
00355 }
00356 
00357 /**
00358  * Check if the request is accepted.
00359  * \param pAuds Pointer to AUDDStream instance.
00360  * \param pReq  Pointer to a USBGenericRequest instance.
00361  * \return 1 if accepted.
00362  */
00363 uint32_t AUDDStream_IsRequestAccepted(
00364     AUDDStream *pAuds,
00365     const USBGenericRequest *pReq)
00366 {
00367     uint8_t bIf     = AUDGenericRequest_GetInterface(pReq);
00368     uint8_t bEntity = AUDGenericRequest_GetEntity(pReq);
00369     uint8_t bCh     = AUDFeatureUnitRequest_GetChannel(pReq);
00370 
00371     /* AudioControl Interface */
00372     if (bIf == pAuds->bAcInterface) {
00373         if (bCh > pAuds->bNumChannels)
00374             return 0;
00375 
00376         if (bEntity != pAuds->bFeatureUnitIn
00377             && bEntity != pAuds->bFeatureUnitOut)
00378             return 0;
00379     }
00380     /* AudioStream Interface not handled */
00381     else
00382         return 0;
00383 
00384     return 1;
00385 }
00386 
00387 /**
00388  * Change Stream Mute status.
00389  * \param pAuds     Pointer to AUDDStream instance.
00390  * \param bChannel  Channel number.
00391  * \param bmMute     1 to mute, 0 to unmute.
00392  */
00393 uint32_t AUDDStream_ChangeMute(AUDDStream *pAuds,
00394                                uint8_t bChannel,
00395                                uint8_t bMute)
00396 {
00397     if (pAuds->bNumChannels < bChannel)
00398         return USBRC_PARAM_ERR;
00399 
00400     pAuds->bmMute =  bMute;
00401 
00402     if (pAuds->fCallback)
00403         pAuds->fCallback(AUDD_EC_MuteChanged,
00404                          bChannel,
00405                          pAuds->pArg);
00406 
00407     return USBRC_SUCCESS;
00408 }
00409 
00410 /**
00411  * Set Stream Volume status.
00412  * \param pAuds     Pointer to AUDDStream instance.
00413  * \param bChannel  Channel number.
00414  * \param wVolume   New volume value.
00415  */
00416 uint32_t AUDDStream_SetVolume(AUDDStream *pAuds,
00417                               uint8_t  bChannel,
00418                               uint16_t wVolume)
00419 {
00420     if (pAuds->pwVolumes == 0)
00421         return USBRC_PARAM_ERR;
00422 
00423     if (bChannel > pAuds->bNumChannels)
00424         return USBRC_PARAM_ERR;
00425 
00426     pAuds->pwVolumes[bChannel] = wVolume;
00427 
00428     if (pAuds->fCallback) {
00429         pAuds->fCallback(AUDD_EC_VolumeChanged,
00430                          bChannel,
00431                          pAuds->pArg);
00432     }
00433 
00434     return USBRC_SUCCESS;
00435 }
00436 
00437 /**
00438  * Receives data from the host through the audio function (as speaker).
00439  * This function behaves like USBD_Read.
00440  * \param pAuds        Pointer to AUDDStream instance.
00441  * \param pData  Pointer to the data buffer to put received data.
00442  * \param dwSize Size of the data buffer in bytes.
00443  * \param fCallback Optional callback function to invoke when the transfer
00444  *                  finishes.
00445  * \param pArg      Optional argument to the callback function.
00446  * \return USBD_STATUS_SUCCESS if the read operation has been started normally;
00447  *         otherwise, the corresponding error code.
00448  */
00449 uint32_t AUDDStream_Read(
00450     AUDDStream *pAuds,
00451     void *pData, uint32_t dwSize,
00452     TransferCallback fCallback, void *pArg)
00453 {
00454     if (pAuds->bEndpointOut == 0)
00455         return USBRC_PARAM_ERR;
00456 
00457     return USBD_Read(pAuds->bEndpointOut,
00458                      pData, dwSize,
00459                      fCallback, pArg);
00460 }
00461 
00462 /**
00463  * Initialize Frame List for sending audio data.
00464  * \param pAuds     Pointer to AUDDStream instance.
00465  * \param pListInit Pointer to the allocated list for audio write.
00466  * \param pDmaInit  Pointer to the allocated DMA descriptors for autio write
00467  *                  (if DMA supported).
00468  * \param listSize  Circular list size.
00469  * \param delaySize Start transfer after delaySize frames filled in.
00470  * \param callback  Optional callback function for transfer.
00471  * \param argument  Optional callback argument.
00472  * \return USBD_STATUS_SUCCESS if setup successfully; otherwise an error code.
00473  */
00474 uint32_t AUDDStream_SetupWrite(
00475     AUDDStream *pAuds,
00476     void *pListInit,
00477     void *pDmaInit,
00478     uint16_t listSize,
00479     uint16_t delaySize,
00480     TransferCallback callback,
00481     void *argument)
00482 {
00483     uint32_t error;
00484 
00485     pDmaInit = pDmaInit;
00486 
00487     if (pAuds->bEndpointIn == 0)
00488         return USBRC_STATE_ERR;
00489 
00490     error = USBD_HAL_SetupMblTransfer(pAuds->bEndpointIn,
00491                                       pListInit,
00492                                       listSize,
00493                                       delaySize);
00494 
00495     if (error)  return error;
00496 
00497     error = USBD_HAL_SetTransferCallback(pAuds->bEndpointIn,
00498                                          callback, argument);
00499     return error;
00500 }
00501 
00502 
00503 /**
00504  *  Add frame buffer to audio sending list.
00505  *  \param pAuds   Pointer to AUDDStream instance.
00506  *  \param pBuffer Pointer to data frame to send.
00507  *  \param wLength Frame size in bytes.
00508  *  \return USBD_STATUS_SUCCESS if the transfer is started successfully;
00509  *          otherwise an error code.
00510  */
00511 uint32_t AUDDStream_Write(AUDDStream *pAuds, void *pBuffer, uint16_t wLength)
00512 {
00513     if (pAuds->bEndpointIn == 0)
00514         return USBRC_STATE_ERR;
00515 
00516     return USBD_HAL_Write(pAuds->bEndpointIn,
00517                           pBuffer, wLength);
00518 }
00519 
00520 /**
00521  * Close the stream. All pending transfers are canceled.
00522  * \param pStream Pointer to AUDDStream instance.
00523  */
00524 uint32_t AUDDStream_Close(AUDDStream *pStream)
00525 {
00526     uint32_t bmEPs = 0;
00527 
00528     /* Close output stream */
00529     if (pStream->bEndpointIn)
00530         bmEPs |= 1 << pStream->bEndpointIn;
00531 
00532     /* Close input stream */
00533     if (pStream->bEndpointOut)
00534         bmEPs |= 1 << pStream->bEndpointOut;
00535 
00536     USBD_HAL_ResetEPs(bmEPs, USBRC_CANCELED, 1);
00537 
00538     return USBRC_SUCCESS;
00539 }
00540 
00541 /*
00542  *          Audio Speakerphone functions
00543  */
00544 
00545 /**
00546  * Initialize AUDDStream instance.
00547  * Note the number of channels excludes the master control, so
00548  * actual volume array size should be (1 + numChannels).
00549  * \param pAuds Pointer to AUDDStream instance.
00550  * \param numChannels Number of channels in the stream (excluding master,<31).
00551  * \param wChannelVolumes Data array for channel volume values,
00552  *                        must include master (1 + numChannels).
00553  * \param fCallback Callback function for stream control events.
00554  * \param pArg      Pointer to event handler arguments.
00555  */
00556 void AUDDSpeakerPhone_InitializeStream(
00557     AUDDStream *pAuds,
00558     uint8_t     numChannels,
00559     uint16_t    wChannelVolumes[],
00560     AUDDStreamEventCallback fCallback,
00561     void *pArg)
00562 {
00563     pAuds->bAcInterface    = 0xFF;
00564     pAuds->bFeatureUnitOut = 0xFF;
00565     pAuds->bFeatureUnitIn  = 0xFF;
00566     pAuds->bAsInterface    = 0xFF;
00567     pAuds->bEndpointOut    = 0;
00568     pAuds->bEndpointIn     = 0;
00569 
00570     pAuds->bNumChannels   = numChannels;
00571     pAuds->bmMute         = 0;
00572     pAuds->pwVolumes      = wChannelVolumes;
00573 
00574     pAuds->fCallback = fCallback;
00575     pAuds->pArg      = pArg;
00576 }
00577 
00578 /**
00579  * Initialize AUDDSpeakerPhone instance.
00580  * \param pAudf       Pointer to AUDDSpeakerPhone instance.
00581  * \param pUsbd       Pointer to USBDDriver instance.
00582  * \param pSpeaker    Pointer to speaker streaming interface.
00583  * \param pMicrophone Pointer to microphone streaming interface.
00584  */
00585 void AUDDSpeakerPhone_Initialize(
00586     AUDDSpeakerPhone *pAudf,
00587     USBDDriver *pUsbd,
00588     AUDDStream *pSpeaker,
00589     AUDDStream *pMicrophone)
00590 {
00591     pAudf->pUsbd       = pUsbd;
00592     pAudf->pSpeaker    = pSpeaker;
00593     pAudf->pMicrophone = pMicrophone;
00594 }
00595 
00596 /**
00597  * Parse USB Audio streaming information for AUDDStream instance.
00598  * \param pAudf        Pointer to AUDDSpeakerPhone instance.
00599  * \param pDescriptors Pointer to descriptor list.
00600  * \param dwLength     Descriptor list size in bytes.
00601  */
00602 USBGenericDescriptor *AUDDSpeakerPhone_ParseInterfaces(
00603     AUDDSpeakerPhone *pAudf,
00604     USBGenericDescriptor *pDescriptors,
00605     uint32_t dwLength)
00606 {
00607     AUDDParseData data;
00608 
00609     data.pAudf = pAudf;
00610     data.pIfDesc = 0;
00611 
00612     return USBGenericDescriptor_Parse(pDescriptors,
00613                                       dwLength,
00614                                       (USBDescriptorParseFunction)AUDDSpeakerPhone_Parse,
00615                                       (void *)&data);
00616 }
00617 
00618 /**
00619  * Close the stream. All pending transfers are canceled.
00620  * \param pAudf        Pointer to AUDDSpeakerPhone instance.
00621  * \param bInterface   Stream interface number
00622  */
00623 uint32_t AUDDSpeakerPhone_CloseStream(
00624     AUDDSpeakerPhone *pAudf,
00625     uint32_t bInterface)
00626 {
00627     if (pAudf->pSpeaker->bAsInterface == bInterface) {
00628         //        USBD_HAL_ResetEPs(1 << pAudf->pSpeaker->bEndpointOut,
00629         //                          USBRC_CANCELED,
00630         //                          1);
00631     } else if (pAudf->pMicrophone->bAsInterface == bInterface) {
00632         //        USBD_HAL_ResetEPs(1 << pAudf->pMicrophone->bEndpointIn,
00633         //                          USBRC_CANCELED,
00634         //                          1);
00635     }
00636 
00637     return USBRC_SUCCESS;
00638 }
00639 
00640 /**
00641  *  Handles audio-specific USB requests sent by the host
00642  *  \param pAudf    Pointer to AUDDSpeakerPhone instance.
00643  *  \param pRequest Pointer to a USBGenericRequest instance.
00644  *  \return USBRC_PARAM_ERR if not handled.
00645  */
00646 uint32_t AUDDSpeakerPhone_RequestHandler(
00647     AUDDSpeakerPhone *pAudf,
00648     const USBGenericRequest *pRequest)
00649 {
00650     //USBDDriver *pUsbd = pAudf->pUsbd;
00651 
00652     if (USBGenericRequest_GetType(pRequest) != USBGenericRequest_CLASS)
00653         return USBRC_PARAM_ERR;
00654 
00655     TRACE_INFO_WP("Aud ");
00656 
00657     switch (USBGenericRequest_GetRequest(pRequest)) {
00658     case AUDGenericRequest_SETCUR:
00659         AUDD_SetCUR(pAudf, pRequest);
00660         break;
00661 
00662     case AUDGenericRequest_GETCUR:
00663         AUDD_GetCUR(pAudf, pRequest);
00664         break;
00665 
00666     default:
00667         return USBRC_PARAM_ERR;
00668     }
00669 
00670     return USBRC_SUCCESS;
00671 }
00672 
00673 /**
00674  * Receives data from the host through the audio function (as speaker).
00675  * This function behaves like USBD_Read.
00676  * \param pAudf        Pointer to AUDDSpeakerPhone instance.
00677  * \param pData  Pointer to the data buffer to put received data.
00678  * \param dwSize Size of the data buffer in bytes.
00679  * \param fCallback Optional callback function to invoke when the transfer
00680  *                  finishes.
00681  * \param pArg      Optional argument to the callback function.
00682  * \return USBD_STATUS_SUCCESS if the read operation has been started normally;
00683  *         otherwise, the corresponding error code.
00684  */
00685 uint32_t AUDDSpeakerPhone_Read(
00686     AUDDSpeakerPhone *pAudf,
00687     void *pData, uint32_t dwSize,
00688     TransferCallback fCallback, void *pArg)
00689 {
00690     if (pAudf->pSpeaker == 0)
00691         return USBRC_PARAM_ERR;
00692 
00693     if (pAudf->pSpeaker->bEndpointOut == 0)
00694         return USBRC_PARAM_ERR;
00695 
00696     return USBD_Read(pAudf->pSpeaker->bEndpointOut,
00697                      pData, dwSize,
00698                      fCallback, pArg);
00699 }
00700 
00701 /**
00702  * Initialize Frame List for sending audio data.
00703  * \param pAudf     Pointer to AUDDSpeakerPhone instance.
00704  * \param pListInit Pointer to the allocated list for audio write.
00705  * \param pDmaInit  Pointer to the allocated DMA descriptors for autio write
00706  *                  (if DMA supported).
00707  * \param listSize  Circular list size.
00708  * \param delaySize Start transfer after delaySize frames filled in.
00709  * \param callback  Optional callback function for transfer.
00710  * \param argument  Optional callback argument.
00711  * \return USBD_STATUS_SUCCESS if setup successfully; otherwise an error code.
00712  */
00713 uint32_t AUDDSpeakerPhone_SetupWrite(
00714     AUDDSpeakerPhone *pAudf,
00715     void *pListInit,
00716     void *pDmaInit,
00717     uint16_t listSize,
00718     uint16_t delaySize,
00719     TransferCallback callback,
00720     void *argument)
00721 {
00722     uint32_t error;
00723 
00724     pDmaInit = pDmaInit;
00725 
00726     if (pAudf->pMicrophone == 0)
00727         return USBRC_PARAM_ERR;
00728 
00729     if (pAudf->pMicrophone->bEndpointIn == 0)
00730         return USBRC_STATE_ERR;
00731 
00732     error = USBD_HAL_SetupMblTransfer(pAudf->pMicrophone->bEndpointIn,
00733                                       pListInit,
00734                                       listSize,
00735                                       delaySize);
00736 
00737     if (error)  return error;
00738 
00739     error = USBD_HAL_SetTransferCallback(
00740                 pAudf->pMicrophone->bEndpointIn,
00741                 callback, argument);
00742     return error;
00743 }
00744 
00745 
00746 /**
00747  *  Add frame buffer to audio sending list.
00748  *  \param pAudf   Pointer to AUDDSpeakerPhone instance.
00749  *  \param pBuffer Pointer to data frame to send.
00750  *  \param wLength Frame size in bytes.
00751  *  \return USBD_STATUS_SUCCESS if the transfer is started successfully;
00752  *          otherwise an error code.
00753  */
00754 uint32_t AUDDSpeakerPhone_Write(AUDDSpeakerPhone *pAudf, void *pBuffer,
00755                                 uint16_t wLength)
00756 {
00757     if (pAudf->pSpeaker == 0)
00758         return USBRC_PARAM_ERR;
00759 
00760     if (pAudf->pSpeaker->bEndpointIn == 0)
00761         return USBRC_STATE_ERR;
00762 
00763     return USBD_HAL_Write(pAudf->pSpeaker->bEndpointIn,
00764                           pBuffer, wLength);
00765 }
00766 
00767 /**@}*/
00768 
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines