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>© 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