1 /**
2   ******************************************************************************
3   * @file    usbd_cdc.c
4   * @author  MCD Application Team
5   * @version V2.4.2
6   * @date    11-December-2015
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   *           These aspects may be enriched or modified for a specific user application.
33   *
34   *            This driver doesn't implement the following aspects of the specification
35   *            (but it is possible to manage these features with some modifications on this driver):
36   *             - Any class-specific aspect relative to communication classes should be managed by user application.
37   *             - All communication classes other than PSTN are not managed
38   *
39   *  @endverbatim
40   *
41   ******************************************************************************
42   * @attention
43   *
44   * <h2><center>&copy; COPYRIGHT 2015 STMicroelectronics</center></h2>
45   *
46   * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
47   * You may not use this file except in compliance with the License.
48   * You may obtain a copy of the License at:
49   *
50   *        http://www.st.com/software_license_agreement_liberty_v2
51   *
52   * Unless required by applicable law or agreed to in writing, software
53   * distributed under the License is distributed on an "AS IS" BASIS,
54   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
55   * See the License for the specific language governing permissions and
56   * limitations under the License.
57   *
58   ******************************************************************************
59   */
60 
61 /* Includes ------------------------------------------------------------------*/
62 #include "usbd_cdc.h"
63 #include "usbd_desc.h"
64 #include "usbd_ctlreq.h"
65 
66 
67 /** @addtogroup STM32_USB_DEVICE_LIBRARY
68   * @{
69   */
70 
71 
72 /** @defgroup USBD_CDC
73   * @brief usbd core module
74   * @{
75   */
76 
77 /** @defgroup USBD_CDC_Private_TypesDefinitions
78   * @{
79   */
80 /**
81   * @}
82   */
83 
84 
85 /** @defgroup USBD_CDC_Private_Defines
86   * @{
87   */
88 /**
89   * @}
90   */
91 
92 
93 /** @defgroup USBD_CDC_Private_Macros
94   * @{
95   */
96 
97 /**
98   * @}
99   */
100 
101 
102 /** @defgroup USBD_CDC_Private_FunctionPrototypes
103   * @{
104   */
105 
106 
107 static uint8_t  USBD_CDC_Init (USBD_HandleTypeDef *pdev,
108                                uint8_t cfgidx);
109 
110 static uint8_t  USBD_CDC_DeInit (USBD_HandleTypeDef *pdev,
111                                  uint8_t cfgidx);
112 
113 static uint8_t  USBD_CDC_Setup (USBD_HandleTypeDef *pdev,
114                                 USBD_SetupReqTypedef *req);
115 
116 static uint8_t  USBD_CDC_DataIn (USBD_HandleTypeDef *pdev,
117                                  uint8_t epnum);
118 
119 static uint8_t  USBD_CDC_DataOut (USBD_HandleTypeDef *pdev,
120                                  uint8_t epnum);
121 
122 static uint8_t  USBD_CDC_EP0_RxReady (USBD_HandleTypeDef *pdev);
123 
124 static uint8_t  *USBD_CDC_GetFSCfgDesc (uint16_t *length);
125 
126 static uint8_t  *USBD_CDC_GetHSCfgDesc (uint16_t *length);
127 
128 static uint8_t  *USBD_CDC_GetOtherSpeedCfgDesc (uint16_t *length);
129 
130 static uint8_t  *USBD_CDC_GetOtherSpeedCfgDesc (uint16_t *length);
131 
132 uint8_t  *USBD_CDC_GetDeviceQualifierDescriptor (uint16_t *length);
133 
134 /* USB Standard Device Descriptor */
135 __ALIGN_BEGIN static uint8_t USBD_CDC_DeviceQualifierDesc[USB_LEN_DEV_QUALIFIER_DESC] __ALIGN_END =
136 {
137   USB_LEN_DEV_QUALIFIER_DESC,
138   USB_DESC_TYPE_DEVICE_QUALIFIER,
139   0x00,
140   0x02,
141   0x00,
142   0x00,
143   0x00,
144   0x40,
145   0x01,
146   0x00,
147 };
148 
149 /**
150   * @}
151   */
152 
153 /** @defgroup USBD_CDC_Private_Variables
154   * @{
155   */
156 
157 
158 /* CDC interface class callbacks structure */
159 USBD_ClassTypeDef  USBD_CDC =
160 {
161   USBD_CDC_Init,
162   USBD_CDC_DeInit,
163   USBD_CDC_Setup,
164   NULL,                 /* EP0_TxSent, */
165   USBD_CDC_EP0_RxReady,
166   USBD_CDC_DataIn,
167   USBD_CDC_DataOut,
168   NULL,
169   NULL,
170   NULL,
171   USBD_CDC_GetHSCfgDesc,
172   USBD_CDC_GetFSCfgDesc,
173   USBD_CDC_GetOtherSpeedCfgDesc,
174   USBD_CDC_GetDeviceQualifierDescriptor,
175 };
176 
177 /* USB CDC device Configuration Descriptor */
178 __ALIGN_BEGIN uint8_t USBD_CDC_CfgHSDesc[USB_CDC_CONFIG_DESC_SIZ] __ALIGN_END =
179 {
180   /*Configuration Descriptor*/
181   0x09,   /* bLength: Configuration Descriptor size */
182   USB_DESC_TYPE_CONFIGURATION,      /* bDescriptorType: Configuration */
183   USB_CDC_CONFIG_DESC_SIZ,                /* wTotalLength:no of returned bytes */
184   0x00,
185   0x02,   /* bNumInterfaces: 2 interface */
186   0x01,   /* bConfigurationValue: Configuration value */
187   0x00,   /* iConfiguration: Index of string descriptor describing the configuration */
188   0xC0,   /* bmAttributes: self powered */
189   0x32,   /* MaxPower 0 mA */
190 
191   /*---------------------------------------------------------------------------*/
192 
193   /*Interface Descriptor */
194   0x09,   /* bLength: Interface Descriptor size */
195   USB_DESC_TYPE_INTERFACE,  /* bDescriptorType: Interface */
196   /* Interface descriptor type */
197   0x00,   /* bInterfaceNumber: Number of Interface */
198   0x00,   /* bAlternateSetting: Alternate setting */
199   0x01,   /* bNumEndpoints: One endpoints used */
200   0x02,   /* bInterfaceClass: Communication Interface Class */
201   0x02,   /* bInterfaceSubClass: Abstract Control Model */
202   0x01,   /* bInterfaceProtocol: Common AT commands */
203   0x00,   /* iInterface: */
204 
205   /*Header Functional Descriptor*/
206   0x05,   /* bLength: Endpoint Descriptor size */
207   0x24,   /* bDescriptorType: CS_INTERFACE */
208   0x00,   /* bDescriptorSubtype: Header Func Desc */
209   0x10,   /* bcdCDC: spec release number */
210   0x01,
211 
212   /*Call Management Functional Descriptor*/
213   0x05,   /* bFunctionLength */
214   0x24,   /* bDescriptorType: CS_INTERFACE */
215   0x01,   /* bDescriptorSubtype: Call Management Func Desc */
216   0x00,   /* bmCapabilities: D0+D1 */
217   0x01,   /* bDataInterface: 1 */
218 
219   /*ACM Functional Descriptor*/
220   0x04,   /* bFunctionLength */
221   0x24,   /* bDescriptorType: CS_INTERFACE */
222   0x02,   /* bDescriptorSubtype: Abstract Control Management desc */
223   0x02,   /* bmCapabilities */
224 
225   /*Union Functional Descriptor*/
226   0x05,   /* bFunctionLength */
227   0x24,   /* bDescriptorType: CS_INTERFACE */
228   0x06,   /* bDescriptorSubtype: Union func desc */
229   0x00,   /* bMasterInterface: Communication class interface */
230   0x01,   /* bSlaveInterface0: Data Class Interface */
231 
232   /*Endpoint 2 Descriptor*/
233   0x07,                           /* bLength: Endpoint Descriptor size */
234   USB_DESC_TYPE_ENDPOINT,   /* bDescriptorType: Endpoint */
235   CDC_CMD_EP,                     /* bEndpointAddress */
236   0x03,                           /* bmAttributes: Interrupt */
237   LOBYTE(CDC_CMD_PACKET_SIZE),     /* wMaxPacketSize: */
238   HIBYTE(CDC_CMD_PACKET_SIZE),
239   0x10,                           /* bInterval: */
240   /*---------------------------------------------------------------------------*/
241 
242   /*Data class interface descriptor*/
243   0x09,   /* bLength: Endpoint Descriptor size */
244   USB_DESC_TYPE_INTERFACE,  /* bDescriptorType: */
245   0x01,   /* bInterfaceNumber: Number of Interface */
246   0x00,   /* bAlternateSetting: Alternate setting */
247   0x02,   /* bNumEndpoints: Two endpoints used */
248   0x0A,   /* bInterfaceClass: CDC */
249   0x00,   /* bInterfaceSubClass: */
250   0x00,   /* bInterfaceProtocol: */
251   0x00,   /* iInterface: */
252 
253   /*Endpoint OUT Descriptor*/
254   0x07,   /* bLength: Endpoint Descriptor size */
255   USB_DESC_TYPE_ENDPOINT,      /* bDescriptorType: Endpoint */
256   CDC_OUT_EP,                        /* bEndpointAddress */
257   0x02,                              /* bmAttributes: Bulk */
258   LOBYTE(CDC_DATA_HS_MAX_PACKET_SIZE),  /* wMaxPacketSize: */
259   HIBYTE(CDC_DATA_HS_MAX_PACKET_SIZE),
260   0x00,                              /* bInterval: ignore for Bulk transfer */
261 
262   /*Endpoint IN Descriptor*/
263   0x07,   /* bLength: Endpoint Descriptor size */
264   USB_DESC_TYPE_ENDPOINT,      /* bDescriptorType: Endpoint */
265   CDC_IN_EP,                         /* bEndpointAddress */
266   0x02,                              /* bmAttributes: Bulk */
267   LOBYTE(CDC_DATA_HS_MAX_PACKET_SIZE),  /* wMaxPacketSize: */
268   HIBYTE(CDC_DATA_HS_MAX_PACKET_SIZE),
269   0x00                               /* bInterval: ignore for Bulk transfer */
270 } ;
271 
272 
273 /* USB CDC device Configuration Descriptor */
274 __ALIGN_BEGIN uint8_t USBD_CDC_CfgFSDesc[USB_CDC_CONFIG_DESC_SIZ] __ALIGN_END =
275 {
276   /*Configuration Descriptor*/
277   0x09,   /* bLength: Configuration Descriptor size */
278   USB_DESC_TYPE_CONFIGURATION,      /* bDescriptorType: Configuration */
279   USB_CDC_CONFIG_DESC_SIZ,                /* wTotalLength:no of returned bytes */
280   0x00,
281   0x02,   /* bNumInterfaces: 2 interface */
282   0x01,   /* bConfigurationValue: Configuration value */
283   0x00,   /* iConfiguration: Index of string descriptor describing the configuration */
284   0xC0,   /* bmAttributes: self powered */
285   0x32,   /* MaxPower 0 mA */
286 
287   /*---------------------------------------------------------------------------*/
288 
289   /*Interface Descriptor */
290   0x09,   /* bLength: Interface Descriptor size */
291   USB_DESC_TYPE_INTERFACE,  /* bDescriptorType: Interface */
292   /* Interface descriptor type */
293   0x00,   /* bInterfaceNumber: Number of Interface */
294   0x00,   /* bAlternateSetting: Alternate setting */
295   0x01,   /* bNumEndpoints: One endpoints used */
296   0x02,   /* bInterfaceClass: Communication Interface Class */
297   0x02,   /* bInterfaceSubClass: Abstract Control Model */
298   0x01,   /* bInterfaceProtocol: Common AT commands */
299   0x00,   /* iInterface: */
300 
301   /*Header Functional Descriptor*/
302   0x05,   /* bLength: Endpoint Descriptor size */
303   0x24,   /* bDescriptorType: CS_INTERFACE */
304   0x00,   /* bDescriptorSubtype: Header Func Desc */
305   0x10,   /* bcdCDC: spec release number */
306   0x01,
307 
308   /*Call Management Functional Descriptor*/
309   0x05,   /* bFunctionLength */
310   0x24,   /* bDescriptorType: CS_INTERFACE */
311   0x01,   /* bDescriptorSubtype: Call Management Func Desc */
312   0x00,   /* bmCapabilities: D0+D1 */
313   0x01,   /* bDataInterface: 1 */
314 
315   /*ACM Functional Descriptor*/
316   0x04,   /* bFunctionLength */
317   0x24,   /* bDescriptorType: CS_INTERFACE */
318   0x02,   /* bDescriptorSubtype: Abstract Control Management desc */
319   0x02,   /* bmCapabilities */
320 
321   /*Union Functional Descriptor*/
322   0x05,   /* bFunctionLength */
323   0x24,   /* bDescriptorType: CS_INTERFACE */
324   0x06,   /* bDescriptorSubtype: Union func desc */
325   0x00,   /* bMasterInterface: Communication class interface */
326   0x01,   /* bSlaveInterface0: Data Class Interface */
327 
328   /*Endpoint 2 Descriptor*/
329   0x07,                           /* bLength: Endpoint Descriptor size */
330   USB_DESC_TYPE_ENDPOINT,   /* bDescriptorType: Endpoint */
331   CDC_CMD_EP,                     /* bEndpointAddress */
332   0x03,                           /* bmAttributes: Interrupt */
333   LOBYTE(CDC_CMD_PACKET_SIZE),     /* wMaxPacketSize: */
334   HIBYTE(CDC_CMD_PACKET_SIZE),
335   0x10,                           /* bInterval: */
336   /*---------------------------------------------------------------------------*/
337 
338   /*Data class interface descriptor*/
339   0x09,   /* bLength: Endpoint Descriptor size */
340   USB_DESC_TYPE_INTERFACE,  /* bDescriptorType: */
341   0x01,   /* bInterfaceNumber: Number of Interface */
342   0x00,   /* bAlternateSetting: Alternate setting */
343   0x02,   /* bNumEndpoints: Two endpoints used */
344   0x0A,   /* bInterfaceClass: CDC */
345   0x00,   /* bInterfaceSubClass: */
346   0x00,   /* bInterfaceProtocol: */
347   0x00,   /* iInterface: */
348 
349   /*Endpoint OUT Descriptor*/
350   0x07,   /* bLength: Endpoint Descriptor size */
351   USB_DESC_TYPE_ENDPOINT,      /* bDescriptorType: Endpoint */
352   CDC_OUT_EP,                        /* bEndpointAddress */
353   0x02,                              /* bmAttributes: Bulk */
354   LOBYTE(CDC_DATA_FS_MAX_PACKET_SIZE),  /* wMaxPacketSize: */
355   HIBYTE(CDC_DATA_FS_MAX_PACKET_SIZE),
356   0x00,                              /* bInterval: ignore for Bulk transfer */
357 
358   /*Endpoint IN Descriptor*/
359   0x07,   /* bLength: Endpoint Descriptor size */
360   USB_DESC_TYPE_ENDPOINT,      /* bDescriptorType: Endpoint */
361   CDC_IN_EP,                         /* bEndpointAddress */
362   0x02,                              /* bmAttributes: Bulk */
363   LOBYTE(CDC_DATA_FS_MAX_PACKET_SIZE),  /* wMaxPacketSize: */
364   HIBYTE(CDC_DATA_FS_MAX_PACKET_SIZE),
365   0x00                               /* bInterval: ignore for Bulk transfer */
366 } ;
367 
368 __ALIGN_BEGIN uint8_t USBD_CDC_OtherSpeedCfgDesc[USB_CDC_CONFIG_DESC_SIZ] __ALIGN_END =
369 {
370   0x09,   /* bLength: Configuation Descriptor size */
371   USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION,
372   USB_CDC_CONFIG_DESC_SIZ,
373   0x00,
374   0x02,   /* bNumInterfaces: 2 interfaces */
375   0x01,   /* bConfigurationValue: */
376   0x04,   /* iConfiguration: */
377   0xC0,   /* bmAttributes: */
378   0x32,   /* MaxPower 100 mA */
379 
380   /*Interface Descriptor */
381   0x09,   /* bLength: Interface Descriptor size */
382   USB_DESC_TYPE_INTERFACE,  /* bDescriptorType: Interface */
383   /* Interface descriptor type */
384   0x00,   /* bInterfaceNumber: Number of Interface */
385   0x00,   /* bAlternateSetting: Alternate setting */
386   0x01,   /* bNumEndpoints: One endpoints used */
387   0x02,   /* bInterfaceClass: Communication Interface Class */
388   0x02,   /* bInterfaceSubClass: Abstract Control Model */
389   0x01,   /* bInterfaceProtocol: Common AT commands */
390   0x00,   /* iInterface: */
391 
392   /*Header Functional Descriptor*/
393   0x05,   /* bLength: Endpoint Descriptor size */
394   0x24,   /* bDescriptorType: CS_INTERFACE */
395   0x00,   /* bDescriptorSubtype: Header Func Desc */
396   0x10,   /* bcdCDC: spec release number */
397   0x01,
398 
399   /*Call Management Functional Descriptor*/
400   0x05,   /* bFunctionLength */
401   0x24,   /* bDescriptorType: CS_INTERFACE */
402   0x01,   /* bDescriptorSubtype: Call Management Func Desc */
403   0x00,   /* bmCapabilities: D0+D1 */
404   0x01,   /* bDataInterface: 1 */
405 
406   /*ACM Functional Descriptor*/
407   0x04,   /* bFunctionLength */
408   0x24,   /* bDescriptorType: CS_INTERFACE */
409   0x02,   /* bDescriptorSubtype: Abstract Control Management desc */
410   0x02,   /* bmCapabilities */
411 
412   /*Union Functional Descriptor*/
413   0x05,   /* bFunctionLength */
414   0x24,   /* bDescriptorType: CS_INTERFACE */
415   0x06,   /* bDescriptorSubtype: Union func desc */
416   0x00,   /* bMasterInterface: Communication class interface */
417   0x01,   /* bSlaveInterface0: Data Class Interface */
418 
419   /*Endpoint 2 Descriptor*/
420   0x07,                           /* bLength: Endpoint Descriptor size */
421   USB_DESC_TYPE_ENDPOINT      ,   /* bDescriptorType: Endpoint */
422   CDC_CMD_EP,                     /* bEndpointAddress */
423   0x03,                           /* bmAttributes: Interrupt */
424   LOBYTE(CDC_CMD_PACKET_SIZE),     /* wMaxPacketSize: */
425   HIBYTE(CDC_CMD_PACKET_SIZE),
426   0xFF,                           /* bInterval: */
427 
428   /*---------------------------------------------------------------------------*/
429 
430   /*Data class interface descriptor*/
431   0x09,   /* bLength: Endpoint Descriptor size */
432   USB_DESC_TYPE_INTERFACE,  /* bDescriptorType: */
433   0x01,   /* bInterfaceNumber: Number of Interface */
434   0x00,   /* bAlternateSetting: Alternate setting */
435   0x02,   /* bNumEndpoints: Two endpoints used */
436   0x0A,   /* bInterfaceClass: CDC */
437   0x00,   /* bInterfaceSubClass: */
438   0x00,   /* bInterfaceProtocol: */
439   0x00,   /* iInterface: */
440 
441   /*Endpoint OUT Descriptor*/
442   0x07,   /* bLength: Endpoint Descriptor size */
443   USB_DESC_TYPE_ENDPOINT,      /* bDescriptorType: Endpoint */
444   CDC_OUT_EP,                        /* bEndpointAddress */
445   0x02,                              /* bmAttributes: Bulk */
446   0x40,                              /* wMaxPacketSize: */
447   0x00,
448   0x00,                              /* bInterval: ignore for Bulk transfer */
449 
450   /*Endpoint IN Descriptor*/
451   0x07,   /* bLength: Endpoint Descriptor size */
452   USB_DESC_TYPE_ENDPOINT,     /* bDescriptorType: Endpoint */
453   CDC_IN_EP,                        /* bEndpointAddress */
454   0x02,                             /* bmAttributes: Bulk */
455   0x40,                             /* wMaxPacketSize: */
456   0x00,
457   0x00                              /* bInterval */
458 };
459 
460 /**
461   * @}
462   */
463 
464 /** @defgroup USBD_CDC_Private_Functions
465   * @{
466   */
467 
468 /**
469   * @brief  USBD_CDC_Init
470   *         Initialize the CDC interface
471   * @param  pdev: device instance
472   * @param  cfgidx: Configuration index
473   * @retval status
474   */
USBD_CDC_Init(USBD_HandleTypeDef * pdev,uint8_t cfgidx)475 static uint8_t  USBD_CDC_Init (USBD_HandleTypeDef *pdev,
476                                uint8_t cfgidx)
477 {
478   uint8_t ret = 0;
479   USBD_CDC_HandleTypeDef   *hcdc;
480 
481   if(pdev->dev_speed == USBD_SPEED_HIGH  )
482   {
483     /* Open EP IN */
484     USBD_LL_OpenEP(pdev,
485                    CDC_IN_EP,
486                    USBD_EP_TYPE_BULK,
487                    CDC_DATA_HS_IN_PACKET_SIZE);
488 
489     /* Open EP OUT */
490     USBD_LL_OpenEP(pdev,
491                    CDC_OUT_EP,
492                    USBD_EP_TYPE_BULK,
493                    CDC_DATA_HS_OUT_PACKET_SIZE);
494 
495   }
496   else
497   {
498     /* Open EP IN */
499     USBD_LL_OpenEP(pdev,
500                    CDC_IN_EP,
501                    USBD_EP_TYPE_BULK,
502                    CDC_DATA_FS_IN_PACKET_SIZE);
503 
504     /* Open EP OUT */
505     USBD_LL_OpenEP(pdev,
506                    CDC_OUT_EP,
507                    USBD_EP_TYPE_BULK,
508                    CDC_DATA_FS_OUT_PACKET_SIZE);
509   }
510   /* Open Command IN EP */
511   USBD_LL_OpenEP(pdev,
512                  CDC_CMD_EP,
513                  USBD_EP_TYPE_INTR,
514                  CDC_CMD_PACKET_SIZE);
515 
516 
517   pdev->pClassData = USBD_malloc(sizeof (USBD_CDC_HandleTypeDef));
518 
519   if(pdev->pClassData == NULL)
520   {
521     ret = 1;
522   }
523   else
524   {
525     hcdc = (USBD_CDC_HandleTypeDef*) pdev->pClassData;
526 
527     /* Init  physical Interface components */
528     ((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Init();
529 
530     /* Init Xfer states */
531     hcdc->TxState =0;
532     hcdc->RxState =0;
533 
534     if(pdev->dev_speed == USBD_SPEED_HIGH  )
535     {
536       /* Prepare Out endpoint to receive next packet */
537       USBD_LL_PrepareReceive(pdev,
538                              CDC_OUT_EP,
539                              hcdc->RxBuffer,
540                              CDC_DATA_HS_OUT_PACKET_SIZE);
541     }
542     else
543     {
544       /* Prepare Out endpoint to receive next packet */
545       USBD_LL_PrepareReceive(pdev,
546                              CDC_OUT_EP,
547                              hcdc->RxBuffer,
548                              CDC_DATA_FS_OUT_PACKET_SIZE);
549     }
550 
551 
552   }
553   return ret;
554 }
555 
556 /**
557   * @brief  USBD_CDC_Init
558   *         DeInitialize the CDC layer
559   * @param  pdev: device instance
560   * @param  cfgidx: Configuration index
561   * @retval status
562   */
USBD_CDC_DeInit(USBD_HandleTypeDef * pdev,uint8_t cfgidx)563 static uint8_t  USBD_CDC_DeInit (USBD_HandleTypeDef *pdev,
564                                  uint8_t cfgidx)
565 {
566   uint8_t ret = 0;
567 
568   /* Open EP IN */
569   USBD_LL_CloseEP(pdev,
570               CDC_IN_EP);
571 
572   /* Open EP OUT */
573   USBD_LL_CloseEP(pdev,
574               CDC_OUT_EP);
575 
576   /* Open Command IN EP */
577   USBD_LL_CloseEP(pdev,
578               CDC_CMD_EP);
579 
580 
581   /* DeInit  physical Interface components */
582   if(pdev->pClassData != NULL)
583   {
584     ((USBD_CDC_ItfTypeDef *)pdev->pUserData)->DeInit();
585     USBD_free(pdev->pClassData);
586     pdev->pClassData = NULL;
587   }
588 
589   return ret;
590 }
591 
592 /**
593   * @brief  USBD_CDC_Setup
594   *         Handle the CDC specific requests
595   * @param  pdev: instance
596   * @param  req: usb requests
597   * @retval status
598   */
USBD_CDC_Setup(USBD_HandleTypeDef * pdev,USBD_SetupReqTypedef * req)599 static uint8_t  USBD_CDC_Setup (USBD_HandleTypeDef *pdev,
600                                 USBD_SetupReqTypedef *req)
601 {
602   USBD_CDC_HandleTypeDef   *hcdc = (USBD_CDC_HandleTypeDef*) pdev->pClassData;
603   static uint8_t ifalt = 0;
604 
605   switch (req->bmRequest & USB_REQ_TYPE_MASK)
606   {
607   case USB_REQ_TYPE_CLASS :
608     if (req->wLength)
609     {
610       if (req->bmRequest & 0x80)
611       {
612         ((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Control(req->bRequest,
613                                                           (uint8_t *)hcdc->data,
614                                                           req->wLength);
615           USBD_CtlSendData (pdev,
616                             (uint8_t *)hcdc->data,
617                             req->wLength);
618       }
619       else
620       {
621         hcdc->CmdOpCode = req->bRequest;
622         hcdc->CmdLength = req->wLength;
623 
624         USBD_CtlPrepareRx (pdev,
625                            (uint8_t *)hcdc->data,
626                            req->wLength);
627       }
628 
629     }
630     else
631     {
632       ((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Control(req->bRequest,
633                                                         (uint8_t*)req,
634                                                         0);
635     }
636     break;
637 
638   case USB_REQ_TYPE_STANDARD:
639     switch (req->bRequest)
640     {
641     case USB_REQ_GET_INTERFACE :
642       USBD_CtlSendData (pdev,
643                         &ifalt,
644                         1);
645       break;
646 
647     case USB_REQ_SET_INTERFACE :
648       break;
649     }
650 
651   default:
652     break;
653   }
654   return USBD_OK;
655 }
656 
657 /**
658   * @brief  USBD_CDC_DataIn
659   *         Data sent on non-control IN endpoint
660   * @param  pdev: device instance
661   * @param  epnum: endpoint number
662   * @retval status
663   */
USBD_CDC_DataIn(USBD_HandleTypeDef * pdev,uint8_t epnum)664 static uint8_t  USBD_CDC_DataIn (USBD_HandleTypeDef *pdev, uint8_t epnum)
665 {
666   USBD_CDC_HandleTypeDef   *hcdc = (USBD_CDC_HandleTypeDef*) pdev->pClassData;
667 
668   if(pdev->pClassData != NULL)
669   {
670 
671     hcdc->TxState = 0;
672 
673     return USBD_OK;
674   }
675   else
676   {
677     return USBD_FAIL;
678   }
679 }
680 
681 /**
682   * @brief  USBD_CDC_DataOut
683   *         Data received on non-control Out endpoint
684   * @param  pdev: device instance
685   * @param  epnum: endpoint number
686   * @retval status
687   */
USBD_CDC_DataOut(USBD_HandleTypeDef * pdev,uint8_t epnum)688 static uint8_t  USBD_CDC_DataOut (USBD_HandleTypeDef *pdev, uint8_t epnum)
689 {
690   USBD_CDC_HandleTypeDef   *hcdc = (USBD_CDC_HandleTypeDef*) pdev->pClassData;
691 
692   /* Get the received data length */
693   hcdc->RxLength = USBD_LL_GetRxDataSize (pdev, epnum);
694 
695   /* USB data will be immediately processed, this allow next USB traffic being
696   NAKed till the end of the application Xfer */
697   if(pdev->pClassData != NULL)
698   {
699     ((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Receive(hcdc->RxBuffer, &hcdc->RxLength);
700 
701     return USBD_OK;
702   }
703   else
704   {
705     return USBD_FAIL;
706   }
707 }
708 
709 
710 
711 /**
712   * @brief  USBD_CDC_DataOut
713   *         Data received on non-control Out endpoint
714   * @param  pdev: device instance
715   * @param  epnum: endpoint number
716   * @retval status
717   */
USBD_CDC_EP0_RxReady(USBD_HandleTypeDef * pdev)718 static uint8_t  USBD_CDC_EP0_RxReady (USBD_HandleTypeDef *pdev)
719 {
720   USBD_CDC_HandleTypeDef   *hcdc = (USBD_CDC_HandleTypeDef*) pdev->pClassData;
721 
722   if((pdev->pUserData != NULL) && (hcdc->CmdOpCode != 0xFF))
723   {
724     ((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Control(hcdc->CmdOpCode,
725                                                       (uint8_t *)hcdc->data,
726                                                       hcdc->CmdLength);
727       hcdc->CmdOpCode = 0xFF;
728 
729   }
730   return USBD_OK;
731 }
732 
733 /**
734   * @brief  USBD_CDC_GetFSCfgDesc
735   *         Return configuration descriptor
736   * @param  speed : current device speed
737   * @param  length : pointer data length
738   * @retval pointer to descriptor buffer
739   */
USBD_CDC_GetFSCfgDesc(uint16_t * length)740 static uint8_t  *USBD_CDC_GetFSCfgDesc (uint16_t *length)
741 {
742   *length = sizeof (USBD_CDC_CfgFSDesc);
743   return USBD_CDC_CfgFSDesc;
744 }
745 
746 /**
747   * @brief  USBD_CDC_GetHSCfgDesc
748   *         Return configuration descriptor
749   * @param  speed : current device speed
750   * @param  length : pointer data length
751   * @retval pointer to descriptor buffer
752   */
USBD_CDC_GetHSCfgDesc(uint16_t * length)753 static uint8_t  *USBD_CDC_GetHSCfgDesc (uint16_t *length)
754 {
755   *length = sizeof (USBD_CDC_CfgHSDesc);
756   return USBD_CDC_CfgHSDesc;
757 }
758 
759 /**
760   * @brief  USBD_CDC_GetCfgDesc
761   *         Return configuration descriptor
762   * @param  speed : current device speed
763   * @param  length : pointer data length
764   * @retval pointer to descriptor buffer
765   */
USBD_CDC_GetOtherSpeedCfgDesc(uint16_t * length)766 static uint8_t  *USBD_CDC_GetOtherSpeedCfgDesc (uint16_t *length)
767 {
768   *length = sizeof (USBD_CDC_OtherSpeedCfgDesc);
769   return USBD_CDC_OtherSpeedCfgDesc;
770 }
771 
772 /**
773 * @brief  DeviceQualifierDescriptor
774 *         return Device Qualifier descriptor
775 * @param  length : pointer data length
776 * @retval pointer to descriptor buffer
777 */
USBD_CDC_GetDeviceQualifierDescriptor(uint16_t * length)778 uint8_t  *USBD_CDC_GetDeviceQualifierDescriptor (uint16_t *length)
779 {
780   *length = sizeof (USBD_CDC_DeviceQualifierDesc);
781   return USBD_CDC_DeviceQualifierDesc;
782 }
783 
784 /**
785 * @brief  USBD_CDC_RegisterInterface
786   * @param  pdev: device instance
787   * @param  fops: CD  Interface callback
788   * @retval status
789   */
USBD_CDC_RegisterInterface(USBD_HandleTypeDef * pdev,USBD_CDC_ItfTypeDef * fops)790 uint8_t  USBD_CDC_RegisterInterface  (USBD_HandleTypeDef   *pdev,
791                                       USBD_CDC_ItfTypeDef *fops)
792 {
793   uint8_t  ret = USBD_FAIL;
794 
795   if(fops != NULL)
796   {
797     pdev->pUserData= fops;
798     ret = USBD_OK;
799   }
800 
801   return ret;
802 }
803 
804 /**
805   * @brief  USBD_CDC_SetTxBuffer
806   * @param  pdev: device instance
807   * @param  pbuff: Tx Buffer
808   * @retval status
809   */
USBD_CDC_SetTxBuffer(USBD_HandleTypeDef * pdev,uint8_t * pbuff,uint16_t length)810 uint8_t  USBD_CDC_SetTxBuffer  (USBD_HandleTypeDef   *pdev,
811                                 uint8_t  *pbuff,
812                                 uint16_t length)
813 {
814   USBD_CDC_HandleTypeDef   *hcdc = (USBD_CDC_HandleTypeDef*) pdev->pClassData;
815 
816   hcdc->TxBuffer = pbuff;
817   hcdc->TxLength = length;
818 
819   return USBD_OK;
820 }
821 
822 
823 /**
824   * @brief  USBD_CDC_SetRxBuffer
825   * @param  pdev: device instance
826   * @param  pbuff: Rx Buffer
827   * @retval status
828   */
USBD_CDC_SetRxBuffer(USBD_HandleTypeDef * pdev,uint8_t * pbuff)829 uint8_t  USBD_CDC_SetRxBuffer  (USBD_HandleTypeDef   *pdev,
830                                    uint8_t  *pbuff)
831 {
832   USBD_CDC_HandleTypeDef   *hcdc = (USBD_CDC_HandleTypeDef*) pdev->pClassData;
833 
834   hcdc->RxBuffer = pbuff;
835 
836   return USBD_OK;
837 }
838 
839 /**
840   * @brief  USBD_CDC_DataOut
841   *         Data received on non-control Out endpoint
842   * @param  pdev: device instance
843   * @param  epnum: endpoint number
844   * @retval status
845   */
USBD_CDC_TransmitPacket(USBD_HandleTypeDef * pdev)846 uint8_t  USBD_CDC_TransmitPacket(USBD_HandleTypeDef *pdev)
847 {
848   USBD_CDC_HandleTypeDef   *hcdc = (USBD_CDC_HandleTypeDef*) pdev->pClassData;
849 
850   if(pdev->pClassData != NULL)
851   {
852     if(hcdc->TxState == 0)
853     {
854       /* Tx Transfer in progress */
855       hcdc->TxState = 1;
856 
857       /* Transmit next packet */
858       USBD_LL_Transmit(pdev,
859                        CDC_IN_EP,
860                        hcdc->TxBuffer,
861                        hcdc->TxLength);
862 
863       return USBD_OK;
864     }
865     else
866     {
867       return USBD_BUSY;
868     }
869   }
870   else
871   {
872     return USBD_FAIL;
873   }
874 }
875 
876 
877 /**
878   * @brief  USBD_CDC_ReceivePacket
879   *         prepare OUT Endpoint for reception
880   * @param  pdev: device instance
881   * @retval status
882   */
USBD_CDC_ReceivePacket(USBD_HandleTypeDef * pdev)883 uint8_t  USBD_CDC_ReceivePacket(USBD_HandleTypeDef *pdev)
884 {
885   USBD_CDC_HandleTypeDef   *hcdc = (USBD_CDC_HandleTypeDef*) pdev->pClassData;
886 
887   /* Suspend or Resume USB Out process */
888   if(pdev->pClassData != NULL)
889   {
890     if(pdev->dev_speed == USBD_SPEED_HIGH  )
891     {
892       /* Prepare Out endpoint to receive next packet */
893       USBD_LL_PrepareReceive(pdev,
894                              CDC_OUT_EP,
895                              hcdc->RxBuffer,
896                              CDC_DATA_HS_OUT_PACKET_SIZE);
897     }
898     else
899     {
900       /* Prepare Out endpoint to receive next packet */
901       USBD_LL_PrepareReceive(pdev,
902                              CDC_OUT_EP,
903                              hcdc->RxBuffer,
904                              CDC_DATA_FS_OUT_PACKET_SIZE);
905     }
906     return USBD_OK;
907   }
908   else
909   {
910     return USBD_FAIL;
911   }
912 }
913 /**
914   * @}
915   */
916 
917 /**
918   * @}
919   */
920 
921 /**
922   * @}
923   */
924 
925 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
926