Browse code

Add source code of the firmware for the IO Board

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