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