Merge pull request #93 from zyp/master
[fw/stlink] / example / stm32f4 / STM32_USB_Device_Library / Class / cdc / src / usbd_cdc_core.c
1 /**
2   ******************************************************************************
3   * @file    usbd_cdc_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 CDC Class:
9   *           - Initialization and Configuration of high and low layer
10   *           - Enumeration as CDC Device (and enumeration for each implemented memory interface)
11   *           - OUT/IN data transfer
12   *           - Command IN transfer (class requests management)
13   *           - Error management
14   *           
15   *  @verbatim
16   *      
17   *          ===================================================================      
18   *                                CDC Class Driver Description
19   *          =================================================================== 
20   *           This driver manages the "Universal Serial Bus Class Definitions for Communications Devices
21   *           Revision 1.2 November 16, 2007" and the sub-protocol specification of "Universal Serial Bus 
22   *           Communications Class Subclass Specification for PSTN Devices Revision 1.2 February 9, 2007"
23   *           This driver implements the following aspects of the specification:
24   *             - Device descriptor management
25   *             - Configuration descriptor management
26   *             - Enumeration as CDC device with 2 data endpoints (IN and OUT) and 1 command endpoint (IN)
27   *             - Requests management (as described in section 6.2 in specification)
28   *             - Abstract Control Model compliant
29   *             - Union Functional collection (using 1 IN endpoint for control)
30   *             - Data interface class
31
32   *           @note
33   *             For the Abstract Control Model, this core allows only transmitting the requests to
34   *             lower layer dispatcher (ie. usbd_cdc_vcp.c/.h) which should manage each request and
35   *             perform relative actions.
36   * 
37   *           These aspects may be enriched or modified for a specific user application.
38   *          
39   *            This driver doesn't implement the following aspects of the specification 
40   *            (but it is possible to manage these features with some modifications on this driver):
41   *             - Any class-specific aspect relative to communication classes should be managed by user application.
42   *             - All communication classes other than PSTN are not managed
43   *      
44   *  @endverbatim
45   *                                  
46   ******************************************************************************               
47   * @attention
48   *
49   * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
50   * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
51   * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
52   * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
53   * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
54   * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
55   *
56   * <h2><center>&copy; COPYRIGHT 2011 STMicroelectronics</center></h2>
57   ******************************************************************************
58   */ 
59
60 /* Includes ------------------------------------------------------------------*/
61 #include "usbd_cdc_core.h"
62 #include "usbd_desc.h"
63 #include "usbd_req.h"
64
65
66 /** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY
67   * @{
68   */
69
70
71 /** @defgroup usbd_cdc 
72   * @brief usbd core module
73   * @{
74   */ 
75
76 /** @defgroup usbd_cdc_Private_TypesDefinitions
77   * @{
78   */ 
79 /**
80   * @}
81   */ 
82
83
84 /** @defgroup usbd_cdc_Private_Defines
85   * @{
86   */ 
87 /**
88   * @}
89   */ 
90
91
92 /** @defgroup usbd_cdc_Private_Macros
93   * @{
94   */ 
95 /**
96   * @}
97   */ 
98
99
100 /** @defgroup usbd_cdc_Private_FunctionPrototypes
101   * @{
102   */
103
104 /*********************************************
105    CDC Device library callbacks
106  *********************************************/
107 static uint8_t  usbd_cdc_Init        (void  *pdev, uint8_t cfgidx);
108 static uint8_t  usbd_cdc_DeInit      (void  *pdev, uint8_t cfgidx);
109 static uint8_t  usbd_cdc_Setup       (void  *pdev, USB_SETUP_REQ *req);
110 static uint8_t  usbd_cdc_EP0_RxReady  (void *pdev);
111 static uint8_t  usbd_cdc_DataIn      (void *pdev, uint8_t epnum);
112 static uint8_t  usbd_cdc_DataOut     (void *pdev, uint8_t epnum);
113 static uint8_t  usbd_cdc_SOF         (void *pdev);
114
115 /*********************************************
116    CDC specific management functions
117  *********************************************/
118 static void Handle_USBAsynchXfer  (void *pdev);
119 static uint8_t  *USBD_cdc_GetCfgDesc (uint8_t speed, uint16_t *length);
120 #ifdef USE_USB_OTG_HS  
121 static uint8_t  *USBD_cdc_GetOtherCfgDesc (uint8_t speed, uint16_t *length);
122 #endif
123 /**
124   * @}
125   */ 
126
127 /** @defgroup usbd_cdc_Private_Variables
128   * @{
129   */ 
130 extern CDC_IF_Prop_TypeDef  APP_FOPS;
131 extern uint8_t USBD_DeviceDesc   [USB_SIZ_DEVICE_DESC];
132
133 #ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
134   #if defined ( __ICCARM__ ) /*!< IAR Compiler */
135     #pragma data_alignment=4   
136   #endif
137 #endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */
138 __ALIGN_BEGIN uint8_t usbd_cdc_CfgDesc  [USB_CDC_CONFIG_DESC_SIZ] __ALIGN_END ;
139
140 #ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
141   #if defined ( __ICCARM__ ) /*!< IAR Compiler */
142     #pragma data_alignment=4   
143   #endif
144 #endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */
145 __ALIGN_BEGIN uint8_t usbd_cdc_OtherCfgDesc  [USB_CDC_CONFIG_DESC_SIZ] __ALIGN_END ;
146
147 #ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
148   #if defined ( __ICCARM__ ) /*!< IAR Compiler */
149     #pragma data_alignment=4   
150   #endif
151 #endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */
152 __ALIGN_BEGIN static __IO uint32_t  usbd_cdc_AltSet  __ALIGN_END = 0;
153
154 #ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
155   #if defined ( __ICCARM__ ) /*!< IAR Compiler */
156     #pragma data_alignment=4   
157   #endif
158 #endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */
159 __ALIGN_BEGIN uint8_t USB_Rx_Buffer   [CDC_DATA_MAX_PACKET_SIZE] __ALIGN_END ;
160
161 #ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
162   #if defined ( __ICCARM__ ) /*!< IAR Compiler */
163     #pragma data_alignment=4   
164   #endif
165 #endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */
166 __ALIGN_BEGIN uint8_t APP_Rx_Buffer   [APP_RX_DATA_SIZE] __ALIGN_END ; 
167
168
169 #ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
170   #if defined ( __ICCARM__ ) /*!< IAR Compiler */
171     #pragma data_alignment=4   
172   #endif
173 #endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */
174 __ALIGN_BEGIN uint8_t CmdBuff[CDC_CMD_PACKET_SZE] __ALIGN_END ;
175
176 uint32_t APP_Rx_ptr_in  = 0;
177 uint32_t APP_Rx_ptr_out = 0;
178 uint32_t APP_Rx_length  = 0;
179
180 uint8_t  USB_Tx_State = 0;
181
182 static uint32_t cdcCmd = 0xFF;
183 static uint32_t cdcLen = 0;
184
185 /* CDC interface class callbacks structure */
186 USBD_Class_cb_TypeDef  USBD_CDC_cb = 
187 {
188   usbd_cdc_Init,
189   usbd_cdc_DeInit,
190   usbd_cdc_Setup,
191   NULL,                 /* EP0_TxSent, */
192   usbd_cdc_EP0_RxReady,
193   usbd_cdc_DataIn,
194   usbd_cdc_DataOut,
195   usbd_cdc_SOF,
196   NULL,
197   NULL,     
198   USBD_cdc_GetCfgDesc,
199 #ifdef USE_USB_OTG_HS   
200   USBD_cdc_GetOtherCfgDesc, /* use same cobfig as per FS */
201 #endif /* USE_USB_OTG_HS  */
202 };
203
204 #ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
205   #if defined ( __ICCARM__ ) /*!< IAR Compiler */
206     #pragma data_alignment=4   
207   #endif
208 #endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */
209 /* USB CDC device Configuration Descriptor */
210 __ALIGN_BEGIN uint8_t usbd_cdc_CfgDesc[USB_CDC_CONFIG_DESC_SIZ]  __ALIGN_END =
211 {
212   /*Configuration Descriptor*/
213   0x09,   /* bLength: Configuration Descriptor size */
214   USB_CONFIGURATION_DESCRIPTOR_TYPE,      /* bDescriptorType: Configuration */
215   USB_CDC_CONFIG_DESC_SIZ,                /* wTotalLength:no of returned bytes */
216   0x00,
217   0x02,   /* bNumInterfaces: 2 interface */
218   0x01,   /* bConfigurationValue: Configuration value */
219   0x00,   /* iConfiguration: Index of string descriptor describing the configuration */
220   0xC0,   /* bmAttributes: self powered */
221   0x32,   /* MaxPower 0 mA */
222   
223   /*---------------------------------------------------------------------------*/
224   
225   /*Interface Descriptor */
226   0x09,   /* bLength: Interface Descriptor size */
227   USB_INTERFACE_DESCRIPTOR_TYPE,  /* bDescriptorType: Interface */
228   /* Interface descriptor type */
229   0x00,   /* bInterfaceNumber: Number of Interface */
230   0x00,   /* bAlternateSetting: Alternate setting */
231   0x01,   /* bNumEndpoints: One endpoints used */
232   0x02,   /* bInterfaceClass: Communication Interface Class */
233   0x02,   /* bInterfaceSubClass: Abstract Control Model */
234   0x01,   /* bInterfaceProtocol: Common AT commands */
235   0x00,   /* iInterface: */
236   
237   /*Header Functional Descriptor*/
238   0x05,   /* bLength: Endpoint Descriptor size */
239   0x24,   /* bDescriptorType: CS_INTERFACE */
240   0x00,   /* bDescriptorSubtype: Header Func Desc */
241   0x10,   /* bcdCDC: spec release number */
242   0x01,
243   
244   /*Call Management Functional Descriptor*/
245   0x05,   /* bFunctionLength */
246   0x24,   /* bDescriptorType: CS_INTERFACE */
247   0x01,   /* bDescriptorSubtype: Call Management Func Desc */
248   0x00,   /* bmCapabilities: D0+D1 */
249   0x01,   /* bDataInterface: 1 */
250   
251   /*ACM Functional Descriptor*/
252   0x04,   /* bFunctionLength */
253   0x24,   /* bDescriptorType: CS_INTERFACE */
254   0x02,   /* bDescriptorSubtype: Abstract Control Management desc */
255   0x02,   /* bmCapabilities */
256   
257   /*Union Functional Descriptor*/
258   0x05,   /* bFunctionLength */
259   0x24,   /* bDescriptorType: CS_INTERFACE */
260   0x06,   /* bDescriptorSubtype: Union func desc */
261   0x00,   /* bMasterInterface: Communication class interface */
262   0x01,   /* bSlaveInterface0: Data Class Interface */
263   
264   /*Endpoint 2 Descriptor*/
265   0x07,                           /* bLength: Endpoint Descriptor size */
266   USB_ENDPOINT_DESCRIPTOR_TYPE,   /* bDescriptorType: Endpoint */
267   CDC_CMD_EP,                     /* bEndpointAddress */
268   0x03,                           /* bmAttributes: Interrupt */
269   LOBYTE(CDC_CMD_PACKET_SZE),     /* wMaxPacketSize: */
270   HIBYTE(CDC_CMD_PACKET_SZE),
271 #ifdef USE_USB_OTG_HS
272   0x10,                           /* bInterval: */
273 #else
274   0xFF,                           /* bInterval: */
275 #endif /* USE_USB_OTG_HS */
276   
277   /*---------------------------------------------------------------------------*/
278   
279   /*Data class interface descriptor*/
280   0x09,   /* bLength: Endpoint Descriptor size */
281   USB_INTERFACE_DESCRIPTOR_TYPE,  /* bDescriptorType: */
282   0x01,   /* bInterfaceNumber: Number of Interface */
283   0x00,   /* bAlternateSetting: Alternate setting */
284   0x02,   /* bNumEndpoints: Two endpoints used */
285   0x0A,   /* bInterfaceClass: CDC */
286   0x00,   /* bInterfaceSubClass: */
287   0x00,   /* bInterfaceProtocol: */
288   0x00,   /* iInterface: */
289   
290   /*Endpoint OUT Descriptor*/
291   0x07,   /* bLength: Endpoint Descriptor size */
292   USB_ENDPOINT_DESCRIPTOR_TYPE,      /* bDescriptorType: Endpoint */
293   CDC_OUT_EP,                        /* bEndpointAddress */
294   0x02,                              /* bmAttributes: Bulk */
295   LOBYTE(CDC_DATA_MAX_PACKET_SIZE),  /* wMaxPacketSize: */
296   HIBYTE(CDC_DATA_MAX_PACKET_SIZE),
297   0x00,                              /* bInterval: ignore for Bulk transfer */
298   
299   /*Endpoint IN Descriptor*/
300   0x07,   /* bLength: Endpoint Descriptor size */
301   USB_ENDPOINT_DESCRIPTOR_TYPE,      /* bDescriptorType: Endpoint */
302   CDC_IN_EP,                         /* bEndpointAddress */
303   0x02,                              /* bmAttributes: Bulk */
304   LOBYTE(CDC_DATA_MAX_PACKET_SIZE),  /* wMaxPacketSize: */
305   HIBYTE(CDC_DATA_MAX_PACKET_SIZE),
306   0x00                               /* bInterval: ignore for Bulk transfer */
307 } ;
308
309 #ifdef USE_USB_OTG_HS
310 #ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
311   #if defined ( __ICCARM__ ) /*!< IAR Compiler */
312     #pragma data_alignment=4   
313   #endif
314 #endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */ 
315 __ALIGN_BEGIN uint8_t usbd_cdc_OtherCfgDesc[USB_CDC_CONFIG_DESC_SIZ]  __ALIGN_END =
316
317   0x09,   /* bLength: Configuation Descriptor size */
318   USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION,   
319   USB_CDC_CONFIG_DESC_SIZ,
320   0x00,
321   0x02,   /* bNumInterfaces: 2 interfaces */
322   0x01,   /* bConfigurationValue: */
323   0x04,   /* iConfiguration: */
324   0xC0,   /* bmAttributes: */
325   0x32,   /* MaxPower 100 mA */  
326   
327   /*Interface Descriptor */
328   0x09,   /* bLength: Interface Descriptor size */
329   USB_INTERFACE_DESCRIPTOR_TYPE,  /* bDescriptorType: Interface */
330   /* Interface descriptor type */
331   0x00,   /* bInterfaceNumber: Number of Interface */
332   0x00,   /* bAlternateSetting: Alternate setting */
333   0x01,   /* bNumEndpoints: One endpoints used */
334   0x02,   /* bInterfaceClass: Communication Interface Class */
335   0x02,   /* bInterfaceSubClass: Abstract Control Model */
336   0x01,   /* bInterfaceProtocol: Common AT commands */
337   0x00,   /* iInterface: */
338   
339   /*Header Functional Descriptor*/
340   0x05,   /* bLength: Endpoint Descriptor size */
341   0x24,   /* bDescriptorType: CS_INTERFACE */
342   0x00,   /* bDescriptorSubtype: Header Func Desc */
343   0x10,   /* bcdCDC: spec release number */
344   0x01,
345   
346   /*Call Management Functional Descriptor*/
347   0x05,   /* bFunctionLength */
348   0x24,   /* bDescriptorType: CS_INTERFACE */
349   0x01,   /* bDescriptorSubtype: Call Management Func Desc */
350   0x00,   /* bmCapabilities: D0+D1 */
351   0x01,   /* bDataInterface: 1 */
352   
353   /*ACM Functional Descriptor*/
354   0x04,   /* bFunctionLength */
355   0x24,   /* bDescriptorType: CS_INTERFACE */
356   0x02,   /* bDescriptorSubtype: Abstract Control Management desc */
357   0x02,   /* bmCapabilities */
358   
359   /*Union Functional Descriptor*/
360   0x05,   /* bFunctionLength */
361   0x24,   /* bDescriptorType: CS_INTERFACE */
362   0x06,   /* bDescriptorSubtype: Union func desc */
363   0x00,   /* bMasterInterface: Communication class interface */
364   0x01,   /* bSlaveInterface0: Data Class Interface */
365   
366   /*Endpoint 2 Descriptor*/
367   0x07,                           /* bLength: Endpoint Descriptor size */
368   USB_ENDPOINT_DESCRIPTOR_TYPE,   /* bDescriptorType: Endpoint */
369   CDC_CMD_EP,                     /* bEndpointAddress */
370   0x03,                           /* bmAttributes: Interrupt */
371   LOBYTE(CDC_CMD_PACKET_SZE),     /* wMaxPacketSize: */
372   HIBYTE(CDC_CMD_PACKET_SZE),
373   0xFF,                           /* bInterval: */
374   
375   /*---------------------------------------------------------------------------*/
376   
377   /*Data class interface descriptor*/
378   0x09,   /* bLength: Endpoint Descriptor size */
379   USB_INTERFACE_DESCRIPTOR_TYPE,  /* bDescriptorType: */
380   0x01,   /* bInterfaceNumber: Number of Interface */
381   0x00,   /* bAlternateSetting: Alternate setting */
382   0x02,   /* bNumEndpoints: Two endpoints used */
383   0x0A,   /* bInterfaceClass: CDC */
384   0x00,   /* bInterfaceSubClass: */
385   0x00,   /* bInterfaceProtocol: */
386   0x00,   /* iInterface: */
387   
388   /*Endpoint OUT Descriptor*/
389   0x07,   /* bLength: Endpoint Descriptor size */
390   USB_ENDPOINT_DESCRIPTOR_TYPE,      /* bDescriptorType: Endpoint */
391   CDC_OUT_EP,                        /* bEndpointAddress */
392   0x02,                              /* bmAttributes: Bulk */
393   0x40,                              /* wMaxPacketSize: */
394   0x00,
395   0x00,                              /* bInterval: ignore for Bulk transfer */
396   
397   /*Endpoint IN Descriptor*/
398   0x07,   /* bLength: Endpoint Descriptor size */
399   USB_ENDPOINT_DESCRIPTOR_TYPE,     /* bDescriptorType: Endpoint */
400   CDC_IN_EP,                        /* bEndpointAddress */
401   0x02,                             /* bmAttributes: Bulk */
402   0x40,                             /* wMaxPacketSize: */
403   0x00,
404   0x00                              /* bInterval */
405 };
406 #endif /* USE_USB_OTG_HS  */
407
408 /**
409   * @}
410   */ 
411
412 /** @defgroup usbd_cdc_Private_Functions
413   * @{
414   */ 
415
416 /**
417   * @brief  usbd_cdc_Init
418   *         Initilaize the CDC interface
419   * @param  pdev: device instance
420   * @param  cfgidx: Configuration index
421   * @retval status
422   */
423 static uint8_t  usbd_cdc_Init (void  *pdev, 
424                                uint8_t cfgidx)
425 {
426   uint8_t *pbuf;
427
428   /* Open EP IN */
429   DCD_EP_Open(pdev,
430               CDC_IN_EP,
431               CDC_DATA_IN_PACKET_SIZE,
432               USB_OTG_EP_BULK);
433   
434   /* Open EP OUT */
435   DCD_EP_Open(pdev,
436               CDC_OUT_EP,
437               CDC_DATA_OUT_PACKET_SIZE,
438               USB_OTG_EP_BULK);
439   
440   /* Open Command IN EP */
441   DCD_EP_Open(pdev,
442               CDC_CMD_EP,
443               CDC_CMD_PACKET_SZE,
444               USB_OTG_EP_INT);
445   
446   pbuf = (uint8_t *)USBD_DeviceDesc;
447   pbuf[4] = DEVICE_CLASS_CDC;
448   pbuf[5] = DEVICE_SUBCLASS_CDC;
449   
450   /* Initialize the Interface physical components */
451   APP_FOPS.pIf_Init();
452
453   /* Prepare Out endpoint to receive next packet */
454   DCD_EP_PrepareRx(pdev,
455                    CDC_OUT_EP,
456                    (uint8_t*)(USB_Rx_Buffer),
457                    CDC_DATA_OUT_PACKET_SIZE);
458   
459   return USBD_OK;
460 }
461
462 /**
463   * @brief  usbd_cdc_Init
464   *         DeInitialize the CDC layer
465   * @param  pdev: device instance
466   * @param  cfgidx: Configuration index
467   * @retval status
468   */
469 static uint8_t  usbd_cdc_DeInit (void  *pdev, 
470                                  uint8_t cfgidx)
471 {
472   /* Open EP IN */
473   DCD_EP_Close(pdev,
474               CDC_IN_EP);
475   
476   /* Open EP OUT */
477   DCD_EP_Close(pdev,
478               CDC_OUT_EP);
479   
480   /* Open Command IN EP */
481   DCD_EP_Close(pdev,
482               CDC_CMD_EP);
483
484   /* Restore default state of the Interface physical components */
485   APP_FOPS.pIf_DeInit();
486   
487   return USBD_OK;
488 }
489
490 /**
491   * @brief  usbd_cdc_Setup
492   *         Handle the CDC specific requests
493   * @param  pdev: instance
494   * @param  req: usb requests
495   * @retval status
496   */
497 static uint8_t  usbd_cdc_Setup (void  *pdev, 
498                                 USB_SETUP_REQ *req)
499 {
500   uint16_t len;
501   uint8_t  *pbuf;
502   
503   switch (req->bmRequest & USB_REQ_TYPE_MASK)
504   {
505     /* CDC Class Requests -------------------------------*/
506   case USB_REQ_TYPE_CLASS :
507       /* Check if the request is a data setup packet */
508       if (req->wLength)
509       {
510         /* Check if the request is Device-to-Host */
511         if (req->bmRequest & 0x80)
512         {
513           /* Get the data to be sent to Host from interface layer */
514           APP_FOPS.pIf_Ctrl(req->bRequest, CmdBuff, req->wLength);
515           
516           /* Send the data to the host */
517           USBD_CtlSendData (pdev, 
518                             CmdBuff,
519                             req->wLength);          
520         }
521         else /* Host-to-Device requeset */
522         {
523           /* Set the value of the current command to be processed */
524           cdcCmd = req->bRequest;
525           cdcLen = req->wLength;
526           
527           /* Prepare the reception of the buffer over EP0
528           Next step: the received data will be managed in usbd_cdc_EP0_TxSent() 
529           function. */
530           USBD_CtlPrepareRx (pdev,
531                              CmdBuff,
532                              req->wLength);          
533         }
534       }
535       else /* No Data request */
536       {
537         /* Transfer the command to the interface layer */
538         APP_FOPS.pIf_Ctrl(req->bRequest, NULL, 0);
539       }
540       
541       return USBD_OK;
542       
543     default:
544       USBD_CtlError (pdev, req);
545       return USBD_FAIL;
546     
547       
548       
549     /* Standard Requests -------------------------------*/
550   case USB_REQ_TYPE_STANDARD:
551     switch (req->bRequest)
552     {
553     case USB_REQ_GET_DESCRIPTOR: 
554       if( (req->wValue >> 8) == CDC_DESCRIPTOR_TYPE)
555       {
556 #ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
557         pbuf = usbd_cdc_Desc;   
558 #else
559         pbuf = usbd_cdc_CfgDesc + 9 + (9 * USBD_ITF_MAX_NUM);
560 #endif 
561         len = MIN(USB_CDC_DESC_SIZ , req->wLength);
562       }
563       
564       USBD_CtlSendData (pdev, 
565                         pbuf,
566                         len);
567       break;
568       
569     case USB_REQ_GET_INTERFACE :
570       USBD_CtlSendData (pdev,
571                         (uint8_t *)&usbd_cdc_AltSet,
572                         1);
573       break;
574       
575     case USB_REQ_SET_INTERFACE :
576       if ((uint8_t)(req->wValue) < USBD_ITF_MAX_NUM)
577       {
578         usbd_cdc_AltSet = (uint8_t)(req->wValue);
579       }
580       else
581       {
582         /* Call the error management function (command will be nacked */
583         USBD_CtlError (pdev, req);
584       }
585       break;
586     }
587   }
588   return USBD_OK;
589 }
590
591 /**
592   * @brief  usbd_cdc_EP0_RxReady
593   *         Data received on control endpoint
594   * @param  pdev: device device instance
595   * @retval status
596   */
597 static uint8_t  usbd_cdc_EP0_RxReady (void  *pdev)
598
599   if (cdcCmd != NO_CMD)
600   {
601     /* Process the data */
602     APP_FOPS.pIf_Ctrl(cdcCmd, CmdBuff, cdcLen);
603     
604     /* Reset the command variable to default value */
605     cdcCmd = NO_CMD;
606   }
607   
608   return USBD_OK;
609 }
610
611 /**
612   * @brief  usbd_audio_DataIn
613   *         Data sent on non-control IN endpoint
614   * @param  pdev: device instance
615   * @param  epnum: endpoint number
616   * @retval status
617   */
618 static uint8_t  usbd_cdc_DataIn (void *pdev, uint8_t epnum)
619 {
620   uint16_t USB_Tx_ptr;
621   uint16_t USB_Tx_length;
622
623   if (USB_Tx_State == 1)
624   {
625     if (APP_Rx_length == 0) 
626     {
627       USB_Tx_State = 0;
628     }
629     else 
630     {
631       if (APP_Rx_length > CDC_DATA_IN_PACKET_SIZE){
632         USB_Tx_ptr = APP_Rx_ptr_out;
633         USB_Tx_length = CDC_DATA_IN_PACKET_SIZE;
634         
635         APP_Rx_ptr_out += CDC_DATA_IN_PACKET_SIZE;
636         APP_Rx_length -= CDC_DATA_IN_PACKET_SIZE;    
637       }
638       else 
639       {
640         USB_Tx_ptr = APP_Rx_ptr_out;
641         USB_Tx_length = APP_Rx_length;
642         
643         APP_Rx_ptr_out += APP_Rx_length;
644         APP_Rx_length = 0;
645       }
646       
647       /* Prepare the available data buffer to be sent on IN endpoint */
648       DCD_EP_Tx (pdev,
649                  CDC_IN_EP,
650                  (uint8_t*)&APP_Rx_Buffer[USB_Tx_ptr],
651                  USB_Tx_length);
652     }
653   }  
654   
655   return USBD_OK;
656 }
657
658 /**
659   * @brief  usbd_audio_DataOut
660   *         Data received on non-control Out endpoint
661   * @param  pdev: device instance
662   * @param  epnum: endpoint number
663   * @retval status
664   */
665 static uint8_t  usbd_cdc_DataOut (void *pdev, uint8_t epnum)
666 {      
667   uint16_t USB_Rx_Cnt;
668   
669   /* Get the received data buffer and update the counter */
670   USB_Rx_Cnt = ((USB_OTG_CORE_HANDLE*)pdev)->dev.out_ep[epnum].xfer_count;
671   
672   /* USB data will be immediately processed, this allow next USB traffic being 
673      NAKed till the end of the application Xfer */
674   APP_FOPS.pIf_DataRx(USB_Rx_Buffer, USB_Rx_Cnt);
675   
676   /* Prepare Out endpoint to receive next packet */
677   DCD_EP_PrepareRx(pdev,
678                    CDC_OUT_EP,
679                    (uint8_t*)(USB_Rx_Buffer),
680                    CDC_DATA_OUT_PACKET_SIZE);
681
682   return USBD_OK;
683 }
684
685 /**
686   * @brief  usbd_audio_SOF
687   *         Start Of Frame event management
688   * @param  pdev: instance
689   * @param  epnum: endpoint number
690   * @retval status
691   */
692 static uint8_t  usbd_cdc_SOF (void *pdev)
693 {      
694   static uint32_t FrameCount = 0;
695   
696   if (FrameCount++ == CDC_IN_FRAME_INTERVAL)
697   {
698     /* Reset the frame counter */
699     FrameCount = 0;
700     
701     /* Check the data to be sent through IN pipe */
702     Handle_USBAsynchXfer(pdev);
703   }
704   
705   return USBD_OK;
706 }
707
708 /**
709   * @brief  Handle_USBAsynchXfer
710   *         Send data to USB
711   * @param  pdev: instance
712   * @retval None
713   */
714 static void Handle_USBAsynchXfer (void *pdev)
715 {
716   uint16_t USB_Tx_ptr;
717   uint16_t USB_Tx_length;
718   
719   if(USB_Tx_State != 1)
720   {
721     if (APP_Rx_ptr_out == APP_RX_DATA_SIZE)
722     {
723       APP_Rx_ptr_out = 0;
724     }
725     
726     if(APP_Rx_ptr_out == APP_Rx_ptr_in) 
727     {
728       USB_Tx_State = 0; 
729       return;
730     }
731     
732     if(APP_Rx_ptr_out > APP_Rx_ptr_in) /* rollback */
733     { 
734       APP_Rx_length = APP_RX_DATA_SIZE - APP_Rx_ptr_out;
735     
736     }
737     else 
738     {
739       APP_Rx_length = APP_Rx_ptr_in - APP_Rx_ptr_out;
740      
741     }
742 #ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
743      APP_Rx_length &= ~0x03;
744 #endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */
745     
746     if (APP_Rx_length > CDC_DATA_IN_PACKET_SIZE)
747     {
748       USB_Tx_ptr = APP_Rx_ptr_out;
749       USB_Tx_length = CDC_DATA_IN_PACKET_SIZE;
750       
751       APP_Rx_ptr_out += CDC_DATA_IN_PACKET_SIZE;        
752       APP_Rx_length -= CDC_DATA_IN_PACKET_SIZE;
753     }
754     else
755     {
756       USB_Tx_ptr = APP_Rx_ptr_out;
757       USB_Tx_length = APP_Rx_length;
758       
759       APP_Rx_ptr_out += APP_Rx_length;
760       APP_Rx_length = 0;
761     }
762     USB_Tx_State = 1; 
763
764     DCD_EP_Tx (pdev,
765                CDC_IN_EP,
766                (uint8_t*)&APP_Rx_Buffer[USB_Tx_ptr],
767                USB_Tx_length);
768   }  
769   
770 }
771
772 /**
773   * @brief  USBD_cdc_GetCfgDesc 
774   *         Return configuration descriptor
775   * @param  speed : current device speed
776   * @param  length : pointer data length
777   * @retval pointer to descriptor buffer
778   */
779 static uint8_t  *USBD_cdc_GetCfgDesc (uint8_t speed, uint16_t *length)
780 {
781   *length = sizeof (usbd_cdc_CfgDesc);
782   return usbd_cdc_CfgDesc;
783 }
784
785 /**
786   * @brief  USBD_cdc_GetCfgDesc 
787   *         Return configuration descriptor
788   * @param  speed : current device speed
789   * @param  length : pointer data length
790   * @retval pointer to descriptor buffer
791   */
792 #ifdef USE_USB_OTG_HS 
793 static uint8_t  *USBD_cdc_GetOtherCfgDesc (uint8_t speed, uint16_t *length)
794 {
795   *length = sizeof (usbd_cdc_OtherCfgDesc);
796   return usbd_cdc_OtherCfgDesc;
797 }
798 #endif
799 /**
800   * @}
801   */ 
802
803 /**
804   * @}
805   */ 
806
807 /**
808   * @}
809   */ 
810
811 /******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/