Subversion Repositories dualCDC

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 mjames 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"
56
EndBSPDependencies */
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
 
102
 
103
static uint8_t  USBD_CDC_Init(USBD_HandleTypeDef *pdev,
104
                              uint8_t cfgidx);
105
 
106
static uint8_t  USBD_CDC_DeInit(USBD_HandleTypeDef *pdev,
107
                                uint8_t cfgidx);
108
 
109
static uint8_t  USBD_CDC_Setup(USBD_HandleTypeDef *pdev,
110
                               USBD_SetupReqTypedef *req);
111
 
112
static uint8_t  USBD_CDC_DataIn(USBD_HandleTypeDef *pdev,
113
                                uint8_t epnum);
114
 
115
static uint8_t  USBD_CDC_DataOut(USBD_HandleTypeDef *pdev,
116
                                 uint8_t epnum);
117
 
118
static uint8_t  USBD_CDC_EP0_RxReady(USBD_HandleTypeDef *pdev);
119
 
120
static uint8_t  *USBD_CDC_GetFSCfgDesc(uint16_t *length);
121
 
122
static uint8_t  *USBD_CDC_GetHSCfgDesc(uint16_t *length);
123
 
124
static uint8_t  *USBD_CDC_GetOtherSpeedCfgDesc(uint16_t *length);
125
 
126
static uint8_t  *USBD_CDC_GetOtherSpeedCfgDesc(uint16_t *length);
127
 
128
uint8_t  *USBD_CDC_GetDeviceQualifierDescriptor(uint16_t *length);
129
 
130
/* USB Standard Device Descriptor */
131
__ALIGN_BEGIN static uint8_t USBD_CDC_DeviceQualifierDesc[USB_LEN_DEV_QUALIFIER_DESC] __ALIGN_END =
132
{
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,
143
};
144
 
145
/**
146
  * @}
147
  */
148
 
149
/** @defgroup USBD_CDC_Private_Variables
150
  * @{
151
  */
152
 
153
 
154
/* CDC interface class callbacks structure */
155
USBD_ClassTypeDef  USBD_CDC =
156
{
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,
171
};
172
 
173
/* USB CDC device Configuration Descriptor */
174
__ALIGN_BEGIN uint8_t USBD_CDC_CfgHSDesc[USB_CDC_CONFIG_DESC_SIZ] __ALIGN_END =
175
{
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 */
186
 
187
  /*---------------------------------------------------------------------------*/
188
 
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: */
200
 
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,
207
 
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 */
214
 
215
  /*ACM Functional Descriptor*/
216
  0x04,   /* bFunctionLength */
217
  0x24,   /* bDescriptorType: CS_INTERFACE */
218
  0x02,   /* bDescriptorSubtype: Abstract Control Management desc */
219
  0x02,   /* bmCapabilities */
220
 
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 */
227
 
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
  /*---------------------------------------------------------------------------*/
237
 
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: */
248
 
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 */
257
 
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 */
266
} ;
267
 
268
 
269
/* USB CDC device Configuration Descriptor */
270
__ALIGN_BEGIN uint8_t USBD_CDC_CfgFSDesc[USB_CDC_CONFIG_DESC_SIZ] __ALIGN_END =
271
{
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 */
282
 
283
  /*---------------------------------------------------------------------------*/
284
 
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: */
296
 
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,
303
 
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 */
310
 
311
  /*ACM Functional Descriptor*/
312
  0x04,   /* bFunctionLength */
313
  0x24,   /* bDescriptorType: CS_INTERFACE */
314
  0x02,   /* bDescriptorSubtype: Abstract Control Management desc */
315
  0x02,   /* bmCapabilities */
316
 
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 */
323
 
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
  /*---------------------------------------------------------------------------*/
333
 
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: */
344
 
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 */
353
 
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 */
362
} ;
363
 
364
__ALIGN_BEGIN uint8_t USBD_CDC_OtherSpeedCfgDesc[USB_CDC_CONFIG_DESC_SIZ] __ALIGN_END =
365
{
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 */
375
 
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: */
387
 
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,
394
 
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 */
401
 
402
  /*ACM Functional Descriptor*/
403
  0x04,   /* bFunctionLength */
404
  0x24,   /* bDescriptorType: CS_INTERFACE */
405
  0x02,   /* bDescriptorSubtype: Abstract Control Management desc */
406
  0x02,   /* bmCapabilities */
407
 
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 */
414
 
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: */
423
 
424
  /*---------------------------------------------------------------------------*/
425
 
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: */
436
 
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 */
445
 
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 */
454
};
455
 
456
/**
457
  * @}
458
  */
459
 
460
/** @defgroup USBD_CDC_Private_Functions
461
  * @{
462
  */
463
 
464
/**
465
  * @brief  USBD_CDC_Init
466
  *         Initialize the CDC interface
467
  * @param  pdev: device instance
468
  * @param  cfgidx: Configuration index
469
  * @retval status
470
  */
471
static uint8_t  USBD_CDC_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
472
{
473
  uint8_t ret = 0U;
474
  USBD_CDC_HandleTypeDef   *hcdc;
475
 
476
  if (pdev->dev_speed == USBD_SPEED_HIGH)
477
  {
478
    /* Open EP IN */
479
    USBD_LL_OpenEP(pdev, CDC_IN_EP, USBD_EP_TYPE_BULK,
480
                   CDC_DATA_HS_IN_PACKET_SIZE);
481
 
482
    pdev->ep_in[CDC_IN_EP & 0xFU].is_used = 1U;
483
 
484
    /* Open EP OUT */
485
    USBD_LL_OpenEP(pdev, CDC_OUT_EP, USBD_EP_TYPE_BULK,
486
                   CDC_DATA_HS_OUT_PACKET_SIZE);
487
 
488
    pdev->ep_out[CDC_OUT_EP & 0xFU].is_used = 1U;
489
 
490
  }
491
  else
492
  {
493
    /* Open EP IN */
494
    USBD_LL_OpenEP(pdev, CDC_IN_EP, USBD_EP_TYPE_BULK,
495
                   CDC_DATA_FS_IN_PACKET_SIZE);
496
 
497
    pdev->ep_in[CDC_IN_EP & 0xFU].is_used = 1U;
498
 
499
    /* Open EP OUT */
500
    USBD_LL_OpenEP(pdev, CDC_OUT_EP, USBD_EP_TYPE_BULK,
501
                   CDC_DATA_FS_OUT_PACKET_SIZE);
502
 
503
    pdev->ep_out[CDC_OUT_EP & 0xFU].is_used = 1U;
504
  }
505
  /* Open Command IN EP */
506
  USBD_LL_OpenEP(pdev, CDC_CMD_EP, USBD_EP_TYPE_INTR, CDC_CMD_PACKET_SIZE);
507
  pdev->ep_in[CDC_CMD_EP & 0xFU].is_used = 1U;
508
 
509
  pdev->pClassData = USBD_malloc(sizeof(USBD_CDC_HandleTypeDef));
510
 
511
  if (pdev->pClassData == NULL)
512
  {
513
    ret = 1U;
514
  }
515
  else
516
  {
517
    hcdc = (USBD_CDC_HandleTypeDef *) pdev->pClassData;
518
 
519
    /* Init  physical Interface components */
520
    ((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Init();
521
 
522
    /* Init Xfer states */
523
    hcdc->TxState = 0U;
524
    hcdc->RxState = 0U;
525
 
526
    if (pdev->dev_speed == USBD_SPEED_HIGH)
527
    {
528
      /* Prepare Out endpoint to receive next packet */
529
      USBD_LL_PrepareReceive(pdev, CDC_OUT_EP, hcdc->RxBuffer,
530
                             CDC_DATA_HS_OUT_PACKET_SIZE);
531
    }
532
    else
533
    {
534
      /* Prepare Out endpoint to receive next packet */
535
      USBD_LL_PrepareReceive(pdev, CDC_OUT_EP, hcdc->RxBuffer,
536
                             CDC_DATA_FS_OUT_PACKET_SIZE);
537
    }
538
  }
539
  return ret;
540
}
541
 
542
/**
543
  * @brief  USBD_CDC_Init
544
  *         DeInitialize the CDC layer
545
  * @param  pdev: device instance
546
  * @param  cfgidx: Configuration index
547
  * @retval status
548
  */
549
static uint8_t  USBD_CDC_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
550
{
551
  uint8_t ret = 0U;
552
 
553
  /* Close EP IN */
554
  USBD_LL_CloseEP(pdev, CDC_IN_EP);
555
  pdev->ep_in[CDC_IN_EP & 0xFU].is_used = 0U;
556
 
557
  /* Close EP OUT */
558
  USBD_LL_CloseEP(pdev, CDC_OUT_EP);
559
  pdev->ep_out[CDC_OUT_EP & 0xFU].is_used = 0U;
560
 
561
  /* Close Command IN EP */
562
  USBD_LL_CloseEP(pdev, CDC_CMD_EP);
563
  pdev->ep_in[CDC_CMD_EP & 0xFU].is_used = 0U;
564
 
565
  /* DeInit  physical Interface components */
566
  if (pdev->pClassData != NULL)
567
  {
568
    ((USBD_CDC_ItfTypeDef *)pdev->pUserData)->DeInit();
569
    USBD_free(pdev->pClassData);
570
    pdev->pClassData = NULL;
571
  }
572
 
573
  return ret;
574
}
575
 
576
/**
577
  * @brief  USBD_CDC_Setup
578
  *         Handle the CDC specific requests
579
  * @param  pdev: instance
580
  * @param  req: usb requests
581
  * @retval status
582
  */
583
static uint8_t  USBD_CDC_Setup(USBD_HandleTypeDef *pdev,
584
                               USBD_SetupReqTypedef *req)
585
{
586
  USBD_CDC_HandleTypeDef   *hcdc = (USBD_CDC_HandleTypeDef *) pdev->pClassData;
587
  uint8_t ifalt = 0U;
588
  uint16_t status_info = 0U;
589
  uint8_t ret = USBD_OK;
590
 
591
  switch (req->bmRequest & USB_REQ_TYPE_MASK)
592
  {
593
    case USB_REQ_TYPE_CLASS :
594
      if (req->wLength)
595
      {
596
        if (req->bmRequest & 0x80U)
597
        {
598
          ((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Control(req->bRequest,
599
                                                            (uint8_t *)(void *)hcdc->data,
600
                                                            req->wLength);
601
 
602
          USBD_CtlSendData(pdev, (uint8_t *)(void *)hcdc->data, req->wLength);
603
        }
604
        else
605
        {
606
          hcdc->CmdOpCode = req->bRequest;
607
          hcdc->CmdLength = (uint8_t)req->wLength;
608
 
609
          USBD_CtlPrepareRx(pdev, (uint8_t *)(void *)hcdc->data, req->wLength);
610
        }
611
      }
612
      else
613
      {
614
        ((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Control(req->bRequest,
615
                                                          (uint8_t *)(void *)req, 0U);
616
      }
617
      break;
618
 
619
    case USB_REQ_TYPE_STANDARD:
620
      switch (req->bRequest)
621
      {
622
        case USB_REQ_GET_STATUS:
623
          if (pdev->dev_state == USBD_STATE_CONFIGURED)
624
          {
625
            USBD_CtlSendData(pdev, (uint8_t *)(void *)&status_info, 2U);
626
          }
627
          else
628
          {
629
            USBD_CtlError(pdev, req);
630
            ret = USBD_FAIL;
631
          }
632
          break;
633
 
634
        case USB_REQ_GET_INTERFACE:
635
          if (pdev->dev_state == USBD_STATE_CONFIGURED)
636
          {
637
            USBD_CtlSendData(pdev, &ifalt, 1U);
638
          }
639
          else
640
          {
641
            USBD_CtlError(pdev, req);
642
            ret = USBD_FAIL;
643
          }
644
          break;
645
 
646
        case USB_REQ_SET_INTERFACE:
647
          if (pdev->dev_state != USBD_STATE_CONFIGURED)
648
          {
649
            USBD_CtlError(pdev, req);
650
            ret = USBD_FAIL;
651
          }
652
          break;
653
 
654
        default:
655
          USBD_CtlError(pdev, req);
656
          ret = USBD_FAIL;
657
          break;
658
      }
659
      break;
660
 
661
    default:
662
      USBD_CtlError(pdev, req);
663
      ret = USBD_FAIL;
664
      break;
665
  }
666
 
667
  return ret;
668
}
669
 
670
/**
671
  * @brief  USBD_CDC_DataIn
672
  *         Data sent on non-control IN endpoint
673
  * @param  pdev: device instance
674
  * @param  epnum: endpoint number
675
  * @retval status
676
  */
677
static uint8_t  USBD_CDC_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum)
678
{
679
  USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef *)pdev->pClassData;
680
  PCD_HandleTypeDef *hpcd = pdev->pData;
681
 
682
  if (pdev->pClassData != NULL)
683
  {
684
    if ((pdev->ep_in[epnum].total_length > 0U) && ((pdev->ep_in[epnum].total_length % hpcd->IN_ep[epnum].maxpacket) == 0U))
685
    {
686
      /* Update the packet total length */
687
      pdev->ep_in[epnum].total_length = 0U;
688
 
689
      /* Send ZLP */
690
      USBD_LL_Transmit(pdev, epnum, NULL, 0U);
691
    }
692
    else
693
    {
694
      hcdc->TxState = 0U;
695
    }
696
    return USBD_OK;
697
  }
698
  else
699
  {
700
    return USBD_FAIL;
701
  }
702
}
703
 
704
/**
705
  * @brief  USBD_CDC_DataOut
706
  *         Data received on non-control Out endpoint
707
  * @param  pdev: device instance
708
  * @param  epnum: endpoint number
709
  * @retval status
710
  */
711
static uint8_t  USBD_CDC_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum)
712
{
713
  USBD_CDC_HandleTypeDef   *hcdc = (USBD_CDC_HandleTypeDef *) pdev->pClassData;
714
 
715
  /* Get the received data length */
716
  hcdc->RxLength = USBD_LL_GetRxDataSize(pdev, epnum);
717
 
718
  /* USB data will be immediately processed, this allow next USB traffic being
719
  NAKed till the end of the application Xfer */
720
  if (pdev->pClassData != NULL)
721
  {
722
    ((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Receive(hcdc->RxBuffer, &hcdc->RxLength);
723
 
724
    return USBD_OK;
725
  }
726
  else
727
  {
728
    return USBD_FAIL;
729
  }
730
}
731
 
732
/**
733
  * @brief  USBD_CDC_EP0_RxReady
734
  *         Handle EP0 Rx Ready event
735
  * @param  pdev: device instance
736
  * @retval status
737
  */
738
static uint8_t  USBD_CDC_EP0_RxReady(USBD_HandleTypeDef *pdev)
739
{
740
  USBD_CDC_HandleTypeDef   *hcdc = (USBD_CDC_HandleTypeDef *) pdev->pClassData;
741
 
742
  if ((pdev->pUserData != NULL) && (hcdc->CmdOpCode != 0xFFU))
743
  {
744
    ((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Control(hcdc->CmdOpCode,
745
                                                      (uint8_t *)(void *)hcdc->data,
746
                                                      (uint16_t)hcdc->CmdLength);
747
    hcdc->CmdOpCode = 0xFFU;
748
 
749
  }
750
  return USBD_OK;
751
}
752
 
753
/**
754
  * @brief  USBD_CDC_GetFSCfgDesc
755
  *         Return configuration descriptor
756
  * @param  speed : current device speed
757
  * @param  length : pointer data length
758
  * @retval pointer to descriptor buffer
759
  */
760
static uint8_t  *USBD_CDC_GetFSCfgDesc(uint16_t *length)
761
{
762
  *length = sizeof(USBD_CDC_CfgFSDesc);
763
  return USBD_CDC_CfgFSDesc;
764
}
765
 
766
/**
767
  * @brief  USBD_CDC_GetHSCfgDesc
768
  *         Return configuration descriptor
769
  * @param  speed : current device speed
770
  * @param  length : pointer data length
771
  * @retval pointer to descriptor buffer
772
  */
773
static uint8_t  *USBD_CDC_GetHSCfgDesc(uint16_t *length)
774
{
775
  *length = sizeof(USBD_CDC_CfgHSDesc);
776
  return USBD_CDC_CfgHSDesc;
777
}
778
 
779
/**
780
  * @brief  USBD_CDC_GetCfgDesc
781
  *         Return configuration descriptor
782
  * @param  speed : current device speed
783
  * @param  length : pointer data length
784
  * @retval pointer to descriptor buffer
785
  */
786
static uint8_t  *USBD_CDC_GetOtherSpeedCfgDesc(uint16_t *length)
787
{
788
  *length = sizeof(USBD_CDC_OtherSpeedCfgDesc);
789
  return USBD_CDC_OtherSpeedCfgDesc;
790
}
791
 
792
/**
793
* @brief  DeviceQualifierDescriptor
794
*         return Device Qualifier descriptor
795
* @param  length : pointer data length
796
* @retval pointer to descriptor buffer
797
*/
798
uint8_t  *USBD_CDC_GetDeviceQualifierDescriptor(uint16_t *length)
799
{
800
  *length = sizeof(USBD_CDC_DeviceQualifierDesc);
801
  return USBD_CDC_DeviceQualifierDesc;
802
}
803
 
804
/**
805
* @brief  USBD_CDC_RegisterInterface
806
  * @param  pdev: device instance
807
  * @param  fops: CD  Interface callback
808
  * @retval status
809
  */
810
uint8_t  USBD_CDC_RegisterInterface(USBD_HandleTypeDef   *pdev,
811
                                    USBD_CDC_ItfTypeDef *fops)
812
{
813
  uint8_t  ret = USBD_FAIL;
814
 
815
  if (fops != NULL)
816
  {
817
    pdev->pUserData = fops;
818
    ret = USBD_OK;
819
  }
820
 
821
  return ret;
822
}
823
 
824
/**
825
  * @brief  USBD_CDC_SetTxBuffer
826
  * @param  pdev: device instance
827
  * @param  pbuff: Tx Buffer
828
  * @retval status
829
  */
830
uint8_t  USBD_CDC_SetTxBuffer(USBD_HandleTypeDef   *pdev,
831
                              uint8_t  *pbuff,
832
                              uint16_t length)
833
{
834
  USBD_CDC_HandleTypeDef   *hcdc = (USBD_CDC_HandleTypeDef *) pdev->pClassData;
835
 
836
  hcdc->TxBuffer = pbuff;
837
  hcdc->TxLength = length;
838
 
839
  return USBD_OK;
840
}
841
 
842
 
843
/**
844
  * @brief  USBD_CDC_SetRxBuffer
845
  * @param  pdev: device instance
846
  * @param  pbuff: Rx Buffer
847
  * @retval status
848
  */
849
uint8_t  USBD_CDC_SetRxBuffer(USBD_HandleTypeDef   *pdev,
850
                              uint8_t  *pbuff)
851
{
852
  USBD_CDC_HandleTypeDef   *hcdc = (USBD_CDC_HandleTypeDef *) pdev->pClassData;
853
 
854
  hcdc->RxBuffer = pbuff;
855
 
856
  return USBD_OK;
857
}
858
 
859
/**
860
  * @brief  USBD_CDC_TransmitPacket
861
  *         Transmit packet on IN endpoint
862
  * @param  pdev: device instance
863
  * @retval status
864
  */
865
uint8_t  USBD_CDC_TransmitPacket(USBD_HandleTypeDef *pdev)
866
{
867
  USBD_CDC_HandleTypeDef   *hcdc = (USBD_CDC_HandleTypeDef *) pdev->pClassData;
868
 
869
  if (pdev->pClassData != NULL)
870
  {
871
    if (hcdc->TxState == 0U)
872
    {
873
      /* Tx Transfer in progress */
874
      hcdc->TxState = 1U;
875
 
876
      /* Update the packet total length */
877
      pdev->ep_in[CDC_IN_EP & 0xFU].total_length = hcdc->TxLength;
878
 
879
      /* Transmit next packet */
880
      USBD_LL_Transmit(pdev, CDC_IN_EP, hcdc->TxBuffer,
881
                       (uint16_t)hcdc->TxLength);
882
 
883
      return USBD_OK;
884
    }
885
    else
886
    {
887
      return USBD_BUSY;
888
    }
889
  }
890
  else
891
  {
892
    return USBD_FAIL;
893
  }
894
}
895
 
896
 
897
/**
898
  * @brief  USBD_CDC_ReceivePacket
899
  *         prepare OUT Endpoint for reception
900
  * @param  pdev: device instance
901
  * @retval status
902
  */
903
uint8_t  USBD_CDC_ReceivePacket(USBD_HandleTypeDef *pdev)
904
{
905
  USBD_CDC_HandleTypeDef   *hcdc = (USBD_CDC_HandleTypeDef *) pdev->pClassData;
906
 
907
  /* Suspend or Resume USB Out process */
908
  if (pdev->pClassData != NULL)
909
  {
910
    if (pdev->dev_speed == USBD_SPEED_HIGH)
911
    {
912
      /* Prepare Out endpoint to receive next packet */
913
      USBD_LL_PrepareReceive(pdev,
914
                             CDC_OUT_EP,
915
                             hcdc->RxBuffer,
916
                             CDC_DATA_HS_OUT_PACKET_SIZE);
917
    }
918
    else
919
    {
920
      /* Prepare Out endpoint to receive next packet */
921
      USBD_LL_PrepareReceive(pdev,
922
                             CDC_OUT_EP,
923
                             hcdc->RxBuffer,
924
                             CDC_DATA_FS_OUT_PACKET_SIZE);
925
    }
926
    return USBD_OK;
927
  }
928
  else
929
  {
930
    return USBD_FAIL;
931
  }
932
}
933
/**
934
  * @}
935
  */
936
 
937
/**
938
  * @}
939
  */
940
 
941
/**
942
  * @}
943
  */
944
 
945
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/