STAR
Cal STAR — firmware, DAQ server, and engine design
Loading...
Searching...
No Matches
usbd_cdc.c
Go to the documentation of this file.
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
12 *
13 ******************************************************************************
14 * @attention
15 *
16 * Copyright (c) 2015 STMicroelectronics.
17 * All rights reserved.
18 *
19 * This software is licensed under terms that can be found in the LICENSE file
20 * in the root directory of this software component.
21 * If no LICENSE file comes with this software, it is provided AS-IS.
22 *
23 ******************************************************************************
24 * @verbatim
25 *
26 * ===================================================================
27 * CDC Class Driver Description
28 * ===================================================================
29 * This driver manages the "Universal Serial Bus Class Definitions for Communications Devices
30 * Revision 1.2 November 16, 2007" and the sub-protocol specification of "Universal Serial Bus
31 * Communications Class Subclass Specification for PSTN Devices Revision 1.2 February 9, 2007"
32 * This driver implements the following aspects of the specification:
33 * - Device descriptor management
34 * - Configuration descriptor management
35 * - Enumeration as CDC device with 2 data endpoints (IN and OUT) and 1 command endpoint (IN)
36 * - Requests management (as described in section 6.2 in specification)
37 * - Abstract Control Model compliant
38 * - Union Functional collection (using 1 IN endpoint for control)
39 * - Data interface class
40 *
41 * These aspects may be enriched or modified for a specific user application.
42 *
43 * This driver doesn't implement the following aspects of the specification
44 * (but it is possible to manage these features with some modifications on this driver):
45 * - Any class-specific aspect relative to communication classes should be managed by user application.
46 * - All communication classes other than PSTN are not managed
47 *
48 * @endverbatim
49 *
50 ******************************************************************************
51 */
52
53/* BSPDependencies
54- "stm32xxxxx_{eval}{discovery}{nucleo_144}.c"
55- "stm32xxxxx_{eval}{discovery}_io.c"
56EndBSPDependencies */
57
58/* Includes ------------------------------------------------------------------*/
59#include "usbd_cdc.h"
60#include "usbd_ctlreq.h"
61
62
63/** @addtogroup STM32_USB_DEVICE_LIBRARY
64 * @{
65 */
66
67
68/** @defgroup USBD_CDC
69 * @brief usbd core module
70 * @{
71 */
72
73/** @defgroup USBD_CDC_Private_TypesDefinitions
74 * @{
75 */
76/**
77 * @}
78 */
79
80
81/** @defgroup USBD_CDC_Private_Defines
82 * @{
83 */
84/**
85 * @}
86 */
87
88
89/** @defgroup USBD_CDC_Private_Macros
90 * @{
91 */
92
93/**
94 * @}
95 */
96
97
98/** @defgroup USBD_CDC_Private_FunctionPrototypes
99 * @{
100 */
101
102static uint8_t USBD_CDC_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx);
103static uint8_t USBD_CDC_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx);
104static uint8_t USBD_CDC_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req);
105static uint8_t USBD_CDC_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum);
106static uint8_t USBD_CDC_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum);
107static uint8_t USBD_CDC_EP0_RxReady(USBD_HandleTypeDef *pdev);
108#ifndef USE_USBD_COMPOSITE
109static uint8_t *USBD_CDC_GetFSCfgDesc(uint16_t *length);
110static uint8_t *USBD_CDC_GetHSCfgDesc(uint16_t *length);
111static uint8_t *USBD_CDC_GetOtherSpeedCfgDesc(uint16_t *length);
112uint8_t *USBD_CDC_GetDeviceQualifierDescriptor(uint16_t *length);
113#endif /* USE_USBD_COMPOSITE */
114
115#ifndef USE_USBD_COMPOSITE
116/* USB Standard Device Descriptor */
117__ALIGN_BEGIN static uint8_t USBD_CDC_DeviceQualifierDesc[USB_LEN_DEV_QUALIFIER_DESC] __ALIGN_END =
118{
121 0x00,
122 0x02,
123 0x00,
124 0x00,
125 0x00,
126 0x40,
127 0x01,
128 0x00,
129};
130#endif /* USE_USBD_COMPOSITE */
131/**
132 * @}
133 */
134
135/** @defgroup USBD_CDC_Private_Variables
136 * @{
137 */
138
139
140/* CDC interface class callbacks structure */
142{
146 NULL, /* EP0_TxSent */
150 NULL,
151 NULL,
152 NULL,
153#ifdef USE_USBD_COMPOSITE
154 NULL,
155 NULL,
156 NULL,
157 NULL,
158#else
163#endif /* USE_USBD_COMPOSITE */
164#if (USBD_SUPPORT_USER_STRING_DESC == 1U)
165 NULL,
166#endif /* USBD_SUPPORT_USER_STRING_DESC */
167};
168
169#ifndef USE_USBD_COMPOSITE
170/* USB CDC device Configuration Descriptor */
171__ALIGN_BEGIN static uint8_t USBD_CDC_CfgDesc[USB_CDC_CONFIG_DESC_SIZ] __ALIGN_END =
172{
173 /* Configuration Descriptor */
174 0x09, /* bLength: Configuration Descriptor size */
175 USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */
176 USB_CDC_CONFIG_DESC_SIZ, /* wTotalLength */
177 0x00,
178 0x02, /* bNumInterfaces: 2 interfaces */
179 0x01, /* bConfigurationValue: Configuration value */
180 0x00, /* iConfiguration: Index of string descriptor
181 describing the configuration */
182#if (USBD_SELF_POWERED == 1U)
183 0xC0, /* bmAttributes: Bus Powered according to user configuration */
184#else
185 0x80, /* bmAttributes: Bus Powered according to user configuration */
186#endif /* USBD_SELF_POWERED */
187 USBD_MAX_POWER, /* MaxPower (mA) */
188
189 /*---------------------------------------------------------------------------*/
190
191 /* Interface Descriptor */
192 0x09, /* bLength: Interface Descriptor size */
193 USB_DESC_TYPE_INTERFACE, /* bDescriptorType: Interface */
194 /* Interface descriptor type */
195 0x00, /* bInterfaceNumber: Number of Interface */
196 0x00, /* bAlternateSetting: Alternate setting */
197 0x01, /* bNumEndpoints: One endpoint used */
198 0x02, /* bInterfaceClass: Communication Interface Class */
199 0x02, /* bInterfaceSubClass: Abstract Control Model */
200 0x01, /* bInterfaceProtocol: Common AT commands */
201 0x00, /* iInterface */
202
203 /* Header Functional Descriptor */
204 0x05, /* bLength: Endpoint Descriptor size */
205 0x24, /* bDescriptorType: CS_INTERFACE */
206 0x00, /* bDescriptorSubtype: Header Func Desc */
207 0x10, /* bcdCDC: spec release number */
208 0x01,
209
210 /* Call Management Functional Descriptor */
211 0x05, /* bFunctionLength */
212 0x24, /* bDescriptorType: CS_INTERFACE */
213 0x01, /* bDescriptorSubtype: Call Management Func Desc */
214 0x00, /* bmCapabilities: D0+D1 */
215 0x01, /* bDataInterface */
216
217 /* ACM Functional Descriptor */
218 0x04, /* bFunctionLength */
219 0x24, /* bDescriptorType: CS_INTERFACE */
220 0x02, /* bDescriptorSubtype: Abstract Control Management desc */
221 0x02, /* bmCapabilities */
222
223 /* Union Functional Descriptor */
224 0x05, /* bFunctionLength */
225 0x24, /* bDescriptorType: CS_INTERFACE */
226 0x06, /* bDescriptorSubtype: Union func desc */
227 0x00, /* bMasterInterface: Communication class interface */
228 0x01, /* bSlaveInterface0: Data Class Interface */
229
230 /* Endpoint 2 Descriptor */
231 0x07, /* bLength: Endpoint Descriptor size */
232 USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
233 CDC_CMD_EP, /* bEndpointAddress */
234 0x03, /* bmAttributes: Interrupt */
235 LOBYTE(CDC_CMD_PACKET_SIZE), /* wMaxPacketSize */
237 CDC_FS_BINTERVAL, /* bInterval */
238 /*---------------------------------------------------------------------------*/
239
240 /* Data class interface descriptor */
241 0x09, /* bLength: Endpoint Descriptor size */
242 USB_DESC_TYPE_INTERFACE, /* bDescriptorType: */
243 0x01, /* bInterfaceNumber: Number of Interface */
244 0x00, /* bAlternateSetting: Alternate setting */
245 0x02, /* bNumEndpoints: Two endpoints used */
246 0x0A, /* bInterfaceClass: CDC */
247 0x00, /* bInterfaceSubClass */
248 0x00, /* bInterfaceProtocol */
249 0x00, /* iInterface */
250
251 /* Endpoint OUT Descriptor */
252 0x07, /* bLength: Endpoint Descriptor size */
253 USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
254 CDC_OUT_EP, /* bEndpointAddress */
255 0x02, /* bmAttributes: Bulk */
256 LOBYTE(CDC_DATA_FS_MAX_PACKET_SIZE), /* wMaxPacketSize */
258 0x00, /* bInterval */
259
260 /* Endpoint IN Descriptor */
261 0x07, /* bLength: Endpoint Descriptor size */
262 USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
263 CDC_IN_EP, /* bEndpointAddress */
264 0x02, /* bmAttributes: Bulk */
265 LOBYTE(CDC_DATA_FS_MAX_PACKET_SIZE), /* wMaxPacketSize */
267 0x00 /* bInterval */
268};
269#endif /* USE_USBD_COMPOSITE */
270
271static uint8_t CDCInEpAdd = CDC_IN_EP;
272static uint8_t CDCOutEpAdd = CDC_OUT_EP;
273static uint8_t CDCCmdEpAdd = CDC_CMD_EP;
274
275/**
276 * @}
277 */
278
279/** @defgroup USBD_CDC_Private_Functions
280 * @{
281 */
282
283/**
284 * @brief USBD_CDC_Init
285 * Initialize the CDC interface
286 * @param pdev: device instance
287 * @param cfgidx: Configuration index
288 * @retval status
289 */
290static uint8_t USBD_CDC_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
291{
292 UNUSED(cfgidx);
294
296
297 if (hcdc == NULL)
298 {
299 pdev->pClassDataCmsit[pdev->classId] = NULL;
300 return (uint8_t)USBD_EMEM;
301 }
302
303 (void)USBD_memset(hcdc, 0, sizeof(USBD_CDC_HandleTypeDef));
304
305 pdev->pClassDataCmsit[pdev->classId] = (void *)hcdc;
306 pdev->pClassData = pdev->pClassDataCmsit[pdev->classId];
307
308#ifdef USE_USBD_COMPOSITE
309 /* Get the Endpoints addresses allocated for this class instance */
310 CDCInEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_BULK, (uint8_t)pdev->classId);
311 CDCOutEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_OUT, USBD_EP_TYPE_BULK, (uint8_t)pdev->classId);
312 CDCCmdEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_INTR, (uint8_t)pdev->classId);
313#endif /* USE_USBD_COMPOSITE */
314
315 if (pdev->dev_speed == USBD_SPEED_HIGH)
316 {
317 /* Open EP IN */
320
321 pdev->ep_in[CDCInEpAdd & 0xFU].is_used = 1U;
322
323 /* Open EP OUT */
326
327 pdev->ep_out[CDCOutEpAdd & 0xFU].is_used = 1U;
328
329 /* Set bInterval for CDC CMD Endpoint */
331 }
332 else
333 {
334 /* Open EP IN */
337
338 pdev->ep_in[CDCInEpAdd & 0xFU].is_used = 1U;
339
340 /* Open EP OUT */
343
344 pdev->ep_out[CDCOutEpAdd & 0xFU].is_used = 1U;
345
346 /* Set bInterval for CMD Endpoint */
348 }
349
350 /* Open Command IN EP */
352 pdev->ep_in[CDCCmdEpAdd & 0xFU].is_used = 1U;
353
354 hcdc->RxBuffer = NULL;
355
356 /* Init physical Interface components */
357 ((USBD_CDC_ItfTypeDef *)pdev->pUserData[pdev->classId])->Init();
358
359 /* Init Xfer states */
360 hcdc->TxState = 0U;
361 hcdc->RxState = 0U;
362
363 if (hcdc->RxBuffer == NULL)
364 {
365 return (uint8_t)USBD_EMEM;
366 }
367
368 if (pdev->dev_speed == USBD_SPEED_HIGH)
369 {
370 /* Prepare Out endpoint to receive next packet */
373 }
374 else
375 {
376 /* Prepare Out endpoint to receive next packet */
379 }
380
381 return (uint8_t)USBD_OK;
382}
383
384/**
385 * @brief USBD_CDC_Init
386 * DeInitialize the CDC layer
387 * @param pdev: device instance
388 * @param cfgidx: Configuration index
389 * @retval status
390 */
391static uint8_t USBD_CDC_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
392{
393 UNUSED(cfgidx);
394
395
396#ifdef USE_USBD_COMPOSITE
397 /* Get the Endpoints addresses allocated for this CDC class instance */
398 CDCInEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_BULK, (uint8_t)pdev->classId);
399 CDCOutEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_OUT, USBD_EP_TYPE_BULK, (uint8_t)pdev->classId);
400 CDCCmdEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_INTR, (uint8_t)pdev->classId);
401#endif /* USE_USBD_COMPOSITE */
402
403 /* Close EP IN */
404 (void)USBD_LL_CloseEP(pdev, CDCInEpAdd);
405 pdev->ep_in[CDCInEpAdd & 0xFU].is_used = 0U;
406
407 /* Close EP OUT */
408 (void)USBD_LL_CloseEP(pdev, CDCOutEpAdd);
409 pdev->ep_out[CDCOutEpAdd & 0xFU].is_used = 0U;
410
411 /* Close Command IN EP */
412 (void)USBD_LL_CloseEP(pdev, CDCCmdEpAdd);
413 pdev->ep_in[CDCCmdEpAdd & 0xFU].is_used = 0U;
414 pdev->ep_in[CDCCmdEpAdd & 0xFU].bInterval = 0U;
415
416 /* DeInit physical Interface components */
417 if (pdev->pClassDataCmsit[pdev->classId] != NULL)
418 {
419 ((USBD_CDC_ItfTypeDef *)pdev->pUserData[pdev->classId])->DeInit();
420 (void)USBD_free(pdev->pClassDataCmsit[pdev->classId]);
421 pdev->pClassDataCmsit[pdev->classId] = NULL;
422 pdev->pClassData = NULL;
423 }
424
425 return (uint8_t)USBD_OK;
426}
427
428/**
429 * @brief USBD_CDC_Setup
430 * Handle the CDC specific requests
431 * @param pdev: instance
432 * @param req: usb requests
433 * @retval status
434 */
437{
439 uint16_t len;
440 uint8_t ifalt = 0U;
441 uint16_t status_info = 0U;
443
444 if (hcdc == NULL)
445 {
446 return (uint8_t)USBD_FAIL;
447 }
448
449 switch (req->bmRequest & USB_REQ_TYPE_MASK)
450 {
452 if (req->wLength != 0U)
453 {
454 if ((req->bmRequest & 0x80U) != 0U)
455 {
456 ((USBD_CDC_ItfTypeDef *)pdev->pUserData[pdev->classId])->Control(req->bRequest,
457 (uint8_t *)hcdc->data,
458 req->wLength);
459
460 len = MIN(CDC_REQ_MAX_DATA_SIZE, req->wLength);
461 (void)USBD_CtlSendData(pdev, (uint8_t *)hcdc->data, len);
462 }
463 else
464 {
465 hcdc->CmdOpCode = req->bRequest;
466 hcdc->CmdLength = (uint8_t)MIN(req->wLength, USB_MAX_EP0_SIZE);
467
468 (void)USBD_CtlPrepareRx(pdev, (uint8_t *)hcdc->data, hcdc->CmdLength);
469 }
470 }
471 else
472 {
473 ((USBD_CDC_ItfTypeDef *)pdev->pUserData[pdev->classId])->Control(req->bRequest,
474 (uint8_t *)req, 0U);
475 }
476 break;
477
479 switch (req->bRequest)
480 {
482 if (pdev->dev_state == USBD_STATE_CONFIGURED)
483 {
484 (void)USBD_CtlSendData(pdev, (uint8_t *)&status_info, 2U);
485 }
486 else
487 {
488 USBD_CtlError(pdev, req);
489 ret = USBD_FAIL;
490 }
491 break;
492
494 if (pdev->dev_state == USBD_STATE_CONFIGURED)
495 {
496 (void)USBD_CtlSendData(pdev, &ifalt, 1U);
497 }
498 else
499 {
500 USBD_CtlError(pdev, req);
501 ret = USBD_FAIL;
502 }
503 break;
504
506 if (pdev->dev_state != USBD_STATE_CONFIGURED)
507 {
508 USBD_CtlError(pdev, req);
509 ret = USBD_FAIL;
510 }
511 break;
512
514 break;
515
516 default:
517 USBD_CtlError(pdev, req);
518 ret = USBD_FAIL;
519 break;
520 }
521 break;
522
523 default:
524 USBD_CtlError(pdev, req);
525 ret = USBD_FAIL;
526 break;
527 }
528
529 return (uint8_t)ret;
530}
531
532/**
533 * @brief USBD_CDC_DataIn
534 * Data sent on non-control IN endpoint
535 * @param pdev: device instance
536 * @param epnum: endpoint number
537 * @retval status
538 */
539static uint8_t USBD_CDC_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum)
540{
542 PCD_HandleTypeDef *hpcd = (PCD_HandleTypeDef *)pdev->pData;
543
544 if (pdev->pClassDataCmsit[pdev->classId] == NULL)
545 {
546 return (uint8_t)USBD_FAIL;
547 }
548
549 hcdc = (USBD_CDC_HandleTypeDef *)pdev->pClassDataCmsit[pdev->classId];
550
551 if ((pdev->ep_in[epnum & 0xFU].total_length > 0U) &&
552 ((pdev->ep_in[epnum & 0xFU].total_length % hpcd->IN_ep[epnum & 0xFU].maxpacket) == 0U))
553 {
554 /* Update the packet total length */
555 pdev->ep_in[epnum & 0xFU].total_length = 0U;
556
557 /* Send ZLP */
558 (void)USBD_LL_Transmit(pdev, epnum, NULL, 0U);
559 }
560 else
561 {
562 hcdc->TxState = 0U;
563
564 if (((USBD_CDC_ItfTypeDef *)pdev->pUserData[pdev->classId])->TransmitCplt != NULL)
565 {
566 ((USBD_CDC_ItfTypeDef *)pdev->pUserData[pdev->classId])->TransmitCplt(hcdc->TxBuffer, &hcdc->TxLength, epnum);
567 }
568 }
569
570 return (uint8_t)USBD_OK;
571}
572
573/**
574 * @brief USBD_CDC_DataOut
575 * Data received on non-control Out endpoint
576 * @param pdev: device instance
577 * @param epnum: endpoint number
578 * @retval status
579 */
580static uint8_t USBD_CDC_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum)
581{
583
584 if (pdev->pClassDataCmsit[pdev->classId] == NULL)
585 {
586 return (uint8_t)USBD_FAIL;
587 }
588
589 /* Get the received data length */
590 hcdc->RxLength = USBD_LL_GetRxDataSize(pdev, epnum);
591
592 /* USB data will be immediately processed, this allow next USB traffic being
593 NAKed till the end of the application Xfer */
594
595 ((USBD_CDC_ItfTypeDef *)pdev->pUserData[pdev->classId])->Receive(hcdc->RxBuffer, &hcdc->RxLength);
596
597 return (uint8_t)USBD_OK;
598}
599
600/**
601 * @brief USBD_CDC_EP0_RxReady
602 * Handle EP0 Rx Ready event
603 * @param pdev: device instance
604 * @retval status
605 */
607{
609
610 if (hcdc == NULL)
611 {
612 return (uint8_t)USBD_FAIL;
613 }
614
615 if ((pdev->pUserData[pdev->classId] != NULL) && (hcdc->CmdOpCode != 0xFFU))
616 {
617 ((USBD_CDC_ItfTypeDef *)pdev->pUserData[pdev->classId])->Control(hcdc->CmdOpCode,
618 (uint8_t *)hcdc->data,
619 (uint16_t)hcdc->CmdLength);
620 hcdc->CmdOpCode = 0xFFU;
621 }
622
623 return (uint8_t)USBD_OK;
624}
625#ifndef USE_USBD_COMPOSITE
626/**
627 * @brief USBD_CDC_GetFSCfgDesc
628 * Return configuration descriptor
629 * @param length : pointer data length
630 * @retval pointer to descriptor buffer
631 */
632static uint8_t *USBD_CDC_GetFSCfgDesc(uint16_t *length)
633{
634 USBD_EpDescTypeDef *pEpCmdDesc = USBD_GetEpDesc(USBD_CDC_CfgDesc, CDC_CMD_EP);
635 USBD_EpDescTypeDef *pEpOutDesc = USBD_GetEpDesc(USBD_CDC_CfgDesc, CDC_OUT_EP);
636 USBD_EpDescTypeDef *pEpInDesc = USBD_GetEpDesc(USBD_CDC_CfgDesc, CDC_IN_EP);
637
638 if (pEpCmdDesc != NULL)
639 {
640 pEpCmdDesc->bInterval = CDC_FS_BINTERVAL;
641 }
642
643 if (pEpOutDesc != NULL)
644 {
645 pEpOutDesc->wMaxPacketSize = CDC_DATA_FS_MAX_PACKET_SIZE;
646 }
647
648 if (pEpInDesc != NULL)
649 {
650 pEpInDesc->wMaxPacketSize = CDC_DATA_FS_MAX_PACKET_SIZE;
651 }
652
653 *length = (uint16_t)sizeof(USBD_CDC_CfgDesc);
654 return USBD_CDC_CfgDesc;
655}
656
657/**
658 * @brief USBD_CDC_GetHSCfgDesc
659 * Return configuration descriptor
660 * @param length : pointer data length
661 * @retval pointer to descriptor buffer
662 */
663static uint8_t *USBD_CDC_GetHSCfgDesc(uint16_t *length)
664{
665 USBD_EpDescTypeDef *pEpCmdDesc = USBD_GetEpDesc(USBD_CDC_CfgDesc, CDC_CMD_EP);
666 USBD_EpDescTypeDef *pEpOutDesc = USBD_GetEpDesc(USBD_CDC_CfgDesc, CDC_OUT_EP);
667 USBD_EpDescTypeDef *pEpInDesc = USBD_GetEpDesc(USBD_CDC_CfgDesc, CDC_IN_EP);
668
669 if (pEpCmdDesc != NULL)
670 {
671 pEpCmdDesc->bInterval = CDC_HS_BINTERVAL;
672 }
673
674 if (pEpOutDesc != NULL)
675 {
676 pEpOutDesc->wMaxPacketSize = CDC_DATA_HS_MAX_PACKET_SIZE;
677 }
678
679 if (pEpInDesc != NULL)
680 {
681 pEpInDesc->wMaxPacketSize = CDC_DATA_HS_MAX_PACKET_SIZE;
682 }
683
684 *length = (uint16_t)sizeof(USBD_CDC_CfgDesc);
685 return USBD_CDC_CfgDesc;
686}
687
688/**
689 * @brief USBD_CDC_GetOtherSpeedCfgDesc
690 * Return configuration descriptor
691 * @param length : pointer data length
692 * @retval pointer to descriptor buffer
693 */
694static uint8_t *USBD_CDC_GetOtherSpeedCfgDesc(uint16_t *length)
695{
696 USBD_EpDescTypeDef *pEpCmdDesc = USBD_GetEpDesc(USBD_CDC_CfgDesc, CDC_CMD_EP);
697 USBD_EpDescTypeDef *pEpOutDesc = USBD_GetEpDesc(USBD_CDC_CfgDesc, CDC_OUT_EP);
698 USBD_EpDescTypeDef *pEpInDesc = USBD_GetEpDesc(USBD_CDC_CfgDesc, CDC_IN_EP);
699
700 if (pEpCmdDesc != NULL)
701 {
702 pEpCmdDesc->bInterval = CDC_FS_BINTERVAL;
703 }
704
705 if (pEpOutDesc != NULL)
706 {
707 pEpOutDesc->wMaxPacketSize = CDC_DATA_FS_MAX_PACKET_SIZE;
708 }
709
710 if (pEpInDesc != NULL)
711 {
712 pEpInDesc->wMaxPacketSize = CDC_DATA_FS_MAX_PACKET_SIZE;
713 }
714
715 *length = (uint16_t)sizeof(USBD_CDC_CfgDesc);
716 return USBD_CDC_CfgDesc;
717}
718
719/**
720 * @brief USBD_CDC_GetDeviceQualifierDescriptor
721 * return Device Qualifier descriptor
722 * @param length : pointer data length
723 * @retval pointer to descriptor buffer
724 */
726{
727 *length = (uint16_t)sizeof(USBD_CDC_DeviceQualifierDesc);
728
729 return USBD_CDC_DeviceQualifierDesc;
730}
731#endif /* USE_USBD_COMPOSITE */
732/**
733 * @brief USBD_CDC_RegisterInterface
734 * @param pdev: device instance
735 * @param fops: CD Interface callback
736 * @retval status
737 */
740{
741 if (fops == NULL)
742 {
743 return (uint8_t)USBD_FAIL;
744 }
745
746 pdev->pUserData[pdev->classId] = fops;
747
748 return (uint8_t)USBD_OK;
749}
750
751
752/**
753 * @brief USBD_CDC_SetTxBuffer
754 * @param pdev: device instance
755 * @param pbuff: Tx Buffer
756 * @param length: length of data to be sent
757 * @param ClassId: The Class ID
758 * @retval status
759 */
760#ifdef USE_USBD_COMPOSITE
762 uint8_t *pbuff, uint32_t length, uint8_t ClassId)
763{
765#else
767 uint8_t *pbuff, uint32_t length)
768{
770#endif /* USE_USBD_COMPOSITE */
771
772 if (hcdc == NULL)
773 {
774 return (uint8_t)USBD_FAIL;
775 }
776
777 hcdc->TxBuffer = pbuff;
778 hcdc->TxLength = length;
779
780 return (uint8_t)USBD_OK;
781}
782
783/**
784 * @brief USBD_CDC_SetRxBuffer
785 * @param pdev: device instance
786 * @param pbuff: Rx Buffer
787 * @retval status
788 */
789uint8_t USBD_CDC_SetRxBuffer(USBD_HandleTypeDef *pdev, uint8_t *pbuff)
790{
792
793 if (hcdc == NULL)
794 {
795 return (uint8_t)USBD_FAIL;
796 }
797
798 hcdc->RxBuffer = pbuff;
799
800 return (uint8_t)USBD_OK;
801}
802
803
804/**
805 * @brief USBD_CDC_TransmitPacket
806 * Transmit packet on IN endpoint
807 * @param pdev: device instance
808 * @param ClassId: The Class ID
809 * @retval status
810 */
811#ifdef USE_USBD_COMPOSITE
812uint8_t USBD_CDC_TransmitPacket(USBD_HandleTypeDef *pdev, uint8_t ClassId)
813{
815#else
817{
819#endif /* USE_USBD_COMPOSITE */
820
822
823#ifdef USE_USBD_COMPOSITE
824 /* Get the Endpoints addresses allocated for this class instance */
825 CDCInEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_IN, USBD_EP_TYPE_BULK, ClassId);
826#endif /* USE_USBD_COMPOSITE */
827
828 if (hcdc == NULL)
829 {
830 return (uint8_t)USBD_FAIL;
831 }
832
833 if (hcdc->TxState == 0U)
834 {
835 /* Tx Transfer in progress */
836 hcdc->TxState = 1U;
837
838 /* Update the packet total length */
839 pdev->ep_in[CDCInEpAdd & 0xFU].total_length = hcdc->TxLength;
840
841 /* Transmit next packet */
842 (void)USBD_LL_Transmit(pdev, CDCInEpAdd, hcdc->TxBuffer, hcdc->TxLength);
843
844 ret = USBD_OK;
845 }
846
847 return (uint8_t)ret;
848}
849
850/**
851 * @brief USBD_CDC_ReceivePacket
852 * prepare OUT Endpoint for reception
853 * @param pdev: device instance
854 * @retval status
855 */
857{
859
860#ifdef USE_USBD_COMPOSITE
861 /* Get the Endpoints addresses allocated for this class instance */
862 CDCOutEpAdd = USBD_CoreGetEPAdd(pdev, USBD_EP_OUT, USBD_EP_TYPE_BULK, (uint8_t)pdev->classId);
863#endif /* USE_USBD_COMPOSITE */
864
865 if (pdev->pClassDataCmsit[pdev->classId] == NULL)
866 {
867 return (uint8_t)USBD_FAIL;
868 }
869
870 if (pdev->dev_speed == USBD_SPEED_HIGH)
871 {
872 /* Prepare Out endpoint to receive next packet */
875 }
876 else
877 {
878 /* Prepare Out endpoint to receive next packet */
881 }
882
883 return (uint8_t)USBD_OK;
884}
885/**
886 * @}
887 */
888
889/**
890 * @}
891 */
892
893/**
894 * @}
895 */
896
static uint8_t * USBD_CDC_GetFSCfgDesc(uint16_t *length)
USBD_CDC_GetFSCfgDesc Return configuration descriptor.
Definition usbd_cdc.c:632
static uint8_t USBD_CDC_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
USBD_CDC_Init DeInitialize the CDC layer.
Definition usbd_cdc.c:391
static uint8_t USBD_CDC_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum)
USBD_CDC_DataIn Data sent on non-control IN endpoint.
Definition usbd_cdc.c:539
static uint8_t USBD_CDC_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum)
USBD_CDC_DataOut Data received on non-control Out endpoint.
Definition usbd_cdc.c:580
static uint8_t USBD_CDC_EP0_RxReady(USBD_HandleTypeDef *pdev)
USBD_CDC_EP0_RxReady Handle EP0 Rx Ready event.
Definition usbd_cdc.c:606
static uint8_t USBD_CDC_Setup(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req)
USBD_CDC_Setup Handle the CDC specific requests.
Definition usbd_cdc.c:435
uint8_t * USBD_CDC_GetDeviceQualifierDescriptor(uint16_t *length)
USBD_CDC_GetDeviceQualifierDescriptor return Device Qualifier descriptor.
Definition usbd_cdc.c:725
static uint8_t * USBD_CDC_GetOtherSpeedCfgDesc(uint16_t *length)
USBD_CDC_GetOtherSpeedCfgDesc Return configuration descriptor.
Definition usbd_cdc.c:694
static uint8_t USBD_CDC_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
USBD_CDC_Init Initialize the CDC interface.
Definition usbd_cdc.c:290
static uint8_t * USBD_CDC_GetHSCfgDesc(uint16_t *length)
USBD_CDC_GetHSCfgDesc Return configuration descriptor.
Definition usbd_cdc.c:663
uint8_t USBD_CDC_RegisterInterface(USBD_HandleTypeDef *pdev, USBD_CDC_ItfTypeDef *fops)
USBD_CDC_RegisterInterface.
Definition usbd_cdc.c:738
uint8_t USBD_CDC_ReceivePacket(USBD_HandleTypeDef *pdev)
USBD_CDC_ReceivePacket prepare OUT Endpoint for reception.
Definition usbd_cdc.c:856
uint8_t USBD_CDC_SetRxBuffer(USBD_HandleTypeDef *pdev, uint8_t *pbuff)
USBD_CDC_SetRxBuffer.
Definition usbd_cdc.c:789
uint8_t USBD_CDC_TransmitPacket(USBD_HandleTypeDef *pdev)
USBD_CDC_TransmitPacket Transmit packet on IN endpoint.
Definition usbd_cdc.c:816
uint8_t USBD_CDC_SetTxBuffer(USBD_HandleTypeDef *pdev, uint8_t *pbuff, uint32_t length)
USBD_CDC_SetTxBuffer.
Definition usbd_cdc.c:766
static uint8_t CDCCmdEpAdd
Definition usbd_cdc.c:273
static uint8_t CDCOutEpAdd
Definition usbd_cdc.c:272
static uint8_t CDCInEpAdd
Definition usbd_cdc.c:271
#define USBD_malloc
Alias for memory allocation.
Definition usbd_conf.h:94
#define USBD_free
Alias for memory release.
Definition usbd_conf.h:97
#define USBD_memset
Alias for memory set.
Definition usbd_conf.h:100
USBD_StatusTypeDef USBD_LL_Transmit(USBD_HandleTypeDef *pdev, uint8_t ep_addr, uint8_t *pbuf, uint32_t size)
Transmits data over an endpoint.
Definition usbd_conf.c:560
USBD_StatusTypeDef USBD_LL_PrepareReceive(USBD_HandleTypeDef *pdev, uint8_t ep_addr, uint8_t *pbuf, uint32_t size)
Prepares an endpoint for reception.
Definition usbd_conf.c:580
USBD_StatusTypeDef USBD_LL_OpenEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr, uint8_t ep_type, uint16_t ep_mps)
Opens an endpoint of the low level driver.
Definition usbd_conf.c:430
USBD_StatusTypeDef USBD_LL_CloseEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr)
Closes an endpoint of the low level driver.
Definition usbd_conf.c:448
uint32_t USBD_LL_GetRxDataSize(USBD_HandleTypeDef *pdev, uint8_t ep_addr)
Returns the last transferred packet size.
Definition usbd_conf.c:598
void * USBD_GetEpDesc(uint8_t *pConfDesc, uint8_t EpAddr)
USBD_GetEpDesc This function return the Endpoint descriptor.
Definition usbd_core.c:1157
USBD_ClassTypeDef USBD_CDC
Definition usbd_cdc.c:141
#define LOBYTE(x)
Definition usbd_def.h:442
#define MIN(a, b)
Definition usbd_def.h:450
#define HIBYTE(x)
Definition usbd_def.h:446
struct _USBD_HandleTypeDef USBD_HandleTypeDef
struct usb_setup_req USBD_SetupReqTypedef
struct _Device_cb USBD_ClassTypeDef
USBD_StatusTypeDef
Definition usbd_def.h:280
@ USBD_SPEED_HIGH
Definition usbd_def.h:273
@ USBD_FAIL
Definition usbd_def.h:284
@ USBD_OK
Definition usbd_def.h:281
@ USBD_EMEM
Definition usbd_def.h:283
@ USBD_BUSY
Definition usbd_def.h:282
USBD_StatusTypeDef USBD_CtlSendData(USBD_HandleTypeDef *pdev, uint8_t *pbuf, uint32_t len)
USBD_CtlSendData send data on the ctl pipe.
Definition usbd_ioreq.c:86
USBD_StatusTypeDef USBD_CtlPrepareRx(USBD_HandleTypeDef *pdev, uint8_t *pbuf, uint32_t len)
USBD_CtlPrepareRx receive data on the ctl pipe.
Definition usbd_ioreq.c:131
void USBD_CtlError(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req)
USBD_CtlError Handle USB low level Error.
#define NULL
Definition usbd_def.h:44
#define USB_REQ_GET_INTERFACE
Definition usbd_def.h:127
#define USB_REQ_SET_INTERFACE
Definition usbd_def.h:128
#define USB_MAX_EP0_SIZE
Definition usbd_def.h:157
#define USB_DESC_TYPE_CONFIGURATION
Definition usbd_def.h:132
#define USB_REQ_TYPE_STANDARD
Definition usbd_def.h:109
#define USB_REQ_CLEAR_FEATURE
Definition usbd_def.h:120
#define USBD_STATE_CONFIGURED
Definition usbd_def.h:162
#define USBD_EP_TYPE_BULK
Definition usbd_def.h:177
#define USB_REQ_TYPE_MASK
Definition usbd_def.h:112
#define USB_REQ_GET_STATUS
Definition usbd_def.h:119
#define USB_LEN_DEV_QUALIFIER_DESC
Definition usbd_def.h:93
#define USB_DESC_TYPE_ENDPOINT
Definition usbd_def.h:135
#define USB_DESC_TYPE_INTERFACE
Definition usbd_def.h:134
#define USB_DESC_TYPE_DEVICE_QUALIFIER
Definition usbd_def.h:136
#define USBD_MAX_POWER
Definition usbd_def.h:82
#define USBD_EP_TYPE_INTR
Definition usbd_def.h:178
#define USB_REQ_TYPE_CLASS
Definition usbd_def.h:110
#define CDC_IN_EP
Definition usbd_cdc.h:44
#define CDC_FS_BINTERVAL
Definition usbd_cdc.h:58
#define CDC_OUT_EP
Definition usbd_cdc.h:47
#define CDC_DATA_HS_IN_PACKET_SIZE
Definition usbd_cdc.h:70
#define CDC_DATA_FS_MAX_PACKET_SIZE
Definition usbd_cdc.h:67
#define CDC_DATA_FS_OUT_PACKET_SIZE
Definition usbd_cdc.h:74
#define CDC_DATA_HS_OUT_PACKET_SIZE
Definition usbd_cdc.h:71
#define CDC_REQ_MAX_DATA_SIZE
Definition usbd_cdc.h:76
#define CDC_DATA_HS_MAX_PACKET_SIZE
Definition usbd_cdc.h:66
#define USB_CDC_CONFIG_DESC_SIZ
Definition usbd_cdc.h:69
#define CDC_CMD_EP
Definition usbd_cdc.h:50
#define CDC_CMD_PACKET_SIZE
Definition usbd_cdc.h:62
#define CDC_DATA_FS_IN_PACKET_SIZE
Definition usbd_cdc.h:73
#define CDC_HS_BINTERVAL
Definition usbd_cdc.h:54
struct _USBD_CDC_Itf USBD_CDC_ItfTypeDef
#define UNUSED(x)
#define __ALIGN_END
__IO uint32_t TxState
Definition usbd_cdc.h:130
uint32_t data[CDC_DATA_HS_MAX_PACKET_SIZE/4U]
Definition usbd_cdc.h:122
__IO uint32_t RxState
Definition usbd_cdc.h:131
uint32_t total_length
Definition usbd_def.h:308
USBD_EndpointTypeDef ep_in[16]
Definition usbd_def.h:368
USBD_EndpointTypeDef ep_out[16]
Definition usbd_def.h:369
void * pClassDataCmsit[USBD_MAX_SUPPORTED_CLASS]
Definition usbd_def.h:384
USBD_SpeedTypeDef dev_speed
Definition usbd_def.h:367
__IO uint8_t dev_state
Definition usbd_def.h:372
void * pUserData[USBD_MAX_SUPPORTED_CLASS]
Definition usbd_def.h:385
header file for the usbd_cdc.c file.