Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: ton_demo ton_template
usbd_ctlreq.c
00001 /** 00002 ****************************************************************************** 00003 * @file usbd_req.c 00004 * @author MCD Application Team 00005 * @version V2.3.0 00006 * @date 04-November-2014 00007 * @brief This file provides the standard USB requests following chapter 9. 00008 ****************************************************************************** 00009 * @attention 00010 * 00011 * <h2><center>© COPYRIGHT 2014 STMicroelectronics</center></h2> 00012 * 00013 * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); 00014 * You may not use this file except in compliance with the License. 00015 * You may obtain a copy of the License at: 00016 * 00017 * http://www.st.com/software_license_agreement_liberty_v2 00018 * 00019 * Unless required by applicable law or agreed to in writing, software 00020 * distributed under the License is distributed on an "AS IS" BASIS, 00021 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00022 * See the License for the specific language governing permissions and 00023 * limitations under the License. 00024 * 00025 ****************************************************************************** 00026 */ 00027 00028 /* Includes ------------------------------------------------------------------*/ 00029 #include "usbd_ctlreq.h" 00030 #include "usbd_ioreq.h" 00031 00032 00033 /** @addtogroup STM32_USBD_STATE_DEVICE_LIBRARY 00034 * @{ 00035 */ 00036 00037 00038 /** @defgroup USBD_REQ 00039 * @brief USB standard requests module 00040 * @{ 00041 */ 00042 00043 /** @defgroup USBD_REQ_Private_TypesDefinitions 00044 * @{ 00045 */ 00046 /** 00047 * @} 00048 */ 00049 00050 00051 /** @defgroup USBD_REQ_Private_Defines 00052 * @{ 00053 */ 00054 00055 /** 00056 * @} 00057 */ 00058 00059 00060 /** @defgroup USBD_REQ_Private_Macros 00061 * @{ 00062 */ 00063 /** 00064 * @} 00065 */ 00066 00067 00068 /** @defgroup USBD_REQ_Private_Variables 00069 * @{ 00070 */ 00071 /** 00072 * @} 00073 */ 00074 00075 00076 /** @defgroup USBD_REQ_Private_FunctionPrototypes 00077 * @{ 00078 */ 00079 static void USBD_GetDescriptor(USBD_HandleTypeDef *pdev , 00080 USBD_SetupReqTypedef *req); 00081 00082 static void USBD_SetAddress(USBD_HandleTypeDef *pdev , 00083 USBD_SetupReqTypedef *req); 00084 00085 static void USBD_SetConfig(USBD_HandleTypeDef *pdev , 00086 USBD_SetupReqTypedef *req); 00087 00088 static void USBD_GetConfig(USBD_HandleTypeDef *pdev , 00089 USBD_SetupReqTypedef *req); 00090 00091 static void USBD_GetStatus(USBD_HandleTypeDef *pdev , 00092 USBD_SetupReqTypedef *req); 00093 00094 static void USBD_SetFeature(USBD_HandleTypeDef *pdev , 00095 USBD_SetupReqTypedef *req); 00096 00097 static void USBD_ClrFeature(USBD_HandleTypeDef *pdev , 00098 USBD_SetupReqTypedef *req); 00099 00100 static uint8_t USBD_GetLen(uint8_t *buf); 00101 00102 /** 00103 * @} 00104 */ 00105 00106 00107 /** @defgroup USBD_REQ_Private_Functions 00108 * @{ 00109 */ 00110 00111 00112 /** 00113 * @brief USBD_StdDevReq 00114 * Handle standard usb device requests 00115 * @param pdev: device instance 00116 * @param req: usb request 00117 * @retval status 00118 */ 00119 USBD_StatusTypeDef USBD_StdDevReq (USBD_HandleTypeDef *pdev , USBD_SetupReqTypedef *req) 00120 { 00121 USBD_StatusTypeDef ret = USBD_OK; 00122 00123 switch (req->bRequest) 00124 { 00125 case USB_REQ_GET_DESCRIPTOR: 00126 00127 USBD_GetDescriptor (pdev, req) ; 00128 break; 00129 00130 case USB_REQ_SET_ADDRESS: 00131 USBD_SetAddress(pdev, req); 00132 break; 00133 00134 case USB_REQ_SET_CONFIGURATION: 00135 USBD_SetConfig (pdev , req); 00136 break; 00137 00138 case USB_REQ_GET_CONFIGURATION: 00139 USBD_GetConfig (pdev , req); 00140 break; 00141 00142 case USB_REQ_GET_STATUS: 00143 USBD_GetStatus (pdev , req); 00144 break; 00145 00146 00147 case USB_REQ_SET_FEATURE: 00148 USBD_SetFeature (pdev , req); 00149 break; 00150 00151 case USB_REQ_CLEAR_FEATURE: 00152 USBD_ClrFeature (pdev , req); 00153 break; 00154 00155 default: 00156 USBD_CtlError(pdev , req); 00157 break; 00158 } 00159 00160 return ret; 00161 } 00162 00163 /** 00164 * @brief USBD_StdItfReq 00165 * Handle standard usb interface requests 00166 * @param pdev: device instance 00167 * @param req: usb request 00168 * @retval status 00169 */ 00170 USBD_StatusTypeDef USBD_StdItfReq (USBD_HandleTypeDef *pdev , USBD_SetupReqTypedef *req) 00171 { 00172 USBD_StatusTypeDef ret = USBD_OK; 00173 00174 switch (pdev->dev_state) 00175 { 00176 case USBD_STATE_CONFIGURED: 00177 00178 if (LOBYTE(req->wIndex) <= USBD_MAX_NUM_INTERFACES) 00179 { 00180 pdev->pClass->Setup (pdev, req); 00181 00182 if((req->wLength == 0)&& (ret == USBD_OK)) 00183 { 00184 USBD_CtlSendStatus(pdev); 00185 } 00186 } 00187 else 00188 { 00189 USBD_CtlError(pdev , req); 00190 } 00191 break; 00192 00193 default: 00194 USBD_CtlError(pdev , req); 00195 break; 00196 } 00197 return USBD_OK; 00198 } 00199 00200 /** 00201 * @brief USBD_StdEPReq 00202 * Handle standard usb endpoint requests 00203 * @param pdev: device instance 00204 * @param req: usb request 00205 * @retval status 00206 */ 00207 USBD_StatusTypeDef USBD_StdEPReq (USBD_HandleTypeDef *pdev , USBD_SetupReqTypedef *req) 00208 { 00209 00210 uint8_t ep_addr; 00211 USBD_StatusTypeDef ret = USBD_OK; 00212 USBD_EndpointTypeDef *pep; 00213 ep_addr = LOBYTE(req->wIndex); 00214 00215 switch (req->bRequest) 00216 { 00217 00218 case USB_REQ_SET_FEATURE : 00219 00220 switch (pdev->dev_state) 00221 { 00222 case USBD_STATE_ADDRESSED: 00223 if ((ep_addr != 0x00) && (ep_addr != 0x80)) 00224 { 00225 USBD_LL_StallEP(pdev , ep_addr); 00226 } 00227 break; 00228 00229 case USBD_STATE_CONFIGURED: 00230 if (req->wValue == USB_FEATURE_EP_HALT) 00231 { 00232 if ((ep_addr != 0x00) && (ep_addr != 0x80)) 00233 { 00234 USBD_LL_StallEP(pdev , ep_addr); 00235 00236 } 00237 } 00238 pdev->pClass->Setup (pdev, req); 00239 USBD_CtlSendStatus(pdev); 00240 00241 break; 00242 00243 default: 00244 USBD_CtlError(pdev , req); 00245 break; 00246 } 00247 break; 00248 00249 case USB_REQ_CLEAR_FEATURE : 00250 00251 switch (pdev->dev_state) 00252 { 00253 case USBD_STATE_ADDRESSED: 00254 if ((ep_addr != 0x00) && (ep_addr != 0x80)) 00255 { 00256 USBD_LL_StallEP(pdev , ep_addr); 00257 } 00258 break; 00259 00260 case USBD_STATE_CONFIGURED: 00261 if (req->wValue == USB_FEATURE_EP_HALT) 00262 { 00263 if ((ep_addr & 0x7F) != 0x00) 00264 { 00265 USBD_LL_ClearStallEP(pdev , ep_addr); 00266 pdev->pClass->Setup (pdev, req); 00267 } 00268 USBD_CtlSendStatus(pdev); 00269 } 00270 break; 00271 00272 default: 00273 USBD_CtlError(pdev , req); 00274 break; 00275 } 00276 break; 00277 00278 case USB_REQ_GET_STATUS: 00279 switch (pdev->dev_state) 00280 { 00281 case USBD_STATE_ADDRESSED: 00282 if ((ep_addr & 0x7F) != 0x00) 00283 { 00284 USBD_LL_StallEP(pdev , ep_addr); 00285 } 00286 break; 00287 00288 case USBD_STATE_CONFIGURED: 00289 pep = ((ep_addr & 0x80) == 0x80) ? &pdev->ep_in[ep_addr & 0x7F]:\ 00290 &pdev->ep_out[ep_addr & 0x7F]; 00291 if(USBD_LL_IsStallEP(pdev, ep_addr)) 00292 { 00293 pep->status = 0x0001; 00294 } 00295 else 00296 { 00297 pep->status = 0x0000; 00298 } 00299 00300 USBD_CtlSendData (pdev, 00301 (uint8_t *)&pep->status, 00302 2); 00303 break; 00304 00305 default: 00306 USBD_CtlError(pdev , req); 00307 break; 00308 } 00309 break; 00310 00311 default: 00312 break; 00313 } 00314 return ret; 00315 } 00316 /** 00317 * @brief USBD_GetDescriptor 00318 * Handle Get Descriptor requests 00319 * @param pdev: device instance 00320 * @param req: usb request 00321 * @retval status 00322 */ 00323 static void USBD_GetDescriptor(USBD_HandleTypeDef *pdev , 00324 USBD_SetupReqTypedef *req) 00325 { 00326 uint16_t len; 00327 uint8_t *pbuf; 00328 00329 00330 switch (req->wValue >> 8) 00331 { 00332 case USB_DESC_TYPE_DEVICE: 00333 pbuf = pdev->pDesc->GetDeviceDescriptor(pdev->dev_speed, &len); 00334 break; 00335 00336 case USB_DESC_TYPE_CONFIGURATION: 00337 if(pdev->dev_speed == USBD_SPEED_HIGH ) 00338 { 00339 pbuf = (uint8_t *)pdev->pClass->GetHSConfigDescriptor(&len); 00340 pbuf[1] = USB_DESC_TYPE_CONFIGURATION; 00341 } 00342 else 00343 { 00344 pbuf = (uint8_t *)pdev->pClass->GetFSConfigDescriptor(&len); 00345 pbuf[1] = USB_DESC_TYPE_CONFIGURATION; 00346 } 00347 break; 00348 00349 case USB_DESC_TYPE_STRING: 00350 switch ((uint8_t)(req->wValue)) 00351 { 00352 case USBD_IDX_LANGID_STR: 00353 pbuf = pdev->pDesc->GetLangIDStrDescriptor(pdev->dev_speed, &len); 00354 break; 00355 00356 case USBD_IDX_MFC_STR: 00357 pbuf = pdev->pDesc->GetManufacturerStrDescriptor(pdev->dev_speed, &len); 00358 break; 00359 00360 case USBD_IDX_PRODUCT_STR: 00361 pbuf = pdev->pDesc->GetProductStrDescriptor(pdev->dev_speed, &len); 00362 break; 00363 00364 case USBD_IDX_SERIAL_STR: 00365 pbuf = pdev->pDesc->GetSerialStrDescriptor(pdev->dev_speed, &len); 00366 break; 00367 00368 case USBD_IDX_CONFIG_STR: 00369 pbuf = pdev->pDesc->GetConfigurationStrDescriptor(pdev->dev_speed, &len); 00370 break; 00371 00372 case USBD_IDX_INTERFACE_STR: 00373 pbuf = pdev->pDesc->GetInterfaceStrDescriptor(pdev->dev_speed, &len); 00374 break; 00375 00376 default: 00377 #if (USBD_SUPPORT_USER_STRING == 1) 00378 pbuf = pdev->pClass->GetUsrStrDescriptor(pdev, (req->wValue) , &len); 00379 break; 00380 #else 00381 USBD_CtlError(pdev , req); 00382 return; 00383 #endif 00384 } 00385 break; 00386 case USB_DESC_TYPE_DEVICE_QUALIFIER: 00387 00388 if(pdev->dev_speed == USBD_SPEED_HIGH ) 00389 { 00390 pbuf = (uint8_t *)pdev->pClass->GetDeviceQualifierDescriptor(&len); 00391 break; 00392 } 00393 else 00394 { 00395 USBD_CtlError(pdev , req); 00396 return; 00397 } 00398 00399 case USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION: 00400 if(pdev->dev_speed == USBD_SPEED_HIGH ) 00401 { 00402 pbuf = (uint8_t *)pdev->pClass->GetOtherSpeedConfigDescriptor(&len); 00403 pbuf[1] = USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION; 00404 break; 00405 } 00406 else 00407 { 00408 USBD_CtlError(pdev , req); 00409 return; 00410 } 00411 00412 default: 00413 USBD_CtlError(pdev , req); 00414 return; 00415 } 00416 00417 if((len != 0)&& (req->wLength != 0)) 00418 { 00419 00420 len = MIN(len , req->wLength); 00421 00422 USBD_CtlSendData (pdev, 00423 pbuf, 00424 len); 00425 } 00426 00427 } 00428 00429 /** 00430 * @brief USBD_SetAddress 00431 * Set device address 00432 * @param pdev: device instance 00433 * @param req: usb request 00434 * @retval status 00435 */ 00436 static void USBD_SetAddress(USBD_HandleTypeDef *pdev , 00437 USBD_SetupReqTypedef *req) 00438 { 00439 uint8_t dev_addr; 00440 00441 if ((req->wIndex == 0) && (req->wLength == 0)) 00442 { 00443 dev_addr = (uint8_t)(req->wValue) & 0x7F; 00444 00445 if (pdev->dev_state == USBD_STATE_CONFIGURED) 00446 { 00447 USBD_CtlError(pdev , req); 00448 } 00449 else 00450 { 00451 pdev->dev_address = dev_addr; 00452 USBD_LL_SetUSBAddress(pdev, dev_addr); 00453 USBD_CtlSendStatus(pdev); 00454 00455 if (dev_addr != 0) 00456 { 00457 pdev->dev_state = USBD_STATE_ADDRESSED; 00458 } 00459 else 00460 { 00461 pdev->dev_state = USBD_STATE_DEFAULT; 00462 } 00463 } 00464 } 00465 else 00466 { 00467 USBD_CtlError(pdev , req); 00468 } 00469 } 00470 00471 /** 00472 * @brief USBD_SetConfig 00473 * Handle Set device configuration request 00474 * @param pdev: device instance 00475 * @param req: usb request 00476 * @retval status 00477 */ 00478 static void USBD_SetConfig(USBD_HandleTypeDef *pdev , 00479 USBD_SetupReqTypedef *req) 00480 { 00481 00482 static uint8_t cfgidx; 00483 00484 cfgidx = (uint8_t)(req->wValue); 00485 00486 if (cfgidx > USBD_MAX_NUM_CONFIGURATION ) 00487 { 00488 USBD_CtlError(pdev , req); 00489 } 00490 else 00491 { 00492 switch (pdev->dev_state) 00493 { 00494 case USBD_STATE_ADDRESSED: 00495 if (cfgidx) 00496 { 00497 pdev->dev_config = cfgidx; 00498 pdev->dev_state = USBD_STATE_CONFIGURED; 00499 if(USBD_SetClassConfig(pdev , cfgidx) == USBD_FAIL) 00500 { 00501 USBD_CtlError(pdev , req); 00502 return; 00503 } 00504 USBD_CtlSendStatus(pdev); 00505 } 00506 else 00507 { 00508 USBD_CtlSendStatus(pdev); 00509 } 00510 break; 00511 00512 case USBD_STATE_CONFIGURED: 00513 if (cfgidx == 0) 00514 { 00515 pdev->dev_state = USBD_STATE_ADDRESSED; 00516 pdev->dev_config = cfgidx; 00517 USBD_ClrClassConfig(pdev , cfgidx); 00518 USBD_CtlSendStatus(pdev); 00519 00520 } 00521 else if (cfgidx != pdev->dev_config) 00522 { 00523 /* Clear old configuration */ 00524 USBD_ClrClassConfig(pdev , pdev->dev_config); 00525 00526 /* set new configuration */ 00527 pdev->dev_config = cfgidx; 00528 if(USBD_SetClassConfig(pdev , cfgidx) == USBD_FAIL) 00529 { 00530 USBD_CtlError(pdev , req); 00531 return; 00532 } 00533 USBD_CtlSendStatus(pdev); 00534 } 00535 else 00536 { 00537 USBD_CtlSendStatus(pdev); 00538 } 00539 break; 00540 00541 default: 00542 USBD_CtlError(pdev , req); 00543 break; 00544 } 00545 } 00546 } 00547 00548 /** 00549 * @brief USBD_GetConfig 00550 * Handle Get device configuration request 00551 * @param pdev: device instance 00552 * @param req: usb request 00553 * @retval status 00554 */ 00555 static void USBD_GetConfig(USBD_HandleTypeDef *pdev , 00556 USBD_SetupReqTypedef *req) 00557 { 00558 00559 if (req->wLength != 1) 00560 { 00561 USBD_CtlError(pdev , req); 00562 } 00563 else 00564 { 00565 switch (pdev->dev_state ) 00566 { 00567 case USBD_STATE_ADDRESSED: 00568 pdev->dev_default_config = 0; 00569 USBD_CtlSendData (pdev, 00570 (uint8_t *)&pdev->dev_default_config, 00571 1); 00572 break; 00573 00574 case USBD_STATE_CONFIGURED: 00575 00576 USBD_CtlSendData (pdev, 00577 (uint8_t *)&pdev->dev_config, 00578 1); 00579 break; 00580 00581 default: 00582 USBD_CtlError(pdev , req); 00583 break; 00584 } 00585 } 00586 } 00587 00588 /** 00589 * @brief USBD_GetStatus 00590 * Handle Get Status request 00591 * @param pdev: device instance 00592 * @param req: usb request 00593 * @retval status 00594 */ 00595 static void USBD_GetStatus(USBD_HandleTypeDef *pdev , 00596 USBD_SetupReqTypedef *req) 00597 { 00598 00599 00600 switch (pdev->dev_state) 00601 { 00602 case USBD_STATE_ADDRESSED: 00603 case USBD_STATE_CONFIGURED: 00604 00605 #if ( USBD_SELF_POWERED == 1) 00606 pdev->dev_config_status = USB_CONFIG_SELF_POWERED; 00607 #else 00608 pdev->dev_config_status = 0; 00609 #endif 00610 00611 if (pdev->dev_remote_wakeup) 00612 { 00613 pdev->dev_config_status |= USB_CONFIG_REMOTE_WAKEUP; 00614 } 00615 00616 USBD_CtlSendData (pdev, 00617 (uint8_t *)& pdev->dev_config_status, 00618 2); 00619 break; 00620 00621 default : 00622 USBD_CtlError(pdev , req); 00623 break; 00624 } 00625 } 00626 00627 00628 /** 00629 * @brief USBD_SetFeature 00630 * Handle Set device feature request 00631 * @param pdev: device instance 00632 * @param req: usb request 00633 * @retval status 00634 */ 00635 static void USBD_SetFeature(USBD_HandleTypeDef *pdev , 00636 USBD_SetupReqTypedef *req) 00637 { 00638 00639 if (req->wValue == USB_FEATURE_REMOTE_WAKEUP) 00640 { 00641 pdev->dev_remote_wakeup = 1; 00642 pdev->pClass->Setup (pdev, req); 00643 USBD_CtlSendStatus(pdev); 00644 } 00645 00646 } 00647 00648 00649 /** 00650 * @brief USBD_ClrFeature 00651 * Handle clear device feature request 00652 * @param pdev: device instance 00653 * @param req: usb request 00654 * @retval status 00655 */ 00656 static void USBD_ClrFeature(USBD_HandleTypeDef *pdev , 00657 USBD_SetupReqTypedef *req) 00658 { 00659 switch (pdev->dev_state) 00660 { 00661 case USBD_STATE_ADDRESSED: 00662 case USBD_STATE_CONFIGURED: 00663 if (req->wValue == USB_FEATURE_REMOTE_WAKEUP) 00664 { 00665 pdev->dev_remote_wakeup = 0; 00666 pdev->pClass->Setup (pdev, req); 00667 USBD_CtlSendStatus(pdev); 00668 } 00669 break; 00670 00671 default : 00672 USBD_CtlError(pdev , req); 00673 break; 00674 } 00675 } 00676 00677 /** 00678 * @brief USBD_ParseSetupRequest 00679 * Copy buffer into setup structure 00680 * @param pdev: device instance 00681 * @param req: usb request 00682 * @retval None 00683 */ 00684 00685 void USBD_ParseSetupRequest(USBD_SetupReqTypedef *req, uint8_t *pdata) 00686 { 00687 req->bmRequest = *(uint8_t *) (pdata); 00688 req->bRequest = *(uint8_t *) (pdata + 1); 00689 req->wValue = SWAPBYTE (pdata + 2); 00690 req->wIndex = SWAPBYTE (pdata + 4); 00691 req->wLength = SWAPBYTE (pdata + 6); 00692 00693 } 00694 00695 /** 00696 * @brief USBD_CtlError 00697 * Handle USB low level Error 00698 * @param pdev: device instance 00699 * @param req: usb request 00700 * @retval None 00701 */ 00702 00703 void USBD_CtlError( USBD_HandleTypeDef *pdev , 00704 USBD_SetupReqTypedef *req) 00705 { 00706 USBD_LL_StallEP(pdev , 0x80); 00707 USBD_LL_StallEP(pdev , 0); 00708 } 00709 00710 00711 /** 00712 * @brief USBD_GetString 00713 * Convert Ascii string into unicode one 00714 * @param desc : descriptor buffer 00715 * @param unicode : Formatted string buffer (unicode) 00716 * @param len : descriptor length 00717 * @retval None 00718 */ 00719 void USBD_GetString(uint8_t *desc, uint8_t *unicode, uint16_t *len) 00720 { 00721 uint8_t idx = 0; 00722 00723 if (desc != NULL) 00724 { 00725 *len = USBD_GetLen(desc) * 2 + 2; 00726 unicode[idx++] = *len; 00727 unicode[idx++] = USB_DESC_TYPE_STRING; 00728 00729 while (*desc != '\0') 00730 { 00731 unicode[idx++] = *desc++; 00732 unicode[idx++] = 0x00; 00733 } 00734 } 00735 } 00736 00737 /** 00738 * @brief USBD_GetLen 00739 * return the string length 00740 * @param buf : pointer to the ascii string buffer 00741 * @retval string length 00742 */ 00743 static uint8_t USBD_GetLen(uint8_t *buf) 00744 { 00745 uint8_t len = 0; 00746 00747 while (*buf != '\0') 00748 { 00749 len++; 00750 buf++; 00751 } 00752 00753 return len; 00754 } 00755 /** 00756 * @} 00757 */ 00758 00759 00760 /** 00761 * @} 00762 */ 00763 00764 00765 /** 00766 * @} 00767 */ 00768 00769 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
Generated on Tue Jul 12 2022 20:52:33 by
1.7.2