Added USB Device library sources
[fw/stlink] / example / stm32f4 / STM32_USB_Device_Library / Class / audio / src / usbd_audio_core.c
1 /**
2   ******************************************************************************
3   * @file    usbd_audio_core.c
4   * @author  MCD Application Team
5   * @version V1.0.0
6   * @date    22-July-2011
7   * @brief   This file provides the high layer firmware functions to manage the 
8   *          following functionalities of the USB Audio Class:
9   *           - Initialization and Configuration of high and low layer
10   *           - Enumeration as Audio Streaming Device
11   *           - Audio Streaming data transfer
12   *           - AudioControl requests management
13   *           - Error management
14   *           
15   *  @verbatim
16   *      
17   *          ===================================================================      
18   *                                Audio Class Driver Description
19   *          =================================================================== 
20   *           This driver manages the Audio Class 1.0 following the "USB Device Class Definition for
21   *           Audio Devices V1.0 Mar 18, 98".
22   *           This driver implements the following aspects of the specification:
23   *             - Device descriptor management
24   *             - Configuration descriptor management
25   *             - Standard AC Interface Descriptor management
26   *             - 1 Audio Streaming Interface (with single channel, PCM, Stereo mode)
27   *             - 1 Audio Streaming Endpoint
28   *             - 1 Audio Terminal Input (1 channel)
29   *             - Audio Class-Specific AC Interfaces
30   *             - Audio Class-Specific AS Interfaces
31   *             - AudioControl Requests: only SET_CUR and GET_CUR requests are supported (for Mute)
32   *             - Audio Feature Unit (limited to Mute control)
33   *             - Audio Synchronization type: Asynchronous
34   *             - Single fixed audio sampling rate (configurable in usbd_conf.h file)
35   *          
36   *           @note
37   *            The Audio Class 1.0 is based on USB Specification 1.0 and thus supports only
38   *            Low and Full speed modes and does not allow High Speed transfers.
39   *            Please refer to "USB Device Class Definition for Audio Devices V1.0 Mar 18, 98"
40   *            for more details.
41   * 
42   *           These aspects may be enriched or modified for a specific user application.
43   *          
44   *            This driver doesn't implement the following aspects of the specification 
45   *            (but it is possible to manage these features with some modifications on this driver):
46   *             - AudioControl Endpoint management
47   *             - AudioControl requsests other than SET_CUR and GET_CUR
48   *             - Abstraction layer for AudioControl requests (only Mute functionality is managed)
49   *             - Audio Synchronization type: Adaptive
50   *             - Audio Compression modules and interfaces
51   *             - MIDI interfaces and modules
52   *             - Mixer/Selector/Processing/Extension Units (Feature unit is limited to Mute control)
53   *             - Any other application-specific modules
54   *             - Multiple and Variable audio sampling rates
55   *             - Out Streaming Endpoint/Interface (microphone)
56   *      
57   *  @endverbatim
58   *                                  
59   ******************************************************************************               
60   * @attention
61   *
62   * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
63   * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
64   * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
65   * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
66   * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
67   * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
68   *
69   * <h2><center>&copy; COPYRIGHT 2011 STMicroelectronics</center></h2>
70   ******************************************************************************
71   */ 
72
73 /* Includes ------------------------------------------------------------------*/
74
75 #include "usbd_audio_core.h"
76 #include "usbd_audio_out_if.h"
77
78 /** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY
79   * @{
80   */
81
82
83 /** @defgroup usbd_audio 
84   * @brief usbd core module
85   * @{
86   */ 
87
88 /** @defgroup usbd_audio_Private_TypesDefinitions
89   * @{
90   */ 
91 /**
92   * @}
93   */ 
94
95
96 /** @defgroup usbd_audio_Private_Defines
97   * @{
98   */ 
99 /**
100   * @}
101   */ 
102
103
104 /** @defgroup usbd_audio_Private_Macros
105   * @{
106   */ 
107 /**
108   * @}
109   */ 
110
111
112 /** @defgroup usbd_audio_Private_FunctionPrototypes
113   * @{
114   */
115
116 /*********************************************
117    AUDIO Device library callbacks
118  *********************************************/
119 static uint8_t  usbd_audio_Init       (void  *pdev, uint8_t cfgidx);
120 static uint8_t  usbd_audio_DeInit     (void  *pdev, uint8_t cfgidx);
121 static uint8_t  usbd_audio_Setup      (void  *pdev, USB_SETUP_REQ *req);
122 static uint8_t  usbd_audio_EP0_RxReady(void *pdev);
123 static uint8_t  usbd_audio_DataIn     (void *pdev, uint8_t epnum);
124 static uint8_t  usbd_audio_DataOut    (void *pdev, uint8_t epnum);
125 static uint8_t  usbd_audio_SOF        (void *pdev);
126 static uint8_t  usbd_audio_OUT_Incplt (void  *pdev);
127
128 /*********************************************
129    AUDIO Requests management functions
130  *********************************************/
131 static void AUDIO_Req_GetCurrent(void *pdev, USB_SETUP_REQ *req);
132 static void AUDIO_Req_SetCurrent(void *pdev, USB_SETUP_REQ *req);
133 static uint8_t  *USBD_audio_GetCfgDesc (uint8_t speed, uint16_t *length);
134 /**
135   * @}
136   */ 
137
138 /** @defgroup usbd_audio_Private_Variables
139   * @{
140   */ 
141 /* Main Buffer for Audio Data Out transfers and its relative pointers */
142 uint8_t  IsocOutBuff [TOTAL_OUT_BUF_SIZE * 2];
143 uint8_t* IsocOutWrPtr = IsocOutBuff;
144 uint8_t* IsocOutRdPtr = IsocOutBuff;
145
146 /* Main Buffer for Audio Control Rrequests transfers and its relative variables */
147 uint8_t  AudioCtl[64];
148 uint8_t  AudioCtlCmd = 0;
149 uint32_t AudioCtlLen = 0;
150 uint8_t  AudioCtlUnit = 0;
151
152 static uint32_t PlayFlag = 0;
153
154 static __IO uint32_t  usbd_audio_AltSet = 0;
155 static uint8_t usbd_audio_CfgDesc[AUDIO_CONFIG_DESC_SIZE];
156
157 /* AUDIO interface class callbacks structure */
158 USBD_Class_cb_TypeDef  AUDIO_cb = 
159 {
160   usbd_audio_Init,
161   usbd_audio_DeInit,
162   usbd_audio_Setup,
163   NULL, /* EP0_TxSent */
164   usbd_audio_EP0_RxReady,
165   usbd_audio_DataIn,
166   usbd_audio_DataOut,
167   usbd_audio_SOF,
168   NULL,
169   usbd_audio_OUT_Incplt,   
170   USBD_audio_GetCfgDesc,
171 #ifdef USB_OTG_HS_CORE  
172   USBD_audio_GetCfgDesc, /* use same config as per FS */
173 #endif    
174 };
175
176 /* USB AUDIO device Configuration Descriptor */
177 static uint8_t usbd_audio_CfgDesc[AUDIO_CONFIG_DESC_SIZE] =
178 {
179   /* Configuration 1 */
180   0x09,                                 /* bLength */
181   USB_CONFIGURATION_DESCRIPTOR_TYPE,    /* bDescriptorType */
182   LOBYTE(AUDIO_CONFIG_DESC_SIZE),       /* wTotalLength  109 bytes*/
183   HIBYTE(AUDIO_CONFIG_DESC_SIZE),      
184   0x02,                                 /* bNumInterfaces */
185   0x01,                                 /* bConfigurationValue */
186   0x00,                                 /* iConfiguration */
187   0xC0,                                 /* bmAttributes  BUS Powred*/
188   0x32,                                 /* bMaxPower = 100 mA*/
189   /* 09 byte*/
190   
191   /* USB Speaker Standard interface descriptor */
192   AUDIO_INTERFACE_DESC_SIZE,            /* bLength */
193   USB_INTERFACE_DESCRIPTOR_TYPE,        /* bDescriptorType */
194   0x00,                                 /* bInterfaceNumber */
195   0x00,                                 /* bAlternateSetting */
196   0x00,                                 /* bNumEndpoints */
197   USB_DEVICE_CLASS_AUDIO,               /* bInterfaceClass */
198   AUDIO_SUBCLASS_AUDIOCONTROL,          /* bInterfaceSubClass */
199   AUDIO_PROTOCOL_UNDEFINED,             /* bInterfaceProtocol */
200   0x00,                                 /* iInterface */
201   /* 09 byte*/
202   
203   /* USB Speaker Class-specific AC Interface Descriptor */
204   AUDIO_INTERFACE_DESC_SIZE,            /* bLength */
205   AUDIO_INTERFACE_DESCRIPTOR_TYPE,      /* bDescriptorType */
206   AUDIO_CONTROL_HEADER,                 /* bDescriptorSubtype */
207   0x00,          /* 1.00 */             /* bcdADC */
208   0x01,
209   0x27,                                 /* wTotalLength = 39*/
210   0x00,
211   0x01,                                 /* bInCollection */
212   0x01,                                 /* baInterfaceNr */
213   /* 09 byte*/
214   
215   /* USB Speaker Input Terminal Descriptor */
216   AUDIO_INPUT_TERMINAL_DESC_SIZE,       /* bLength */
217   AUDIO_INTERFACE_DESCRIPTOR_TYPE,      /* bDescriptorType */
218   AUDIO_CONTROL_INPUT_TERMINAL,         /* bDescriptorSubtype */
219   0x01,                                 /* bTerminalID */
220   0x01,                                 /* wTerminalType AUDIO_TERMINAL_USB_STREAMING   0x0101 */
221   0x01,
222   0x00,                                 /* bAssocTerminal */
223   0x01,                                 /* bNrChannels */
224   0x00,                                 /* wChannelConfig 0x0000  Mono */
225   0x00,
226   0x00,                                 /* iChannelNames */
227   0x00,                                 /* iTerminal */
228   /* 12 byte*/
229   
230   /* USB Speaker Audio Feature Unit Descriptor */
231   0x09,                                 /* bLength */
232   AUDIO_INTERFACE_DESCRIPTOR_TYPE,      /* bDescriptorType */
233   AUDIO_CONTROL_FEATURE_UNIT,           /* bDescriptorSubtype */
234   AUDIO_OUT_STREAMING_CTRL,             /* bUnitID */
235   0x01,                                 /* bSourceID */
236   0x01,                                 /* bControlSize */
237   AUDIO_CONTROL_MUTE,                   /* bmaControls(0) */
238   0x00,                                 /* bmaControls(1) */
239   0x00,                                 /* iTerminal */
240   /* 09 byte*/
241   
242   /*USB Speaker Output Terminal Descriptor */
243   0x09,      /* bLength */
244   AUDIO_INTERFACE_DESCRIPTOR_TYPE,      /* bDescriptorType */
245   AUDIO_CONTROL_OUTPUT_TERMINAL,        /* bDescriptorSubtype */
246   0x03,                                 /* bTerminalID */
247   0x01,                                 /* wTerminalType  0x0301*/
248   0x03,
249   0x00,                                 /* bAssocTerminal */
250   0x02,                                 /* bSourceID */
251   0x00,                                 /* iTerminal */
252   /* 09 byte*/
253   
254   /* USB Speaker Standard AS Interface Descriptor - Audio Streaming Zero Bandwith */
255   /* Interface 1, Alternate Setting 0                                             */
256   AUDIO_INTERFACE_DESC_SIZE,  /* bLength */
257   USB_INTERFACE_DESCRIPTOR_TYPE,        /* bDescriptorType */
258   0x01,                                 /* bInterfaceNumber */
259   0x00,                                 /* bAlternateSetting */
260   0x00,                                 /* bNumEndpoints */
261   USB_DEVICE_CLASS_AUDIO,               /* bInterfaceClass */
262   AUDIO_SUBCLASS_AUDIOSTREAMING,        /* bInterfaceSubClass */
263   AUDIO_PROTOCOL_UNDEFINED,             /* bInterfaceProtocol */
264   0x00,                                 /* iInterface */
265   /* 09 byte*/
266   
267   /* USB Speaker Standard AS Interface Descriptor - Audio Streaming Operational */
268   /* Interface 1, Alternate Setting 1                                           */
269   AUDIO_INTERFACE_DESC_SIZE,  /* bLength */
270   USB_INTERFACE_DESCRIPTOR_TYPE,        /* bDescriptorType */
271   0x01,                                 /* bInterfaceNumber */
272   0x01,                                 /* bAlternateSetting */
273   0x01,                                 /* bNumEndpoints */
274   USB_DEVICE_CLASS_AUDIO,               /* bInterfaceClass */
275   AUDIO_SUBCLASS_AUDIOSTREAMING,        /* bInterfaceSubClass */
276   AUDIO_PROTOCOL_UNDEFINED,             /* bInterfaceProtocol */
277   0x00,                                 /* iInterface */
278   /* 09 byte*/
279   
280   /* USB Speaker Audio Streaming Interface Descriptor */
281   AUDIO_STREAMING_INTERFACE_DESC_SIZE,  /* bLength */
282   AUDIO_INTERFACE_DESCRIPTOR_TYPE,      /* bDescriptorType */
283   AUDIO_STREAMING_GENERAL,              /* bDescriptorSubtype */
284   0x01,                                 /* bTerminalLink */
285   0x01,                                 /* bDelay */
286   0x01,                                 /* wFormatTag AUDIO_FORMAT_PCM  0x0001*/
287   0x00,
288   /* 07 byte*/
289   
290   /* USB Speaker Audio Type III Format Interface Descriptor */
291   0x0B,                                 /* bLength */
292   AUDIO_INTERFACE_DESCRIPTOR_TYPE,      /* bDescriptorType */
293   AUDIO_STREAMING_FORMAT_TYPE,          /* bDescriptorSubtype */
294   AUDIO_FORMAT_TYPE_III,                /* bFormatType */ 
295   0x02,                                 /* bNrChannels */
296   0x02,                                 /* bSubFrameSize :  2 Bytes per frame (16bits) */
297   16,                                   /* bBitResolution (16-bits per sample) */ 
298   0x01,                                 /* bSamFreqType only one frequency supported */ 
299   SAMPLE_FREQ(USBD_AUDIO_FREQ),         /* Audio sampling frequency coded on 3 bytes */
300   /* 11 byte*/
301   
302   /* Endpoint 1 - Standard Descriptor */
303   AUDIO_STANDARD_ENDPOINT_DESC_SIZE,    /* bLength */
304   USB_ENDPOINT_DESCRIPTOR_TYPE,         /* bDescriptorType */
305   AUDIO_OUT_EP,                         /* bEndpointAddress 1 out endpoint*/
306   USB_ENDPOINT_TYPE_ISOCHRONOUS,        /* bmAttributes */
307   AUDIO_PACKET_SZE(USBD_AUDIO_FREQ),    /* wMaxPacketSize in Bytes (Freq(Samples)*2(Stereo)*2(HalfWord)) */
308   0x01,                                 /* bInterval */
309   0x00,                                 /* bRefresh */
310   0x00,                                 /* bSynchAddress */
311   /* 09 byte*/
312   
313   /* Endpoint - Audio Streaming Descriptor*/
314   AUDIO_STREAMING_ENDPOINT_DESC_SIZE,   /* bLength */
315   AUDIO_ENDPOINT_DESCRIPTOR_TYPE,       /* bDescriptorType */
316   AUDIO_ENDPOINT_GENERAL,               /* bDescriptor */
317   0x00,                                 /* bmAttributes */
318   0x00,                                 /* bLockDelayUnits */
319   0x00,                                 /* wLockDelay */
320   0x00,
321   /* 07 byte*/
322 } ;
323
324 /**
325   * @}
326   */ 
327
328 /** @defgroup usbd_audio_Private_Functions
329   * @{
330   */ 
331
332 /**
333 * @brief  usbd_audio_Init
334 *         Initilaizes the AUDIO interface.
335 * @param  pdev: device instance
336 * @param  cfgidx: Configuration index
337 * @retval status
338 */
339 static uint8_t  usbd_audio_Init (void  *pdev, 
340                                  uint8_t cfgidx)
341 {  
342   /* Open EP OUT */
343   DCD_EP_Open(pdev,
344               AUDIO_OUT_EP,
345               AUDIO_OUT_PACKET,
346               USB_OTG_EP_ISOC);
347
348   /* Initialize the Audio output Hardware layer */
349   if (AUDIO_OUT_fops.Init(USBD_AUDIO_FREQ, DEFAULT_VOLUME, 0) != USBD_OK)
350   {
351     return USBD_FAIL;
352   }
353     
354   /* Prepare Out endpoint to receive audio data */
355   DCD_EP_PrepareRx(pdev,
356                    AUDIO_OUT_EP,
357                    (uint8_t*)IsocOutBuff,                        
358                    AUDIO_OUT_PACKET);  
359   
360   return USBD_OK;
361 }
362
363 /**
364 * @brief  usbd_audio_Init
365 *         DeInitializes the AUDIO layer.
366 * @param  pdev: device instance
367 * @param  cfgidx: Configuration index
368 * @retval status
369 */
370 static uint8_t  usbd_audio_DeInit (void  *pdev, 
371                                    uint8_t cfgidx)
372
373   DCD_EP_Close (pdev , AUDIO_OUT_EP);
374   
375   /* DeInitialize the Audio output Hardware layer */
376   if (AUDIO_OUT_fops.DeInit(0) != USBD_OK)
377   {
378     return USBD_FAIL;
379   }
380   
381   return USBD_OK;
382 }
383
384 /**
385   * @brief  usbd_audio_Setup
386   *         Handles the Audio control request parsing.
387   * @param  pdev: instance
388   * @param  req: usb requests
389   * @retval status
390   */
391 static uint8_t  usbd_audio_Setup (void  *pdev, 
392                                   USB_SETUP_REQ *req)
393 {
394   uint16_t len;
395   uint8_t  *pbuf;
396   
397   switch (req->bmRequest & USB_REQ_TYPE_MASK)
398   {
399     /* AUDIO Class Requests -------------------------------*/
400   case USB_REQ_TYPE_CLASS :    
401     switch (req->bRequest)
402     {
403     case AUDIO_REQ_GET_CUR:
404       AUDIO_Req_GetCurrent(pdev, req);
405       break;
406       
407     case AUDIO_REQ_SET_CUR:
408       AUDIO_Req_SetCurrent(pdev, req);   
409       break;
410
411     default:
412       USBD_CtlError (pdev, req);
413       return USBD_FAIL;
414     }
415     break;
416     
417     /* Standard Requests -------------------------------*/
418   case USB_REQ_TYPE_STANDARD:
419     switch (req->bRequest)
420     {
421     case USB_REQ_GET_DESCRIPTOR: 
422       if( (req->wValue >> 8) == AUDIO_DESCRIPTOR_TYPE)
423       {
424 #ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
425         pbuf = usbd_audio_Desc;   
426 #else
427         pbuf = usbd_audio_CfgDesc + 18;
428 #endif 
429         len = MIN(USB_AUDIO_DESC_SIZ , req->wLength);
430       }
431       
432       USBD_CtlSendData (pdev, 
433                         pbuf,
434                         len);
435       break;
436       
437     case USB_REQ_GET_INTERFACE :
438       USBD_CtlSendData (pdev,
439                         (uint8_t *)&usbd_audio_AltSet,
440                         1);
441       break;
442       
443     case USB_REQ_SET_INTERFACE :
444       if ((uint8_t)(req->wValue) < AUDIO_TOTAL_IF_NUM)
445       {
446         usbd_audio_AltSet = (uint8_t)(req->wValue);
447       }
448       else
449       {
450         /* Call the error management function (command will be nacked */
451         USBD_CtlError (pdev, req);
452       }
453       break;
454     }
455   }
456   return USBD_OK;
457 }
458
459 /**
460   * @brief  usbd_audio_EP0_RxReady
461   *         Handles audio control requests data.
462   * @param  pdev: device device instance
463   * @retval status
464   */
465 static uint8_t  usbd_audio_EP0_RxReady (void  *pdev)
466
467   /* Check if an AudioControl request has been issued */
468   if (AudioCtlCmd == AUDIO_REQ_SET_CUR)
469   {/* In this driver, to simplify code, only SET_CUR request is managed */
470     /* Check for which addressed unit the AudioControl request has been issued */
471     if (AudioCtlUnit == AUDIO_OUT_STREAMING_CTRL)
472     {/* In this driver, to simplify code, only one unit is manage */
473       /* Call the audio interface mute function */
474       AUDIO_OUT_fops.MuteCtl(AudioCtl[0]);
475       
476       /* Reset the AudioCtlCmd variable to prevent re-entering this function */
477       AudioCtlCmd = 0;
478       AudioCtlLen = 0;
479     }
480   } 
481   
482   return USBD_OK;
483 }
484
485 /**
486   * @brief  usbd_audio_DataIn
487   *         Handles the audio IN data stage.
488   * @param  pdev: instance
489   * @param  epnum: endpoint number
490   * @retval status
491   */
492 static uint8_t  usbd_audio_DataIn (void *pdev, uint8_t epnum)
493 {
494   return USBD_OK;
495 }
496
497 /**
498   * @brief  usbd_audio_DataOut
499   *         Handles the Audio Out data stage.
500   * @param  pdev: instance
501   * @param  epnum: endpoint number
502   * @retval status
503   */
504 static uint8_t  usbd_audio_DataOut (void *pdev, uint8_t epnum)
505 {     
506   if (epnum == AUDIO_OUT_EP)
507   {    
508     /* Increment the Buffer pointer or roll it back when all buffers are full */
509     if (IsocOutWrPtr >= (IsocOutBuff + (AUDIO_OUT_PACKET * OUT_PACKET_NUM)))
510     {/* All buffers are full: roll back */
511       IsocOutWrPtr = IsocOutBuff;
512     }
513     else
514     {/* Increment the buffer pointer */
515       IsocOutWrPtr += AUDIO_OUT_PACKET;
516     }
517     
518     /* Toggle the frame index */  
519     ((USB_OTG_CORE_HANDLE*)pdev)->dev.out_ep[epnum].even_odd_frame = 
520       (((USB_OTG_CORE_HANDLE*)pdev)->dev.out_ep[epnum].even_odd_frame)? 0:1;
521       
522     /* Prepare Out endpoint to receive next audio packet */
523     DCD_EP_PrepareRx(pdev,
524                      AUDIO_OUT_EP,
525                      (uint8_t*)(IsocOutWrPtr),
526                      AUDIO_OUT_PACKET);
527       
528     /* Trigger the start of streaming only when half buffer is full */
529     if ((PlayFlag == 0) && (IsocOutWrPtr >= (IsocOutBuff + ((AUDIO_OUT_PACKET * OUT_PACKET_NUM) / 2))))
530     {
531       /* Enable start of Streaming */
532       PlayFlag = 1;
533     }
534   }
535   
536   return USBD_OK;
537 }
538
539 /**
540   * @brief  usbd_audio_SOF
541   *         Handles the SOF event (data buffer update and synchronization).
542   * @param  pdev: instance
543   * @param  epnum: endpoint number
544   * @retval status
545   */
546 static uint8_t  usbd_audio_SOF (void *pdev)
547 {     
548   /* Check if there are available data in stream buffer.
549     In this function, a single variable (PlayFlag) is used to avoid software delays.
550     The play operation must be executed as soon as possible after the SOF detection. */
551   if (PlayFlag)
552   {      
553     /* Start playing received packet */
554     AUDIO_OUT_fops.AudioCmd((uint8_t*)(IsocOutRdPtr),  /* Samples buffer pointer */
555                             AUDIO_OUT_PACKET,          /* Number of samples in Bytes */
556                             AUDIO_CMD_PLAY);           /* Command to be processed */
557     
558     /* Increment the Buffer pointer or roll it back when all buffers all full */  
559     if (IsocOutRdPtr >= (IsocOutBuff + (AUDIO_OUT_PACKET * OUT_PACKET_NUM)))
560     {/* Roll back to the start of buffer */
561       IsocOutRdPtr = IsocOutBuff;
562     }
563     else
564     {/* Increment to the next sub-buffer */
565       IsocOutRdPtr += AUDIO_OUT_PACKET;
566     }
567     
568     /* If all available buffers have been consumed, stop playing */
569     if (IsocOutRdPtr == IsocOutWrPtr)
570     {    
571       /* Pause the audio stream */
572       AUDIO_OUT_fops.AudioCmd((uint8_t*)(IsocOutBuff),   /* Samples buffer pointer */
573                               AUDIO_OUT_PACKET,          /* Number of samples in Bytes */
574                               AUDIO_CMD_PAUSE);          /* Command to be processed */
575       
576       /* Stop entering play loop */
577       PlayFlag = 0;
578       
579       /* Reset buffer pointers */
580       IsocOutRdPtr = IsocOutBuff;
581       IsocOutWrPtr = IsocOutBuff;
582     }
583   }
584   
585   return USBD_OK;
586 }
587
588 /**
589   * @brief  usbd_audio_OUT_Incplt
590   *         Handles the iso out incomplete event.
591   * @param  pdev: instance
592   * @retval status
593   */
594 static uint8_t  usbd_audio_OUT_Incplt (void  *pdev)
595 {
596   return USBD_OK;
597 }
598
599 /******************************************************************************
600      AUDIO Class requests management
601 ******************************************************************************/
602 /**
603   * @brief  AUDIO_Req_GetCurrent
604   *         Handles the GET_CUR Audio control request.
605   * @param  pdev: instance
606   * @param  req: setup class request
607   * @retval status
608   */
609 static void AUDIO_Req_GetCurrent(void *pdev, USB_SETUP_REQ *req)
610 {  
611   /* Send the current mute state */
612   USBD_CtlSendData (pdev, 
613                     AudioCtl,
614                     req->wLength);
615 }
616
617 /**
618   * @brief  AUDIO_Req_SetCurrent
619   *         Handles the SET_CUR Audio control request.
620   * @param  pdev: instance
621   * @param  req: setup class request
622   * @retval status
623   */
624 static void AUDIO_Req_SetCurrent(void *pdev, USB_SETUP_REQ *req)
625
626   if (req->wLength)
627   {
628     /* Prepare the reception of the buffer over EP0 */
629     USBD_CtlPrepareRx (pdev, 
630                        AudioCtl,
631                        req->wLength);
632     
633     /* Set the global variables indicating current request and its length 
634     to the function usbd_audio_EP0_RxReady() which will process the request */
635     AudioCtlCmd = AUDIO_REQ_SET_CUR;     /* Set the request value */
636     AudioCtlLen = req->wLength;          /* Set the request data length */
637     AudioCtlUnit = HIBYTE(req->wIndex);  /* Set the request target unit */
638   }
639 }
640
641 /**
642   * @brief  USBD_audio_GetCfgDesc 
643   *         Returns configuration descriptor.
644   * @param  speed : current device speed
645   * @param  length : pointer data length
646   * @retval pointer to descriptor buffer
647   */
648 static uint8_t  *USBD_audio_GetCfgDesc (uint8_t speed, uint16_t *length)
649 {
650   *length = sizeof (usbd_audio_CfgDesc);
651   return usbd_audio_CfgDesc;
652 }
653 /**
654   * @}
655   */ 
656
657 /**
658   * @}
659   */ 
660
661 /**
662   * @}
663   */ 
664
665 /******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/