2 ******************************************************************************
4 * @author MCD Application Team
5 * @brief This file provides the high layer firmware functions to manage the
6 * following functionalities of the USB CDC Class:
7 * - Initialization and Configuration of high and low layer
8 * - Enumeration as CDC Device (and enumeration for each implemented memory interface)
9 * - OUT/IN data transfer
10 * - Command IN transfer (class requests management)
15 * ===================================================================
16 * CDC Class Driver Description
17 * ===================================================================
18 * This driver manages the "Universal Serial Bus Class Definitions for Communications Devices
19 * Revision 1.2 November 16, 2007" and the sub-protocol specification of "Universal Serial Bus
20 * Communications Class Subclass Specification for PSTN Devices Revision 1.2 February 9, 2007"
21 * This driver implements the following aspects of the specification:
22 * - Device descriptor management
23 * - Configuration descriptor management
24 * - Enumeration as CDC device with 2 data endpoints (IN and OUT) and 1 command endpoint (IN)
25 * - Requests management (as described in section 6.2 in specification)
26 * - Abstract Control Model compliant
27 * - Union Functional collection (using 1 IN endpoint for control)
28 * - Data interface class
30 * These aspects may be enriched or modified for a specific user application.
32 * This driver doesn't implement the following aspects of the specification
33 * (but it is possible to manage these features with some modifications on this driver):
34 * - Any class-specific aspect relative to communication classes should be managed by user application.
35 * - All communication classes other than PSTN are not managed
39 ******************************************************************************
42 * <h2><center>© Copyright (c) 2015 STMicroelectronics.
43 * All rights reserved.</center></h2>
45 * This software component is licensed by ST under Ultimate Liberty license
46 * SLA0044, the "License"; You may not use this file except in compliance with
47 * the License. You may obtain a copy of the License at:
50 ******************************************************************************
54 - "stm32xxxxx_{eval}{discovery}{nucleo_144}.c"
55 - "stm32xxxxx_{eval}{discovery}_io.c"
58 /* Includes ------------------------------------------------------------------*/
60 #include "usbd_ctlreq.h"
63 /** @addtogroup STM32_USB_DEVICE_LIBRARY
68 /** @defgroup USBD_CDC
69 * @brief usbd core module
73 /** @defgroup USBD_CDC_Private_TypesDefinitions
81 /** @defgroup USBD_CDC_Private_Defines
89 /** @defgroup USBD_CDC_Private_Macros
98 /** @defgroup USBD_CDC_Private_FunctionPrototypes
103 static uint8_t USBD_CDC_Init(USBD_HandleTypeDef
*pdev
,
106 static uint8_t USBD_CDC_DeInit(USBD_HandleTypeDef
*pdev
,
109 static uint8_t USBD_CDC_Setup(USBD_HandleTypeDef
*pdev
,
110 USBD_SetupReqTypedef
*req
);
112 static uint8_t USBD_CDC_DataIn(USBD_HandleTypeDef
*pdev
,
115 static uint8_t USBD_CDC_DataOut(USBD_HandleTypeDef
*pdev
,
118 static uint8_t USBD_CDC_EP0_RxReady(USBD_HandleTypeDef
*pdev
);
120 static uint8_t *USBD_CDC_GetFSCfgDesc(uint16_t *length
);
122 static uint8_t *USBD_CDC_GetHSCfgDesc(uint16_t *length
);
124 static uint8_t *USBD_CDC_GetOtherSpeedCfgDesc(uint16_t *length
);
126 static uint8_t *USBD_CDC_GetOtherSpeedCfgDesc(uint16_t *length
);
128 uint8_t *USBD_CDC_GetDeviceQualifierDescriptor(uint16_t *length
);
130 /* USB Standard Device Descriptor */
131 __ALIGN_BEGIN
static uint8_t USBD_CDC_DeviceQualifierDesc
[USB_LEN_DEV_QUALIFIER_DESC
] __ALIGN_END
=
133 USB_LEN_DEV_QUALIFIER_DESC
,
134 USB_DESC_TYPE_DEVICE_QUALIFIER
,
149 /** @defgroup USBD_CDC_Private_Variables
154 /* CDC interface class callbacks structure */
155 USBD_ClassTypeDef USBD_CDC
=
160 NULL
, /* EP0_TxSent, */
161 USBD_CDC_EP0_RxReady
,
167 USBD_CDC_GetHSCfgDesc
,
168 USBD_CDC_GetFSCfgDesc
,
169 USBD_CDC_GetOtherSpeedCfgDesc
,
170 USBD_CDC_GetDeviceQualifierDescriptor
,
173 /* USB CDC device Configuration Descriptor */
174 __ALIGN_BEGIN
uint8_t USBD_CDC_CfgHSDesc
[USB_CDC_CONFIG_DESC_SIZ
] __ALIGN_END
=
176 /*Configuration Descriptor*/
177 0x09, /* bLength: Configuration Descriptor size */
178 USB_DESC_TYPE_CONFIGURATION
, /* bDescriptorType: Configuration */
179 USB_CDC_CONFIG_DESC_SIZ
, /* wTotalLength:no of returned bytes */
181 0x02, /* bNumInterfaces: 2 interface */
182 0x01, /* bConfigurationValue: Configuration value */
183 0x00, /* iConfiguration: Index of string descriptor describing the configuration */
184 0xC0, /* bmAttributes: self powered */
185 0x32, /* MaxPower 0 mA */
187 /*---------------------------------------------------------------------------*/
189 /*Interface Descriptor */
190 0x09, /* bLength: Interface Descriptor size */
191 USB_DESC_TYPE_INTERFACE
, /* bDescriptorType: Interface */
192 /* Interface descriptor type */
193 0x00, /* bInterfaceNumber: Number of Interface */
194 0x00, /* bAlternateSetting: Alternate setting */
195 0x01, /* bNumEndpoints: One endpoints used */
196 0x02, /* bInterfaceClass: Communication Interface Class */
197 0x02, /* bInterfaceSubClass: Abstract Control Model */
198 0x01, /* bInterfaceProtocol: Common AT commands */
199 0x00, /* iInterface: */
201 /*Header Functional Descriptor*/
202 0x05, /* bLength: Endpoint Descriptor size */
203 0x24, /* bDescriptorType: CS_INTERFACE */
204 0x00, /* bDescriptorSubtype: Header Func Desc */
205 0x10, /* bcdCDC: spec release number */
208 /*Call Management Functional Descriptor*/
209 0x05, /* bFunctionLength */
210 0x24, /* bDescriptorType: CS_INTERFACE */
211 0x01, /* bDescriptorSubtype: Call Management Func Desc */
212 0x00, /* bmCapabilities: D0+D1 */
213 0x01, /* bDataInterface: 1 */
215 /*ACM Functional Descriptor*/
216 0x04, /* bFunctionLength */
217 0x24, /* bDescriptorType: CS_INTERFACE */
218 0x02, /* bDescriptorSubtype: Abstract Control Management desc */
219 0x02, /* bmCapabilities */
221 /*Union Functional Descriptor*/
222 0x05, /* bFunctionLength */
223 0x24, /* bDescriptorType: CS_INTERFACE */
224 0x06, /* bDescriptorSubtype: Union func desc */
225 0x00, /* bMasterInterface: Communication class interface */
226 0x01, /* bSlaveInterface0: Data Class Interface */
228 /*Endpoint 2 Descriptor*/
229 0x07, /* bLength: Endpoint Descriptor size */
230 USB_DESC_TYPE_ENDPOINT
, /* bDescriptorType: Endpoint */
231 CDC_CMD_EP
, /* bEndpointAddress */
232 0x03, /* bmAttributes: Interrupt */
233 LOBYTE(CDC_CMD_PACKET_SIZE
), /* wMaxPacketSize: */
234 HIBYTE(CDC_CMD_PACKET_SIZE
),
235 CDC_HS_BINTERVAL
, /* bInterval: */
236 /*---------------------------------------------------------------------------*/
238 /*Data class interface descriptor*/
239 0x09, /* bLength: Endpoint Descriptor size */
240 USB_DESC_TYPE_INTERFACE
, /* bDescriptorType: */
241 0x01, /* bInterfaceNumber: Number of Interface */
242 0x00, /* bAlternateSetting: Alternate setting */
243 0x02, /* bNumEndpoints: Two endpoints used */
244 0x0A, /* bInterfaceClass: CDC */
245 0x00, /* bInterfaceSubClass: */
246 0x00, /* bInterfaceProtocol: */
247 0x00, /* iInterface: */
249 /*Endpoint OUT Descriptor*/
250 0x07, /* bLength: Endpoint Descriptor size */
251 USB_DESC_TYPE_ENDPOINT
, /* bDescriptorType: Endpoint */
252 CDC_OUT_EP
, /* bEndpointAddress */
253 0x02, /* bmAttributes: Bulk */
254 LOBYTE(CDC_DATA_HS_MAX_PACKET_SIZE
), /* wMaxPacketSize: */
255 HIBYTE(CDC_DATA_HS_MAX_PACKET_SIZE
),
256 0x00, /* bInterval: ignore for Bulk transfer */
258 /*Endpoint IN Descriptor*/
259 0x07, /* bLength: Endpoint Descriptor size */
260 USB_DESC_TYPE_ENDPOINT
, /* bDescriptorType: Endpoint */
261 CDC_IN_EP
, /* bEndpointAddress */
262 0x02, /* bmAttributes: Bulk */
263 LOBYTE(CDC_DATA_HS_MAX_PACKET_SIZE
), /* wMaxPacketSize: */
264 HIBYTE(CDC_DATA_HS_MAX_PACKET_SIZE
),
265 0x00 /* bInterval: ignore for Bulk transfer */
269 /* USB CDC device Configuration Descriptor */
270 __ALIGN_BEGIN
uint8_t USBD_CDC_CfgFSDesc
[USB_CDC_CONFIG_DESC_SIZ
] __ALIGN_END
=
272 /*Configuration Descriptor*/
273 0x09, /* bLength: Configuration Descriptor size */
274 USB_DESC_TYPE_CONFIGURATION
, /* bDescriptorType: Configuration */
275 USB_CDC_CONFIG_DESC_SIZ
, /* wTotalLength:no of returned bytes */
277 0x02, /* bNumInterfaces: 2 interface */
278 0x01, /* bConfigurationValue: Configuration value */
279 0x00, /* iConfiguration: Index of string descriptor describing the configuration */
280 0xC0, /* bmAttributes: self powered */
281 0x32, /* MaxPower 0 mA */
283 /*---------------------------------------------------------------------------*/
285 /*Interface Descriptor */
286 0x09, /* bLength: Interface Descriptor size */
287 USB_DESC_TYPE_INTERFACE
, /* bDescriptorType: Interface */
288 /* Interface descriptor type */
289 0x00, /* bInterfaceNumber: Number of Interface */
290 0x00, /* bAlternateSetting: Alternate setting */
291 0x01, /* bNumEndpoints: One endpoints used */
292 0x02, /* bInterfaceClass: Communication Interface Class */
293 0x02, /* bInterfaceSubClass: Abstract Control Model */
294 0x01, /* bInterfaceProtocol: Common AT commands */
295 0x00, /* iInterface: */
297 /*Header Functional Descriptor*/
298 0x05, /* bLength: Endpoint Descriptor size */
299 0x24, /* bDescriptorType: CS_INTERFACE */
300 0x00, /* bDescriptorSubtype: Header Func Desc */
301 0x10, /* bcdCDC: spec release number */
304 /*Call Management Functional Descriptor*/
305 0x05, /* bFunctionLength */
306 0x24, /* bDescriptorType: CS_INTERFACE */
307 0x01, /* bDescriptorSubtype: Call Management Func Desc */
308 0x00, /* bmCapabilities: D0+D1 */
309 0x01, /* bDataInterface: 1 */
311 /*ACM Functional Descriptor*/
312 0x04, /* bFunctionLength */
313 0x24, /* bDescriptorType: CS_INTERFACE */
314 0x02, /* bDescriptorSubtype: Abstract Control Management desc */
315 0x02, /* bmCapabilities */
317 /*Union Functional Descriptor*/
318 0x05, /* bFunctionLength */
319 0x24, /* bDescriptorType: CS_INTERFACE */
320 0x06, /* bDescriptorSubtype: Union func desc */
321 0x00, /* bMasterInterface: Communication class interface */
322 0x01, /* bSlaveInterface0: Data Class Interface */
324 /*Endpoint 2 Descriptor*/
325 0x07, /* bLength: Endpoint Descriptor size */
326 USB_DESC_TYPE_ENDPOINT
, /* bDescriptorType: Endpoint */
327 CDC_CMD_EP
, /* bEndpointAddress */
328 0x03, /* bmAttributes: Interrupt */
329 LOBYTE(CDC_CMD_PACKET_SIZE
), /* wMaxPacketSize: */
330 HIBYTE(CDC_CMD_PACKET_SIZE
),
331 CDC_FS_BINTERVAL
, /* bInterval: */
332 /*---------------------------------------------------------------------------*/
334 /*Data class interface descriptor*/
335 0x09, /* bLength: Endpoint Descriptor size */
336 USB_DESC_TYPE_INTERFACE
, /* bDescriptorType: */
337 0x01, /* bInterfaceNumber: Number of Interface */
338 0x00, /* bAlternateSetting: Alternate setting */
339 0x02, /* bNumEndpoints: Two endpoints used */
340 0x0A, /* bInterfaceClass: CDC */
341 0x00, /* bInterfaceSubClass: */
342 0x00, /* bInterfaceProtocol: */
343 0x00, /* iInterface: */
345 /*Endpoint OUT Descriptor*/
346 0x07, /* bLength: Endpoint Descriptor size */
347 USB_DESC_TYPE_ENDPOINT
, /* bDescriptorType: Endpoint */
348 CDC_OUT_EP
, /* bEndpointAddress */
349 0x02, /* bmAttributes: Bulk */
350 LOBYTE(CDC_DATA_FS_MAX_PACKET_SIZE
), /* wMaxPacketSize: */
351 HIBYTE(CDC_DATA_FS_MAX_PACKET_SIZE
),
352 0x00, /* bInterval: ignore for Bulk transfer */
354 /*Endpoint IN Descriptor*/
355 0x07, /* bLength: Endpoint Descriptor size */
356 USB_DESC_TYPE_ENDPOINT
, /* bDescriptorType: Endpoint */
357 CDC_IN_EP
, /* bEndpointAddress */
358 0x02, /* bmAttributes: Bulk */
359 LOBYTE(CDC_DATA_FS_MAX_PACKET_SIZE
), /* wMaxPacketSize: */
360 HIBYTE(CDC_DATA_FS_MAX_PACKET_SIZE
),
361 0x00 /* bInterval: ignore for Bulk transfer */
364 __ALIGN_BEGIN
uint8_t USBD_CDC_OtherSpeedCfgDesc
[USB_CDC_CONFIG_DESC_SIZ
] __ALIGN_END
=
366 0x09, /* bLength: Configuation Descriptor size */
367 USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION
,
368 USB_CDC_CONFIG_DESC_SIZ
,
370 0x02, /* bNumInterfaces: 2 interfaces */
371 0x01, /* bConfigurationValue: */
372 0x04, /* iConfiguration: */
373 0xC0, /* bmAttributes: */
374 0x32, /* MaxPower 100 mA */
376 /*Interface Descriptor */
377 0x09, /* bLength: Interface Descriptor size */
378 USB_DESC_TYPE_INTERFACE
, /* bDescriptorType: Interface */
379 /* Interface descriptor type */
380 0x00, /* bInterfaceNumber: Number of Interface */
381 0x00, /* bAlternateSetting: Alternate setting */
382 0x01, /* bNumEndpoints: One endpoints used */
383 0x02, /* bInterfaceClass: Communication Interface Class */
384 0x02, /* bInterfaceSubClass: Abstract Control Model */
385 0x01, /* bInterfaceProtocol: Common AT commands */
386 0x00, /* iInterface: */
388 /*Header Functional Descriptor*/
389 0x05, /* bLength: Endpoint Descriptor size */
390 0x24, /* bDescriptorType: CS_INTERFACE */
391 0x00, /* bDescriptorSubtype: Header Func Desc */
392 0x10, /* bcdCDC: spec release number */
395 /*Call Management Functional Descriptor*/
396 0x05, /* bFunctionLength */
397 0x24, /* bDescriptorType: CS_INTERFACE */
398 0x01, /* bDescriptorSubtype: Call Management Func Desc */
399 0x00, /* bmCapabilities: D0+D1 */
400 0x01, /* bDataInterface: 1 */
402 /*ACM Functional Descriptor*/
403 0x04, /* bFunctionLength */
404 0x24, /* bDescriptorType: CS_INTERFACE */
405 0x02, /* bDescriptorSubtype: Abstract Control Management desc */
406 0x02, /* bmCapabilities */
408 /*Union Functional Descriptor*/
409 0x05, /* bFunctionLength */
410 0x24, /* bDescriptorType: CS_INTERFACE */
411 0x06, /* bDescriptorSubtype: Union func desc */
412 0x00, /* bMasterInterface: Communication class interface */
413 0x01, /* bSlaveInterface0: Data Class Interface */
415 /*Endpoint 2 Descriptor*/
416 0x07, /* bLength: Endpoint Descriptor size */
417 USB_DESC_TYPE_ENDPOINT
, /* bDescriptorType: Endpoint */
418 CDC_CMD_EP
, /* bEndpointAddress */
419 0x03, /* bmAttributes: Interrupt */
420 LOBYTE(CDC_CMD_PACKET_SIZE
), /* wMaxPacketSize: */
421 HIBYTE(CDC_CMD_PACKET_SIZE
),
422 CDC_FS_BINTERVAL
, /* bInterval: */
424 /*---------------------------------------------------------------------------*/
426 /*Data class interface descriptor*/
427 0x09, /* bLength: Endpoint Descriptor size */
428 USB_DESC_TYPE_INTERFACE
, /* bDescriptorType: */
429 0x01, /* bInterfaceNumber: Number of Interface */
430 0x00, /* bAlternateSetting: Alternate setting */
431 0x02, /* bNumEndpoints: Two endpoints used */
432 0x0A, /* bInterfaceClass: CDC */
433 0x00, /* bInterfaceSubClass: */
434 0x00, /* bInterfaceProtocol: */
435 0x00, /* iInterface: */
437 /*Endpoint OUT Descriptor*/
438 0x07, /* bLength: Endpoint Descriptor size */
439 USB_DESC_TYPE_ENDPOINT
, /* bDescriptorType: Endpoint */
440 CDC_OUT_EP
, /* bEndpointAddress */
441 0x02, /* bmAttributes: Bulk */
442 0x40, /* wMaxPacketSize: */
444 0x00, /* bInterval: ignore for Bulk transfer */
446 /*Endpoint IN Descriptor*/
447 0x07, /* bLength: Endpoint Descriptor size */
448 USB_DESC_TYPE_ENDPOINT
, /* bDescriptorType: Endpoint */
449 CDC_IN_EP
, /* bEndpointAddress */
450 0x02, /* bmAttributes: Bulk */
451 0x40, /* wMaxPacketSize: */
460 /** @defgroup USBD_CDC_Private_Functions
465 * @brief USBD_CDC_Init
466 * Initialize the CDC interface
467 * @param pdev: device instance
468 * @param cfgidx: Configuration index
471 static uint8_t USBD_CDC_Init(USBD_HandleTypeDef
*pdev
, uint8_t cfgidx
)
476 USBD_CDC_HandleTypeDef
*hcdc
;
478 if (pdev
->dev_speed
== USBD_SPEED_HIGH
)
481 USBD_LL_OpenEP(pdev
, CDC_IN_EP
, USBD_EP_TYPE_BULK
,
482 CDC_DATA_HS_IN_PACKET_SIZE
);
484 pdev
->ep_in
[CDC_IN_EP
& 0xFU
].is_used
= 1U;
487 USBD_LL_OpenEP(pdev
, CDC_OUT_EP
, USBD_EP_TYPE_BULK
,
488 CDC_DATA_HS_OUT_PACKET_SIZE
);
490 pdev
->ep_out
[CDC_OUT_EP
& 0xFU
].is_used
= 1U;
496 USBD_LL_OpenEP(pdev
, CDC_IN_EP
, USBD_EP_TYPE_BULK
,
497 CDC_DATA_FS_IN_PACKET_SIZE
);
499 pdev
->ep_in
[CDC_IN_EP
& 0xFU
].is_used
= 1U;
502 USBD_LL_OpenEP(pdev
, CDC_OUT_EP
, USBD_EP_TYPE_BULK
,
503 CDC_DATA_FS_OUT_PACKET_SIZE
);
505 pdev
->ep_out
[CDC_OUT_EP
& 0xFU
].is_used
= 1U;
507 /* Open Command IN EP */
508 USBD_LL_OpenEP(pdev
, CDC_CMD_EP
, USBD_EP_TYPE_INTR
, CDC_CMD_PACKET_SIZE
);
509 pdev
->ep_in
[CDC_CMD_EP
& 0xFU
].is_used
= 1U;
511 pdev
->pCDC_ClassData
= USBD_malloc(sizeof(USBD_CDC_HandleTypeDef
));
513 if (pdev
->pCDC_ClassData
== NULL
)
519 hcdc
= (USBD_CDC_HandleTypeDef
*) pdev
->pCDC_ClassData
;
521 /* Init physical Interface components */
522 ((USBD_CDC_ItfTypeDef
*)pdev
->pCDC_UserData
)->Init();
524 /* Init Xfer states */
528 if (pdev
->dev_speed
== USBD_SPEED_HIGH
)
530 /* Prepare Out endpoint to receive next packet */
531 USBD_LL_PrepareReceive(pdev
, CDC_OUT_EP
, hcdc
->RxBuffer
,
532 CDC_DATA_HS_OUT_PACKET_SIZE
);
536 /* Prepare Out endpoint to receive next packet */
537 USBD_LL_PrepareReceive(pdev
, CDC_OUT_EP
, hcdc
->RxBuffer
,
538 CDC_DATA_FS_OUT_PACKET_SIZE
);
545 * @brief USBD_CDC_Init
546 * DeInitialize the CDC layer
547 * @param pdev: device instance
548 * @param cfgidx: Configuration index
551 static uint8_t USBD_CDC_DeInit(USBD_HandleTypeDef
*pdev
, uint8_t cfgidx
)
558 USBD_LL_CloseEP(pdev
, CDC_IN_EP
);
559 pdev
->ep_in
[CDC_IN_EP
& 0xFU
].is_used
= 0U;
562 USBD_LL_CloseEP(pdev
, CDC_OUT_EP
);
563 pdev
->ep_out
[CDC_OUT_EP
& 0xFU
].is_used
= 0U;
565 /* Close Command IN EP */
566 USBD_LL_CloseEP(pdev
, CDC_CMD_EP
);
567 pdev
->ep_in
[CDC_CMD_EP
& 0xFU
].is_used
= 0U;
569 /* DeInit physical Interface components */
570 if (pdev
->pCDC_ClassData
!= NULL
)
572 ((USBD_CDC_ItfTypeDef
*)pdev
->pCDC_UserData
)->DeInit();
573 USBD_free(pdev
->pCDC_ClassData
);
574 pdev
->pCDC_ClassData
= NULL
;
581 * @brief USBD_CDC_Setup
582 * Handle the CDC specific requests
583 * @param pdev: instance
584 * @param req: usb requests
587 static uint8_t USBD_CDC_Setup(USBD_HandleTypeDef
*pdev
,
588 USBD_SetupReqTypedef
*req
)
590 USBD_CDC_HandleTypeDef
*hcdc
= (USBD_CDC_HandleTypeDef
*) pdev
->pCDC_ClassData
;
592 uint16_t status_info
= 0U;
593 uint8_t ret
= USBD_OK
;
595 switch (req
->bmRequest
& USB_REQ_TYPE_MASK
)
597 case USB_REQ_TYPE_CLASS
:
600 if (req
->bmRequest
& 0x80U
)
602 ((USBD_CDC_ItfTypeDef
*)pdev
->pCDC_UserData
)->Control(req
->bRequest
,
603 (uint8_t *)(void *)hcdc
->data
,
606 USBD_CtlSendData(pdev
, (uint8_t *)(void *)hcdc
->data
, req
->wLength
);
610 hcdc
->CmdOpCode
= req
->bRequest
;
611 hcdc
->CmdLength
= (uint8_t)req
->wLength
;
613 USBD_CtlPrepareRx(pdev
, (uint8_t *)(void *)hcdc
->data
, req
->wLength
);
618 ((USBD_CDC_ItfTypeDef
*)pdev
->pCDC_UserData
)->Control(req
->bRequest
,
619 (uint8_t *)(void *)req
, 0U);
623 case USB_REQ_TYPE_STANDARD
:
624 switch (req
->bRequest
)
626 case USB_REQ_GET_STATUS
:
627 if (pdev
->dev_state
== USBD_STATE_CONFIGURED
)
629 USBD_CtlSendData(pdev
, (uint8_t *)(void *)&status_info
, 2U);
633 USBD_CtlError(pdev
, req
);
638 case USB_REQ_GET_INTERFACE
:
639 if (pdev
->dev_state
== USBD_STATE_CONFIGURED
)
641 USBD_CtlSendData(pdev
, &ifalt
, 1U);
645 USBD_CtlError(pdev
, req
);
650 case USB_REQ_SET_INTERFACE
:
651 if (pdev
->dev_state
!= USBD_STATE_CONFIGURED
)
653 USBD_CtlError(pdev
, req
);
659 USBD_CtlError(pdev
, req
);
666 USBD_CtlError(pdev
, req
);
675 * @brief USBD_CDC_DataIn
676 * Data sent on non-control IN endpoint
677 * @param pdev: device instance
678 * @param epnum: endpoint number
681 static uint8_t USBD_CDC_DataIn(USBD_HandleTypeDef
*pdev
, uint8_t epnum
)
683 USBD_CDC_HandleTypeDef
*hcdc
= (USBD_CDC_HandleTypeDef
*)pdev
->pCDC_ClassData
;
684 PCD_HandleTypeDef
*hpcd
= pdev
->pData
;
686 if (pdev
->pCDC_ClassData
!= NULL
)
688 if ((pdev
->ep_in
[epnum
].total_length
> 0U) && ((pdev
->ep_in
[epnum
].total_length
% hpcd
->IN_ep
[epnum
].maxpacket
) == 0U))
690 /* Update the packet total length */
691 pdev
->ep_in
[epnum
].total_length
= 0U;
694 USBD_LL_Transmit(pdev
, epnum
, NULL
, 0U);
709 * @brief USBD_CDC_DataOut
710 * Data received on non-control Out endpoint
711 * @param pdev: device instance
712 * @param epnum: endpoint number
715 static uint8_t USBD_CDC_DataOut(USBD_HandleTypeDef
*pdev
, uint8_t epnum
)
717 USBD_CDC_HandleTypeDef
*hcdc
= (USBD_CDC_HandleTypeDef
*) pdev
->pCDC_ClassData
;
719 /* Get the received data length */
720 hcdc
->RxLength
= USBD_LL_GetRxDataSize(pdev
, epnum
);
722 /* USB data will be immediately processed, this allow next USB traffic being
723 NAKed till the end of the application Xfer */
724 if (pdev
->pCDC_ClassData
!= NULL
)
726 ((USBD_CDC_ItfTypeDef
*)pdev
->pCDC_UserData
)->Receive(hcdc
->RxBuffer
, &hcdc
->RxLength
);
737 * @brief USBD_CDC_EP0_RxReady
738 * Handle EP0 Rx Ready event
739 * @param pdev: device instance
742 static uint8_t USBD_CDC_EP0_RxReady(USBD_HandleTypeDef
*pdev
)
744 USBD_CDC_HandleTypeDef
*hcdc
= (USBD_CDC_HandleTypeDef
*) pdev
->pCDC_ClassData
;
746 if ((pdev
->pCDC_UserData
!= NULL
) && (hcdc
->CmdOpCode
!= 0xFFU
))
748 ((USBD_CDC_ItfTypeDef
*)pdev
->pCDC_UserData
)->Control(hcdc
->CmdOpCode
,
749 (uint8_t *)(void *)hcdc
->data
,
750 (uint16_t)hcdc
->CmdLength
);
751 hcdc
->CmdOpCode
= 0xFFU
;
758 * @brief USBD_CDC_GetFSCfgDesc
759 * Return configuration descriptor
760 * @param speed : current device speed
761 * @param length : pointer data length
762 * @retval pointer to descriptor buffer
764 static uint8_t *USBD_CDC_GetFSCfgDesc(uint16_t *length
)
766 *length
= sizeof(USBD_CDC_CfgFSDesc
);
767 return USBD_CDC_CfgFSDesc
;
771 * @brief USBD_CDC_GetHSCfgDesc
772 * Return configuration descriptor
773 * @param speed : current device speed
774 * @param length : pointer data length
775 * @retval pointer to descriptor buffer
777 static uint8_t *USBD_CDC_GetHSCfgDesc(uint16_t *length
)
779 *length
= sizeof(USBD_CDC_CfgHSDesc
);
780 return USBD_CDC_CfgHSDesc
;
784 * @brief USBD_CDC_GetCfgDesc
785 * Return configuration descriptor
786 * @param speed : current device speed
787 * @param length : pointer data length
788 * @retval pointer to descriptor buffer
790 static uint8_t *USBD_CDC_GetOtherSpeedCfgDesc(uint16_t *length
)
792 *length
= sizeof(USBD_CDC_OtherSpeedCfgDesc
);
793 return USBD_CDC_OtherSpeedCfgDesc
;
797 * @brief DeviceQualifierDescriptor
798 * return Device Qualifier descriptor
799 * @param length : pointer data length
800 * @retval pointer to descriptor buffer
802 uint8_t *USBD_CDC_GetDeviceQualifierDescriptor(uint16_t *length
)
804 *length
= sizeof(USBD_CDC_DeviceQualifierDesc
);
805 return USBD_CDC_DeviceQualifierDesc
;
809 * @brief USBD_CDC_RegisterInterface
810 * @param pdev: device instance
811 * @param fops: CD Interface callback
814 uint8_t USBD_CDC_RegisterInterface(USBD_HandleTypeDef
*pdev
,
815 USBD_CDC_ItfTypeDef
*fops
)
817 uint8_t ret
= USBD_FAIL
;
821 pdev
->pCDC_UserData
= fops
;
829 * @brief USBD_CDC_SetTxBuffer
830 * @param pdev: device instance
831 * @param pbuff: Tx Buffer
834 uint8_t USBD_CDC_SetTxBuffer(USBD_HandleTypeDef
*pdev
,
838 USBD_CDC_HandleTypeDef
*hcdc
= (USBD_CDC_HandleTypeDef
*) pdev
->pCDC_ClassData
;
840 hcdc
->TxBuffer
= pbuff
;
841 hcdc
->TxLength
= length
;
848 * @brief USBD_CDC_SetRxBuffer
849 * @param pdev: device instance
850 * @param pbuff: Rx Buffer
853 uint8_t USBD_CDC_SetRxBuffer(USBD_HandleTypeDef
*pdev
,
856 USBD_CDC_HandleTypeDef
*hcdc
= (USBD_CDC_HandleTypeDef
*) pdev
->pCDC_ClassData
;
858 hcdc
->RxBuffer
= pbuff
;
864 * @brief USBD_CDC_TransmitPacket
865 * Transmit packet on IN endpoint
866 * @param pdev: device instance
869 uint8_t USBD_CDC_TransmitPacket(USBD_HandleTypeDef
*pdev
)
871 USBD_CDC_HandleTypeDef
*hcdc
= (USBD_CDC_HandleTypeDef
*) pdev
->pCDC_ClassData
;
873 if (pdev
->pCDC_ClassData
!= NULL
)
875 if (hcdc
->TxState
== 0U)
877 /* Tx Transfer in progress */
880 /* Update the packet total length */
881 pdev
->ep_in
[CDC_IN_EP
& 0xFU
].total_length
= hcdc
->TxLength
;
883 /* Transmit next packet */
884 USBD_LL_Transmit(pdev
, CDC_IN_EP
, hcdc
->TxBuffer
,
885 (uint16_t)hcdc
->TxLength
);
902 * @brief USBD_CDC_ReceivePacket
903 * prepare OUT Endpoint for reception
904 * @param pdev: device instance
907 uint8_t USBD_CDC_ReceivePacket(USBD_HandleTypeDef
*pdev
)
909 USBD_CDC_HandleTypeDef
*hcdc
= (USBD_CDC_HandleTypeDef
*) pdev
->pCDC_ClassData
;
911 /* Suspend or Resume USB Out process */
912 if (pdev
->pCDC_ClassData
!= NULL
)
914 if (pdev
->dev_speed
== USBD_SPEED_HIGH
)
916 /* Prepare Out endpoint to receive next packet */
917 USBD_LL_PrepareReceive(pdev
,
920 CDC_DATA_HS_OUT_PACKET_SIZE
);
924 /* Prepare Out endpoint to receive next packet */
925 USBD_LL_PrepareReceive(pdev
,
928 CDC_DATA_FS_OUT_PACKET_SIZE
);
949 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/