SAMV71 Xplained Ultra Software Package 1.3

AUDDStream.c

Go to the documentation of this file.
00001 /* ----------------------------------------------------------------------------
00002  *         ATMEL Microcontroller Software Support
00003  * ----------------------------------------------------------------------------
00004  * Copyright (c) 2008, Atmel Corporation
00005  *
00006  * All rights reserved.
00007  *
00008  * Redistribution and use in source and binary forms, with or without
00009  * modification, are permitted provided that the following conditions are met:
00010  *
00011  * - Redistributions of source code must retain the above copyright notice,
00012  * this list of conditions and the disclaimer below.
00013  *
00014  * Atmel's name may not be used to endorse or promote products derived from
00015  * this software without specific prior written permission.
00016  *
00017  * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
00018  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
00019  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
00020  * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
00021  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
00022  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
00023  * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00024  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00025  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
00026  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00027  * ----------------------------------------------------------------------------
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         /* AudioControl interface */
00111         if (pIf->bInterfaceClass ==
00112                         AUDControlInterfaceDescriptor_CLASS
00113             && pIf->bInterfaceSubClass ==
00114                         AUDControlInterfaceDescriptor_SUBCLASS) {
00115             pArg->pIfDesc = pIf;
00116 
00117             if (pSpeaker) pSpeaker->bAcInterface = pIf->bInterfaceNumber;
00118             if (pMic)     pMic->bAcInterface = pIf->bInterfaceNumber;
00119         }
00120         /* AudioStreaming interface with endpoint */
00121         else if (pIf->bInterfaceClass ==
00122                     AUDStreamingInterfaceDescriptor_CLASS
00123             && pIf->bInterfaceSubClass ==
00124                     AUDStreamingInterfaceDescriptor_SUBCLASS) {
00125             pArg->pIfDesc = pIf;
00126         }
00127         /* Not Audio interface, force end */
00128         else if (pArg->pIfDesc){
00129             return USBRC_PARTIAL_DONE;
00130         }
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             }
00146             else if (pSpeaker) {
00147                 pSpeaker->bEndpointOut = pEp->bEndpointAddress;
00148                 pSpeaker->bAsInterface = pArg->pIfDesc->bInterfaceNumber;
00149                 /* Fixed FU */
00150                 pSpeaker->bFeatureUnitOut = AUDD_ID_SpeakerFU;
00151             }
00152         }
00153     }
00154 
00155     if (pSpeaker) {
00156         if (pSpeaker->bAcInterface != 0xFF
00157             && pSpeaker->bAsInterface != 0xFF
00158             && pSpeaker->bFeatureUnitOut != 0xFF
00159             && pSpeaker->bEndpointOut != 0) {
00160             bSpeakerDone = 1;
00161         }
00162     }
00163     else    bSpeakerDone = 1;
00164 
00165     if (pMic) {
00166         if (pMic->bAcInterface != 0xFF
00167             && pMic->bAsInterface != 0xFF
00168             && pMic->bFeatureUnitIn != 0xFF
00169             && pMic->bEndpointIn != 0) {
00170             bMicDone = 1;
00171         }
00172     }
00173     else    bMicDone = 1;
00174 
00175     if (bSpeakerDone && bMicDone)
00176         return USBRC_FINISHED;
00177     
00178     return USBRC_SUCCESS;
00179 }
00180 
00181 /**
00182  * Callback triggered after the new mute status of a channel has been read.
00183  * Changes the mute status of the given channel accordingly.
00184  * \param pData Pointer to AUDDXfrExt (transfer extension data).
00185  */
00186 static void AUDD_MuteReceived(AUDDXfrExt *pData)
00187 {
00188     AUDDStream_ChangeMute(pData->pStream,
00189                           pData->bCh,
00190                           (uint8_t)pData->usbBuffer);
00191     USBD_Write(0, 0, 0, 0, 0);
00192 }
00193 
00194 /**
00195  * Callback triggered after the new volume status of a channel has been read.
00196  * Changes the volume status of the given channel accordingly.
00197  * \param pData Pointer to AUDDXfrExt (transfer extension data).
00198  */
00199 static void AUDD_VolumeReceived(AUDDXfrExt *pData)
00200 {
00201     AUDDStream_SetVolume(pData->pStream,
00202                          pData->bCh,
00203                          pData->usbBuffer);
00204     USBD_Write(0, 0, 0, 0, 0);
00205 }
00206 
00207 /**
00208  * Get Target AUDDStream for control
00209  * \param pAudf         Pointer to AUDDSpeakerPhone instance.
00210  * \param bAcInterface  Interface number
00211  * \param bEntity       Entity ID
00212  * \param bChannel      Channel number
00213  * \return Pointer to AUDDStream instance
00214  */
00215 static AUDDStream *AUDD_GetCtlStream(
00216     AUDDSpeakerPhone *pAudf,
00217     uint8_t bAcInterface,
00218     uint8_t bEntity,
00219     uint8_t bChannel)
00220 {
00221     AUDDStream *pAuds = 0;
00222 
00223     if (bEntity == pAudf->pSpeaker->bFeatureUnitOut
00224         || bEntity == pAudf->pSpeaker->bFeatureUnitIn)
00225         pAuds = pAudf->pSpeaker;
00226     else if (bEntity == pAudf->pMicrophone->bFeatureUnitIn
00227         || bEntity == pAudf->pMicrophone->bFeatureUnitOut)
00228         pAuds = pAudf->pMicrophone;
00229 
00230     if (pAuds != 0
00231         && bAcInterface == pAuds->bAcInterface
00232         && bChannel <= pAuds->bNumChannels) {
00233         return pAuds;
00234     }
00235 
00236     return 0;
00237 }
00238 
00239 /**
00240  * Handle the SET_CUR request.
00241  * \param pAudf Pointer to AUDDSpeakerPhone instance.
00242  * \param pReq  Pointer to USBGenericRequest instance.
00243  */
00244 static void AUDD_SetCUR(
00245     AUDDSpeakerPhone *pAudf,
00246     const USBGenericRequest* pReq)
00247 {
00248     uint8_t bIf     = AUDGenericRequest_GetInterface(pReq);
00249     uint8_t bEntity = AUDGenericRequest_GetEntity(pReq);
00250     uint8_t bLength = USBGenericRequest_GetLength(pReq);
00251     uint8_t bCh     = AUDFeatureUnitRequest_GetChannel(pReq);
00252     uint8_t bCtrl   = AUDFeatureUnitRequest_GetControl(pReq);
00253     uint8_t bSet = 1;
00254     AUDDStream *pAuds = AUDD_GetCtlStream(pAudf, bIf, bEntity, bCh);
00255     TransferCallback fCallback;
00256 
00257     TRACE_INFO_WP("sCUR ");
00258     TRACE_DEBUG("\b(E%d, CtlS%d, Ch%d, L%d) ", bEntity, bCtrl, bCh, bLength);
00259 
00260     /* Set Mute to AC, 1 byte */
00261     if (bCtrl == AUDFeatureUnitRequest_MUTE
00262         && bLength == 1
00263         && pAuds) {
00264         fCallback = (TransferCallback) AUDD_MuteReceived;
00265     }
00266     else if (bCtrl == AUDFeatureUnitRequest_VOLUME
00267         && bLength == 2
00268         && pAuds && pAuds->pwVolumes) {
00269         fCallback = (TransferCallback) AUDD_VolumeReceived;
00270     }
00271     else
00272         bSet = 0;
00273 
00274     if (bSet) {
00275 
00276         auddXfrData.pStream = pAuds;
00277         auddXfrData.bEntity = bEntity;
00278         auddXfrData.bCh     = bCh;
00279         USBD_Read(0,
00280                   &auddXfrData.usbBuffer,
00281                   bLength,
00282                   fCallback,
00283                   (void *) &auddXfrData);
00284     }
00285     else {
00286 
00287         USBD_Stall(0);
00288     }
00289 
00290 }
00291 
00292 /**
00293  * Handle the GET_CUR request.
00294  * \param pAudf Pointer to AUDDSpeakerPhone instance.
00295  * \param pReq  Pointer to USBGenericRequest instance.
00296  */
00297 static void AUDD_GetCUR(
00298     AUDDSpeakerPhone *pAudf,
00299     const USBGenericRequest *pReq)
00300 {
00301     uint8_t bIf     = AUDGenericRequest_GetInterface(pReq);
00302     uint8_t bEntity = AUDGenericRequest_GetEntity(pReq);
00303     uint8_t bLength = USBGenericRequest_GetLength(pReq);
00304     uint8_t bCh     = AUDFeatureUnitRequest_GetChannel(pReq);
00305     uint8_t bCtrl   = AUDFeatureUnitRequest_GetControl(pReq);
00306     uint8_t bGet = 1;
00307     AUDDStream *pAuds = AUDD_GetCtlStream(pAudf, bIf, bEntity, bCh);
00308 
00309     TRACE_INFO_WP("gCUR ");
00310     TRACE_INFO_WP("\b(E%d, CtlS%d, Ch%d, L%d) ", bEntity, bCtrl, bCh, bLength);
00311 
00312     /* Get Mute 1 byte */
00313     if (bCtrl == AUDFeatureUnitRequest_MUTE
00314         && bLength == 1
00315         && pAuds) {
00316         auddXfrData.usbBuffer = ((pAuds->bmMute & (1<<bCh)) > 0);
00317     }
00318     else if (bCtrl == AUDFeatureUnitRequest_VOLUME
00319         && bLength == 2
00320         && pAuds && pAuds->pwVolumes) {
00321         auddXfrData.usbBuffer = pAuds->pwVolumes[bCh];
00322     }
00323     else
00324         bGet = 0;
00325 
00326     if (bGet) {
00327 
00328         USBD_Write(0, &auddXfrData.usbBuffer, bLength, 0, 0);
00329     }
00330     else {
00331 
00332         USBD_Stall(0);
00333     }
00334 }
00335 
00336 /*------------------------------------------------------------------------------
00337  *         Exported Functions
00338  *------------------------------------------------------------------------------*/
00339 
00340 /**
00341  * Initialize AUDDStream instance.
00342  * Note the number of channels excludes the master control, so
00343  * actual volume array size should be (1 + numChannels).
00344  * \param pAuds Pointer to AUDDStream instance.
00345  * \param numChannels     Number of channels in the stream (<31).
00346  * \param wChannelVolumes Data array for channel volume values.
00347  * \param fCallback Callback function for stream events.
00348  * \param pArg      Pointer to event handler arguments.
00349  */
00350 void AUDDStream_Initialize(AUDDStream *pAuds,
00351                            uint8_t     numChannels,
00352                            uint16_t    wChannelVolumes[],
00353                            AUDDStreamEventCallback fCallback,
00354                            void* pArg)
00355 {
00356     pAuds->bAcInterface    = 0xFF;
00357     pAuds->bFeatureUnitOut = 0xFF;
00358     pAuds->bFeatureUnitIn  = 0xFF;
00359     pAuds->bAsInterface    = 0xFF;
00360     pAuds->bEndpointOut    = 0;
00361     pAuds->bEndpointIn     = 0;
00362 
00363     pAuds->bNumChannels   = numChannels;
00364     pAuds->bmMute         = 0;
00365     pAuds->pwVolumes      = wChannelVolumes;
00366 
00367     pAuds->fCallback = fCallback;
00368     pAuds->pArg      = pArg;
00369 }
00370 
00371 /**
00372  * Check if the request is accepted.
00373  * \param pAuds Pointer to AUDDStream instance.
00374  * \param pReq  Pointer to a USBGenericRequest instance.
00375  * \return 1 if accepted.
00376  */
00377 uint32_t AUDDStream_IsRequestAccepted(
00378     AUDDStream *pAuds,
00379     const USBGenericRequest *pReq)
00380 {
00381     uint8_t bIf     = AUDGenericRequest_GetInterface(pReq);
00382     uint8_t bEntity = AUDGenericRequest_GetEntity(pReq);
00383     uint8_t bCh     = AUDFeatureUnitRequest_GetChannel(pReq);
00384     /* AudioControl Interface */
00385     if (bIf == pAuds->bAcInterface) {
00386         if (bCh > pAuds->bNumChannels)
00387             return 0;
00388         if (bEntity != pAuds->bFeatureUnitIn
00389             && bEntity != pAuds->bFeatureUnitOut)
00390             return 0;
00391     }
00392     /* AudioStream Interface not handled */
00393     else {
00394         return 0;
00395     }
00396     return 1;
00397 }
00398 
00399 /**
00400  * Change Stream Mute status.
00401  * \param pAuds     Pointer to AUDDStream instance.
00402  * \param bChannel  Channel number.
00403  * \param bmMute     1 to mute, 0 to unmute.
00404  */
00405 uint32_t AUDDStream_ChangeMute(AUDDStream *pAuds,
00406                                uint8_t bChannel,
00407                                uint8_t bMute)
00408 {
00409     uint32_t bmMute = (bMute << bChannel);
00410 
00411     if (pAuds->bNumChannels < bChannel)
00412         return USBRC_PARAM_ERR;
00413 
00414     pAuds->bmMute =  bMute;
00415     
00416     if (pAuds->fCallback)
00417         pAuds->fCallback(AUDD_EC_MuteChanged,
00418                          bChannel,
00419                          pAuds->pArg);
00420 
00421     return USBRC_SUCCESS;
00422 }
00423 
00424 /**
00425  * Set Stream Volume status.
00426  * \param pAuds     Pointer to AUDDStream instance.
00427  * \param bChannel  Channel number.
00428  * \param wVolume   New volume value.
00429  */
00430 uint32_t AUDDStream_SetVolume(AUDDStream *pAuds,
00431                               uint8_t  bChannel,
00432                               uint16_t wVolume)
00433 {
00434     if (pAuds->pwVolumes == 0)
00435         return USBRC_PARAM_ERR;
00436     if (bChannel > pAuds->bNumChannels)
00437         return USBRC_PARAM_ERR;
00438 
00439     pAuds->pwVolumes[bChannel] = wVolume;
00440     if (pAuds->fCallback) {
00441         pAuds->fCallback(AUDD_EC_VolumeChanged,
00442                          bChannel,
00443                          pAuds->pArg);
00444     }
00445 
00446     return USBRC_SUCCESS;
00447 }
00448 
00449 /**
00450  * Receives data from the host through the audio function (as speaker).
00451  * This function behaves like USBD_Read.
00452  * \param pAuds        Pointer to AUDDStream instance.
00453  * \param pData  Pointer to the data buffer to put received data.
00454  * \param dwSize Size of the data buffer in bytes.
00455  * \param fCallback Optional callback function to invoke when the transfer
00456  *                  finishes.
00457  * \param pArg      Optional argument to the callback function.
00458  * \return USBD_STATUS_SUCCESS if the read operation has been started normally;
00459  *         otherwise, the corresponding error code.
00460  */
00461 uint32_t AUDDStream_Read(
00462     AUDDStream *pAuds,
00463     void * pData,uint32_t dwSize,
00464     TransferCallback fCallback,void * pArg)
00465 {
00466     if (pAuds->bEndpointOut == 0)
00467         return USBRC_PARAM_ERR;
00468     return USBD_Read(pAuds->bEndpointOut,
00469                      pData, dwSize,
00470                      fCallback, pArg);
00471 }
00472 
00473 /**
00474  * Initialize Frame List for sending audio data.
00475  * \param pAuds     Pointer to AUDDStream instance.
00476  * \param pListInit Pointer to the allocated list for audio write.
00477  * \param pDmaInit  Pointer to the allocated DMA descriptors for autio write
00478  *                  (if DMA supported).
00479  * \param listSize  Circular list size.
00480  * \param delaySize Start transfer after delaySize frames filled in.
00481  * \param callback  Optional callback function for transfer.
00482  * \param argument  Optional callback argument.
00483  * \return USBD_STATUS_SUCCESS if setup successfully; otherwise an error code.
00484  */
00485 uint32_t AUDDStream_SetupWrite(
00486     AUDDStream *pAuds,
00487     void * pListInit,
00488     void * pDmaInit,
00489     uint16_t listSize,
00490     uint16_t delaySize,
00491     TransferCallback callback,
00492     void * argument)
00493 {
00494     uint32_t error;
00495     
00496     pDmaInit = pDmaInit;
00497 
00498     if (pAuds->bEndpointIn == 0)
00499         return USBRC_STATE_ERR;
00500 
00501     error = USBD_HAL_SetupMblTransfer(pAuds->bEndpointIn,
00502                                       pListInit,
00503                                       listSize,
00504                                       delaySize);
00505     if (error)  return error;
00506 
00507     error = USBD_HAL_SetTransferCallback(pAuds->bEndpointIn,
00508                                          callback, argument);
00509     return error;
00510 }
00511 
00512 
00513 /**
00514  *  Add frame buffer to audio sending list.
00515  *  \param pAuds   Pointer to AUDDStream instance.
00516  *  \param pBuffer Pointer to data frame to send.
00517  *  \param wLength Frame size in bytes.
00518  *  \return USBD_STATUS_SUCCESS if the transfer is started successfully;
00519  *          otherwise an error code.
00520  */
00521 uint32_t AUDDStream_Write(AUDDStream *pAuds, void* pBuffer, uint16_t wLength)
00522 {
00523     if (pAuds->bEndpointIn == 0)
00524         return USBRC_STATE_ERR;
00525 
00526     return USBD_HAL_Write(pAuds->bEndpointIn,
00527                           pBuffer, wLength);
00528 }
00529 
00530 /**
00531  * Close the stream. All pending transfers are canceled.
00532  * \param pStream Pointer to AUDDStream instance.
00533  */
00534 uint32_t AUDDStream_Close(AUDDStream *pStream)
00535 {
00536     uint32_t bmEPs = 0;
00537 
00538     /* Close output stream */
00539     if (pStream->bEndpointIn) {
00540         bmEPs |= 1 << pStream->bEndpointIn;
00541     }
00542     /* Close input stream */
00543     if (pStream->bEndpointOut) {
00544         bmEPs |= 1 << pStream->bEndpointOut;
00545     }
00546     USBD_HAL_ResetEPs(bmEPs, USBRC_CANCELED, 1);
00547 
00548     return USBRC_SUCCESS;
00549 }
00550 
00551 /*
00552  *          Audio Speakerphone functions
00553  */
00554 
00555 /**
00556  * Initialize AUDDStream instance.
00557  * Note the number of channels excludes the master control, so
00558  * actual volume array size should be (1 + numChannels).
00559  * \param pAuds Pointer to AUDDStream instance.
00560  * \param numChannels Number of channels in the stream (excluding master,<31).
00561  * \param wChannelVolumes Data array for channel volume values,
00562  *                        must include master (1 + numChannels).
00563  * \param fCallback Callback function for stream control events.
00564  * \param pArg      Pointer to event handler arguments.
00565  */
00566 void AUDDSpeakerPhone_InitializeStream(
00567     AUDDStream *pAuds,
00568     uint8_t     numChannels,
00569     uint16_t    wChannelVolumes[],
00570     AUDDStreamEventCallback fCallback,
00571     void* pArg)
00572 {
00573     pAuds->bAcInterface    = 0xFF;
00574     pAuds->bFeatureUnitOut = 0xFF;
00575     pAuds->bFeatureUnitIn  = 0xFF;
00576     pAuds->bAsInterface    = 0xFF;
00577     pAuds->bEndpointOut    = 0;
00578     pAuds->bEndpointIn     = 0;
00579 
00580     pAuds->bNumChannels   = numChannels;
00581     pAuds->bmMute         = 0;
00582     pAuds->pwVolumes      = wChannelVolumes;
00583 
00584     pAuds->fCallback = fCallback;
00585     pAuds->pArg      = pArg;
00586 }
00587 
00588 /**
00589  * Initialize AUDDSpeakerPhone instance.
00590  * \param pAudf       Pointer to AUDDSpeakerPhone instance.
00591  * \param pUsbd       Pointer to USBDDriver instance.
00592  * \param pSpeaker    Pointer to speaker streaming interface.
00593  * \param pMicrophone Pointer to microphone streaming interface.
00594  */
00595 void AUDDSpeakerPhone_Initialize(
00596     AUDDSpeakerPhone *pAudf,
00597     USBDDriver *pUsbd,
00598     AUDDStream *pSpeaker,
00599     AUDDStream *pMicrophone)
00600 {
00601     pAudf->pUsbd       = pUsbd;
00602     pAudf->pSpeaker    = pSpeaker;
00603     pAudf->pMicrophone = pMicrophone;
00604 }
00605 
00606 /**
00607  * Parse USB Audio streaming information for AUDDStream instance.
00608  * \param pAudf        Pointer to AUDDSpeakerPhone instance.
00609  * \param pDescriptors Pointer to descriptor list.
00610  * \param dwLength     Descriptor list size in bytes.
00611  */
00612 USBGenericDescriptor *AUDDSpeakerPhone_ParseInterfaces(
00613     AUDDSpeakerPhone *pAudf,
00614     USBGenericDescriptor *pDescriptors,
00615     uint32_t dwLength)
00616 {
00617     AUDDParseData data;
00618 
00619     data.pAudf = pAudf;
00620     data.pIfDesc = 0;
00621 
00622     return USBGenericDescriptor_Parse(pDescriptors,
00623                                       dwLength,
00624                                       (USBDescriptorParseFunction)AUDDSpeakerPhone_Parse,
00625                                       (void*)&data);
00626 }
00627 
00628 /**
00629  * Close the stream. All pending transfers are canceled.
00630  * \param pAudf        Pointer to AUDDSpeakerPhone instance.
00631  * \param bInterface   Stream interface number
00632  */
00633 uint32_t AUDDSpeakerPhone_CloseStream(
00634     AUDDSpeakerPhone *pAudf,
00635     uint32_t bInterface)
00636 {
00637     if (pAudf->pSpeaker->bAsInterface == bInterface) {
00638 //        USBD_HAL_ResetEPs(1 << pAudf->pSpeaker->bEndpointOut,
00639 //                          USBRC_CANCELED,
00640 //                          1);
00641     }
00642     else if (pAudf->pMicrophone->bAsInterface == bInterface) {
00643 //        USBD_HAL_ResetEPs(1 << pAudf->pMicrophone->bEndpointIn,
00644 //                          USBRC_CANCELED,
00645 //                          1);
00646     }
00647 
00648     return USBRC_SUCCESS;
00649 }
00650 
00651 /**
00652  *  Handles audio-specific USB requests sent by the host
00653  *  \param pAudf    Pointer to AUDDSpeakerPhone instance.
00654  *  \param pRequest Pointer to a USBGenericRequest instance.
00655  *  \return USBRC_PARAM_ERR if not handled.
00656  */
00657 uint32_t AUDDSpeakerPhone_RequestHandler(
00658     AUDDSpeakerPhone *pAudf,
00659     const USBGenericRequest* pRequest)
00660 {
00661     //USBDDriver *pUsbd = pAudf->pUsbd;
00662 
00663     if (USBGenericRequest_GetType(pRequest) != USBGenericRequest_CLASS)
00664         return USBRC_PARAM_ERR;
00665 
00666     TRACE_INFO_WP("Aud ");
00667     switch (USBGenericRequest_GetRequest(pRequest)) {
00668     case AUDGenericRequest_SETCUR:
00669         AUDD_SetCUR(pAudf, pRequest);
00670         break;
00671     case AUDGenericRequest_GETCUR:
00672         AUDD_GetCUR(pAudf, pRequest);
00673         break;
00674 
00675     default:
00676         return USBRC_PARAM_ERR;
00677     }
00678 
00679     return USBRC_SUCCESS;
00680 }
00681 
00682 /**
00683  * Receives data from the host through the audio function (as speaker).
00684  * This function behaves like USBD_Read.
00685  * \param pAudf        Pointer to AUDDSpeakerPhone instance.
00686  * \param pData  Pointer to the data buffer to put received data.
00687  * \param dwSize Size of the data buffer in bytes.
00688  * \param fCallback Optional callback function to invoke when the transfer
00689  *                  finishes.
00690  * \param pArg      Optional argument to the callback function.
00691  * \return USBD_STATUS_SUCCESS if the read operation has been started normally;
00692  *         otherwise, the corresponding error code.
00693  */
00694 uint32_t AUDDSpeakerPhone_Read(
00695     AUDDSpeakerPhone *pAudf,
00696     void * pData,uint32_t dwSize,
00697     TransferCallback fCallback,void * pArg)
00698 {
00699     if (pAudf->pSpeaker == 0)
00700         return USBRC_PARAM_ERR;
00701     if (pAudf->pSpeaker->bEndpointOut == 0)
00702         return USBRC_PARAM_ERR;
00703     return USBD_Read(pAudf->pSpeaker->bEndpointOut,
00704                      pData, dwSize,
00705                      fCallback, pArg);
00706 }
00707 
00708 /**
00709  * Initialize Frame List for sending audio data.
00710  * \param pAudf     Pointer to AUDDSpeakerPhone instance.
00711  * \param pListInit Pointer to the allocated list for audio write.
00712  * \param pDmaInit  Pointer to the allocated DMA descriptors for autio write
00713  *                  (if DMA supported).
00714  * \param listSize  Circular list size.
00715  * \param delaySize Start transfer after delaySize frames filled in.
00716  * \param callback  Optional callback function for transfer.
00717  * \param argument  Optional callback argument.
00718  * \return USBD_STATUS_SUCCESS if setup successfully; otherwise an error code.
00719  */
00720 uint32_t AUDDSpeakerPhone_SetupWrite(
00721     AUDDSpeakerPhone *pAudf,
00722     void * pListInit,
00723     void * pDmaInit,
00724     uint16_t listSize,
00725     uint16_t delaySize,
00726     TransferCallback callback,
00727     void * argument)
00728 {
00729     uint32_t error;
00730     
00731     pDmaInit = pDmaInit;
00732 
00733     if (pAudf->pMicrophone == 0)
00734         return USBRC_PARAM_ERR;
00735     if (pAudf->pMicrophone->bEndpointIn == 0)
00736         return USBRC_STATE_ERR;
00737 
00738     error = USBD_HAL_SetupMblTransfer(pAudf->pMicrophone->bEndpointIn,
00739                                       pListInit,
00740                                       listSize,
00741                                       delaySize);
00742     if (error)  return error;
00743 
00744     error = USBD_HAL_SetTransferCallback(
00745                                     pAudf->pMicrophone->bEndpointIn,
00746                                     callback, argument);
00747     return error;
00748 }
00749 
00750 
00751 /**
00752  *  Add frame buffer to audio sending list.
00753  *  \param pAudf   Pointer to AUDDSpeakerPhone instance.
00754  *  \param pBuffer Pointer to data frame to send.
00755  *  \param wLength Frame size in bytes.
00756  *  \return USBD_STATUS_SUCCESS if the transfer is started successfully;
00757  *          otherwise an error code.
00758  */
00759 uint32_t AUDDSpeakerPhone_Write(AUDDSpeakerPhone *pAudf, void* pBuffer, uint16_t wLength)
00760 {
00761     if (pAudf->pSpeaker == 0)
00762         return USBRC_PARAM_ERR;
00763     if (pAudf->pSpeaker->bEndpointIn == 0)
00764         return USBRC_STATE_ERR;
00765 
00766     return USBD_HAL_Write(pAudf->pSpeaker->bEndpointIn,
00767                           pBuffer, wLength);
00768 }
00769 
00770 /**@}*/
00771 
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines