Subversion Repositories LedShow

Rev

Rev 2 | Details | Compare with Previous | 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
9 mjames 5
  * @brief   This file provides the high layer firmware functions to manage the
2 mjames 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
9 mjames 12
  *
2 mjames 13
  *  @verbatim
9 mjames 14
  *
15
  *          ===================================================================
2 mjames 16
  *                                CDC Class Driver Description
9 mjames 17
  *          ===================================================================
2 mjames 18
  *           This driver manages the "Universal Serial Bus Class Definitions for Communications Devices
9 mjames 19
  *           Revision 1.2 November 16, 2007" and the sub-protocol specification of "Universal Serial Bus
2 mjames 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
9 mjames 29
  *
2 mjames 30
  *           These aspects may be enriched or modified for a specific user application.
9 mjames 31
  *
32
  *            This driver doesn't implement the following aspects of the specification
2 mjames 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
9 mjames 36
  *
2 mjames 37
  *  @endverbatim
9 mjames 38
  *
2 mjames 39
  ******************************************************************************
40
  * @attention
41
  *
9 mjames 42
  * <h2><center>&copy; Copyright (c) 2015 STMicroelectronics.
43
  * All rights reserved.</center></h2>
2 mjames 44
  *
9 mjames 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
2 mjames 49
  *
50
  ******************************************************************************
9 mjames 51
  */
2 mjames 52
 
9 mjames 53
/* BSPDependencies
54
- "stm32xxxxx_{eval}{discovery}{nucleo_144}.c"
55
- "stm32xxxxx_{eval}{discovery}_io.c"
56
EndBSPDependencies */
57
 
2 mjames 58
/* Includes ------------------------------------------------------------------*/
59
#include "usbd_cdc.h"
60
#include "usbd_ctlreq.h"
61
 
62
 
63
/** @addtogroup STM32_USB_DEVICE_LIBRARY
64
  * @{
65
  */
66
 
67
 
9 mjames 68
/** @defgroup USBD_CDC
2 mjames 69
  * @brief usbd core module
70
  * @{
9 mjames 71
  */
2 mjames 72
 
73
/** @defgroup USBD_CDC_Private_TypesDefinitions
74
  * @{
9 mjames 75
  */
2 mjames 76
/**
77
  * @}
9 mjames 78
  */
2 mjames 79
 
80
 
81
/** @defgroup USBD_CDC_Private_Defines
82
  * @{
9 mjames 83
  */
2 mjames 84
/**
85
  * @}
9 mjames 86
  */
2 mjames 87
 
88
 
89
/** @defgroup USBD_CDC_Private_Macros
90
  * @{
9 mjames 91
  */
2 mjames 92
 
93
/**
94
  * @}
9 mjames 95
  */
2 mjames 96
 
97
 
98
/** @defgroup USBD_CDC_Private_FunctionPrototypes
99
  * @{
100
  */
101
 
102
 
9 mjames 103
static uint8_t  USBD_CDC_Init(USBD_HandleTypeDef *pdev,
104
                              uint8_t cfgidx);
2 mjames 105
 
9 mjames 106
static uint8_t  USBD_CDC_DeInit(USBD_HandleTypeDef *pdev,
107
                                uint8_t cfgidx);
2 mjames 108
 
9 mjames 109
static uint8_t  USBD_CDC_Setup(USBD_HandleTypeDef *pdev,
110
                               USBD_SetupReqTypedef *req);
2 mjames 111
 
9 mjames 112
static uint8_t  USBD_CDC_DataIn(USBD_HandleTypeDef *pdev,
113
                                uint8_t epnum);
2 mjames 114
 
9 mjames 115
static uint8_t  USBD_CDC_DataOut(USBD_HandleTypeDef *pdev,
2 mjames 116
                                 uint8_t epnum);
117
 
9 mjames 118
static uint8_t  USBD_CDC_EP0_RxReady(USBD_HandleTypeDef *pdev);
2 mjames 119
 
9 mjames 120
static uint8_t  *USBD_CDC_GetFSCfgDesc(uint16_t *length);
2 mjames 121
 
9 mjames 122
static uint8_t  *USBD_CDC_GetHSCfgDesc(uint16_t *length);
2 mjames 123
 
9 mjames 124
static uint8_t  *USBD_CDC_GetOtherSpeedCfgDesc(uint16_t *length);
2 mjames 125
 
9 mjames 126
static uint8_t  *USBD_CDC_GetOtherSpeedCfgDesc(uint16_t *length);
2 mjames 127
 
9 mjames 128
uint8_t  *USBD_CDC_GetDeviceQualifierDescriptor(uint16_t *length);
2 mjames 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
  * @}
9 mjames 147
  */
2 mjames 148
 
149
/** @defgroup USBD_CDC_Private_Variables
150
  * @{
9 mjames 151
  */
2 mjames 152
 
153
 
154
/* CDC interface class callbacks structure */
9 mjames 155
USBD_ClassTypeDef  USBD_CDC =
2 mjames 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,
9 mjames 166
  NULL,
167
  USBD_CDC_GetHSCfgDesc,
168
  USBD_CDC_GetFSCfgDesc,
169
  USBD_CDC_GetOtherSpeedCfgDesc,
2 mjames 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 */
9 mjames 186
 
2 mjames 187
  /*---------------------------------------------------------------------------*/
9 mjames 188
 
2 mjames 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: */
9 mjames 200
 
2 mjames 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,
9 mjames 207
 
2 mjames 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 */
9 mjames 214
 
2 mjames 215
  /*ACM Functional Descriptor*/
216
  0x04,   /* bFunctionLength */
217
  0x24,   /* bDescriptorType: CS_INTERFACE */
218
  0x02,   /* bDescriptorSubtype: Abstract Control Management desc */
219
  0x02,   /* bmCapabilities */
9 mjames 220
 
2 mjames 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 */
9 mjames 227
 
2 mjames 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),
9 mjames 235
  CDC_HS_BINTERVAL,                           /* bInterval: */
2 mjames 236
  /*---------------------------------------------------------------------------*/
9 mjames 237
 
2 mjames 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: */
9 mjames 248
 
2 mjames 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 */
9 mjames 257
 
2 mjames 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 */
9 mjames 282
 
2 mjames 283
  /*---------------------------------------------------------------------------*/
9 mjames 284
 
2 mjames 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: */
9 mjames 296
 
2 mjames 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,
9 mjames 303
 
2 mjames 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 */
9 mjames 310
 
2 mjames 311
  /*ACM Functional Descriptor*/
312
  0x04,   /* bFunctionLength */
313
  0x24,   /* bDescriptorType: CS_INTERFACE */
314
  0x02,   /* bDescriptorSubtype: Abstract Control Management desc */
315
  0x02,   /* bmCapabilities */
9 mjames 316
 
2 mjames 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 */
9 mjames 323
 
2 mjames 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),
9 mjames 331
  CDC_FS_BINTERVAL,                           /* bInterval: */
2 mjames 332
  /*---------------------------------------------------------------------------*/
9 mjames 333
 
2 mjames 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: */
9 mjames 344
 
2 mjames 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 */
9 mjames 353
 
2 mjames 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 =
9 mjames 365
{
2 mjames 366
  0x09,   /* bLength: Configuation Descriptor size */
9 mjames 367
  USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION,
2 mjames 368
  USB_CDC_CONFIG_DESC_SIZ,
369
  0x00,
370
  0x02,   /* bNumInterfaces: 2 interfaces */
371
  0x01,   /* bConfigurationValue: */
372
  0x04,   /* iConfiguration: */
373
  0xC0,   /* bmAttributes: */
9 mjames 374
  0x32,   /* MaxPower 100 mA */
375
 
2 mjames 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: */
9 mjames 387
 
2 mjames 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,
9 mjames 394
 
2 mjames 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 */
9 mjames 401
 
2 mjames 402
  /*ACM Functional Descriptor*/
403
  0x04,   /* bFunctionLength */
404
  0x24,   /* bDescriptorType: CS_INTERFACE */
405
  0x02,   /* bDescriptorSubtype: Abstract Control Management desc */
406
  0x02,   /* bmCapabilities */
9 mjames 407
 
2 mjames 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 */
9 mjames 414
 
2 mjames 415
  /*Endpoint 2 Descriptor*/
416
  0x07,                           /* bLength: Endpoint Descriptor size */
9 mjames 417
  USB_DESC_TYPE_ENDPOINT,         /* bDescriptorType: Endpoint */
2 mjames 418
  CDC_CMD_EP,                     /* bEndpointAddress */
419
  0x03,                           /* bmAttributes: Interrupt */
420
  LOBYTE(CDC_CMD_PACKET_SIZE),     /* wMaxPacketSize: */
421
  HIBYTE(CDC_CMD_PACKET_SIZE),
9 mjames 422
  CDC_FS_BINTERVAL,                           /* bInterval: */
423
 
2 mjames 424
  /*---------------------------------------------------------------------------*/
9 mjames 425
 
2 mjames 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: */
9 mjames 436
 
2 mjames 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 */
9 mjames 445
 
2 mjames 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
  * @}
9 mjames 458
  */
2 mjames 459
 
460
/** @defgroup USBD_CDC_Private_Functions
461
  * @{
9 mjames 462
  */
2 mjames 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
  */
9 mjames 471
static uint8_t  USBD_CDC_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
2 mjames 472
{
9 mjames 473
  uint8_t ret = 0U;
2 mjames 474
  USBD_CDC_HandleTypeDef   *hcdc;
9 mjames 475
 
476
  if (pdev->dev_speed == USBD_SPEED_HIGH)
477
  {
2 mjames 478
    /* Open EP IN */
9 mjames 479
    USBD_LL_OpenEP(pdev, CDC_IN_EP, USBD_EP_TYPE_BULK,
2 mjames 480
                   CDC_DATA_HS_IN_PACKET_SIZE);
9 mjames 481
 
482
    pdev->ep_in[CDC_IN_EP & 0xFU].is_used = 1U;
483
 
2 mjames 484
    /* Open EP OUT */
9 mjames 485
    USBD_LL_OpenEP(pdev, CDC_OUT_EP, USBD_EP_TYPE_BULK,
2 mjames 486
                   CDC_DATA_HS_OUT_PACKET_SIZE);
9 mjames 487
 
488
    pdev->ep_out[CDC_OUT_EP & 0xFU].is_used = 1U;
489
 
2 mjames 490
  }
491
  else
492
  {
493
    /* Open EP IN */
9 mjames 494
    USBD_LL_OpenEP(pdev, CDC_IN_EP, USBD_EP_TYPE_BULK,
2 mjames 495
                   CDC_DATA_FS_IN_PACKET_SIZE);
9 mjames 496
 
497
    pdev->ep_in[CDC_IN_EP & 0xFU].is_used = 1U;
498
 
2 mjames 499
    /* Open EP OUT */
9 mjames 500
    USBD_LL_OpenEP(pdev, CDC_OUT_EP, USBD_EP_TYPE_BULK,
2 mjames 501
                   CDC_DATA_FS_OUT_PACKET_SIZE);
9 mjames 502
 
503
    pdev->ep_out[CDC_OUT_EP & 0xFU].is_used = 1U;
2 mjames 504
  }
505
  /* Open Command IN EP */
9 mjames 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)
2 mjames 512
  {
9 mjames 513
    ret = 1U;
2 mjames 514
  }
515
  else
516
  {
9 mjames 517
    hcdc = (USBD_CDC_HandleTypeDef *) pdev->pClassData;
518
 
2 mjames 519
    /* Init  physical Interface components */
520
    ((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Init();
9 mjames 521
 
2 mjames 522
    /* Init Xfer states */
9 mjames 523
    hcdc->TxState = 0U;
524
    hcdc->RxState = 0U;
525
 
526
    if (pdev->dev_speed == USBD_SPEED_HIGH)
527
    {
2 mjames 528
      /* Prepare Out endpoint to receive next packet */
9 mjames 529
      USBD_LL_PrepareReceive(pdev, CDC_OUT_EP, hcdc->RxBuffer,
2 mjames 530
                             CDC_DATA_HS_OUT_PACKET_SIZE);
531
    }
532
    else
533
    {
534
      /* Prepare Out endpoint to receive next packet */
9 mjames 535
      USBD_LL_PrepareReceive(pdev, CDC_OUT_EP, hcdc->RxBuffer,
2 mjames 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
  */
9 mjames 549
static uint8_t  USBD_CDC_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
2 mjames 550
{
9 mjames 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
 
2 mjames 565
  /* DeInit  physical Interface components */
9 mjames 566
  if (pdev->pClassData != NULL)
2 mjames 567
  {
568
    ((USBD_CDC_ItfTypeDef *)pdev->pUserData)->DeInit();
569
    USBD_free(pdev->pClassData);
570
    pdev->pClassData = NULL;
571
  }
9 mjames 572
 
2 mjames 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
  */
9 mjames 583
static uint8_t  USBD_CDC_Setup(USBD_HandleTypeDef *pdev,
584
                               USBD_SetupReqTypedef *req)
2 mjames 585
{
9 mjames 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
 
2 mjames 591
  switch (req->bmRequest & USB_REQ_TYPE_MASK)
592
  {
9 mjames 593
    case USB_REQ_TYPE_CLASS :
594
      if (req->wLength)
2 mjames 595
      {
9 mjames 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
        }
2 mjames 611
      }
612
      else
613
      {
9 mjames 614
        ((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Control(req->bRequest,
615
                                                          (uint8_t *)(void *)req, 0U);
2 mjames 616
      }
9 mjames 617
      break;
2 mjames 618
 
9 mjames 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
      }
2 mjames 659
      break;
9 mjames 660
 
661
    default:
662
      USBD_CtlError(pdev, req);
663
      ret = USBD_FAIL;
2 mjames 664
      break;
665
  }
9 mjames 666
 
667
  return ret;
2 mjames 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
  */
9 mjames 677
static uint8_t  USBD_CDC_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum)
2 mjames 678
{
9 mjames 679
  USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef *)pdev->pClassData;
680
  PCD_HandleTypeDef *hpcd = pdev->pData;
681
 
682
  if (pdev->pClassData != NULL)
2 mjames 683
  {
9 mjames 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;
2 mjames 688
 
9 mjames 689
      /* Send ZLP */
690
      USBD_LL_Transmit(pdev, epnum, NULL, 0U);
691
    }
692
    else
693
    {
694
      hcdc->TxState = 0U;
695
    }
2 mjames 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
  */
9 mjames 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
 
2 mjames 715
  /* Get the received data length */
9 mjames 716
  hcdc->RxLength = USBD_LL_GetRxDataSize(pdev, epnum);
717
 
718
  /* USB data will be immediately processed, this allow next USB traffic being
2 mjames 719
  NAKed till the end of the application Xfer */
9 mjames 720
  if (pdev->pClassData != NULL)
2 mjames 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
/**
9 mjames 733
  * @brief  USBD_CDC_EP0_RxReady
734
  *         Handle EP0 Rx Ready event
2 mjames 735
  * @param  pdev: device instance
736
  * @retval status
737
  */
9 mjames 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))
2 mjames 743
  {
744
    ((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Control(hcdc->CmdOpCode,
9 mjames 745
                                                      (uint8_t *)(void *)hcdc->data,
746
                                                      (uint16_t)hcdc->CmdLength);
747
    hcdc->CmdOpCode = 0xFFU;
748
 
2 mjames 749
  }
750
  return USBD_OK;
751
}
752
 
753
/**
9 mjames 754
  * @brief  USBD_CDC_GetFSCfgDesc
2 mjames 755
  *         Return configuration descriptor
756
  * @param  speed : current device speed
757
  * @param  length : pointer data length
758
  * @retval pointer to descriptor buffer
759
  */
9 mjames 760
static uint8_t  *USBD_CDC_GetFSCfgDesc(uint16_t *length)
2 mjames 761
{
9 mjames 762
  *length = sizeof(USBD_CDC_CfgFSDesc);
2 mjames 763
  return USBD_CDC_CfgFSDesc;
764
}
765
 
766
/**
9 mjames 767
  * @brief  USBD_CDC_GetHSCfgDesc
2 mjames 768
  *         Return configuration descriptor
769
  * @param  speed : current device speed
770
  * @param  length : pointer data length
771
  * @retval pointer to descriptor buffer
772
  */
9 mjames 773
static uint8_t  *USBD_CDC_GetHSCfgDesc(uint16_t *length)
2 mjames 774
{
9 mjames 775
  *length = sizeof(USBD_CDC_CfgHSDesc);
2 mjames 776
  return USBD_CDC_CfgHSDesc;
777
}
778
 
779
/**
9 mjames 780
  * @brief  USBD_CDC_GetCfgDesc
2 mjames 781
  *         Return configuration descriptor
782
  * @param  speed : current device speed
783
  * @param  length : pointer data length
784
  * @retval pointer to descriptor buffer
785
  */
9 mjames 786
static uint8_t  *USBD_CDC_GetOtherSpeedCfgDesc(uint16_t *length)
2 mjames 787
{
9 mjames 788
  *length = sizeof(USBD_CDC_OtherSpeedCfgDesc);
2 mjames 789
  return USBD_CDC_OtherSpeedCfgDesc;
790
}
791
 
792
/**
9 mjames 793
* @brief  DeviceQualifierDescriptor
2 mjames 794
*         return Device Qualifier descriptor
795
* @param  length : pointer data length
796
* @retval pointer to descriptor buffer
797
*/
9 mjames 798
uint8_t  *USBD_CDC_GetDeviceQualifierDescriptor(uint16_t *length)
2 mjames 799
{
9 mjames 800
  *length = sizeof(USBD_CDC_DeviceQualifierDesc);
2 mjames 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
  */
9 mjames 810
uint8_t  USBD_CDC_RegisterInterface(USBD_HandleTypeDef   *pdev,
811
                                    USBD_CDC_ItfTypeDef *fops)
2 mjames 812
{
813
  uint8_t  ret = USBD_FAIL;
9 mjames 814
 
815
  if (fops != NULL)
2 mjames 816
  {
9 mjames 817
    pdev->pUserData = fops;
818
    ret = USBD_OK;
2 mjames 819
  }
9 mjames 820
 
2 mjames 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
  */
9 mjames 830
uint8_t  USBD_CDC_SetTxBuffer(USBD_HandleTypeDef   *pdev,
831
                              uint8_t  *pbuff,
832
                              uint16_t length)
2 mjames 833
{
9 mjames 834
  USBD_CDC_HandleTypeDef   *hcdc = (USBD_CDC_HandleTypeDef *) pdev->pClassData;
835
 
2 mjames 836
  hcdc->TxBuffer = pbuff;
9 mjames 837
  hcdc->TxLength = length;
838
 
839
  return USBD_OK;
2 mjames 840
}
841
 
842
 
843
/**
844
  * @brief  USBD_CDC_SetRxBuffer
845
  * @param  pdev: device instance
846
  * @param  pbuff: Rx Buffer
847
  * @retval status
848
  */
9 mjames 849
uint8_t  USBD_CDC_SetRxBuffer(USBD_HandleTypeDef   *pdev,
850
                              uint8_t  *pbuff)
2 mjames 851
{
9 mjames 852
  USBD_CDC_HandleTypeDef   *hcdc = (USBD_CDC_HandleTypeDef *) pdev->pClassData;
853
 
2 mjames 854
  hcdc->RxBuffer = pbuff;
9 mjames 855
 
2 mjames 856
  return USBD_OK;
857
}
858
 
859
/**
9 mjames 860
  * @brief  USBD_CDC_TransmitPacket
861
  *         Transmit packet on IN endpoint
2 mjames 862
  * @param  pdev: device instance
863
  * @retval status
864
  */
865
uint8_t  USBD_CDC_TransmitPacket(USBD_HandleTypeDef *pdev)
9 mjames 866
{
867
  USBD_CDC_HandleTypeDef   *hcdc = (USBD_CDC_HandleTypeDef *) pdev->pClassData;
868
 
869
  if (pdev->pClassData != NULL)
2 mjames 870
  {
9 mjames 871
    if (hcdc->TxState == 0U)
2 mjames 872
    {
873
      /* Tx Transfer in progress */
9 mjames 874
      hcdc->TxState = 1U;
875
 
876
      /* Update the packet total length */
877
      pdev->ep_in[CDC_IN_EP & 0xFU].total_length = hcdc->TxLength;
878
 
2 mjames 879
      /* Transmit next packet */
9 mjames 880
      USBD_LL_Transmit(pdev, CDC_IN_EP, hcdc->TxBuffer,
881
                       (uint16_t)hcdc->TxLength);
882
 
2 mjames 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)
9 mjames 904
{
905
  USBD_CDC_HandleTypeDef   *hcdc = (USBD_CDC_HandleTypeDef *) pdev->pClassData;
906
 
2 mjames 907
  /* Suspend or Resume USB Out process */
9 mjames 908
  if (pdev->pClassData != NULL)
2 mjames 909
  {
9 mjames 910
    if (pdev->dev_speed == USBD_SPEED_HIGH)
911
    {
2 mjames 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
  * @}
9 mjames 935
  */
2 mjames 936
 
937
/**
938
  * @}
9 mjames 939
  */
2 mjames 940
 
941
/**
942
  * @}
9 mjames 943
  */
2 mjames 944
 
945
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/