2 ******************************************************************************
4 * @author MCD Application Team
7 * @brief This file provides the standard USB requests following chapter 9.
8 ******************************************************************************
11 * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
12 * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
13 * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
14 * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
15 * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
16 * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
18 * <h2><center>© COPYRIGHT 2011 STMicroelectronics</center></h2>
19 ******************************************************************************
22 /* Includes ------------------------------------------------------------------*/
24 #include "usbd_ioreq.h"
25 #include "usbd_desc.h"
28 /** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY
33 /** @defgroup USBD_REQ
34 * @brief USB standard requests module
38 /** @defgroup USBD_REQ_Private_TypesDefinitions
46 /** @defgroup USBD_REQ_Private_Defines
55 /** @defgroup USBD_REQ_Private_Macros
63 /** @defgroup USBD_REQ_Private_Variables
67 #ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
68 #if defined ( __ICCARM__ ) /*!< IAR Compiler */
69 #pragma data_alignment=4
71 #endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */
72 __ALIGN_BEGIN uint32_t USBD_ep_status __ALIGN_END = 0;
74 #ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
75 #if defined ( __ICCARM__ ) /*!< IAR Compiler */
76 #pragma data_alignment=4
78 #endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */
79 __ALIGN_BEGIN uint32_t USBD_default_cfg __ALIGN_END = 0;
81 #ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
82 #if defined ( __ICCARM__ ) /*!< IAR Compiler */
83 #pragma data_alignment=4
85 #endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */
86 __ALIGN_BEGIN uint32_t USBD_cfg_status __ALIGN_END = 0;
88 #ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
89 #if defined ( __ICCARM__ ) /*!< IAR Compiler */
90 #pragma data_alignment=4
92 #endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */
93 __ALIGN_BEGIN uint8_t USBD_StrDesc[USB_MAX_STR_DESC_SIZ] __ALIGN_END ;
99 /** @defgroup USBD_REQ_Private_FunctionPrototypes
102 static void USBD_GetDescriptor(USB_OTG_CORE_HANDLE *pdev,
105 static void USBD_SetAddress(USB_OTG_CORE_HANDLE *pdev,
108 static void USBD_SetConfig(USB_OTG_CORE_HANDLE *pdev,
111 static void USBD_GetConfig(USB_OTG_CORE_HANDLE *pdev,
114 static void USBD_GetStatus(USB_OTG_CORE_HANDLE *pdev,
117 static void USBD_SetFeature(USB_OTG_CORE_HANDLE *pdev,
120 static void USBD_ClrFeature(USB_OTG_CORE_HANDLE *pdev,
123 static uint8_t USBD_GetLen(uint8_t *buf);
129 /** @defgroup USBD_REQ_Private_Functions
135 * @brief USBD_StdDevReq
136 * Handle standard usb device requests
137 * @param pdev: device instance
138 * @param req: usb request
141 USBD_Status USBD_StdDevReq (USB_OTG_CORE_HANDLE *pdev, USB_SETUP_REQ *req)
143 USBD_Status ret = USBD_OK;
145 switch (req->bRequest)
147 case USB_REQ_GET_DESCRIPTOR:
149 USBD_GetDescriptor (pdev, req) ;
152 case USB_REQ_SET_ADDRESS:
153 USBD_SetAddress(pdev, req);
156 case USB_REQ_SET_CONFIGURATION:
157 USBD_SetConfig (pdev , req);
160 case USB_REQ_GET_CONFIGURATION:
161 USBD_GetConfig (pdev , req);
164 case USB_REQ_GET_STATUS:
165 USBD_GetStatus (pdev , req);
169 case USB_REQ_SET_FEATURE:
170 USBD_SetFeature (pdev , req);
173 case USB_REQ_CLEAR_FEATURE:
174 USBD_ClrFeature (pdev , req);
178 USBD_CtlError(pdev , req);
186 * @brief USBD_StdItfReq
187 * Handle standard usb interface requests
188 * @param pdev: USB OTG device instance
189 * @param req: usb request
192 USBD_Status USBD_StdItfReq (USB_OTG_CORE_HANDLE *pdev, USB_SETUP_REQ *req)
194 USBD_Status ret = USBD_OK;
196 switch (pdev->dev.device_status)
198 case USB_OTG_CONFIGURED:
200 if (LOBYTE(req->wIndex) <= USBD_ITF_MAX_NUM)
202 pdev->dev.class_cb->Setup (pdev, req);
204 if((req->wLength == 0)&& (ret == USBD_OK))
206 USBD_CtlSendStatus(pdev);
211 USBD_CtlError(pdev , req);
216 USBD_CtlError(pdev , req);
223 * @brief USBD_StdEPReq
224 * Handle standard usb endpoint requests
225 * @param pdev: USB OTG device instance
226 * @param req: usb request
229 USBD_Status USBD_StdEPReq (USB_OTG_CORE_HANDLE *pdev, USB_SETUP_REQ *req)
233 USBD_Status ret = USBD_OK;
235 ep_addr = LOBYTE(req->wIndex);
237 switch (req->bRequest)
240 case USB_REQ_SET_FEATURE :
242 switch (pdev->dev.device_status)
244 case USB_OTG_ADDRESSED:
245 if ((ep_addr != 0x00) && (ep_addr != 0x80))
247 DCD_EP_Stall(pdev , ep_addr);
251 case USB_OTG_CONFIGURED:
252 if (req->wValue == USB_FEATURE_EP_HALT)
254 if ((ep_addr != 0x00) && (ep_addr != 0x80))
256 DCD_EP_Stall(pdev , ep_addr);
260 pdev->dev.class_cb->Setup (pdev, req);
261 USBD_CtlSendStatus(pdev);
266 USBD_CtlError(pdev , req);
271 case USB_REQ_CLEAR_FEATURE :
273 switch (pdev->dev.device_status)
275 case USB_OTG_ADDRESSED:
276 if ((ep_addr != 0x00) && (ep_addr != 0x80))
278 DCD_EP_Stall(pdev , ep_addr);
282 case USB_OTG_CONFIGURED:
283 if (req->wValue == USB_FEATURE_EP_HALT)
285 if ((ep_addr != 0x00) && (ep_addr != 0x80))
287 DCD_EP_ClrStall(pdev , ep_addr);
288 pdev->dev.class_cb->Setup (pdev, req);
290 USBD_CtlSendStatus(pdev);
295 USBD_CtlError(pdev , req);
300 case USB_REQ_GET_STATUS:
301 switch (pdev->dev.device_status)
303 case USB_OTG_ADDRESSED:
304 if ((ep_addr != 0x00) && (ep_addr != 0x80))
306 DCD_EP_Stall(pdev , ep_addr);
310 case USB_OTG_CONFIGURED:
313 if ((ep_addr & 0x80)== 0x80)
315 if(pdev->dev.in_ep[ep_addr & 0x7F].is_stall)
317 USBD_ep_status = 0x0001;
321 USBD_ep_status = 0x0000;
324 else if ((ep_addr & 0x80)== 0x00)
326 if(pdev->dev.out_ep[ep_addr].is_stall)
328 USBD_ep_status = 0x0001;
333 USBD_ep_status = 0x0000;
336 USBD_CtlSendData (pdev,
337 (uint8_t *)&USBD_ep_status,
342 USBD_CtlError(pdev , req);
353 * @brief USBD_GetDescriptor
354 * Handle Get Descriptor requests
355 * @param pdev: device instance
356 * @param req: usb request
359 static void USBD_GetDescriptor(USB_OTG_CORE_HANDLE *pdev,
365 switch (req->wValue >> 8)
367 case USB_DESC_TYPE_DEVICE:
368 pbuf = pdev->dev.usr_device->GetDeviceDescriptor(pdev->cfg.speed, &len);
369 if ((req->wLength == 64) ||( pdev->dev.device_status == USB_OTG_DEFAULT))
375 case USB_DESC_TYPE_CONFIGURATION:
376 pbuf = (uint8_t *)pdev->dev.class_cb->GetConfigDescriptor(pdev->cfg.speed, &len);
377 #ifdef USB_OTG_HS_CORE
378 if((pdev->cfg.speed == USB_OTG_SPEED_FULL )&&
379 (pdev->cfg.phy_itface == USB_OTG_ULPI_PHY))
381 pbuf = (uint8_t *)pdev->dev.class_cb->GetOtherConfigDescriptor(pdev->cfg.speed, &len);
384 pbuf[1] = USB_DESC_TYPE_CONFIGURATION;
385 pdev->dev.pConfig_descriptor = pbuf;
388 case USB_DESC_TYPE_STRING:
389 switch ((uint8_t)(req->wValue))
391 case USBD_IDX_LANGID_STR:
392 pbuf = pdev->dev.usr_device->GetLangIDStrDescriptor(pdev->cfg.speed, &len);
395 case USBD_IDX_MFC_STR:
396 pbuf = pdev->dev.usr_device->GetManufacturerStrDescriptor(pdev->cfg.speed, &len);
399 case USBD_IDX_PRODUCT_STR:
400 pbuf = pdev->dev.usr_device->GetProductStrDescriptor(pdev->cfg.speed, &len);
403 case USBD_IDX_SERIAL_STR:
404 pbuf = pdev->dev.usr_device->GetSerialStrDescriptor(pdev->cfg.speed, &len);
407 case USBD_IDX_CONFIG_STR:
408 pbuf = pdev->dev.usr_device->GetConfigurationStrDescriptor(pdev->cfg.speed, &len);
411 case USBD_IDX_INTERFACE_STR:
412 pbuf = pdev->dev.usr_device->GetInterfaceStrDescriptor(pdev->cfg.speed, &len);
416 #ifdef USB_SUPPORT_USER_STRING_DESC
417 pbuf = pdev->dev.class_cb->GetUsrStrDescriptor(pdev->cfg.speed, (req->wValue) , &len);
420 USBD_CtlError(pdev , req);
422 #endif /* USBD_CtlError(pdev , req); */
425 case USB_DESC_TYPE_DEVICE_QUALIFIER:
426 #ifdef USB_OTG_HS_CORE
427 if(pdev->cfg.speed == USB_OTG_SPEED_HIGH )
430 pbuf = (uint8_t *)pdev->dev.class_cb->GetConfigDescriptor(pdev->cfg.speed, &len);
432 USBD_DeviceQualifierDesc[4]= pbuf[14];
433 USBD_DeviceQualifierDesc[5]= pbuf[15];
434 USBD_DeviceQualifierDesc[6]= pbuf[16];
436 pbuf = USBD_DeviceQualifierDesc;
437 len = USB_LEN_DEV_QUALIFIER_DESC;
442 USBD_CtlError(pdev , req);
446 USBD_CtlError(pdev , req);
450 case USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION:
451 #ifdef USB_OTG_HS_CORE
453 if(pdev->cfg.speed == USB_OTG_SPEED_HIGH )
455 pbuf = (uint8_t *)pdev->dev.class_cb->GetOtherConfigDescriptor(pdev->cfg.speed, &len);
456 pbuf[1] = USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION;
461 USBD_CtlError(pdev , req);
465 USBD_CtlError(pdev , req);
471 USBD_CtlError(pdev , req);
475 if((len != 0)&& (req->wLength != 0))
478 len = MIN(len , req->wLength);
480 USBD_CtlSendData (pdev,
488 * @brief USBD_SetAddress
490 * @param pdev: device instance
491 * @param req: usb request
494 static void USBD_SetAddress(USB_OTG_CORE_HANDLE *pdev,
499 if ((req->wIndex == 0) && (req->wLength == 0))
501 dev_addr = (uint8_t)(req->wValue) & 0x7F;
503 if (pdev->dev.device_status == USB_OTG_CONFIGURED)
505 USBD_CtlError(pdev , req);
509 pdev->dev.device_address = dev_addr;
510 DCD_EP_SetAddress(pdev, dev_addr);
511 USBD_CtlSendStatus(pdev);
515 pdev->dev.device_status = USB_OTG_ADDRESSED;
519 pdev->dev.device_status = USB_OTG_DEFAULT;
525 USBD_CtlError(pdev , req);
530 * @brief USBD_SetConfig
531 * Handle Set device configuration request
532 * @param pdev: device instance
533 * @param req: usb request
536 static void USBD_SetConfig(USB_OTG_CORE_HANDLE *pdev,
540 static uint8_t cfgidx;
542 cfgidx = (uint8_t)(req->wValue);
544 if (cfgidx > USBD_CFG_MAX_NUM )
546 USBD_CtlError(pdev , req);
550 switch (pdev->dev.device_status)
552 case USB_OTG_ADDRESSED:
555 pdev->dev.device_config = cfgidx;
556 pdev->dev.device_status = USB_OTG_CONFIGURED;
557 USBD_SetCfg(pdev , cfgidx);
558 USBD_CtlSendStatus(pdev);
562 USBD_CtlSendStatus(pdev);
566 case USB_OTG_CONFIGURED:
569 pdev->dev.device_status = USB_OTG_ADDRESSED;
570 pdev->dev.device_config = cfgidx;
571 USBD_ClrCfg(pdev , cfgidx);
572 USBD_CtlSendStatus(pdev);
575 else if (cfgidx != pdev->dev.device_config)
577 /* Clear old configuration */
578 USBD_ClrCfg(pdev , pdev->dev.device_config);
580 /* set new configuration */
581 pdev->dev.device_config = cfgidx;
582 USBD_SetCfg(pdev , cfgidx);
583 USBD_CtlSendStatus(pdev);
587 USBD_CtlSendStatus(pdev);
592 USBD_CtlError(pdev , req);
599 * @brief USBD_GetConfig
600 * Handle Get device configuration request
601 * @param pdev: device instance
602 * @param req: usb request
605 static void USBD_GetConfig(USB_OTG_CORE_HANDLE *pdev,
609 if (req->wLength != 1)
611 USBD_CtlError(pdev , req);
615 switch (pdev->dev.device_status )
617 case USB_OTG_ADDRESSED:
619 USBD_CtlSendData (pdev,
620 (uint8_t *)&USBD_default_cfg,
624 case USB_OTG_CONFIGURED:
626 USBD_CtlSendData (pdev,
627 &pdev->dev.device_config,
632 USBD_CtlError(pdev , req);
639 * @brief USBD_GetStatus
640 * Handle Get Status request
641 * @param pdev: device instance
642 * @param req: usb request
645 static void USBD_GetStatus(USB_OTG_CORE_HANDLE *pdev,
649 switch (pdev->dev.device_status)
651 case USB_OTG_ADDRESSED:
652 case USB_OTG_CONFIGURED:
654 if (pdev->dev.DevRemoteWakeup)
656 USBD_cfg_status = USB_CONFIG_SELF_POWERED | USB_CONFIG_REMOTE_WAKEUP;
660 USBD_cfg_status = USB_CONFIG_SELF_POWERED;
663 USBD_CtlSendData (pdev,
664 (uint8_t *)&USBD_cfg_status,
669 USBD_CtlError(pdev , req);
676 * @brief USBD_SetFeature
677 * Handle Set device feature request
678 * @param pdev: device instance
679 * @param req: usb request
682 static void USBD_SetFeature(USB_OTG_CORE_HANDLE *pdev,
686 USB_OTG_DCTL_TypeDef dctl;
687 uint8_t test_mode = 0;
689 if (req->wValue == USB_FEATURE_REMOTE_WAKEUP)
691 pdev->dev.DevRemoteWakeup = 1;
692 pdev->dev.class_cb->Setup (pdev, req);
693 USBD_CtlSendStatus(pdev);
696 else if ((req->wValue == USB_FEATURE_TEST_MODE) &&
697 ((req->wIndex & 0xFF) == 0))
699 dctl.d32 = USB_OTG_READ_REG32(&pdev->regs.DREGS->DCTL);
701 test_mode = req->wIndex >> 8;
712 case 3: // TEST_SE0_NAK
716 case 4: // TEST_PACKET
720 case 5: // TEST_FORCE_ENABLE
724 USB_OTG_WRITE_REG32(&pdev->regs.DREGS->DCTL, dctl.d32);
725 USBD_CtlSendStatus(pdev);
732 * @brief USBD_ClrFeature
733 * Handle clear device feature request
734 * @param pdev: device instance
735 * @param req: usb request
738 static void USBD_ClrFeature(USB_OTG_CORE_HANDLE *pdev,
741 switch (pdev->dev.device_status)
743 case USB_OTG_ADDRESSED:
744 case USB_OTG_CONFIGURED:
745 if (req->wValue == USB_FEATURE_REMOTE_WAKEUP)
747 pdev->dev.DevRemoteWakeup = 0;
748 pdev->dev.class_cb->Setup (pdev, req);
749 USBD_CtlSendStatus(pdev);
754 USBD_CtlError(pdev , req);
760 * @brief USBD_ParseSetupRequest
761 * Copy buffer into setup structure
762 * @param pdev: device instance
763 * @param req: usb request
767 void USBD_ParseSetupRequest( USB_OTG_CORE_HANDLE *pdev,
770 req->bmRequest = *(uint8_t *) (pdev->dev.setup_packet);
771 req->bRequest = *(uint8_t *) (pdev->dev.setup_packet + 1);
772 req->wValue = SWAPBYTE (pdev->dev.setup_packet + 2);
773 req->wIndex = SWAPBYTE (pdev->dev.setup_packet + 4);
774 req->wLength = SWAPBYTE (pdev->dev.setup_packet + 6);
776 pdev->dev.in_ep[0].ctl_data_len = req->wLength ;
777 pdev->dev.device_state = USB_OTG_EP0_SETUP;
781 * @brief USBD_CtlError
782 * Handle USB low level Error
783 * @param pdev: device instance
784 * @param req: usb request
788 void USBD_CtlError( USB_OTG_CORE_HANDLE *pdev,
791 if((req->bmRequest & 0x80) == 0x80)
793 DCD_EP_Stall(pdev , 0x80);
797 if(req->wLength == 0)
799 DCD_EP_Stall(pdev , 0x80);
803 DCD_EP_Stall(pdev , 0);
806 USB_OTG_EP0_OutStart(pdev);
811 * @brief USBD_GetString
812 * Convert Ascii string into unicode one
813 * @param desc : descriptor buffer
814 * @param unicode : Formatted string buffer (unicode)
815 * @param len : descriptor length
818 void USBD_GetString(uint8_t *desc, uint8_t *unicode, uint16_t *len)
824 *len = USBD_GetLen(desc) * 2 + 2;
825 unicode[idx++] = *len;
826 unicode[idx++] = USB_DESC_TYPE_STRING;
828 while (*desc != NULL)
830 unicode[idx++] = *desc++;
831 unicode[idx++] = 0x00;
838 * return the string length
839 * @param buf : pointer to the ascii string buffer
840 * @retval string length
842 static uint8_t USBD_GetLen(uint8_t *buf)
868 /******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/