Subversion Repositories dashGPS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
16 mjames 1
/**
2
  ******************************************************************************
3
  * @file    usbd_req.c
4
  * @author  MCD Application Team
5
  * @brief   This file provides the standard USB requests following chapter 9.
6
  ******************************************************************************
7
  * @attention
8
  *
9
  * <h2><center>&copy; Copyright (c) 2015 STMicroelectronics.
10
  * All rights reserved.</center></h2>
11
  *
12
  * This software component is licensed by ST under Ultimate Liberty license
13
  * SLA0044, the "License"; You may not use this file except in compliance with
14
  * the License. You may obtain a copy of the License at:
15
  *                      www.st.com/SLA0044
16
  *
17
  ******************************************************************************
18
  */
19
 
20
/* Includes ------------------------------------------------------------------*/
21
#include "usbd_ctlreq.h"
22
#include "usbd_ioreq.h"
23
 
24
 
25
/** @addtogroup STM32_USBD_STATE_DEVICE_LIBRARY
26
  * @{
27
  */
28
 
29
 
30
/** @defgroup USBD_REQ
31
  * @brief USB standard requests module
32
  * @{
33
  */
34
 
35
/** @defgroup USBD_REQ_Private_TypesDefinitions
36
  * @{
37
  */
38
 
39
/**
40
  * @}
41
  */
42
 
43
 
44
/** @defgroup USBD_REQ_Private_Defines
45
  * @{
46
  */
47
 
48
/**
49
  * @}
50
  */
51
 
52
 
53
/** @defgroup USBD_REQ_Private_Macros
54
  * @{
55
  */
56
 
57
/**
58
  * @}
59
  */
60
 
61
 
62
/** @defgroup USBD_REQ_Private_Variables
63
  * @{
64
  */
65
 
66
/**
67
  * @}
68
  */
69
 
70
 
71
/** @defgroup USBD_REQ_Private_FunctionPrototypes
72
  * @{
73
  */
74
static void USBD_GetDescriptor(USBD_HandleTypeDef *pdev,
75
                               USBD_SetupReqTypedef *req);
76
 
77
static void USBD_SetAddress(USBD_HandleTypeDef *pdev,
78
                            USBD_SetupReqTypedef *req);
79
 
80
static void USBD_SetConfig(USBD_HandleTypeDef *pdev,
81
                           USBD_SetupReqTypedef *req);
82
 
83
static void USBD_GetConfig(USBD_HandleTypeDef *pdev,
84
                           USBD_SetupReqTypedef *req);
85
 
86
static void USBD_GetStatus(USBD_HandleTypeDef *pdev,
87
                           USBD_SetupReqTypedef *req);
88
 
89
static void USBD_SetFeature(USBD_HandleTypeDef *pdev,
90
                            USBD_SetupReqTypedef *req);
91
 
92
static void USBD_ClrFeature(USBD_HandleTypeDef *pdev,
93
                            USBD_SetupReqTypedef *req);
94
 
95
static uint8_t USBD_GetLen(uint8_t *buf);
96
 
97
/**
98
  * @}
99
  */
100
 
101
 
102
/** @defgroup USBD_REQ_Private_Functions
103
  * @{
104
  */
105
 
106
 
107
/**
108
* @brief  USBD_StdDevReq
109
*         Handle standard usb device requests
110
* @param  pdev: device instance
111
* @param  req: usb request
112
* @retval status
113
*/
114
USBD_StatusTypeDef  USBD_StdDevReq(USBD_HandleTypeDef *pdev,
115
                                   USBD_SetupReqTypedef *req)
116
{
117
  USBD_StatusTypeDef ret = USBD_OK;
118
 
119
  switch (req->bmRequest & USB_REQ_TYPE_MASK)
120
  {
121
    case USB_REQ_TYPE_CLASS:
122
    case USB_REQ_TYPE_VENDOR:
123
      pdev->pClass->Setup(pdev, req);
124
      break;
125
 
126
    case USB_REQ_TYPE_STANDARD:
127
      switch (req->bRequest)
128
      {
129
        case USB_REQ_GET_DESCRIPTOR:
130
          USBD_GetDescriptor(pdev, req);
131
          break;
132
 
133
        case USB_REQ_SET_ADDRESS:
134
          USBD_SetAddress(pdev, req);
135
          break;
136
 
137
        case USB_REQ_SET_CONFIGURATION:
138
          USBD_SetConfig(pdev, req);
139
          break;
140
 
141
        case USB_REQ_GET_CONFIGURATION:
142
          USBD_GetConfig(pdev, req);
143
          break;
144
 
145
        case USB_REQ_GET_STATUS:
146
          USBD_GetStatus(pdev, req);
147
          break;
148
 
149
        case USB_REQ_SET_FEATURE:
150
          USBD_SetFeature(pdev, req);
151
          break;
152
 
153
        case USB_REQ_CLEAR_FEATURE:
154
          USBD_ClrFeature(pdev, req);
155
          break;
156
 
157
        default:
158
          USBD_CtlError(pdev, req);
159
          break;
160
      }
161
      break;
162
 
163
    default:
164
      USBD_CtlError(pdev, req);
165
      break;
166
  }
167
 
168
  return ret;
169
}
170
 
171
/**
172
* @brief  USBD_StdItfReq
173
*         Handle standard usb interface requests
174
* @param  pdev: device instance
175
* @param  req: usb request
176
* @retval status
177
*/
178
USBD_StatusTypeDef  USBD_StdItfReq(USBD_HandleTypeDef *pdev,
179
                                   USBD_SetupReqTypedef  *req)
180
{
181
  USBD_StatusTypeDef ret = USBD_OK;
182
 
183
  switch (req->bmRequest & USB_REQ_TYPE_MASK)
184
  {
185
    case USB_REQ_TYPE_CLASS:
186
    case USB_REQ_TYPE_VENDOR:
187
    case USB_REQ_TYPE_STANDARD:
188
      switch (pdev->dev_state)
189
      {
190
        case USBD_STATE_DEFAULT:
191
        case USBD_STATE_ADDRESSED:
192
        case USBD_STATE_CONFIGURED:
193
 
194
          if (LOBYTE(req->wIndex) <= USBD_MAX_NUM_INTERFACES)
195
          {
196
            ret = (USBD_StatusTypeDef)pdev->pClass->Setup(pdev, req);
197
 
198
            if ((req->wLength == 0U) && (ret == USBD_OK))
199
            {
200
              USBD_CtlSendStatus(pdev);
201
            }
202
          }
203
          else
204
          {
205
            USBD_CtlError(pdev, req);
206
          }
207
          break;
208
 
209
        default:
210
          USBD_CtlError(pdev, req);
211
          break;
212
      }
213
      break;
214
 
215
    default:
216
      USBD_CtlError(pdev, req);
217
      break;
218
  }
219
 
220
  return USBD_OK;
221
}
222
 
223
/**
224
* @brief  USBD_StdEPReq
225
*         Handle standard usb endpoint requests
226
* @param  pdev: device instance
227
* @param  req: usb request
228
* @retval status
229
*/
230
USBD_StatusTypeDef  USBD_StdEPReq(USBD_HandleTypeDef *pdev,
231
                                  USBD_SetupReqTypedef  *req)
232
{
233
  USBD_EndpointTypeDef *pep;
234
  uint8_t   ep_addr;
235
  USBD_StatusTypeDef ret = USBD_OK;
236
  ep_addr  = LOBYTE(req->wIndex);
237
 
238
  switch (req->bmRequest & USB_REQ_TYPE_MASK)
239
  {
240
    case USB_REQ_TYPE_CLASS:
241
    case USB_REQ_TYPE_VENDOR:
242
      pdev->pClass->Setup(pdev, req);
243
      break;
244
 
245
    case USB_REQ_TYPE_STANDARD:
246
      /* Check if it is a class request */
247
      if ((req->bmRequest & 0x60U) == 0x20U)
248
      {
249
        ret = (USBD_StatusTypeDef)pdev->pClass->Setup(pdev, req);
250
 
251
        return ret;
252
      }
253
 
254
      switch (req->bRequest)
255
      {
256
        case USB_REQ_SET_FEATURE:
257
          switch (pdev->dev_state)
258
          {
259
            case USBD_STATE_ADDRESSED:
260
              if ((ep_addr != 0x00U) && (ep_addr != 0x80U))
261
              {
262
                USBD_LL_StallEP(pdev, ep_addr);
263
                USBD_LL_StallEP(pdev, 0x80U);
264
              }
265
              else
266
              {
267
                USBD_CtlError(pdev, req);
268
              }
269
              break;
270
 
271
            case USBD_STATE_CONFIGURED:
272
              if (req->wValue == USB_FEATURE_EP_HALT)
273
              {
274
                if ((ep_addr != 0x00U) &&
275
                    (ep_addr != 0x80U) && (req->wLength == 0x00U))
276
                {
277
                  USBD_LL_StallEP(pdev, ep_addr);
278
                }
279
              }
280
              USBD_CtlSendStatus(pdev);
281
 
282
              break;
283
 
284
            default:
285
              USBD_CtlError(pdev, req);
286
              break;
287
          }
288
          break;
289
 
290
        case USB_REQ_CLEAR_FEATURE:
291
 
292
          switch (pdev->dev_state)
293
          {
294
            case USBD_STATE_ADDRESSED:
295
              if ((ep_addr != 0x00U) && (ep_addr != 0x80U))
296
              {
297
                USBD_LL_StallEP(pdev, ep_addr);
298
                USBD_LL_StallEP(pdev, 0x80U);
299
              }
300
              else
301
              {
302
                USBD_CtlError(pdev, req);
303
              }
304
              break;
305
 
306
            case USBD_STATE_CONFIGURED:
307
              if (req->wValue == USB_FEATURE_EP_HALT)
308
              {
309
                if ((ep_addr & 0x7FU) != 0x00U)
310
                {
311
                  USBD_LL_ClearStallEP(pdev, ep_addr);
312
                }
313
                USBD_CtlSendStatus(pdev);
314
              }
315
              break;
316
 
317
            default:
318
              USBD_CtlError(pdev, req);
319
              break;
320
          }
321
          break;
322
 
323
        case USB_REQ_GET_STATUS:
324
          switch (pdev->dev_state)
325
          {
326
            case USBD_STATE_ADDRESSED:
327
              if ((ep_addr != 0x00U) && (ep_addr != 0x80U))
328
              {
329
                USBD_CtlError(pdev, req);
330
                break;
331
              }
332
              pep = ((ep_addr & 0x80U) == 0x80U) ? &pdev->ep_in[ep_addr & 0x7FU] : \
333
                    &pdev->ep_out[ep_addr & 0x7FU];
334
 
335
              pep->status = 0x0000U;
336
 
337
              USBD_CtlSendData(pdev, (uint8_t *)(void *)&pep->status, 2U);
338
              break;
339
 
340
            case USBD_STATE_CONFIGURED:
341
              if ((ep_addr & 0x80U) == 0x80U)
342
              {
343
                if (pdev->ep_in[ep_addr & 0xFU].is_used == 0U)
344
                {
345
                  USBD_CtlError(pdev, req);
346
                  break;
347
                }
348
              }
349
              else
350
              {
351
                if (pdev->ep_out[ep_addr & 0xFU].is_used == 0U)
352
                {
353
                  USBD_CtlError(pdev, req);
354
                  break;
355
                }
356
              }
357
 
358
              pep = ((ep_addr & 0x80U) == 0x80U) ? &pdev->ep_in[ep_addr & 0x7FU] : \
359
                    &pdev->ep_out[ep_addr & 0x7FU];
360
 
361
              if ((ep_addr == 0x00U) || (ep_addr == 0x80U))
362
              {
363
                pep->status = 0x0000U;
364
              }
365
              else if (USBD_LL_IsStallEP(pdev, ep_addr))
366
              {
367
                pep->status = 0x0001U;
368
              }
369
              else
370
              {
371
                pep->status = 0x0000U;
372
              }
373
 
374
              USBD_CtlSendData(pdev, (uint8_t *)(void *)&pep->status, 2U);
375
              break;
376
 
377
            default:
378
              USBD_CtlError(pdev, req);
379
              break;
380
          }
381
          break;
382
 
383
        default:
384
          USBD_CtlError(pdev, req);
385
          break;
386
      }
387
      break;
388
 
389
    default:
390
      USBD_CtlError(pdev, req);
391
      break;
392
  }
393
 
394
  return ret;
395
}
396
 
397
 
398
/**
399
* @brief  USBD_GetDescriptor
400
*         Handle Get Descriptor requests
401
* @param  pdev: device instance
402
* @param  req: usb request
403
* @retval status
404
*/
405
static void USBD_GetDescriptor(USBD_HandleTypeDef *pdev,
406
                               USBD_SetupReqTypedef *req)
407
{
408
  uint16_t len = 0U;
409
  uint8_t *pbuf = NULL;
410
  uint8_t err = 0U;
411
 
412
  switch (req->wValue >> 8)
413
  {
414
#if (USBD_LPM_ENABLED == 1U)
415
    case USB_DESC_TYPE_BOS:
416
      if (pdev->pDesc->GetBOSDescriptor != NULL)
417
      {
418
        pbuf = pdev->pDesc->GetBOSDescriptor(pdev->dev_speed, &len);
419
      }
420
      else
421
      {
422
        USBD_CtlError(pdev, req);
423
        err++;
424
      }
425
      break;
426
#endif
427
    case USB_DESC_TYPE_DEVICE:
428
      pbuf = pdev->pDesc->GetDeviceDescriptor(pdev->dev_speed, &len);
429
      break;
430
 
431
    case USB_DESC_TYPE_CONFIGURATION:
432
      if (pdev->dev_speed == USBD_SPEED_HIGH)
433
      {
434
        pbuf = pdev->pClass->GetHSConfigDescriptor(&len);
435
        pbuf[1] = USB_DESC_TYPE_CONFIGURATION;
436
      }
437
      else
438
      {
439
        pbuf = pdev->pClass->GetFSConfigDescriptor(&len);
440
        pbuf[1] = USB_DESC_TYPE_CONFIGURATION;
441
      }
442
      break;
443
 
444
    case USB_DESC_TYPE_STRING:
445
      switch ((uint8_t)(req->wValue))
446
      {
447
        case USBD_IDX_LANGID_STR:
448
          if (pdev->pDesc->GetLangIDStrDescriptor != NULL)
449
          {
450
            pbuf = pdev->pDesc->GetLangIDStrDescriptor(pdev->dev_speed, &len);
451
          }
452
          else
453
          {
454
            USBD_CtlError(pdev, req);
455
            err++;
456
          }
457
          break;
458
 
459
        case USBD_IDX_MFC_STR:
460
          if (pdev->pDesc->GetManufacturerStrDescriptor != NULL)
461
          {
462
            pbuf = pdev->pDesc->GetManufacturerStrDescriptor(pdev->dev_speed, &len);
463
          }
464
          else
465
          {
466
            USBD_CtlError(pdev, req);
467
            err++;
468
          }
469
          break;
470
 
471
        case USBD_IDX_PRODUCT_STR:
472
          if (pdev->pDesc->GetProductStrDescriptor != NULL)
473
          {
474
            pbuf = pdev->pDesc->GetProductStrDescriptor(pdev->dev_speed, &len);
475
          }
476
          else
477
          {
478
            USBD_CtlError(pdev, req);
479
            err++;
480
          }
481
          break;
482
 
483
        case USBD_IDX_SERIAL_STR:
484
          if (pdev->pDesc->GetSerialStrDescriptor != NULL)
485
          {
486
            pbuf = pdev->pDesc->GetSerialStrDescriptor(pdev->dev_speed, &len);
487
          }
488
          else
489
          {
490
            USBD_CtlError(pdev, req);
491
            err++;
492
          }
493
          break;
494
 
495
        case USBD_IDX_CONFIG_STR:
496
          if (pdev->pDesc->GetConfigurationStrDescriptor != NULL)
497
          {
498
            pbuf = pdev->pDesc->GetConfigurationStrDescriptor(pdev->dev_speed, &len);
499
          }
500
          else
501
          {
502
            USBD_CtlError(pdev, req);
503
            err++;
504
          }
505
          break;
506
 
507
        case USBD_IDX_INTERFACE_STR:
508
          if (pdev->pDesc->GetInterfaceStrDescriptor != NULL)
509
          {
510
            pbuf = pdev->pDesc->GetInterfaceStrDescriptor(pdev->dev_speed, &len);
511
          }
512
          else
513
          {
514
            USBD_CtlError(pdev, req);
515
            err++;
516
          }
517
          break;
518
 
519
        default:
520
#if (USBD_SUPPORT_USER_STRING_DESC == 1U)
521
          if (pdev->pClass->GetUsrStrDescriptor != NULL)
522
          {
523
            pbuf = pdev->pClass->GetUsrStrDescriptor(pdev, (req->wValue), &len);
524
          }
525
          else
526
          {
527
            USBD_CtlError(pdev, req);
528
            err++;
529
          }
530
          break;
531
#else
532
          USBD_CtlError(pdev, req);
533
          err++;
534
#endif
535
      }
536
      break;
537
 
538
    case USB_DESC_TYPE_DEVICE_QUALIFIER:
539
      if (pdev->dev_speed == USBD_SPEED_HIGH)
540
      {
541
        pbuf = pdev->pClass->GetDeviceQualifierDescriptor(&len);
542
      }
543
      else
544
      {
545
        USBD_CtlError(pdev, req);
546
        err++;
547
      }
548
      break;
549
 
550
    case USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION:
551
      if (pdev->dev_speed == USBD_SPEED_HIGH)
552
      {
553
        pbuf = pdev->pClass->GetOtherSpeedConfigDescriptor(&len);
554
        pbuf[1] = USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION;
555
      }
556
      else
557
      {
558
        USBD_CtlError(pdev, req);
559
        err++;
560
      }
561
      break;
562
 
563
    default:
564
      USBD_CtlError(pdev, req);
565
      err++;
566
      break;
567
  }
568
 
569
  if (err != 0U)
570
  {
571
    return;
572
  }
573
  else
574
  {
575
    if ((len != 0U) && (req->wLength != 0U))
576
    {
577
      len = MIN(len, req->wLength);
578
      (void)USBD_CtlSendData(pdev, pbuf, len);
579
    }
580
 
581
    if (req->wLength == 0U)
582
    {
583
      (void)USBD_CtlSendStatus(pdev);
584
    }
585
  }
586
}
587
 
588
/**
589
* @brief  USBD_SetAddress
590
*         Set device address
591
* @param  pdev: device instance
592
* @param  req: usb request
593
* @retval status
594
*/
595
static void USBD_SetAddress(USBD_HandleTypeDef *pdev,
596
                            USBD_SetupReqTypedef *req)
597
{
598
  uint8_t  dev_addr;
599
 
600
  if ((req->wIndex == 0U) && (req->wLength == 0U) && (req->wValue < 128U))
601
  {
602
    dev_addr = (uint8_t)(req->wValue) & 0x7FU;
603
 
604
    if (pdev->dev_state == USBD_STATE_CONFIGURED)
605
    {
606
      USBD_CtlError(pdev, req);
607
    }
608
    else
609
    {
610
      pdev->dev_address = dev_addr;
611
      USBD_LL_SetUSBAddress(pdev, dev_addr);
612
      USBD_CtlSendStatus(pdev);
613
 
614
      if (dev_addr != 0U)
615
      {
616
        pdev->dev_state = USBD_STATE_ADDRESSED;
617
      }
618
      else
619
      {
620
        pdev->dev_state = USBD_STATE_DEFAULT;
621
      }
622
    }
623
  }
624
  else
625
  {
626
    USBD_CtlError(pdev, req);
627
  }
628
}
629
 
630
/**
631
* @brief  USBD_SetConfig
632
*         Handle Set device configuration request
633
* @param  pdev: device instance
634
* @param  req: usb request
635
* @retval status
636
*/
637
static void USBD_SetConfig(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req)
638
{
639
  static uint8_t cfgidx;
640
 
641
  cfgidx = (uint8_t)(req->wValue);
642
 
643
  if (cfgidx > USBD_MAX_NUM_CONFIGURATION)
644
  {
645
    USBD_CtlError(pdev, req);
646
  }
647
  else
648
  {
649
    switch (pdev->dev_state)
650
    {
651
      case USBD_STATE_ADDRESSED:
652
        if (cfgidx)
653
        {
654
          pdev->dev_config = cfgidx;
655
          pdev->dev_state = USBD_STATE_CONFIGURED;
656
          if (USBD_SetClassConfig(pdev, cfgidx) == USBD_FAIL)
657
          {
658
            USBD_CtlError(pdev, req);
659
            return;
660
          }
661
          USBD_CtlSendStatus(pdev);
662
        }
663
        else
664
        {
665
          USBD_CtlSendStatus(pdev);
666
        }
667
        break;
668
 
669
      case USBD_STATE_CONFIGURED:
670
        if (cfgidx == 0U)
671
        {
672
          pdev->dev_state = USBD_STATE_ADDRESSED;
673
          pdev->dev_config = cfgidx;
674
          USBD_ClrClassConfig(pdev, cfgidx);
675
          USBD_CtlSendStatus(pdev);
676
        }
677
        else if (cfgidx != pdev->dev_config)
678
        {
679
          /* Clear old configuration */
680
          USBD_ClrClassConfig(pdev, (uint8_t)pdev->dev_config);
681
 
682
          /* set new configuration */
683
          pdev->dev_config = cfgidx;
684
          if (USBD_SetClassConfig(pdev, cfgidx) == USBD_FAIL)
685
          {
686
            USBD_CtlError(pdev, req);
687
            return;
688
          }
689
          USBD_CtlSendStatus(pdev);
690
        }
691
        else
692
        {
693
          USBD_CtlSendStatus(pdev);
694
        }
695
        break;
696
 
697
      default:
698
        USBD_CtlError(pdev, req);
699
        USBD_ClrClassConfig(pdev, cfgidx);
700
        break;
701
    }
702
  }
703
}
704
 
705
/**
706
* @brief  USBD_GetConfig
707
*         Handle Get device configuration request
708
* @param  pdev: device instance
709
* @param  req: usb request
710
* @retval status
711
*/
712
static void USBD_GetConfig(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req)
713
{
714
  if (req->wLength != 1U)
715
  {
716
    USBD_CtlError(pdev, req);
717
  }
718
  else
719
  {
720
    switch (pdev->dev_state)
721
    {
722
      case USBD_STATE_DEFAULT:
723
      case USBD_STATE_ADDRESSED:
724
        pdev->dev_default_config = 0U;
725
        USBD_CtlSendData(pdev, (uint8_t *)(void *)&pdev->dev_default_config, 1U);
726
        break;
727
 
728
      case USBD_STATE_CONFIGURED:
729
        USBD_CtlSendData(pdev, (uint8_t *)(void *)&pdev->dev_config, 1U);
730
        break;
731
 
732
      default:
733
        USBD_CtlError(pdev, req);
734
        break;
735
    }
736
  }
737
}
738
 
739
/**
740
* @brief  USBD_GetStatus
741
*         Handle Get Status request
742
* @param  pdev: device instance
743
* @param  req: usb request
744
* @retval status
745
*/
746
static void USBD_GetStatus(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req)
747
{
748
  switch (pdev->dev_state)
749
  {
750
    case USBD_STATE_DEFAULT:
751
    case USBD_STATE_ADDRESSED:
752
    case USBD_STATE_CONFIGURED:
753
      if (req->wLength != 0x2U)
754
      {
755
        USBD_CtlError(pdev, req);
756
        break;
757
      }
758
 
759
#if (USBD_SELF_POWERED == 1U)
760
      pdev->dev_config_status = USB_CONFIG_SELF_POWERED;
761
#else
762
      pdev->dev_config_status = 0U;
763
#endif
764
 
765
      if (pdev->dev_remote_wakeup)
766
      {
767
        pdev->dev_config_status |= USB_CONFIG_REMOTE_WAKEUP;
768
      }
769
 
770
      USBD_CtlSendData(pdev, (uint8_t *)(void *)&pdev->dev_config_status, 2U);
771
      break;
772
 
773
    default:
774
      USBD_CtlError(pdev, req);
775
      break;
776
  }
777
}
778
 
779
 
780
/**
781
* @brief  USBD_SetFeature
782
*         Handle Set device feature request
783
* @param  pdev: device instance
784
* @param  req: usb request
785
* @retval status
786
*/
787
static void USBD_SetFeature(USBD_HandleTypeDef *pdev,
788
                            USBD_SetupReqTypedef *req)
789
{
790
  if (req->wValue == USB_FEATURE_REMOTE_WAKEUP)
791
  {
792
    pdev->dev_remote_wakeup = 1U;
793
    USBD_CtlSendStatus(pdev);
794
  }
795
}
796
 
797
 
798
/**
799
* @brief  USBD_ClrFeature
800
*         Handle clear device feature request
801
* @param  pdev: device instance
802
* @param  req: usb request
803
* @retval status
804
*/
805
static void USBD_ClrFeature(USBD_HandleTypeDef *pdev,
806
                            USBD_SetupReqTypedef *req)
807
{
808
  switch (pdev->dev_state)
809
  {
810
    case USBD_STATE_DEFAULT:
811
    case USBD_STATE_ADDRESSED:
812
    case USBD_STATE_CONFIGURED:
813
      if (req->wValue == USB_FEATURE_REMOTE_WAKEUP)
814
      {
815
        pdev->dev_remote_wakeup = 0U;
816
        USBD_CtlSendStatus(pdev);
817
      }
818
      break;
819
 
820
    default:
821
      USBD_CtlError(pdev, req);
822
      break;
823
  }
824
}
825
 
826
/**
827
* @brief  USBD_ParseSetupRequest
828
*         Copy buffer into setup structure
829
* @param  pdev: device instance
830
* @param  req: usb request
831
* @retval None
832
*/
833
 
834
void USBD_ParseSetupRequest(USBD_SetupReqTypedef *req, uint8_t *pdata)
835
{
836
  req->bmRequest = *(uint8_t *)(pdata);
837
  req->bRequest = *(uint8_t *)(pdata + 1U);
838
  req->wValue = SWAPBYTE(pdata + 2U);
839
  req->wIndex = SWAPBYTE(pdata + 4U);
840
  req->wLength = SWAPBYTE(pdata + 6U);
841
 
842
}
843
 
844
/**
845
* @brief  USBD_CtlError
846
*         Handle USB low level Error
847
* @param  pdev: device instance
848
* @param  req: usb request
849
* @retval None
850
*/
851
 
852
void USBD_CtlError(USBD_HandleTypeDef *pdev,
853
                   USBD_SetupReqTypedef *req)
854
{
855
  USBD_LL_StallEP(pdev, 0x80U);
856
  USBD_LL_StallEP(pdev, 0U);
857
}
858
 
859
 
860
/**
861
  * @brief  USBD_GetString
862
  *         Convert Ascii string into unicode one
863
  * @param  desc : descriptor buffer
864
  * @param  unicode : Formatted string buffer (unicode)
865
  * @param  len : descriptor length
866
  * @retval None
867
  */
868
void USBD_GetString(uint8_t *desc, uint8_t *unicode, uint16_t *len)
869
{
870
  uint8_t idx = 0U;
871
 
872
  if (desc != NULL)
873
  {
874
    *len = (uint16_t)USBD_GetLen(desc) * 2U + 2U;
875
    unicode[idx++] = *(uint8_t *)(void *)len;
876
    unicode[idx++] = USB_DESC_TYPE_STRING;
877
 
878
    while (*desc != '\0')
879
    {
880
      unicode[idx++] = *desc++;
881
      unicode[idx++] =  0U;
882
    }
883
  }
884
}
885
 
886
/**
887
  * @brief  USBD_GetLen
888
  *         return the string length
889
   * @param  buf : pointer to the ascii string buffer
890
  * @retval string length
891
  */
892
static uint8_t USBD_GetLen(uint8_t *buf)
893
{
894
  uint8_t  len = 0U;
895
 
896
  while (*buf != '\0')
897
  {
898
    len++;
899
    buf++;
900
  }
901
 
902
  return len;
903
}
904
/**
905
  * @}
906
  */
907
 
908
 
909
/**
910
  * @}
911
  */
912
 
913
 
914
/**
915
  * @}
916
  */
917
 
918
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/