source: S-port/trunk/Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Src/usbd_cdc.c@ 1

Last change on this file since 1 was 1, checked in by AlexLir, 2 years ago
File size: 35.3 KB
Line 
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 * @verbatim
14 *
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
29 *
30 * These aspects may be enriched or modified for a specific user application.
31 *
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
36 *
37 * @endverbatim
38 *
39 ******************************************************************************
40 * @attention
41 *
42 * <h2><center>&copy; Copyright (c) 2015 STMicroelectronics.
43 * All rights reserved.</center></h2>
44 *
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
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
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);
112static uint8_t *USBD_CDC_GetOtherSpeedCfgDesc(uint16_t *length);
113uint8_t *USBD_CDC_GetDeviceQualifierDescriptor(uint16_t *length);
114
115/* USB Standard Device Descriptor */
116__ALIGN_BEGIN static uint8_t USBD_CDC_DeviceQualifierDesc[USB_LEN_DEV_QUALIFIER_DESC] __ALIGN_END =
117{
118 USB_LEN_DEV_QUALIFIER_DESC,
119 USB_DESC_TYPE_DEVICE_QUALIFIER,
120 0x00,
121 0x02,
122 0x00,
123 0x00,
124 0x00,
125 0x40,
126 0x01,
127 0x00,
128};
129
130/**
131 * @}
132 */
133
134/** @defgroup USBD_CDC_Private_Variables
135 * @{
136 */
137
138
139/* CDC interface class callbacks structure */
140USBD_ClassTypeDef USBD_CDC =
141{
142 USBD_CDC_Init,
143 USBD_CDC_DeInit,
144 USBD_CDC_Setup,
145 NULL, /* EP0_TxSent, */
146 USBD_CDC_EP0_RxReady,
147 USBD_CDC_DataIn,
148 USBD_CDC_DataOut,
149 NULL,
150 NULL,
151 NULL,
152 USBD_CDC_GetHSCfgDesc,
153 USBD_CDC_GetFSCfgDesc,
154 USBD_CDC_GetOtherSpeedCfgDesc,
155 USBD_CDC_GetDeviceQualifierDescriptor,
156};
157
158/* USB CDC device Configuration Descriptor */
159__ALIGN_BEGIN static uint8_t USBD_CDC_CfgHSDesc[USB_CDC_CONFIG_DESC_SIZ] __ALIGN_END =
160{
161 /* Configuration Descriptor */
162 0x09, /* bLength: Configuration Descriptor size */
163 USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */
164 USB_CDC_CONFIG_DESC_SIZ, /* wTotalLength:no of returned bytes */
165 0x00,
166 0x02, /* bNumInterfaces: 2 interface */
167 0x01, /* bConfigurationValue: Configuration value */
168 0x00, /* iConfiguration: Index of string descriptor describing the configuration */
169#if (USBD_SELF_POWERED == 1U)
170 0xC0, /* bmAttributes: Bus Powered according to user configuration */
171#else
172 0x80, /* bmAttributes: Bus Powered according to user configuration */
173#endif
174 USBD_MAX_POWER, /* MaxPower 100 mA */
175
176 /*---------------------------------------------------------------------------*/
177
178 /* Interface Descriptor */
179 0x09, /* bLength: Interface Descriptor size */
180 USB_DESC_TYPE_INTERFACE, /* bDescriptorType: Interface */
181 0x00, /* bInterfaceNumber: Number of Interface */
182 0x00, /* bAlternateSetting: Alternate setting */
183 0x01, /* bNumEndpoints: One endpoints used */
184 0x02, /* bInterfaceClass: Communication Interface Class */
185 0x02, /* bInterfaceSubClass: Abstract Control Model */
186 0x01, /* bInterfaceProtocol: Common AT commands */
187 0x00, /* iInterface: */
188
189 /* Header Functional Descriptor */
190 0x05, /* bLength: Endpoint Descriptor size */
191 0x24, /* bDescriptorType: CS_INTERFACE */
192 0x00, /* bDescriptorSubtype: Header Func Desc */
193 0x10, /* bcdCDC: spec release number */
194 0x01,
195
196 /* Call Management Functional Descriptor */
197 0x05, /* bFunctionLength */
198 0x24, /* bDescriptorType: CS_INTERFACE */
199 0x01, /* bDescriptorSubtype: Call Management Func Desc */
200 0x00, /* bmCapabilities: D0+D1 */
201 0x01, /* bDataInterface: 1 */
202
203 /* ACM Functional Descriptor */
204 0x04, /* bFunctionLength */
205 0x24, /* bDescriptorType: CS_INTERFACE */
206 0x02, /* bDescriptorSubtype: Abstract Control Management desc */
207 0x02, /* bmCapabilities */
208
209 /* Union Functional Descriptor */
210 0x05, /* bFunctionLength */
211 0x24, /* bDescriptorType: CS_INTERFACE */
212 0x06, /* bDescriptorSubtype: Union func desc */
213 0x00, /* bMasterInterface: Communication class interface */
214 0x01, /* bSlaveInterface0: Data Class Interface */
215
216 /* Endpoint 2 Descriptor */
217 0x07, /* bLength: Endpoint Descriptor size */
218 USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
219 CDC_CMD_EP, /* bEndpointAddress */
220 0x03, /* bmAttributes: Interrupt */
221 LOBYTE(CDC_CMD_PACKET_SIZE), /* wMaxPacketSize: */
222 HIBYTE(CDC_CMD_PACKET_SIZE),
223 CDC_HS_BINTERVAL, /* bInterval: */
224 /*---------------------------------------------------------------------------*/
225
226 /* Data class interface descriptor */
227 0x09, /* bLength: Endpoint Descriptor size */
228 USB_DESC_TYPE_INTERFACE, /* bDescriptorType: */
229 0x01, /* bInterfaceNumber: Number of Interface */
230 0x00, /* bAlternateSetting: Alternate setting */
231 0x02, /* bNumEndpoints: Two endpoints used */
232 0x0A, /* bInterfaceClass: CDC */
233 0x00, /* bInterfaceSubClass: */
234 0x00, /* bInterfaceProtocol: */
235 0x00, /* iInterface: */
236
237 /* Endpoint OUT Descriptor */
238 0x07, /* bLength: Endpoint Descriptor size */
239 USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
240 CDC_OUT_EP, /* bEndpointAddress */
241 0x02, /* bmAttributes: Bulk */
242 LOBYTE(CDC_DATA_HS_MAX_PACKET_SIZE), /* wMaxPacketSize: */
243 HIBYTE(CDC_DATA_HS_MAX_PACKET_SIZE),
244 0x00, /* bInterval: ignore for Bulk transfer */
245
246 /* Endpoint IN Descriptor */
247 0x07, /* bLength: Endpoint Descriptor size */
248 USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
249 CDC_IN_EP, /* bEndpointAddress */
250 0x02, /* bmAttributes: Bulk */
251 LOBYTE(CDC_DATA_HS_MAX_PACKET_SIZE), /* wMaxPacketSize: */
252 HIBYTE(CDC_DATA_HS_MAX_PACKET_SIZE),
253 0x00 /* bInterval: ignore for Bulk transfer */
254};
255
256
257/* USB CDC device Configuration Descriptor */
258__ALIGN_BEGIN static uint8_t USBD_CDC_CfgFSDesc[USB_CDC_CONFIG_DESC_SIZ] __ALIGN_END =
259{
260 /* Configuration Descriptor */
261 0x09, /* bLength: Configuration Descriptor size */
262 USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */
263 USB_CDC_CONFIG_DESC_SIZ, /* wTotalLength:no of returned bytes */
264 0x00,
265 0x02, /* bNumInterfaces: 2 interface */
266 0x01, /* bConfigurationValue: Configuration value */
267 0x00, /* iConfiguration: Index of string descriptor describing the configuration */
268#if (USBD_SELF_POWERED == 1U)
269 0xC0, /* bmAttributes: Bus Powered according to user configuration */
270#else
271 0x80, /* bmAttributes: Bus Powered according to user configuration */
272#endif
273 USBD_MAX_POWER, /* MaxPower 100 mA */
274
275 /*---------------------------------------------------------------------------*/
276
277 /* Interface Descriptor */
278 0x09, /* bLength: Interface Descriptor size */
279 USB_DESC_TYPE_INTERFACE, /* bDescriptorType: Interface */
280 /* Interface descriptor type */
281 0x00, /* bInterfaceNumber: Number of Interface */
282 0x00, /* bAlternateSetting: Alternate setting */
283 0x01, /* bNumEndpoints: One endpoints used */
284 0x02, /* bInterfaceClass: Communication Interface Class */
285 0x02, /* bInterfaceSubClass: Abstract Control Model */
286 0x01, /* bInterfaceProtocol: Common AT commands */
287 0x00, /* iInterface: */
288
289 /* Header Functional Descriptor */
290 0x05, /* bLength: Endpoint Descriptor size */
291 0x24, /* bDescriptorType: CS_INTERFACE */
292 0x00, /* bDescriptorSubtype: Header Func Desc */
293 0x10, /* bcdCDC: spec release number */
294 0x01,
295
296 /* Call Management Functional Descriptor */
297 0x05, /* bFunctionLength */
298 0x24, /* bDescriptorType: CS_INTERFACE */
299 0x01, /* bDescriptorSubtype: Call Management Func Desc */
300 0x00, /* bmCapabilities: D0+D1 */
301 0x01, /* bDataInterface: 1 */
302
303 /* ACM Functional Descriptor */
304 0x04, /* bFunctionLength */
305 0x24, /* bDescriptorType: CS_INTERFACE */
306 0x02, /* bDescriptorSubtype: Abstract Control Management desc */
307 0x02, /* bmCapabilities */
308
309 /* Union Functional Descriptor */
310 0x05, /* bFunctionLength */
311 0x24, /* bDescriptorType: CS_INTERFACE */
312 0x06, /* bDescriptorSubtype: Union func desc */
313 0x00, /* bMasterInterface: Communication class interface */
314 0x01, /* bSlaveInterface0: Data Class Interface */
315
316 /* Endpoint 2 Descriptor */
317 0x07, /* bLength: Endpoint Descriptor size */
318 USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
319 CDC_CMD_EP, /* bEndpointAddress */
320 0x03, /* bmAttributes: Interrupt */
321 LOBYTE(CDC_CMD_PACKET_SIZE), /* wMaxPacketSize: */
322 HIBYTE(CDC_CMD_PACKET_SIZE),
323 CDC_FS_BINTERVAL, /* bInterval: */
324 /*---------------------------------------------------------------------------*/
325
326 /* Data class interface descriptor */
327 0x09, /* bLength: Endpoint Descriptor size */
328 USB_DESC_TYPE_INTERFACE, /* bDescriptorType: */
329 0x01, /* bInterfaceNumber: Number of Interface */
330 0x00, /* bAlternateSetting: Alternate setting */
331 0x02, /* bNumEndpoints: Two endpoints used */
332 0x0A, /* bInterfaceClass: CDC */
333 0x00, /* bInterfaceSubClass: */
334 0x00, /* bInterfaceProtocol: */
335 0x00, /* iInterface: */
336
337 /* Endpoint OUT Descriptor */
338 0x07, /* bLength: Endpoint Descriptor size */
339 USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
340 CDC_OUT_EP, /* bEndpointAddress */
341 0x02, /* bmAttributes: Bulk */
342 LOBYTE(CDC_DATA_FS_MAX_PACKET_SIZE), /* wMaxPacketSize: */
343 HIBYTE(CDC_DATA_FS_MAX_PACKET_SIZE),
344 0x00, /* bInterval: ignore for Bulk transfer */
345
346 /* Endpoint IN Descriptor */
347 0x07, /* bLength: Endpoint Descriptor size */
348 USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
349 CDC_IN_EP, /* bEndpointAddress */
350 0x02, /* bmAttributes: Bulk */
351 LOBYTE(CDC_DATA_FS_MAX_PACKET_SIZE), /* wMaxPacketSize: */
352 HIBYTE(CDC_DATA_FS_MAX_PACKET_SIZE),
353 0x00 /* bInterval: ignore for Bulk transfer */
354};
355
356__ALIGN_BEGIN static uint8_t USBD_CDC_OtherSpeedCfgDesc[USB_CDC_CONFIG_DESC_SIZ] __ALIGN_END =
357{
358 0x09, /* bLength: Configuration Descriptor size */
359 USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION,
360 USB_CDC_CONFIG_DESC_SIZ,
361 0x00,
362 0x02, /* bNumInterfaces: 2 interfaces */
363 0x01, /* bConfigurationValue: */
364 0x04, /* iConfiguration: */
365#if (USBD_SELF_POWERED == 1U)
366 0xC0, /* bmAttributes: Bus Powered according to user configuration */
367#else
368 0x80, /* bmAttributes: Bus Powered according to user configuration */
369#endif
370 USBD_MAX_POWER, /* MaxPower 100 mA */
371
372 /*Interface Descriptor */
373 0x09, /* bLength: Interface Descriptor size */
374 USB_DESC_TYPE_INTERFACE, /* bDescriptorType: Interface */
375 /* Interface descriptor type */
376 0x00, /* bInterfaceNumber: Number of Interface */
377 0x00, /* bAlternateSetting: Alternate setting */
378 0x01, /* bNumEndpoints: One endpoints used */
379 0x02, /* bInterfaceClass: Communication Interface Class */
380 0x02, /* bInterfaceSubClass: Abstract Control Model */
381 0x01, /* bInterfaceProtocol: Common AT commands */
382 0x00, /* iInterface: */
383
384 /* Header Functional Descriptor */
385 0x05, /* bLength: Endpoint Descriptor size */
386 0x24, /* bDescriptorType: CS_INTERFACE */
387 0x00, /* bDescriptorSubtype: Header Func Desc */
388 0x10, /* bcdCDC: spec release number */
389 0x01,
390
391 /*Call Management Functional Descriptor*/
392 0x05, /* bFunctionLength */
393 0x24, /* bDescriptorType: CS_INTERFACE */
394 0x01, /* bDescriptorSubtype: Call Management Func Desc */
395 0x00, /* bmCapabilities: D0+D1 */
396 0x01, /* bDataInterface: 1 */
397
398 /*ACM Functional Descriptor*/
399 0x04, /* bFunctionLength */
400 0x24, /* bDescriptorType: CS_INTERFACE */
401 0x02, /* bDescriptorSubtype: Abstract Control Management desc */
402 0x02, /* bmCapabilities */
403
404 /*Union Functional Descriptor*/
405 0x05, /* bFunctionLength */
406 0x24, /* bDescriptorType: CS_INTERFACE */
407 0x06, /* bDescriptorSubtype: Union func desc */
408 0x00, /* bMasterInterface: Communication class interface */
409 0x01, /* bSlaveInterface0: Data Class Interface */
410
411 /*Endpoint 2 Descriptor*/
412 0x07, /* bLength: Endpoint Descriptor size */
413 USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
414 CDC_CMD_EP, /* bEndpointAddress */
415 0x03, /* bmAttributes: Interrupt */
416 LOBYTE(CDC_CMD_PACKET_SIZE), /* wMaxPacketSize: */
417 HIBYTE(CDC_CMD_PACKET_SIZE),
418 CDC_FS_BINTERVAL, /* bInterval: */
419
420 /*---------------------------------------------------------------------------*/
421
422 /*Data class interface descriptor*/
423 0x09, /* bLength: Endpoint Descriptor size */
424 USB_DESC_TYPE_INTERFACE, /* bDescriptorType: */
425 0x01, /* bInterfaceNumber: Number of Interface */
426 0x00, /* bAlternateSetting: Alternate setting */
427 0x02, /* bNumEndpoints: Two endpoints used */
428 0x0A, /* bInterfaceClass: CDC */
429 0x00, /* bInterfaceSubClass: */
430 0x00, /* bInterfaceProtocol: */
431 0x00, /* iInterface: */
432
433 /*Endpoint OUT Descriptor*/
434 0x07, /* bLength: Endpoint Descriptor size */
435 USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
436 CDC_OUT_EP, /* bEndpointAddress */
437 0x02, /* bmAttributes: Bulk */
438 0x40, /* wMaxPacketSize: */
439 0x00,
440 0x00, /* bInterval: ignore for Bulk transfer */
441
442 /*Endpoint IN Descriptor*/
443 0x07, /* bLength: Endpoint Descriptor size */
444 USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */
445 CDC_IN_EP, /* bEndpointAddress */
446 0x02, /* bmAttributes: Bulk */
447 0x40, /* wMaxPacketSize: */
448 0x00,
449 0x00 /* bInterval */
450};
451
452/**
453 * @}
454 */
455
456/** @defgroup USBD_CDC_Private_Functions
457 * @{
458 */
459
460/**
461 * @brief USBD_CDC_Init
462 * Initialize the CDC interface
463 * @param pdev: device instance
464 * @param cfgidx: Configuration index
465 * @retval status
466 */
467static uint8_t USBD_CDC_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
468{
469 UNUSED(cfgidx);
470 USBD_CDC_HandleTypeDef *hcdc;
471
472 hcdc = USBD_malloc(sizeof(USBD_CDC_HandleTypeDef));
473
474 if (hcdc == NULL)
475 {
476 pdev->pClassData = NULL;
477 return (uint8_t)USBD_EMEM;
478 }
479
480 pdev->pClassData = (void *)hcdc;
481
482 if (pdev->dev_speed == USBD_SPEED_HIGH)
483 {
484 /* Open EP IN */
485 (void)USBD_LL_OpenEP(pdev, CDC_IN_EP, USBD_EP_TYPE_BULK,
486 CDC_DATA_HS_IN_PACKET_SIZE);
487
488 pdev->ep_in[CDC_IN_EP & 0xFU].is_used = 1U;
489
490 /* Open EP OUT */
491 (void)USBD_LL_OpenEP(pdev, CDC_OUT_EP, USBD_EP_TYPE_BULK,
492 CDC_DATA_HS_OUT_PACKET_SIZE);
493
494 pdev->ep_out[CDC_OUT_EP & 0xFU].is_used = 1U;
495
496 /* Set bInterval for CDC CMD Endpoint */
497 pdev->ep_in[CDC_CMD_EP & 0xFU].bInterval = CDC_HS_BINTERVAL;
498 }
499 else
500 {
501 /* Open EP IN */
502 (void)USBD_LL_OpenEP(pdev, CDC_IN_EP, USBD_EP_TYPE_BULK,
503 CDC_DATA_FS_IN_PACKET_SIZE);
504
505 pdev->ep_in[CDC_IN_EP & 0xFU].is_used = 1U;
506
507 /* Open EP OUT */
508 (void)USBD_LL_OpenEP(pdev, CDC_OUT_EP, USBD_EP_TYPE_BULK,
509 CDC_DATA_FS_OUT_PACKET_SIZE);
510
511 pdev->ep_out[CDC_OUT_EP & 0xFU].is_used = 1U;
512
513 /* Set bInterval for CMD Endpoint */
514 pdev->ep_in[CDC_CMD_EP & 0xFU].bInterval = CDC_FS_BINTERVAL;
515 }
516
517 /* Open Command IN EP */
518 (void)USBD_LL_OpenEP(pdev, CDC_CMD_EP, USBD_EP_TYPE_INTR, CDC_CMD_PACKET_SIZE);
519 pdev->ep_in[CDC_CMD_EP & 0xFU].is_used = 1U;
520
521 /* Init physical Interface components */
522 ((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Init();
523
524 /* Init Xfer states */
525 hcdc->TxState = 0U;
526 hcdc->RxState = 0U;
527
528 if (pdev->dev_speed == USBD_SPEED_HIGH)
529 {
530 /* Prepare Out endpoint to receive next packet */
531 (void)USBD_LL_PrepareReceive(pdev, CDC_OUT_EP, hcdc->RxBuffer,
532 CDC_DATA_HS_OUT_PACKET_SIZE);
533 }
534 else
535 {
536 /* Prepare Out endpoint to receive next packet */
537 (void)USBD_LL_PrepareReceive(pdev, CDC_OUT_EP, hcdc->RxBuffer,
538 CDC_DATA_FS_OUT_PACKET_SIZE);
539 }
540
541 return (uint8_t)USBD_OK;
542}
543
544/**
545 * @brief USBD_CDC_Init
546 * DeInitialize the CDC layer
547 * @param pdev: device instance
548 * @param cfgidx: Configuration index
549 * @retval status
550 */
551static uint8_t USBD_CDC_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
552{
553 UNUSED(cfgidx);
554
555 /* Close EP IN */
556 (void)USBD_LL_CloseEP(pdev, CDC_IN_EP);
557 pdev->ep_in[CDC_IN_EP & 0xFU].is_used = 0U;
558
559 /* Close EP OUT */
560 (void)USBD_LL_CloseEP(pdev, CDC_OUT_EP);
561 pdev->ep_out[CDC_OUT_EP & 0xFU].is_used = 0U;
562
563 /* Close Command IN EP */
564 (void)USBD_LL_CloseEP(pdev, CDC_CMD_EP);
565 pdev->ep_in[CDC_CMD_EP & 0xFU].is_used = 0U;
566 pdev->ep_in[CDC_CMD_EP & 0xFU].bInterval = 0U;
567
568 /* DeInit physical Interface components */
569 if (pdev->pClassData != NULL)
570 {
571 ((USBD_CDC_ItfTypeDef *)pdev->pUserData)->DeInit();
572 (void)USBD_free(pdev->pClassData);
573 pdev->pClassData = NULL;
574 }
575
576 return (uint8_t)USBD_OK;
577}
578
579/**
580 * @brief USBD_CDC_Setup
581 * Handle the CDC specific requests
582 * @param pdev: instance
583 * @param req: usb requests
584 * @retval status
585 */
586static uint8_t USBD_CDC_Setup(USBD_HandleTypeDef *pdev,
587 USBD_SetupReqTypedef *req)
588{
589 USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef *)pdev->pClassData;
590 uint16_t len;
591 uint8_t ifalt = 0U;
592 uint16_t status_info = 0U;
593 USBD_StatusTypeDef ret = USBD_OK;
594
595 if (hcdc == NULL)
596 {
597 return (uint8_t)USBD_FAIL;
598 }
599
600 switch (req->bmRequest & USB_REQ_TYPE_MASK)
601 {
602 case USB_REQ_TYPE_CLASS:
603 if (req->wLength != 0U)
604 {
605 if ((req->bmRequest & 0x80U) != 0U)
606 {
607 ((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Control(req->bRequest,
608 (uint8_t *)hcdc->data,
609 req->wLength);
610
611 len = MIN(CDC_REQ_MAX_DATA_SIZE, req->wLength);
612 (void)USBD_CtlSendData(pdev, (uint8_t *)hcdc->data, len);
613 }
614 else
615 {
616 hcdc->CmdOpCode = req->bRequest;
617 hcdc->CmdLength = (uint8_t)req->wLength;
618
619 (void)USBD_CtlPrepareRx(pdev, (uint8_t *)hcdc->data, req->wLength);
620 }
621 }
622 else
623 {
624 ((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Control(req->bRequest,
625 (uint8_t *)req, 0U);
626 }
627 break;
628
629 case USB_REQ_TYPE_STANDARD:
630 switch (req->bRequest)
631 {
632 case USB_REQ_GET_STATUS:
633 if (pdev->dev_state == USBD_STATE_CONFIGURED)
634 {
635 (void)USBD_CtlSendData(pdev, (uint8_t *)&status_info, 2U);
636 }
637 else
638 {
639 USBD_CtlError(pdev, req);
640 ret = USBD_FAIL;
641 }
642 break;
643
644 case USB_REQ_GET_INTERFACE:
645 if (pdev->dev_state == USBD_STATE_CONFIGURED)
646 {
647 (void)USBD_CtlSendData(pdev, &ifalt, 1U);
648 }
649 else
650 {
651 USBD_CtlError(pdev, req);
652 ret = USBD_FAIL;
653 }
654 break;
655
656 case USB_REQ_SET_INTERFACE:
657 if (pdev->dev_state != USBD_STATE_CONFIGURED)
658 {
659 USBD_CtlError(pdev, req);
660 ret = USBD_FAIL;
661 }
662 break;
663
664 case USB_REQ_CLEAR_FEATURE:
665 break;
666
667 default:
668 USBD_CtlError(pdev, req);
669 ret = USBD_FAIL;
670 break;
671 }
672 break;
673
674 default:
675 USBD_CtlError(pdev, req);
676 ret = USBD_FAIL;
677 break;
678 }
679
680 return (uint8_t)ret;
681}
682
683/**
684 * @brief USBD_CDC_DataIn
685 * Data sent on non-control IN endpoint
686 * @param pdev: device instance
687 * @param epnum: endpoint number
688 * @retval status
689 */
690static uint8_t USBD_CDC_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum)
691{
692 USBD_CDC_HandleTypeDef *hcdc;
693 PCD_HandleTypeDef *hpcd = pdev->pData;
694
695 if (pdev->pClassData == NULL)
696 {
697 return (uint8_t)USBD_FAIL;
698 }
699
700 hcdc = (USBD_CDC_HandleTypeDef *)pdev->pClassData;
701
702 if ((pdev->ep_in[epnum].total_length > 0U) &&
703 ((pdev->ep_in[epnum].total_length % hpcd->IN_ep[epnum].maxpacket) == 0U))
704 {
705 /* Update the packet total length */
706 pdev->ep_in[epnum].total_length = 0U;
707
708 /* Send ZLP */
709 (void)USBD_LL_Transmit(pdev, epnum, NULL, 0U);
710 }
711 else
712 {
713 hcdc->TxState = 0U;
714
715 if (((USBD_CDC_ItfTypeDef *)pdev->pUserData)->TransmitCplt != NULL)
716 {
717 ((USBD_CDC_ItfTypeDef *)pdev->pUserData)->TransmitCplt(hcdc->TxBuffer, &hcdc->TxLength, epnum);
718 }
719 }
720
721 return (uint8_t)USBD_OK;
722}
723
724/**
725 * @brief USBD_CDC_DataOut
726 * Data received on non-control Out endpoint
727 * @param pdev: device instance
728 * @param epnum: endpoint number
729 * @retval status
730 */
731static uint8_t USBD_CDC_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum)
732{
733 USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef *)pdev->pClassData;
734
735 if (pdev->pClassData == NULL)
736 {
737 return (uint8_t)USBD_FAIL;
738 }
739
740 /* Get the received data length */
741 hcdc->RxLength = USBD_LL_GetRxDataSize(pdev, epnum);
742
743 /* USB data will be immediately processed, this allow next USB traffic being
744 NAKed till the end of the application Xfer */
745
746 ((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Receive(hcdc->RxBuffer, &hcdc->RxLength);
747
748 return (uint8_t)USBD_OK;
749}
750
751/**
752 * @brief USBD_CDC_EP0_RxReady
753 * Handle EP0 Rx Ready event
754 * @param pdev: device instance
755 * @retval status
756 */
757static uint8_t USBD_CDC_EP0_RxReady(USBD_HandleTypeDef *pdev)
758{
759 USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef *)pdev->pClassData;
760
761 if (hcdc == NULL)
762 {
763 return (uint8_t)USBD_FAIL;
764 }
765
766 if ((pdev->pUserData != NULL) && (hcdc->CmdOpCode != 0xFFU))
767 {
768 ((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Control(hcdc->CmdOpCode,
769 (uint8_t *)hcdc->data,
770 (uint16_t)hcdc->CmdLength);
771 hcdc->CmdOpCode = 0xFFU;
772 }
773
774 return (uint8_t)USBD_OK;
775}
776
777/**
778 * @brief USBD_CDC_GetFSCfgDesc
779 * Return configuration descriptor
780 * @param speed : current device speed
781 * @param length : pointer data length
782 * @retval pointer to descriptor buffer
783 */
784static uint8_t *USBD_CDC_GetFSCfgDesc(uint16_t *length)
785{
786 *length = (uint16_t)sizeof(USBD_CDC_CfgFSDesc);
787
788 return USBD_CDC_CfgFSDesc;
789}
790
791/**
792 * @brief USBD_CDC_GetHSCfgDesc
793 * Return configuration descriptor
794 * @param speed : current device speed
795 * @param length : pointer data length
796 * @retval pointer to descriptor buffer
797 */
798static uint8_t *USBD_CDC_GetHSCfgDesc(uint16_t *length)
799{
800 *length = (uint16_t)sizeof(USBD_CDC_CfgHSDesc);
801
802 return USBD_CDC_CfgHSDesc;
803}
804
805/**
806 * @brief USBD_CDC_GetOtherSpeedCfgDesc
807 * Return configuration descriptor
808 * @param speed : current device speed
809 * @param length : pointer data length
810 * @retval pointer to descriptor buffer
811 */
812static uint8_t *USBD_CDC_GetOtherSpeedCfgDesc(uint16_t *length)
813{
814 *length = (uint16_t)sizeof(USBD_CDC_OtherSpeedCfgDesc);
815
816 return USBD_CDC_OtherSpeedCfgDesc;
817}
818
819/**
820 * @brief USBD_CDC_GetDeviceQualifierDescriptor
821 * return Device Qualifier descriptor
822 * @param length : pointer data length
823 * @retval pointer to descriptor buffer
824 */
825uint8_t *USBD_CDC_GetDeviceQualifierDescriptor(uint16_t *length)
826{
827 *length = (uint16_t)sizeof(USBD_CDC_DeviceQualifierDesc);
828
829 return USBD_CDC_DeviceQualifierDesc;
830}
831
832/**
833 * @brief USBD_CDC_RegisterInterface
834 * @param pdev: device instance
835 * @param fops: CD Interface callback
836 * @retval status
837 */
838uint8_t USBD_CDC_RegisterInterface(USBD_HandleTypeDef *pdev,
839 USBD_CDC_ItfTypeDef *fops)
840{
841 if (fops == NULL)
842 {
843 return (uint8_t)USBD_FAIL;
844 }
845
846 pdev->pUserData = fops;
847
848 return (uint8_t)USBD_OK;
849}
850
851/**
852 * @brief USBD_CDC_SetTxBuffer
853 * @param pdev: device instance
854 * @param pbuff: Tx Buffer
855 * @retval status
856 */
857uint8_t USBD_CDC_SetTxBuffer(USBD_HandleTypeDef *pdev,
858 uint8_t *pbuff, uint32_t length)
859{
860 USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef *)pdev->pClassData;
861
862 if (hcdc == NULL)
863 {
864 return (uint8_t)USBD_FAIL;
865 }
866
867 hcdc->TxBuffer = pbuff;
868 hcdc->TxLength = length;
869
870 return (uint8_t)USBD_OK;
871}
872
873/**
874 * @brief USBD_CDC_SetRxBuffer
875 * @param pdev: device instance
876 * @param pbuff: Rx Buffer
877 * @retval status
878 */
879uint8_t USBD_CDC_SetRxBuffer(USBD_HandleTypeDef *pdev, uint8_t *pbuff)
880{
881 USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef *)pdev->pClassData;
882
883 if (hcdc == NULL)
884 {
885 return (uint8_t)USBD_FAIL;
886 }
887
888 hcdc->RxBuffer = pbuff;
889
890 return (uint8_t)USBD_OK;
891}
892
893/**
894 * @brief USBD_CDC_TransmitPacket
895 * Transmit packet on IN endpoint
896 * @param pdev: device instance
897 * @retval status
898 */
899uint8_t USBD_CDC_TransmitPacket(USBD_HandleTypeDef *pdev)
900{
901 USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef *)pdev->pClassData;
902 USBD_StatusTypeDef ret = USBD_BUSY;
903
904 if (pdev->pClassData == NULL)
905 {
906 return (uint8_t)USBD_FAIL;
907 }
908
909 if (hcdc->TxState == 0U)
910 {
911 /* Tx Transfer in progress */
912 hcdc->TxState = 1U;
913
914 /* Update the packet total length */
915 pdev->ep_in[CDC_IN_EP & 0xFU].total_length = hcdc->TxLength;
916
917 /* Transmit next packet */
918 (void)USBD_LL_Transmit(pdev, CDC_IN_EP, hcdc->TxBuffer, hcdc->TxLength);
919
920 ret = USBD_OK;
921 }
922
923 return (uint8_t)ret;
924}
925
926/**
927 * @brief USBD_CDC_ReceivePacket
928 * prepare OUT Endpoint for reception
929 * @param pdev: device instance
930 * @retval status
931 */
932uint8_t USBD_CDC_ReceivePacket(USBD_HandleTypeDef *pdev)
933{
934 USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef *)pdev->pClassData;
935
936 if (pdev->pClassData == NULL)
937 {
938 return (uint8_t)USBD_FAIL;
939 }
940
941 if (pdev->dev_speed == USBD_SPEED_HIGH)
942 {
943 /* Prepare Out endpoint to receive next packet */
944 (void)USBD_LL_PrepareReceive(pdev, CDC_OUT_EP, hcdc->RxBuffer,
945 CDC_DATA_HS_OUT_PACKET_SIZE);
946 }
947 else
948 {
949 /* Prepare Out endpoint to receive next packet */
950 (void)USBD_LL_PrepareReceive(pdev, CDC_OUT_EP, hcdc->RxBuffer,
951 CDC_DATA_FS_OUT_PACKET_SIZE);
952 }
953
954 return (uint8_t)USBD_OK;
955}
956/**
957 * @}
958 */
959
960/**
961 * @}
962 */
963
964/**
965 * @}
966 */
967
968/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
Note: See TracBrowser for help on using the repository browser.