Subversion Repositories DashDisplay

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
  * @version V2.4.1
6
  * @date    19-June-2015
7
  * @brief   This file provides the high layer firmware functions to manage the
8
  *          following functionalities of the USB CDC Class:
9
  *           - Initialization and Configuration of high and low layer
10
  *           - Enumeration as CDC Device (and enumeration for each implemented memory interface)
11
  *           - OUT/IN data transfer
12
  *           - Command IN transfer (class requests management)
13
  *           - Error management
14
  *          
15
  *  @verbatim
16
  *      
17
  *          ===================================================================      
18
  *                                CDC Class Driver Description
19
  *          ===================================================================
20
  *           This driver manages the "Universal Serial Bus Class Definitions for Communications Devices
21
  *           Revision 1.2 November 16, 2007" and the sub-protocol specification of "Universal Serial Bus
22
  *           Communications Class Subclass Specification for PSTN Devices Revision 1.2 February 9, 2007"
23
  *           This driver implements the following aspects of the specification:
24
  *             - Device descriptor management
25
  *             - Configuration descriptor management
26
  *             - Enumeration as CDC device with 2 data endpoints (IN and OUT) and 1 command endpoint (IN)
27
  *             - Requests management (as described in section 6.2 in specification)
28
  *             - Abstract Control Model compliant
29
  *             - Union Functional collection (using 1 IN endpoint for control)
30
  *             - Data interface class
31
  *
32
  *           These aspects may be enriched or modified for a specific user application.
33
  *          
34
  *            This driver doesn't implement the following aspects of the specification
35
  *            (but it is possible to manage these features with some modifications on this driver):
36
  *             - Any class-specific aspect relative to communication classes should be managed by user application.
37
  *             - All communication classes other than PSTN are not managed
38
  *      
39
  *  @endverbatim
40
  *                                  
41
  ******************************************************************************
42
  * @attention
43
  *
44
  * <h2><center>&copy; COPYRIGHT 2015 STMicroelectronics</center></h2>
45
  *
46
  * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
47
  * You may not use this file except in compliance with the License.
48
  * You may obtain a copy of the License at:
49
  *
50
  *        http://www.st.com/software_license_agreement_liberty_v2
51
  *
52
  * Unless required by applicable law or agreed to in writing, software
53
  * distributed under the License is distributed on an "AS IS" BASIS,
54
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
55
  * See the License for the specific language governing permissions and
56
  * limitations under the License.
57
  *
58
  ******************************************************************************
59
  */
60
 
61
/* Includes ------------------------------------------------------------------*/
62
#include "USBD_CDC.h"
63
#include "usbd_desc.h"
64
#include "usbd_ctlreq.h"
65
 
66
 
67
/** @addtogroup STM32_USB_DEVICE_LIBRARY
68
  * @{
69
  */
70
 
71
 
72
/** @defgroup USBD_CDC
73
  * @brief usbd core module
74
  * @{
75
  */
76
 
77
/** @defgroup USBD_CDC_Private_TypesDefinitions
78
  * @{
79
  */
80
/**
81
  * @}
82
  */
83
 
84
 
85
/** @defgroup USBD_CDC_Private_Defines
86
  * @{
87
  */
88
/**
89
  * @}
90
  */
91
 
92
 
93
/** @defgroup USBD_CDC_Private_Macros
94
  * @{
95
  */
96
 
97
/**
98
  * @}
99
  */
100
 
101
 
102
/** @defgroup USBD_CDC_Private_FunctionPrototypes
103
  * @{
104
  */
105
 
106
 
107
static uint8_t  USBD_CDC_Init (USBD_HandleTypeDef *pdev,
108
                               uint8_t cfgidx);
109
 
110
static uint8_t  USBD_CDC_DeInit (USBD_HandleTypeDef *pdev,
111
                                 uint8_t cfgidx);
112
 
113
static uint8_t  USBD_CDC_Setup (USBD_HandleTypeDef *pdev,
114
                                USBD_SetupReqTypedef *req);
115
 
116
static uint8_t  USBD_CDC_DataIn (USBD_HandleTypeDef *pdev,
117
                                 uint8_t epnum);
118
 
119
static uint8_t  USBD_CDC_DataOut (USBD_HandleTypeDef *pdev,
120
                                 uint8_t epnum);
121
 
122
static uint8_t  USBD_CDC_EP0_RxReady (USBD_HandleTypeDef *pdev);
123
 
124
static uint8_t  *USBD_CDC_GetFSCfgDesc (uint16_t *length);
125
 
126
static uint8_t  *USBD_CDC_GetHSCfgDesc (uint16_t *length);
127
 
128
static uint8_t  *USBD_CDC_GetOtherSpeedCfgDesc (uint16_t *length);
129
 
130
static uint8_t  *USBD_CDC_GetOtherSpeedCfgDesc (uint16_t *length);
131
 
132
uint8_t  *USBD_CDC_GetDeviceQualifierDescriptor (uint16_t *length);
133
 
134
/* USB Standard Device Descriptor */
135
__ALIGN_BEGIN static uint8_t USBD_CDC_DeviceQualifierDesc[USB_LEN_DEV_QUALIFIER_DESC] __ALIGN_END =
136
{
137
  USB_LEN_DEV_QUALIFIER_DESC,
138
  USB_DESC_TYPE_DEVICE_QUALIFIER,
139
  0x00,
140
  0x02,
141
  0x00,
142
  0x00,
143
  0x00,
144
  0x40,
145
  0x01,
146
  0x00,
147
};
148
 
149
/**
150
  * @}
151
  */
152
 
153
/** @defgroup USBD_CDC_Private_Variables
154
  * @{
155
  */
156
 
157
 
158
/* CDC interface class callbacks structure */
159
USBD_ClassTypeDef  USBD_CDC =
160
{
161
  USBD_CDC_Init,
162
  USBD_CDC_DeInit,
163
  USBD_CDC_Setup,
164
  NULL,                 /* EP0_TxSent, */
165
  USBD_CDC_EP0_RxReady,
166
  USBD_CDC_DataIn,
167
  USBD_CDC_DataOut,
168
  NULL,
169
  NULL,
170
  NULL,    
171
  USBD_CDC_GetHSCfgDesc,  
172
  USBD_CDC_GetFSCfgDesc,    
173
  USBD_CDC_GetOtherSpeedCfgDesc,
174
  USBD_CDC_GetDeviceQualifierDescriptor,
175
};
176
 
177
/* USB CDC device Configuration Descriptor */
178
__ALIGN_BEGIN uint8_t USBD_CDC_CfgHSDesc[USB_CDC_CONFIG_DESC_SIZ] __ALIGN_END =
179
{
180
  /*Configuration Descriptor*/
181
  0x09,   /* bLength: Configuration Descriptor size */
182
  USB_DESC_TYPE_CONFIGURATION,      /* bDescriptorType: Configuration */
183
  USB_CDC_CONFIG_DESC_SIZ,                /* wTotalLength:no of returned bytes */
184
  0x00,
185
  0x02,   /* bNumInterfaces: 2 interface */
186
  0x01,   /* bConfigurationValue: Configuration value */
187
  0x00,   /* iConfiguration: Index of string descriptor describing the configuration */
188
  0xC0,   /* bmAttributes: self powered */
189
  0x32,   /* MaxPower 0 mA */
190
 
191
  /*---------------------------------------------------------------------------*/
192
 
193
  /*Interface Descriptor */
194
  0x09,   /* bLength: Interface Descriptor size */
195
  USB_DESC_TYPE_INTERFACE,  /* bDescriptorType: Interface */
196
  /* Interface descriptor type */
197
  0x00,   /* bInterfaceNumber: Number of Interface */
198
  0x00,   /* bAlternateSetting: Alternate setting */
199
  0x01,   /* bNumEndpoints: One endpoints used */
200
  0x02,   /* bInterfaceClass: Communication Interface Class */
201
  0x02,   /* bInterfaceSubClass: Abstract Control Model */
202
  0x01,   /* bInterfaceProtocol: Common AT commands */
203
  0x00,   /* iInterface: */
204
 
205
  /*Header Functional Descriptor*/
206
  0x05,   /* bLength: Endpoint Descriptor size */
207
  0x24,   /* bDescriptorType: CS_INTERFACE */
208
  0x00,   /* bDescriptorSubtype: Header Func Desc */
209
  0x10,   /* bcdCDC: spec release number */
210
  0x01,
211
 
212
  /*Call Management Functional Descriptor*/
213
  0x05,   /* bFunctionLength */
214
  0x24,   /* bDescriptorType: CS_INTERFACE */
215
  0x01,   /* bDescriptorSubtype: Call Management Func Desc */
216
  0x00,   /* bmCapabilities: D0+D1 */
217
  0x01,   /* bDataInterface: 1 */
218
 
219
  /*ACM Functional Descriptor*/
220
  0x04,   /* bFunctionLength */
221
  0x24,   /* bDescriptorType: CS_INTERFACE */
222
  0x02,   /* bDescriptorSubtype: Abstract Control Management desc */
223
  0x02,   /* bmCapabilities */
224
 
225
  /*Union Functional Descriptor*/
226
  0x05,   /* bFunctionLength */
227
  0x24,   /* bDescriptorType: CS_INTERFACE */
228
  0x06,   /* bDescriptorSubtype: Union func desc */
229
  0x00,   /* bMasterInterface: Communication class interface */
230
  0x01,   /* bSlaveInterface0: Data Class Interface */
231
 
232
  /*Endpoint 2 Descriptor*/
233
  0x07,                           /* bLength: Endpoint Descriptor size */
234
  USB_DESC_TYPE_ENDPOINT,   /* bDescriptorType: Endpoint */
235
  CDC_CMD_EP,                     /* bEndpointAddress */
236
  0x03,                           /* bmAttributes: Interrupt */
237
  LOBYTE(CDC_CMD_PACKET_SIZE),     /* wMaxPacketSize: */
238
  HIBYTE(CDC_CMD_PACKET_SIZE),
239
  0x10,                           /* bInterval: */
240
  /*---------------------------------------------------------------------------*/
241
 
242
  /*Data class interface descriptor*/
243
  0x09,   /* bLength: Endpoint Descriptor size */
244
  USB_DESC_TYPE_INTERFACE,  /* bDescriptorType: */
245
  0x01,   /* bInterfaceNumber: Number of Interface */
246
  0x00,   /* bAlternateSetting: Alternate setting */
247
  0x02,   /* bNumEndpoints: Two endpoints used */
248
  0x0A,   /* bInterfaceClass: CDC */
249
  0x00,   /* bInterfaceSubClass: */
250
  0x00,   /* bInterfaceProtocol: */
251
  0x00,   /* iInterface: */
252
 
253
  /*Endpoint OUT Descriptor*/
254
  0x07,   /* bLength: Endpoint Descriptor size */
255
  USB_DESC_TYPE_ENDPOINT,      /* bDescriptorType: Endpoint */
256
  CDC_OUT_EP,                        /* bEndpointAddress */
257
  0x02,                              /* bmAttributes: Bulk */
258
  LOBYTE(CDC_DATA_HS_MAX_PACKET_SIZE),  /* wMaxPacketSize: */
259
  HIBYTE(CDC_DATA_HS_MAX_PACKET_SIZE),
260
  0x00,                              /* bInterval: ignore for Bulk transfer */
261
 
262
  /*Endpoint IN Descriptor*/
263
  0x07,   /* bLength: Endpoint Descriptor size */
264
  USB_DESC_TYPE_ENDPOINT,      /* bDescriptorType: Endpoint */
265
  CDC_IN_EP,                         /* bEndpointAddress */
266
  0x02,                              /* bmAttributes: Bulk */
267
  LOBYTE(CDC_DATA_HS_MAX_PACKET_SIZE),  /* wMaxPacketSize: */
268
  HIBYTE(CDC_DATA_HS_MAX_PACKET_SIZE),
269
  0x00                               /* bInterval: ignore for Bulk transfer */
270
} ;
271
 
272
 
273
/* USB CDC device Configuration Descriptor */
274
__ALIGN_BEGIN uint8_t USBD_CDC_CfgFSDesc[USB_CDC_CONFIG_DESC_SIZ] __ALIGN_END =
275
{
276
  /*Configuration Descriptor*/
277
  0x09,   /* bLength: Configuration Descriptor size */
278
  USB_DESC_TYPE_CONFIGURATION,      /* bDescriptorType: Configuration */
279
  USB_CDC_CONFIG_DESC_SIZ,                /* wTotalLength:no of returned bytes */
280
  0x00,
281
  0x02,   /* bNumInterfaces: 2 interface */
282
  0x01,   /* bConfigurationValue: Configuration value */
283
  0x00,   /* iConfiguration: Index of string descriptor describing the configuration */
284
  0xC0,   /* bmAttributes: self powered */
285
  0x32,   /* MaxPower 0 mA */
286
 
287
  /*---------------------------------------------------------------------------*/
288
 
289
  /*Interface Descriptor */
290
  0x09,   /* bLength: Interface Descriptor size */
291
  USB_DESC_TYPE_INTERFACE,  /* bDescriptorType: Interface */
292
  /* Interface descriptor type */
293
  0x00,   /* bInterfaceNumber: Number of Interface */
294
  0x00,   /* bAlternateSetting: Alternate setting */
295
  0x01,   /* bNumEndpoints: One endpoints used */
296
  0x02,   /* bInterfaceClass: Communication Interface Class */
297
  0x02,   /* bInterfaceSubClass: Abstract Control Model */
298
  0x01,   /* bInterfaceProtocol: Common AT commands */
299
  0x00,   /* iInterface: */
300
 
301
  /*Header Functional Descriptor*/
302
  0x05,   /* bLength: Endpoint Descriptor size */
303
  0x24,   /* bDescriptorType: CS_INTERFACE */
304
  0x00,   /* bDescriptorSubtype: Header Func Desc */
305
  0x10,   /* bcdCDC: spec release number */
306
  0x01,
307
 
308
  /*Call Management Functional Descriptor*/
309
  0x05,   /* bFunctionLength */
310
  0x24,   /* bDescriptorType: CS_INTERFACE */
311
  0x01,   /* bDescriptorSubtype: Call Management Func Desc */
312
  0x00,   /* bmCapabilities: D0+D1 */
313
  0x01,   /* bDataInterface: 1 */
314
 
315
  /*ACM Functional Descriptor*/
316
  0x04,   /* bFunctionLength */
317
  0x24,   /* bDescriptorType: CS_INTERFACE */
318
  0x02,   /* bDescriptorSubtype: Abstract Control Management desc */
319
  0x02,   /* bmCapabilities */
320
 
321
  /*Union Functional Descriptor*/
322
  0x05,   /* bFunctionLength */
323
  0x24,   /* bDescriptorType: CS_INTERFACE */
324
  0x06,   /* bDescriptorSubtype: Union func desc */
325
  0x00,   /* bMasterInterface: Communication class interface */
326
  0x01,   /* bSlaveInterface0: Data Class Interface */
327
 
328
  /*Endpoint 2 Descriptor*/
329
  0x07,                           /* bLength: Endpoint Descriptor size */
330
  USB_DESC_TYPE_ENDPOINT,   /* bDescriptorType: Endpoint */
331
  CDC_CMD_EP,                     /* bEndpointAddress */
332
  0x03,                           /* bmAttributes: Interrupt */
333
  LOBYTE(CDC_CMD_PACKET_SIZE),     /* wMaxPacketSize: */
334
  HIBYTE(CDC_CMD_PACKET_SIZE),
335
  0x10,                           /* bInterval: */
336
  /*---------------------------------------------------------------------------*/
337
 
338
  /*Data class interface descriptor*/
339
  0x09,   /* bLength: Endpoint Descriptor size */
340
  USB_DESC_TYPE_INTERFACE,  /* bDescriptorType: */
341
  0x01,   /* bInterfaceNumber: Number of Interface */
342
  0x00,   /* bAlternateSetting: Alternate setting */
343
  0x02,   /* bNumEndpoints: Two endpoints used */
344
  0x0A,   /* bInterfaceClass: CDC */
345
  0x00,   /* bInterfaceSubClass: */
346
  0x00,   /* bInterfaceProtocol: */
347
  0x00,   /* iInterface: */
348
 
349
  /*Endpoint OUT Descriptor*/
350
  0x07,   /* bLength: Endpoint Descriptor size */
351
  USB_DESC_TYPE_ENDPOINT,      /* bDescriptorType: Endpoint */
352
  CDC_OUT_EP,                        /* bEndpointAddress */
353
  0x02,                              /* bmAttributes: Bulk */
354
  LOBYTE(CDC_DATA_FS_MAX_PACKET_SIZE),  /* wMaxPacketSize: */
355
  HIBYTE(CDC_DATA_FS_MAX_PACKET_SIZE),
356
  0x00,                              /* bInterval: ignore for Bulk transfer */
357
 
358
  /*Endpoint IN Descriptor*/
359
  0x07,   /* bLength: Endpoint Descriptor size */
360
  USB_DESC_TYPE_ENDPOINT,      /* bDescriptorType: Endpoint */
361
  CDC_IN_EP,                         /* bEndpointAddress */
362
  0x02,                              /* bmAttributes: Bulk */
363
  LOBYTE(CDC_DATA_FS_MAX_PACKET_SIZE),  /* wMaxPacketSize: */
364
  HIBYTE(CDC_DATA_FS_MAX_PACKET_SIZE),
365
  0x00                               /* bInterval: ignore for Bulk transfer */
366
} ;
367
 
368
__ALIGN_BEGIN uint8_t USBD_CDC_OtherSpeedCfgDesc[USB_CDC_CONFIG_DESC_SIZ] __ALIGN_END =
369
{
370
  0x09,   /* bLength: Configuation Descriptor size */
371
  USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION,  
372
  USB_CDC_CONFIG_DESC_SIZ,
373
  0x00,
374
  0x02,   /* bNumInterfaces: 2 interfaces */
375
  0x01,   /* bConfigurationValue: */
376
  0x04,   /* iConfiguration: */
377
  0xC0,   /* bmAttributes: */
378
  0x32,   /* MaxPower 100 mA */  
379
 
380
  /*Interface Descriptor */
381
  0x09,   /* bLength: Interface Descriptor size */
382
  USB_DESC_TYPE_INTERFACE,  /* bDescriptorType: Interface */
383
  /* Interface descriptor type */
384
  0x00,   /* bInterfaceNumber: Number of Interface */
385
  0x00,   /* bAlternateSetting: Alternate setting */
386
  0x01,   /* bNumEndpoints: One endpoints used */
387
  0x02,   /* bInterfaceClass: Communication Interface Class */
388
  0x02,   /* bInterfaceSubClass: Abstract Control Model */
389
  0x01,   /* bInterfaceProtocol: Common AT commands */
390
  0x00,   /* iInterface: */
391
 
392
  /*Header Functional Descriptor*/
393
  0x05,   /* bLength: Endpoint Descriptor size */
394
  0x24,   /* bDescriptorType: CS_INTERFACE */
395
  0x00,   /* bDescriptorSubtype: Header Func Desc */
396
  0x10,   /* bcdCDC: spec release number */
397
  0x01,
398
 
399
  /*Call Management Functional Descriptor*/
400
  0x05,   /* bFunctionLength */
401
  0x24,   /* bDescriptorType: CS_INTERFACE */
402
  0x01,   /* bDescriptorSubtype: Call Management Func Desc */
403
  0x00,   /* bmCapabilities: D0+D1 */
404
  0x01,   /* bDataInterface: 1 */
405
 
406
  /*ACM Functional Descriptor*/
407
  0x04,   /* bFunctionLength */
408
  0x24,   /* bDescriptorType: CS_INTERFACE */
409
  0x02,   /* bDescriptorSubtype: Abstract Control Management desc */
410
  0x02,   /* bmCapabilities */
411
 
412
  /*Union Functional Descriptor*/
413
  0x05,   /* bFunctionLength */
414
  0x24,   /* bDescriptorType: CS_INTERFACE */
415
  0x06,   /* bDescriptorSubtype: Union func desc */
416
  0x00,   /* bMasterInterface: Communication class interface */
417
  0x01,   /* bSlaveInterface0: Data Class Interface */
418
 
419
  /*Endpoint 2 Descriptor*/
420
  0x07,                           /* bLength: Endpoint Descriptor size */
421
  USB_DESC_TYPE_ENDPOINT      ,   /* bDescriptorType: Endpoint */
422
  CDC_CMD_EP,                     /* bEndpointAddress */
423
  0x03,                           /* bmAttributes: Interrupt */
424
  LOBYTE(CDC_CMD_PACKET_SIZE),     /* wMaxPacketSize: */
425
  HIBYTE(CDC_CMD_PACKET_SIZE),
426
  0xFF,                           /* bInterval: */
427
 
428
  /*---------------------------------------------------------------------------*/
429
 
430
  /*Data class interface descriptor*/
431
  0x09,   /* bLength: Endpoint Descriptor size */
432
  USB_DESC_TYPE_INTERFACE,  /* bDescriptorType: */
433
  0x01,   /* bInterfaceNumber: Number of Interface */
434
  0x00,   /* bAlternateSetting: Alternate setting */
435
  0x02,   /* bNumEndpoints: Two endpoints used */
436
  0x0A,   /* bInterfaceClass: CDC */
437
  0x00,   /* bInterfaceSubClass: */
438
  0x00,   /* bInterfaceProtocol: */
439
  0x00,   /* iInterface: */
440
 
441
  /*Endpoint OUT Descriptor*/
442
  0x07,   /* bLength: Endpoint Descriptor size */
443
  USB_DESC_TYPE_ENDPOINT,      /* bDescriptorType: Endpoint */
444
  CDC_OUT_EP,                        /* bEndpointAddress */
445
  0x02,                              /* bmAttributes: Bulk */
446
  0x40,                              /* wMaxPacketSize: */
447
  0x00,
448
  0x00,                              /* bInterval: ignore for Bulk transfer */
449
 
450
  /*Endpoint IN Descriptor*/
451
  0x07,   /* bLength: Endpoint Descriptor size */
452
  USB_DESC_TYPE_ENDPOINT,     /* bDescriptorType: Endpoint */
453
  CDC_IN_EP,                        /* bEndpointAddress */
454
  0x02,                             /* bmAttributes: Bulk */
455
  0x40,                             /* wMaxPacketSize: */
456
  0x00,
457
  0x00                              /* bInterval */
458
};
459
 
460
/**
461
  * @}
462
  */
463
 
464
/** @defgroup USBD_CDC_Private_Functions
465
  * @{
466
  */
467
 
468
/**
469
  * @brief  USBD_CDC_Init
470
  *         Initialize the CDC interface
471
  * @param  pdev: device instance
472
  * @param  cfgidx: Configuration index
473
  * @retval status
474
  */
475
static uint8_t  USBD_CDC_Init (USBD_HandleTypeDef *pdev,
476
                               uint8_t cfgidx)
477
{
478
  uint8_t ret = 0;
479
  USBD_CDC_HandleTypeDef   *hcdc;
480
 
481
  if(pdev->dev_speed == USBD_SPEED_HIGH  )
482
  {  
483
    /* Open EP IN */
484
    USBD_LL_OpenEP(pdev,
485
                   CDC_IN_EP,
486
                   USBD_EP_TYPE_BULK,
487
                   CDC_DATA_HS_IN_PACKET_SIZE);
488
 
489
    /* Open EP OUT */
490
    USBD_LL_OpenEP(pdev,
491
                   CDC_OUT_EP,
492
                   USBD_EP_TYPE_BULK,
493
                   CDC_DATA_HS_OUT_PACKET_SIZE);
494
 
495
  }
496
  else
497
  {
498
    /* Open EP IN */
499
    USBD_LL_OpenEP(pdev,
500
                   CDC_IN_EP,
501
                   USBD_EP_TYPE_BULK,
502
                   CDC_DATA_FS_IN_PACKET_SIZE);
503
 
504
    /* Open EP OUT */
505
    USBD_LL_OpenEP(pdev,
506
                   CDC_OUT_EP,
507
                   USBD_EP_TYPE_BULK,
508
                   CDC_DATA_FS_OUT_PACKET_SIZE);
509
  }
510
  /* Open Command IN EP */
511
  USBD_LL_OpenEP(pdev,
512
                 CDC_CMD_EP,
513
                 USBD_EP_TYPE_INTR,
514
                 CDC_CMD_PACKET_SIZE);
515
 
516
 
517
  pdev->pClassData = USBD_malloc(sizeof (USBD_CDC_HandleTypeDef));
518
 
519
  if(pdev->pClassData == NULL)
520
  {
521
    ret = 1;
522
  }
523
  else
524
  {
525
    hcdc = (USBD_CDC_HandleTypeDef*) pdev->pClassData;
526
 
527
    /* Init  physical Interface components */
528
    ((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Init();
529
 
530
    /* Init Xfer states */
531
    hcdc->TxState =0;
532
    hcdc->RxState =0;
533
 
534
    if(pdev->dev_speed == USBD_SPEED_HIGH  )
535
    {      
536
      /* Prepare Out endpoint to receive next packet */
537
      USBD_LL_PrepareReceive(pdev,
538
                             CDC_OUT_EP,
539
                             hcdc->RxBuffer,
540
                             CDC_DATA_HS_OUT_PACKET_SIZE);
541
    }
542
    else
543
    {
544
      /* Prepare Out endpoint to receive next packet */
545
      USBD_LL_PrepareReceive(pdev,
546
                             CDC_OUT_EP,
547
                             hcdc->RxBuffer,
548
                             CDC_DATA_FS_OUT_PACKET_SIZE);
549
    }
550
 
551
 
552
  }
553
  return ret;
554
}
555
 
556
/**
557
  * @brief  USBD_CDC_Init
558
  *         DeInitialize the CDC layer
559
  * @param  pdev: device instance
560
  * @param  cfgidx: Configuration index
561
  * @retval status
562
  */
563
static uint8_t  USBD_CDC_DeInit (USBD_HandleTypeDef *pdev,
564
                                 uint8_t cfgidx)
565
{
566
  uint8_t ret = 0;
567
 
568
  /* Open EP IN */
569
  USBD_LL_CloseEP(pdev,
570
              CDC_IN_EP);
571
 
572
  /* Open EP OUT */
573
  USBD_LL_CloseEP(pdev,
574
              CDC_OUT_EP);
575
 
576
  /* Open Command IN EP */
577
  USBD_LL_CloseEP(pdev,
578
              CDC_CMD_EP);
579
 
580
 
581
  /* DeInit  physical Interface components */
582
  if(pdev->pClassData != NULL)
583
  {
584
    ((USBD_CDC_ItfTypeDef *)pdev->pUserData)->DeInit();
585
    USBD_free(pdev->pClassData);
586
    pdev->pClassData = NULL;
587
  }
588
 
589
  return ret;
590
}
591
 
592
/**
593
  * @brief  USBD_CDC_Setup
594
  *         Handle the CDC specific requests
595
  * @param  pdev: instance
596
  * @param  req: usb requests
597
  * @retval status
598
  */
599
static uint8_t  USBD_CDC_Setup (USBD_HandleTypeDef *pdev,
600
                                USBD_SetupReqTypedef *req)
601
{
602
  USBD_CDC_HandleTypeDef   *hcdc = (USBD_CDC_HandleTypeDef*) pdev->pClassData;
603
  static uint8_t ifalt = 0;
604
 
605
  switch (req->bmRequest & USB_REQ_TYPE_MASK)
606
  {
607
  case USB_REQ_TYPE_CLASS :
608
    if (req->wLength)
609
    {
610
      if (req->bmRequest & 0x80)
611
      {
612
        ((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Control(req->bRequest,
613
                                                          (uint8_t *)hcdc->data,
614
                                                          req->wLength);
615
          USBD_CtlSendData (pdev,
616
                            (uint8_t *)hcdc->data,
617
                            req->wLength);
618
      }
619
      else
620
      {
621
        hcdc->CmdOpCode = req->bRequest;
622
        hcdc->CmdLength = req->wLength;
623
 
624
        USBD_CtlPrepareRx (pdev,
625
                           (uint8_t *)hcdc->data,
626
                           req->wLength);
627
      }
628
 
629
    }
630
    else
631
    {
632
      ((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Control(req->bRequest,
633
                                                        (uint8_t*)req,
634
                                                        0);
635
    }
636
    break;
637
 
638
  case USB_REQ_TYPE_STANDARD:
639
    switch (req->bRequest)
640
    {      
641
    case USB_REQ_GET_INTERFACE :
642
      USBD_CtlSendData (pdev,
643
                        &ifalt,
644
                        1);
645
      break;
646
 
647
    case USB_REQ_SET_INTERFACE :
648
      break;
649
    }
650
 
651
  default:
652
    break;
653
  }
654
  return USBD_OK;
655
}
656
 
657
/**
658
  * @brief  USBD_CDC_DataIn
659
  *         Data sent on non-control IN endpoint
660
  * @param  pdev: device instance
661
  * @param  epnum: endpoint number
662
  * @retval status
663
  */
664
static uint8_t  USBD_CDC_DataIn (USBD_HandleTypeDef *pdev, uint8_t epnum)
665
{
666
  USBD_CDC_HandleTypeDef   *hcdc = (USBD_CDC_HandleTypeDef*) pdev->pClassData;
667
 
668
  if(pdev->pClassData != NULL)
669
  {
670
 
671
    hcdc->TxState = 0;
672
 
673
    return USBD_OK;
674
  }
675
  else
676
  {
677
    return USBD_FAIL;
678
  }
679
}
680
 
681
/**
682
  * @brief  USBD_CDC_DataOut
683
  *         Data received on non-control Out endpoint
684
  * @param  pdev: device instance
685
  * @param  epnum: endpoint number
686
  * @retval status
687
  */
688
static uint8_t  USBD_CDC_DataOut (USBD_HandleTypeDef *pdev, uint8_t epnum)
689
{      
690
  USBD_CDC_HandleTypeDef   *hcdc = (USBD_CDC_HandleTypeDef*) pdev->pClassData;
691
 
692
  /* Get the received data length */
693
  hcdc->RxLength = USBD_LL_GetRxDataSize (pdev, epnum);
694
 
695
  /* USB data will be immediately processed, this allow next USB traffic being
696
  NAKed till the end of the application Xfer */
697
  if(pdev->pClassData != NULL)
698
  {
699
    ((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Receive(hcdc->RxBuffer, &hcdc->RxLength);
700
 
701
    return USBD_OK;
702
  }
703
  else
704
  {
705
    return USBD_FAIL;
706
  }
707
}
708
 
709
 
710
 
711
/**
712
  * @brief  USBD_CDC_DataOut
713
  *         Data received on non-control Out endpoint
714
  * @param  pdev: device instance
715
  * @param  epnum: endpoint number
716
  * @retval status
717
  */
718
static uint8_t  USBD_CDC_EP0_RxReady (USBD_HandleTypeDef *pdev)
719
{
720
  USBD_CDC_HandleTypeDef   *hcdc = (USBD_CDC_HandleTypeDef*) pdev->pClassData;
721
 
722
  if((pdev->pUserData != NULL) && (hcdc->CmdOpCode != 0xFF))
723
  {
724
    ((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Control(hcdc->CmdOpCode,
725
                                                      (uint8_t *)hcdc->data,
726
                                                      hcdc->CmdLength);
727
      hcdc->CmdOpCode = 0xFF;
728
 
729
  }
730
  return USBD_OK;
731
}
732
 
733
/**
734
  * @brief  USBD_CDC_GetFSCfgDesc
735
  *         Return configuration descriptor
736
  * @param  speed : current device speed
737
  * @param  length : pointer data length
738
  * @retval pointer to descriptor buffer
739
  */
740
static uint8_t  *USBD_CDC_GetFSCfgDesc (uint16_t *length)
741
{
742
  *length = sizeof (USBD_CDC_CfgFSDesc);
743
  return USBD_CDC_CfgFSDesc;
744
}
745
 
746
/**
747
  * @brief  USBD_CDC_GetHSCfgDesc
748
  *         Return configuration descriptor
749
  * @param  speed : current device speed
750
  * @param  length : pointer data length
751
  * @retval pointer to descriptor buffer
752
  */
753
static uint8_t  *USBD_CDC_GetHSCfgDesc (uint16_t *length)
754
{
755
  *length = sizeof (USBD_CDC_CfgHSDesc);
756
  return USBD_CDC_CfgHSDesc;
757
}
758
 
759
/**
760
  * @brief  USBD_CDC_GetCfgDesc
761
  *         Return configuration descriptor
762
  * @param  speed : current device speed
763
  * @param  length : pointer data length
764
  * @retval pointer to descriptor buffer
765
  */
766
static uint8_t  *USBD_CDC_GetOtherSpeedCfgDesc (uint16_t *length)
767
{
768
  *length = sizeof (USBD_CDC_OtherSpeedCfgDesc);
769
  return USBD_CDC_OtherSpeedCfgDesc;
770
}
771
 
772
/**
773
* @brief  DeviceQualifierDescriptor
774
*         return Device Qualifier descriptor
775
* @param  length : pointer data length
776
* @retval pointer to descriptor buffer
777
*/
778
uint8_t  *USBD_CDC_GetDeviceQualifierDescriptor (uint16_t *length)
779
{
780
  *length = sizeof (USBD_CDC_DeviceQualifierDesc);
781
  return USBD_CDC_DeviceQualifierDesc;
782
}
783
 
784
/**
785
* @brief  USBD_CDC_RegisterInterface
786
  * @param  pdev: device instance
787
  * @param  fops: CD  Interface callback
788
  * @retval status
789
  */
790
uint8_t  USBD_CDC_RegisterInterface  (USBD_HandleTypeDef   *pdev,
791
                                      USBD_CDC_ItfTypeDef *fops)
792
{
793
  uint8_t  ret = USBD_FAIL;
794
 
795
  if(fops != NULL)
796
  {
797
    pdev->pUserData= fops;
798
    ret = USBD_OK;    
799
  }
800
 
801
  return ret;
802
}
803
 
804
/**
805
  * @brief  USBD_CDC_SetTxBuffer
806
  * @param  pdev: device instance
807
  * @param  pbuff: Tx Buffer
808
  * @retval status
809
  */
810
uint8_t  USBD_CDC_SetTxBuffer  (USBD_HandleTypeDef   *pdev,
811
                                uint8_t  *pbuff,
812
                                uint16_t length)
813
{
814
  USBD_CDC_HandleTypeDef   *hcdc = (USBD_CDC_HandleTypeDef*) pdev->pClassData;
815
 
816
  hcdc->TxBuffer = pbuff;
817
  hcdc->TxLength = length;  
818
 
819
  return USBD_OK;  
820
}
821
 
822
 
823
/**
824
  * @brief  USBD_CDC_SetRxBuffer
825
  * @param  pdev: device instance
826
  * @param  pbuff: Rx Buffer
827
  * @retval status
828
  */
829
uint8_t  USBD_CDC_SetRxBuffer  (USBD_HandleTypeDef   *pdev,
830
                                   uint8_t  *pbuff)
831
{
832
  USBD_CDC_HandleTypeDef   *hcdc = (USBD_CDC_HandleTypeDef*) pdev->pClassData;
833
 
834
  hcdc->RxBuffer = pbuff;
835
 
836
  return USBD_OK;
837
}
838
 
839
/**
840
  * @brief  USBD_CDC_DataOut
841
  *         Data received on non-control Out endpoint
842
  * @param  pdev: device instance
843
  * @param  epnum: endpoint number
844
  * @retval status
845
  */
846
uint8_t  USBD_CDC_TransmitPacket(USBD_HandleTypeDef *pdev)
847
{      
848
  USBD_CDC_HandleTypeDef   *hcdc = (USBD_CDC_HandleTypeDef*) pdev->pClassData;
849
 
850
  if(pdev->pClassData != NULL)
851
  {
852
    if(hcdc->TxState == 0)
853
    {
854
      /* Tx Transfer in progress */
855
      hcdc->TxState = 1;
856
 
857
      /* Transmit next packet */
858
      USBD_LL_Transmit(pdev,
859
                       CDC_IN_EP,
860
                       hcdc->TxBuffer,
861
                       hcdc->TxLength);
862
 
863
      return USBD_OK;
864
    }
865
    else
866
    {
867
      return USBD_BUSY;
868
    }
869
  }
870
  else
871
  {
872
    return USBD_FAIL;
873
  }
874
}
875
 
876
 
877
/**
878
  * @brief  USBD_CDC_ReceivePacket
879
  *         prepare OUT Endpoint for reception
880
  * @param  pdev: device instance
881
  * @retval status
882
  */
883
uint8_t  USBD_CDC_ReceivePacket(USBD_HandleTypeDef *pdev)
884
{      
885
  USBD_CDC_HandleTypeDef   *hcdc = (USBD_CDC_HandleTypeDef*) pdev->pClassData;
886
 
887
  /* Suspend or Resume USB Out process */
888
  if(pdev->pClassData != NULL)
889
  {
890
    if(pdev->dev_speed == USBD_SPEED_HIGH  )
891
    {      
892
      /* Prepare Out endpoint to receive next packet */
893
      USBD_LL_PrepareReceive(pdev,
894
                             CDC_OUT_EP,
895
                             hcdc->RxBuffer,
896
                             CDC_DATA_HS_OUT_PACKET_SIZE);
897
    }
898
    else
899
    {
900
      /* Prepare Out endpoint to receive next packet */
901
      USBD_LL_PrepareReceive(pdev,
902
                             CDC_OUT_EP,
903
                             hcdc->RxBuffer,
904
                             CDC_DATA_FS_OUT_PACKET_SIZE);
905
    }
906
    return USBD_OK;
907
  }
908
  else
909
  {
910
    return USBD_FAIL;
911
  }
912
}
913
/**
914
  * @}
915
  */
916
 
917
/**
918
  * @}
919
  */
920
 
921
/**
922
  * @}
923
  */
924
 
925
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/