USB CDC library for MBED on STM32

Dependents:   PushToGo-F429

Committer:
caoyuan9642
Date:
Sun Sep 09 19:03:18 2018 +0000
Revision:
0:7cf972f622d3
usb

Who changed what in which revision?

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