[H7][LIB][USB] Modify USB Library for composite device
[betaflight.git] / lib / main / STM32H7 / Middlewares / ST / STM32_USB_Device_Library / Class / CDC / Src / usbd_cdc.c
blob1f77d37ed752e8930929de9eaf7dcc16fa18569d
1 /**
2 ******************************************************************************
3 * @file usbd_cdc.c
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)
11 * - Error management
13 * @verbatim
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
37 * @endverbatim
39 ******************************************************************************
40 * @attention
42 * <h2><center>&copy; 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:
48 * www.st.com/SLA0044
50 ******************************************************************************
53 /* BSPDependencies
54 - "stm32xxxxx_{eval}{discovery}{nucleo_144}.c"
55 - "stm32xxxxx_{eval}{discovery}_io.c"
56 EndBSPDependencies */
58 /* Includes ------------------------------------------------------------------*/
59 #include "usbd_cdc.h"
60 #include "usbd_ctlreq.h"
63 /** @addtogroup STM32_USB_DEVICE_LIBRARY
64 * @{
68 /** @defgroup USBD_CDC
69 * @brief usbd core module
70 * @{
73 /** @defgroup USBD_CDC_Private_TypesDefinitions
74 * @{
76 /**
77 * @}
81 /** @defgroup USBD_CDC_Private_Defines
82 * @{
84 /**
85 * @}
89 /** @defgroup USBD_CDC_Private_Macros
90 * @{
93 /**
94 * @}
98 /** @defgroup USBD_CDC_Private_FunctionPrototypes
99 * @{
103 static uint8_t USBD_CDC_Init(USBD_HandleTypeDef *pdev,
104 uint8_t cfgidx);
106 static uint8_t USBD_CDC_DeInit(USBD_HandleTypeDef *pdev,
107 uint8_t cfgidx);
109 static uint8_t USBD_CDC_Setup(USBD_HandleTypeDef *pdev,
110 USBD_SetupReqTypedef *req);
112 static uint8_t USBD_CDC_DataIn(USBD_HandleTypeDef *pdev,
113 uint8_t epnum);
115 static uint8_t USBD_CDC_DataOut(USBD_HandleTypeDef *pdev,
116 uint8_t epnum);
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,
135 0x00,
136 0x02,
137 0x00,
138 0x00,
139 0x00,
140 0x40,
141 0x01,
142 0x00,
146 * @}
149 /** @defgroup USBD_CDC_Private_Variables
150 * @{
154 /* CDC interface class callbacks structure */
155 USBD_ClassTypeDef USBD_CDC =
157 USBD_CDC_Init,
158 USBD_CDC_DeInit,
159 USBD_CDC_Setup,
160 NULL, /* EP0_TxSent, */
161 USBD_CDC_EP0_RxReady,
162 USBD_CDC_DataIn,
163 USBD_CDC_DataOut,
164 NULL,
165 NULL,
166 NULL,
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 */
180 0x00,
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 */
206 0x01,
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 */
276 0x00,
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 */
302 0x01,
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,
369 0x00,
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 */
393 0x01,
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: */
443 0x00,
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: */
452 0x00,
453 0x00 /* bInterval */
457 * @}
460 /** @defgroup USBD_CDC_Private_Functions
461 * @{
465 * @brief USBD_CDC_Init
466 * Initialize the CDC interface
467 * @param pdev: device instance
468 * @param cfgidx: Configuration index
469 * @retval status
471 static uint8_t USBD_CDC_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
473 UNUSED(cfgidx);
475 uint8_t ret = 0U;
476 USBD_CDC_HandleTypeDef *hcdc;
478 if (pdev->dev_speed == USBD_SPEED_HIGH)
480 /* Open EP IN */
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;
486 /* Open EP OUT */
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;
493 else
495 /* Open EP IN */
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;
501 /* Open EP OUT */
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)
515 ret = 1U;
517 else
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 */
525 hcdc->TxState = 0U;
526 hcdc->RxState = 0U;
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);
534 else
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);
541 return ret;
545 * @brief USBD_CDC_Init
546 * DeInitialize the CDC layer
547 * @param pdev: device instance
548 * @param cfgidx: Configuration index
549 * @retval status
551 static uint8_t USBD_CDC_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
553 UNUSED(cfgidx);
555 uint8_t ret = 0U;
557 /* Close EP IN */
558 USBD_LL_CloseEP(pdev, CDC_IN_EP);
559 pdev->ep_in[CDC_IN_EP & 0xFU].is_used = 0U;
561 /* Close EP OUT */
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;
577 return ret;
581 * @brief USBD_CDC_Setup
582 * Handle the CDC specific requests
583 * @param pdev: instance
584 * @param req: usb requests
585 * @retval status
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;
591 uint8_t ifalt = 0U;
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 :
598 if (req->wLength)
600 if (req->bmRequest & 0x80U)
602 ((USBD_CDC_ItfTypeDef *)pdev->pCDC_UserData)->Control(req->bRequest,
603 (uint8_t *)(void *)hcdc->data,
604 req->wLength);
606 USBD_CtlSendData(pdev, (uint8_t *)(void *)hcdc->data, req->wLength);
608 else
610 hcdc->CmdOpCode = req->bRequest;
611 hcdc->CmdLength = (uint8_t)req->wLength;
613 USBD_CtlPrepareRx(pdev, (uint8_t *)(void *)hcdc->data, req->wLength);
616 else
618 ((USBD_CDC_ItfTypeDef *)pdev->pCDC_UserData)->Control(req->bRequest,
619 (uint8_t *)(void *)req, 0U);
621 break;
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);
631 else
633 USBD_CtlError(pdev, req);
634 ret = USBD_FAIL;
636 break;
638 case USB_REQ_GET_INTERFACE:
639 if (pdev->dev_state == USBD_STATE_CONFIGURED)
641 USBD_CtlSendData(pdev, &ifalt, 1U);
643 else
645 USBD_CtlError(pdev, req);
646 ret = USBD_FAIL;
648 break;
650 case USB_REQ_SET_INTERFACE:
651 if (pdev->dev_state != USBD_STATE_CONFIGURED)
653 USBD_CtlError(pdev, req);
654 ret = USBD_FAIL;
656 break;
658 default:
659 USBD_CtlError(pdev, req);
660 ret = USBD_FAIL;
661 break;
663 break;
665 default:
666 USBD_CtlError(pdev, req);
667 ret = USBD_FAIL;
668 break;
671 return ret;
675 * @brief USBD_CDC_DataIn
676 * Data sent on non-control IN endpoint
677 * @param pdev: device instance
678 * @param epnum: endpoint number
679 * @retval status
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;
693 /* Send ZLP */
694 USBD_LL_Transmit(pdev, epnum, NULL, 0U);
696 else
698 hcdc->TxState = 0U;
700 return USBD_OK;
702 else
704 return USBD_FAIL;
709 * @brief USBD_CDC_DataOut
710 * Data received on non-control Out endpoint
711 * @param pdev: device instance
712 * @param epnum: endpoint number
713 * @retval status
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);
728 return USBD_OK;
730 else
732 return USBD_FAIL;
737 * @brief USBD_CDC_EP0_RxReady
738 * Handle EP0 Rx Ready event
739 * @param pdev: device instance
740 * @retval status
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;
754 return USBD_OK;
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
812 * @retval status
814 uint8_t USBD_CDC_RegisterInterface(USBD_HandleTypeDef *pdev,
815 USBD_CDC_ItfTypeDef *fops)
817 uint8_t ret = USBD_FAIL;
819 if (fops != NULL)
821 pdev->pCDC_UserData = fops;
822 ret = USBD_OK;
825 return ret;
829 * @brief USBD_CDC_SetTxBuffer
830 * @param pdev: device instance
831 * @param pbuff: Tx Buffer
832 * @retval status
834 uint8_t USBD_CDC_SetTxBuffer(USBD_HandleTypeDef *pdev,
835 uint8_t *pbuff,
836 uint16_t length)
838 USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef *) pdev->pCDC_ClassData;
840 hcdc->TxBuffer = pbuff;
841 hcdc->TxLength = length;
843 return USBD_OK;
848 * @brief USBD_CDC_SetRxBuffer
849 * @param pdev: device instance
850 * @param pbuff: Rx Buffer
851 * @retval status
853 uint8_t USBD_CDC_SetRxBuffer(USBD_HandleTypeDef *pdev,
854 uint8_t *pbuff)
856 USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef *) pdev->pCDC_ClassData;
858 hcdc->RxBuffer = pbuff;
860 return USBD_OK;
864 * @brief USBD_CDC_TransmitPacket
865 * Transmit packet on IN endpoint
866 * @param pdev: device instance
867 * @retval status
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 */
878 hcdc->TxState = 1U;
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);
887 return USBD_OK;
889 else
891 return USBD_BUSY;
894 else
896 return USBD_FAIL;
902 * @brief USBD_CDC_ReceivePacket
903 * prepare OUT Endpoint for reception
904 * @param pdev: device instance
905 * @retval status
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,
918 CDC_OUT_EP,
919 hcdc->RxBuffer,
920 CDC_DATA_HS_OUT_PACKET_SIZE);
922 else
924 /* Prepare Out endpoint to receive next packet */
925 USBD_LL_PrepareReceive(pdev,
926 CDC_OUT_EP,
927 hcdc->RxBuffer,
928 CDC_DATA_FS_OUT_PACKET_SIZE);
930 return USBD_OK;
932 else
934 return USBD_FAIL;
938 * @}
942 * @}
946 * @}
949 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/