Kleber Silva / IOTON-API

Dependents:   ton_demo ton_template

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers usbd_ctlreq.c Source File

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>&copy; 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****/