Subversion Repositories dashGPS

Rev

Blame | Last modification | View Log | Download | RSS feed

  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****/
  919.