USB CDC library for MBED on STM32
Embed:
(wiki syntax)
Show/hide line numbers
usbd_ctlreq.c
00001 /** 00002 ****************************************************************************** 00003 * @file usbd_req.c 00004 * @author MCD Application Team 00005 * @version V2.4.2 00006 * @date 11-December-2015 00007 * @brief This file provides the standard USB requests following chapter 9. 00008 ****************************************************************************** 00009 * @attention 00010 * 00011 * <h2><center>© COPYRIGHT 2015 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 /* Check if it is a class request */ 00216 if ((req->bmRequest & 0x60) == 0x20) 00217 { 00218 pdev->pClass->Setup (pdev, req); 00219 00220 return USBD_OK; 00221 } 00222 00223 switch (req->bRequest) 00224 { 00225 00226 case USB_REQ_SET_FEATURE : 00227 00228 switch (pdev->dev_state) 00229 { 00230 case USBD_STATE_ADDRESSED: 00231 if ((ep_addr != 0x00) && (ep_addr != 0x80)) 00232 { 00233 USBD_LL_StallEP(pdev , ep_addr); 00234 } 00235 break; 00236 00237 case USBD_STATE_CONFIGURED: 00238 if (req->wValue == USB_FEATURE_EP_HALT) 00239 { 00240 if ((ep_addr != 0x00) && (ep_addr != 0x80)) 00241 { 00242 USBD_LL_StallEP(pdev , ep_addr); 00243 00244 } 00245 } 00246 pdev->pClass->Setup (pdev, req); 00247 USBD_CtlSendStatus(pdev); 00248 00249 break; 00250 00251 default: 00252 USBD_CtlError(pdev , req); 00253 break; 00254 } 00255 break; 00256 00257 case USB_REQ_CLEAR_FEATURE : 00258 00259 switch (pdev->dev_state) 00260 { 00261 case USBD_STATE_ADDRESSED: 00262 if ((ep_addr != 0x00) && (ep_addr != 0x80)) 00263 { 00264 USBD_LL_StallEP(pdev , ep_addr); 00265 } 00266 break; 00267 00268 case USBD_STATE_CONFIGURED: 00269 if (req->wValue == USB_FEATURE_EP_HALT) 00270 { 00271 if ((ep_addr & 0x7F) != 0x00) 00272 { 00273 USBD_LL_ClearStallEP(pdev , ep_addr); 00274 pdev->pClass->Setup (pdev, req); 00275 } 00276 USBD_CtlSendStatus(pdev); 00277 } 00278 break; 00279 00280 default: 00281 USBD_CtlError(pdev , req); 00282 break; 00283 } 00284 break; 00285 00286 case USB_REQ_GET_STATUS: 00287 switch (pdev->dev_state) 00288 { 00289 case USBD_STATE_ADDRESSED: 00290 if ((ep_addr & 0x7F) != 0x00) 00291 { 00292 USBD_LL_StallEP(pdev , ep_addr); 00293 } 00294 break; 00295 00296 case USBD_STATE_CONFIGURED: 00297 pep = ((ep_addr & 0x80) == 0x80) ? &pdev->ep_in[ep_addr & 0x7F]:\ 00298 &pdev->ep_out[ep_addr & 0x7F]; 00299 if(USBD_LL_IsStallEP(pdev, ep_addr)) 00300 { 00301 pep->status = 0x0001; 00302 } 00303 else 00304 { 00305 pep->status = 0x0000; 00306 } 00307 00308 USBD_CtlSendData (pdev, 00309 (uint8_t *)&pep->status, 00310 2); 00311 break; 00312 00313 default: 00314 USBD_CtlError(pdev , req); 00315 break; 00316 } 00317 break; 00318 00319 default: 00320 break; 00321 } 00322 return ret; 00323 } 00324 /** 00325 * @brief USBD_GetDescriptor 00326 * Handle Get Descriptor requests 00327 * @param pdev: device instance 00328 * @param req: usb request 00329 * @retval status 00330 */ 00331 static void USBD_GetDescriptor(USBD_HandleTypeDef *pdev , 00332 USBD_SetupReqTypedef *req) 00333 { 00334 uint16_t len; 00335 uint8_t *pbuf; 00336 00337 00338 switch (req->wValue >> 8) 00339 { 00340 #if (USBD_LPM_ENABLED == 1) 00341 case USB_DESC_TYPE_BOS: 00342 pbuf = pdev->pDesc->GetBOSDescriptor(pdev->dev_speed, &len); 00343 break; 00344 #endif 00345 case USB_DESC_TYPE_DEVICE: 00346 pbuf = pdev->pDesc->GetDeviceDescriptor(pdev->dev_speed, &len); 00347 break; 00348 00349 case USB_DESC_TYPE_CONFIGURATION: 00350 if(pdev->dev_speed == USBD_SPEED_HIGH ) 00351 { 00352 pbuf = (uint8_t *)pdev->pClass->GetHSConfigDescriptor(&len); 00353 pbuf[1] = USB_DESC_TYPE_CONFIGURATION; 00354 } 00355 else 00356 { 00357 pbuf = (uint8_t *)pdev->pClass->GetFSConfigDescriptor(&len); 00358 pbuf[1] = USB_DESC_TYPE_CONFIGURATION; 00359 } 00360 break; 00361 00362 case USB_DESC_TYPE_STRING: 00363 switch ((uint8_t)(req->wValue)) 00364 { 00365 case USBD_IDX_LANGID_STR: 00366 pbuf = pdev->pDesc->GetLangIDStrDescriptor(pdev->dev_speed, &len); 00367 break; 00368 00369 case USBD_IDX_MFC_STR: 00370 pbuf = pdev->pDesc->GetManufacturerStrDescriptor(pdev->dev_speed, &len); 00371 break; 00372 00373 case USBD_IDX_PRODUCT_STR: 00374 pbuf = pdev->pDesc->GetProductStrDescriptor(pdev->dev_speed, &len); 00375 break; 00376 00377 case USBD_IDX_SERIAL_STR: 00378 pbuf = pdev->pDesc->GetSerialStrDescriptor(pdev->dev_speed, &len); 00379 break; 00380 00381 case USBD_IDX_CONFIG_STR: 00382 pbuf = pdev->pDesc->GetConfigurationStrDescriptor(pdev->dev_speed, &len); 00383 break; 00384 00385 case USBD_IDX_INTERFACE_STR: 00386 pbuf = pdev->pDesc->GetInterfaceStrDescriptor(pdev->dev_speed, &len); 00387 break; 00388 00389 default: 00390 #if (USBD_SUPPORT_USER_STRING == 1) 00391 pbuf = pdev->pClass->GetUsrStrDescriptor(pdev, (req->wValue) , &len); 00392 break; 00393 #else 00394 USBD_CtlError(pdev , req); 00395 return; 00396 #endif 00397 } 00398 break; 00399 case USB_DESC_TYPE_DEVICE_QUALIFIER: 00400 00401 if(pdev->dev_speed == USBD_SPEED_HIGH ) 00402 { 00403 pbuf = (uint8_t *)pdev->pClass->GetDeviceQualifierDescriptor(&len); 00404 break; 00405 } 00406 else 00407 { 00408 USBD_CtlError(pdev , req); 00409 return; 00410 } 00411 00412 case USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION: 00413 if(pdev->dev_speed == USBD_SPEED_HIGH ) 00414 { 00415 pbuf = (uint8_t *)pdev->pClass->GetOtherSpeedConfigDescriptor(&len); 00416 pbuf[1] = USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION; 00417 break; 00418 } 00419 else 00420 { 00421 USBD_CtlError(pdev , req); 00422 return; 00423 } 00424 00425 default: 00426 USBD_CtlError(pdev , req); 00427 return; 00428 } 00429 00430 if((len != 0)&& (req->wLength != 0)) 00431 { 00432 00433 len = MIN(len , req->wLength); 00434 00435 USBD_CtlSendData (pdev, 00436 pbuf, 00437 len); 00438 } 00439 00440 } 00441 00442 /** 00443 * @brief USBD_SetAddress 00444 * Set device address 00445 * @param pdev: device instance 00446 * @param req: usb request 00447 * @retval status 00448 */ 00449 static void USBD_SetAddress(USBD_HandleTypeDef *pdev , 00450 USBD_SetupReqTypedef *req) 00451 { 00452 uint8_t dev_addr; 00453 00454 if ((req->wIndex == 0) && (req->wLength == 0)) 00455 { 00456 dev_addr = (uint8_t)(req->wValue) & 0x7F; 00457 00458 if (pdev->dev_state == USBD_STATE_CONFIGURED) 00459 { 00460 USBD_CtlError(pdev , req); 00461 } 00462 else 00463 { 00464 pdev->dev_address = dev_addr; 00465 USBD_LL_SetUSBAddress(pdev, dev_addr); 00466 USBD_CtlSendStatus(pdev); 00467 00468 if (dev_addr != 0) 00469 { 00470 pdev->dev_state = USBD_STATE_ADDRESSED; 00471 } 00472 else 00473 { 00474 pdev->dev_state = USBD_STATE_DEFAULT; 00475 } 00476 } 00477 } 00478 else 00479 { 00480 USBD_CtlError(pdev , req); 00481 } 00482 } 00483 00484 /** 00485 * @brief USBD_SetConfig 00486 * Handle Set device configuration request 00487 * @param pdev: device instance 00488 * @param req: usb request 00489 * @retval status 00490 */ 00491 static void USBD_SetConfig(USBD_HandleTypeDef *pdev , 00492 USBD_SetupReqTypedef *req) 00493 { 00494 00495 static uint8_t cfgidx; 00496 00497 cfgidx = (uint8_t)(req->wValue); 00498 00499 if (cfgidx > USBD_MAX_NUM_CONFIGURATION ) 00500 { 00501 USBD_CtlError(pdev , req); 00502 } 00503 else 00504 { 00505 switch (pdev->dev_state) 00506 { 00507 case USBD_STATE_ADDRESSED: 00508 if (cfgidx) 00509 { 00510 pdev->dev_config = cfgidx; 00511 pdev->dev_state = USBD_STATE_CONFIGURED; 00512 if(USBD_SetClassConfig(pdev , cfgidx) == USBD_FAIL) 00513 { 00514 USBD_CtlError(pdev , req); 00515 return; 00516 } 00517 USBD_CtlSendStatus(pdev); 00518 } 00519 else 00520 { 00521 USBD_CtlSendStatus(pdev); 00522 } 00523 break; 00524 00525 case USBD_STATE_CONFIGURED: 00526 if (cfgidx == 0) 00527 { 00528 pdev->dev_state = USBD_STATE_ADDRESSED; 00529 pdev->dev_config = cfgidx; 00530 USBD_ClrClassConfig(pdev , cfgidx); 00531 USBD_CtlSendStatus(pdev); 00532 00533 } 00534 else if (cfgidx != pdev->dev_config) 00535 { 00536 /* Clear old configuration */ 00537 USBD_ClrClassConfig(pdev , pdev->dev_config); 00538 00539 /* set new configuration */ 00540 pdev->dev_config = cfgidx; 00541 if(USBD_SetClassConfig(pdev , cfgidx) == USBD_FAIL) 00542 { 00543 USBD_CtlError(pdev , req); 00544 return; 00545 } 00546 USBD_CtlSendStatus(pdev); 00547 } 00548 else 00549 { 00550 USBD_CtlSendStatus(pdev); 00551 } 00552 break; 00553 00554 default: 00555 USBD_CtlError(pdev , req); 00556 break; 00557 } 00558 } 00559 } 00560 00561 /** 00562 * @brief USBD_GetConfig 00563 * Handle Get device configuration request 00564 * @param pdev: device instance 00565 * @param req: usb request 00566 * @retval status 00567 */ 00568 static void USBD_GetConfig(USBD_HandleTypeDef *pdev , 00569 USBD_SetupReqTypedef *req) 00570 { 00571 00572 if (req->wLength != 1) 00573 { 00574 USBD_CtlError(pdev , req); 00575 } 00576 else 00577 { 00578 switch (pdev->dev_state ) 00579 { 00580 case USBD_STATE_ADDRESSED: 00581 pdev->dev_default_config = 0; 00582 USBD_CtlSendData (pdev, 00583 (uint8_t *)&pdev->dev_default_config, 00584 1); 00585 break; 00586 00587 case USBD_STATE_CONFIGURED: 00588 00589 USBD_CtlSendData (pdev, 00590 (uint8_t *)&pdev->dev_config, 00591 1); 00592 break; 00593 00594 default: 00595 USBD_CtlError(pdev , req); 00596 break; 00597 } 00598 } 00599 } 00600 00601 /** 00602 * @brief USBD_GetStatus 00603 * Handle Get Status request 00604 * @param pdev: device instance 00605 * @param req: usb request 00606 * @retval status 00607 */ 00608 static void USBD_GetStatus(USBD_HandleTypeDef *pdev , 00609 USBD_SetupReqTypedef *req) 00610 { 00611 00612 00613 switch (pdev->dev_state) 00614 { 00615 case USBD_STATE_ADDRESSED: 00616 case USBD_STATE_CONFIGURED: 00617 00618 #if ( USBD_SELF_POWERED == 1) 00619 pdev->dev_config_status = USB_CONFIG_SELF_POWERED; 00620 #else 00621 pdev->dev_config_status = 0; 00622 #endif 00623 00624 if (pdev->dev_remote_wakeup) 00625 { 00626 pdev->dev_config_status |= USB_CONFIG_REMOTE_WAKEUP; 00627 } 00628 00629 USBD_CtlSendData (pdev, 00630 (uint8_t *)& pdev->dev_config_status, 00631 2); 00632 break; 00633 00634 default : 00635 USBD_CtlError(pdev , req); 00636 break; 00637 } 00638 } 00639 00640 00641 /** 00642 * @brief USBD_SetFeature 00643 * Handle Set device feature request 00644 * @param pdev: device instance 00645 * @param req: usb request 00646 * @retval status 00647 */ 00648 static void USBD_SetFeature(USBD_HandleTypeDef *pdev , 00649 USBD_SetupReqTypedef *req) 00650 { 00651 00652 if (req->wValue == USB_FEATURE_REMOTE_WAKEUP) 00653 { 00654 pdev->dev_remote_wakeup = 1; 00655 pdev->pClass->Setup (pdev, req); 00656 USBD_CtlSendStatus(pdev); 00657 } 00658 00659 } 00660 00661 00662 /** 00663 * @brief USBD_ClrFeature 00664 * Handle clear device feature request 00665 * @param pdev: device instance 00666 * @param req: usb request 00667 * @retval status 00668 */ 00669 static void USBD_ClrFeature(USBD_HandleTypeDef *pdev , 00670 USBD_SetupReqTypedef *req) 00671 { 00672 switch (pdev->dev_state) 00673 { 00674 case USBD_STATE_ADDRESSED: 00675 case USBD_STATE_CONFIGURED: 00676 if (req->wValue == USB_FEATURE_REMOTE_WAKEUP) 00677 { 00678 pdev->dev_remote_wakeup = 0; 00679 pdev->pClass->Setup (pdev, req); 00680 USBD_CtlSendStatus(pdev); 00681 } 00682 break; 00683 00684 default : 00685 USBD_CtlError(pdev , req); 00686 break; 00687 } 00688 } 00689 00690 /** 00691 * @brief USBD_ParseSetupRequest 00692 * Copy buffer into setup structure 00693 * @param pdev: device instance 00694 * @param req: usb request 00695 * @retval None 00696 */ 00697 00698 void USBD_ParseSetupRequest(USBD_SetupReqTypedef *req, uint8_t *pdata) 00699 { 00700 req->bmRequest = *(uint8_t *) (pdata); 00701 req->bRequest = *(uint8_t *) (pdata + 1); 00702 req->wValue = SWAPBYTE (pdata + 2); 00703 req->wIndex = SWAPBYTE (pdata + 4); 00704 req->wLength = SWAPBYTE (pdata + 6); 00705 00706 } 00707 00708 /** 00709 * @brief USBD_CtlError 00710 * Handle USB low level Error 00711 * @param pdev: device instance 00712 * @param req: usb request 00713 * @retval None 00714 */ 00715 00716 void USBD_CtlError( USBD_HandleTypeDef *pdev , 00717 USBD_SetupReqTypedef *req) 00718 { 00719 USBD_LL_StallEP(pdev , 0x80); 00720 USBD_LL_StallEP(pdev , 0); 00721 } 00722 00723 00724 /** 00725 * @brief USBD_GetString 00726 * Convert Ascii string into unicode one 00727 * @param desc : descriptor buffer 00728 * @param unicode : Formatted string buffer (unicode) 00729 * @param len : descriptor length 00730 * @retval None 00731 */ 00732 void USBD_GetString(uint8_t *desc, uint8_t *unicode, uint16_t *len) 00733 { 00734 uint8_t idx = 0; 00735 00736 if (desc != NULL) 00737 { 00738 *len = USBD_GetLen(desc) * 2 + 2; 00739 unicode[idx++] = *len; 00740 unicode[idx++] = USB_DESC_TYPE_STRING; 00741 00742 while (*desc != '\0') 00743 { 00744 unicode[idx++] = *desc++; 00745 unicode[idx++] = 0x00; 00746 } 00747 } 00748 } 00749 00750 /** 00751 * @brief USBD_GetLen 00752 * return the string length 00753 * @param buf : pointer to the ascii string buffer 00754 * @retval string length 00755 */ 00756 static uint8_t USBD_GetLen(uint8_t *buf) 00757 { 00758 uint8_t len = 0; 00759 00760 while (*buf != '\0') 00761 { 00762 len++; 00763 buf++; 00764 } 00765 00766 return len; 00767 } 00768 /** 00769 * @} 00770 */ 00771 00772 00773 /** 00774 * @} 00775 */ 00776 00777 00778 /** 00779 * @} 00780 */ 00781 00782 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ 00783
Generated on Thu Jul 14 2022 15:47:45 by 1.7.2