USB CDC library for MBED on STM32

Dependents:   PushToGo-F429

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers usbd_core.c Source File

usbd_core.c

Go to the documentation of this file.
00001 /**
00002   ******************************************************************************
00003   * @file    usbd_core.c
00004   * @author  MCD Application Team
00005   * @version V2.4.2
00006   * @date    11-December-2015
00007   * @brief   This file provides all the USBD core functions.
00008   ******************************************************************************
00009   * @attention
00010   *
00011   * <h2><center>&copy; 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_core.h"
00030 
00031 /** @addtogroup STM32_USBD_DEVICE_LIBRARY
00032 * @{
00033 */
00034 
00035 
00036 /** @defgroup USBD_CORE 
00037 * @brief usbd core module
00038 * @{
00039 */ 
00040 
00041 /** @defgroup USBD_CORE_Private_TypesDefinitions
00042 * @{
00043 */ 
00044 /**
00045 * @}
00046 */ 
00047 
00048 
00049 /** @defgroup USBD_CORE_Private_Defines
00050 * @{
00051 */ 
00052 
00053 /**
00054 * @}
00055 */ 
00056 
00057 
00058 /** @defgroup USBD_CORE_Private_Macros
00059 * @{
00060 */ 
00061 /**
00062 * @}
00063 */ 
00064 
00065 
00066 
00067 
00068 /** @defgroup USBD_CORE_Private_FunctionPrototypes
00069 * @{
00070 */ 
00071 
00072 /**
00073 * @}
00074 */ 
00075 
00076 /** @defgroup USBD_CORE_Private_Variables
00077 * @{
00078 */ 
00079 
00080 /**
00081 * @}
00082 */ 
00083 
00084 /** @defgroup USBD_CORE_Private_Functions
00085 * @{
00086 */ 
00087 
00088 /**
00089 * @brief  USBD_Init
00090 *         Initializes the device stack and load the class driver
00091 * @param  pdev: device instance
00092 * @param  pdesc: Descriptor structure address
00093 * @param  id: Low level core index
00094 * @retval None
00095 */
00096 USBD_StatusTypeDef USBD_Init(USBD_HandleTypeDef *pdev, USBD_DescriptorsTypeDef *pdesc, uint8_t id)
00097 {
00098   /* Check whether the USB Host handle is valid */
00099   if(pdev == NULL)
00100   {
00101     USBD_ErrLog("Invalid Device handle");
00102     return USBD_FAIL; 
00103   }
00104   
00105   /* Unlink previous class*/
00106   if(pdev->pClass != NULL)
00107   {
00108     pdev->pClass = NULL;
00109   }
00110   
00111   /* Assign USBD Descriptors */
00112   if(pdesc != NULL)
00113   {
00114     pdev->pDesc = pdesc;
00115   }
00116   
00117   /* Set Device initial State */
00118   pdev->dev_state  = USBD_STATE_DEFAULT;
00119   pdev->id = id;
00120   /* Initialize low level driver */
00121   USBD_LL_Init(pdev);
00122   
00123   return USBD_OK; 
00124 }
00125 
00126 /**
00127 * @brief  USBD_DeInit 
00128 *         Re-Initialize th device library
00129 * @param  pdev: device instance
00130 * @retval status: status
00131 */
00132 USBD_StatusTypeDef USBD_DeInit(USBD_HandleTypeDef *pdev)
00133 {
00134   /* Set Default State */
00135   pdev->dev_state  = USBD_STATE_DEFAULT;
00136   
00137   /* Free Class Resources */
00138   pdev->pClass->DeInit(pdev, pdev->dev_config);  
00139   
00140     /* Stop the low level driver  */
00141   USBD_LL_Stop(pdev); 
00142   
00143   /* Initialize low level driver */
00144   USBD_LL_DeInit(pdev);
00145   
00146   return USBD_OK;
00147 }
00148 
00149 
00150 /**
00151   * @brief  USBD_RegisterClass 
00152   *         Link class driver to Device Core.
00153   * @param  pDevice : Device Handle
00154   * @param  pclass: Class handle
00155   * @retval USBD Status
00156   */
00157 USBD_StatusTypeDef  USBD_RegisterClass(USBD_HandleTypeDef *pdev, USBD_ClassTypeDef *pclass)
00158 {
00159   USBD_StatusTypeDef   status = USBD_OK;
00160   if(pclass != 0)
00161   {
00162     /* link the class to the USB Device handle */
00163     pdev->pClass = pclass;
00164     status = USBD_OK;
00165   }
00166   else
00167   {
00168     USBD_ErrLog("Invalid Class handle");
00169     status = USBD_FAIL; 
00170   }
00171   
00172   return status;
00173 }
00174 
00175 /**
00176   * @brief  USBD_Start 
00177   *         Start the USB Device Core.
00178   * @param  pdev: Device Handle
00179   * @retval USBD Status
00180   */
00181 USBD_StatusTypeDef  USBD_Start  (USBD_HandleTypeDef *pdev)
00182 {
00183   
00184   /* Start the low level driver  */
00185   USBD_LL_Start(pdev); 
00186   
00187   return USBD_OK;  
00188 }
00189 
00190 /**
00191   * @brief  USBD_Stop 
00192   *         Stop the USB Device Core.
00193   * @param  pdev: Device Handle
00194   * @retval USBD Status
00195   */
00196 USBD_StatusTypeDef  USBD_Stop   (USBD_HandleTypeDef *pdev)
00197 {
00198   /* Free Class Resources */
00199   pdev->pClass->DeInit(pdev, pdev->dev_config);  
00200 
00201   /* Stop the low level driver  */
00202   USBD_LL_Stop(pdev); 
00203   
00204   return USBD_OK;  
00205 }
00206 
00207 /**
00208 * @brief  USBD_RunTestMode 
00209 *         Launch test mode process
00210 * @param  pdev: device instance
00211 * @retval status
00212 */
00213 USBD_StatusTypeDef  USBD_RunTestMode (USBD_HandleTypeDef  *pdev) 
00214 {
00215   return USBD_OK;
00216 }
00217 
00218 
00219 /**
00220 * @brief  USBD_SetClassConfig 
00221 *        Configure device and start the interface
00222 * @param  pdev: device instance
00223 * @param  cfgidx: configuration index
00224 * @retval status
00225 */
00226 
00227 USBD_StatusTypeDef USBD_SetClassConfig(USBD_HandleTypeDef  *pdev, uint8_t cfgidx)
00228 {
00229   USBD_StatusTypeDef   ret = USBD_FAIL;
00230   
00231   if(pdev->pClass != NULL)
00232   {
00233     /* Set configuration  and Start the Class*/
00234     if(pdev->pClass->Init(pdev, cfgidx) == 0)
00235     {
00236       ret = USBD_OK;
00237     }
00238   }
00239   return ret; 
00240 }
00241 
00242 /**
00243 * @brief  USBD_ClrClassConfig 
00244 *         Clear current configuration
00245 * @param  pdev: device instance
00246 * @param  cfgidx: configuration index
00247 * @retval status: USBD_StatusTypeDef
00248 */
00249 USBD_StatusTypeDef USBD_ClrClassConfig(USBD_HandleTypeDef  *pdev, uint8_t cfgidx)
00250 {
00251   /* Clear configuration  and De-initialize the Class process*/
00252   pdev->pClass->DeInit(pdev, cfgidx);  
00253   return USBD_OK;
00254 }
00255 
00256 
00257 /**
00258 * @brief  USBD_SetupStage 
00259 *         Handle the setup stage
00260 * @param  pdev: device instance
00261 * @retval status
00262 */
00263 USBD_StatusTypeDef USBD_LL_SetupStage(USBD_HandleTypeDef *pdev, uint8_t *psetup)
00264 {
00265 
00266   USBD_ParseSetupRequest(&pdev->request, psetup);
00267   
00268   pdev->ep0_state = USBD_EP0_SETUP;
00269   pdev->ep0_data_len = pdev->request.wLength;
00270   
00271   switch (pdev->request.bmRequest & 0x1F) 
00272   {
00273   case USB_REQ_RECIPIENT_DEVICE:   
00274     USBD_StdDevReq (pdev, &pdev->request);
00275     break;
00276     
00277   case USB_REQ_RECIPIENT_INTERFACE:     
00278     USBD_StdItfReq(pdev, &pdev->request);
00279     break;
00280     
00281   case USB_REQ_RECIPIENT_ENDPOINT:        
00282     USBD_StdEPReq(pdev, &pdev->request);   
00283     break;
00284     
00285   default:           
00286     USBD_LL_StallEP(pdev , pdev->request.bmRequest & 0x80);
00287     break;
00288   }  
00289   return USBD_OK;  
00290 }
00291 
00292 /**
00293 * @brief  USBD_DataOutStage 
00294 *         Handle data OUT stage
00295 * @param  pdev: device instance
00296 * @param  epnum: endpoint index
00297 * @retval status
00298 */
00299 USBD_StatusTypeDef USBD_LL_DataOutStage(USBD_HandleTypeDef *pdev , uint8_t epnum, uint8_t *pdata)
00300 {
00301   USBD_EndpointTypeDef    *pep;
00302   
00303   if(epnum == 0) 
00304   {
00305     pep = &pdev->ep_out[0];
00306     
00307     if ( pdev->ep0_state == USBD_EP0_DATA_OUT)
00308     {
00309       if(pep->rem_length > pep->maxpacket)
00310       {
00311         pep->rem_length -=  pep->maxpacket;
00312        
00313         USBD_CtlContinueRx (pdev, 
00314                             pdata,
00315                             MIN(pep->rem_length ,pep->maxpacket));
00316       }
00317       else
00318       {
00319         if((pdev->pClass->EP0_RxReady != NULL)&&
00320            (pdev->dev_state == USBD_STATE_CONFIGURED))
00321         {
00322           pdev->pClass->EP0_RxReady(pdev); 
00323         }
00324         USBD_CtlSendStatus(pdev);
00325       }
00326     }
00327   }
00328   else if((pdev->pClass->DataOut != NULL)&&
00329           (pdev->dev_state == USBD_STATE_CONFIGURED))
00330   {
00331     pdev->pClass->DataOut(pdev, epnum); 
00332   }  
00333   return USBD_OK;
00334 }
00335 
00336 /**
00337 * @brief  USBD_DataInStage 
00338 *         Handle data in stage
00339 * @param  pdev: device instance
00340 * @param  epnum: endpoint index
00341 * @retval status
00342 */
00343 USBD_StatusTypeDef USBD_LL_DataInStage(USBD_HandleTypeDef *pdev ,uint8_t epnum, uint8_t *pdata)
00344 {
00345   USBD_EndpointTypeDef    *pep;
00346     
00347   if(epnum == 0) 
00348   {
00349     pep = &pdev->ep_in[0];
00350     
00351     if ( pdev->ep0_state == USBD_EP0_DATA_IN)
00352     {
00353       if(pep->rem_length > pep->maxpacket)
00354       {
00355         pep->rem_length -=  pep->maxpacket;
00356         
00357         USBD_CtlContinueSendData (pdev, 
00358                                   pdata, 
00359                                   pep->rem_length);
00360         
00361         /* Prepare endpoint for premature end of transfer */
00362         USBD_LL_PrepareReceive (pdev,
00363                                 0,
00364                                 NULL,
00365                                 0);  
00366       }
00367       else
00368       { /* last packet is MPS multiple, so send ZLP packet */
00369         if((pep->total_length % pep->maxpacket == 0) &&
00370            (pep->total_length >= pep->maxpacket) &&
00371              (pep->total_length < pdev->ep0_data_len ))
00372         {
00373           
00374           USBD_CtlContinueSendData(pdev , NULL, 0);
00375           pdev->ep0_data_len = 0;
00376           
00377         /* Prepare endpoint for premature end of transfer */
00378         USBD_LL_PrepareReceive (pdev,
00379                                 0,
00380                                 NULL,
00381                                 0);
00382         }
00383         else
00384         {
00385           if((pdev->pClass->EP0_TxSent != NULL)&&
00386              (pdev->dev_state == USBD_STATE_CONFIGURED))
00387           {
00388             pdev->pClass->EP0_TxSent(pdev); 
00389           }          
00390           USBD_CtlReceiveStatus(pdev);
00391         }
00392       }
00393     }
00394     if (pdev->dev_test_mode == 1)
00395     {
00396       USBD_RunTestMode(pdev); 
00397       pdev->dev_test_mode = 0;
00398     }
00399   }
00400   else if((pdev->pClass->DataIn != NULL)&& 
00401           (pdev->dev_state == USBD_STATE_CONFIGURED))
00402   {
00403     pdev->pClass->DataIn(pdev, epnum); 
00404   }  
00405   return USBD_OK;
00406 }
00407 
00408 /**
00409 * @brief  USBD_LL_Reset 
00410 *         Handle Reset event
00411 * @param  pdev: device instance
00412 * @retval status
00413 */
00414 
00415 USBD_StatusTypeDef USBD_LL_Reset(USBD_HandleTypeDef  *pdev)
00416 {
00417   /* Open EP0 OUT */
00418   USBD_LL_OpenEP(pdev,
00419               0x00,
00420               USBD_EP_TYPE_CTRL,
00421               USB_MAX_EP0_SIZE);
00422   
00423   pdev->ep_out[0].maxpacket = USB_MAX_EP0_SIZE;
00424   
00425   /* Open EP0 IN */
00426   USBD_LL_OpenEP(pdev,
00427               0x80,
00428               USBD_EP_TYPE_CTRL,
00429               USB_MAX_EP0_SIZE);
00430   
00431   pdev->ep_in[0].maxpacket = USB_MAX_EP0_SIZE;
00432   /* Upon Reset call user call back */
00433   pdev->dev_state = USBD_STATE_DEFAULT;
00434   
00435   if (pdev->pClassData) 
00436     pdev->pClass->DeInit(pdev, pdev->dev_config);  
00437  
00438   
00439   return USBD_OK;
00440 }
00441 
00442 
00443 
00444 
00445 /**
00446 * @brief  USBD_LL_Reset 
00447 *         Handle Reset event
00448 * @param  pdev: device instance
00449 * @retval status
00450 */
00451 USBD_StatusTypeDef USBD_LL_SetSpeed(USBD_HandleTypeDef  *pdev, USBD_SpeedTypeDef speed)
00452 {
00453   pdev->dev_speed = speed;
00454   return USBD_OK;
00455 }
00456 
00457 /**
00458 * @brief  USBD_Suspend 
00459 *         Handle Suspend event
00460 * @param  pdev: device instance
00461 * @retval status
00462 */
00463 
00464 USBD_StatusTypeDef USBD_LL_Suspend(USBD_HandleTypeDef  *pdev)
00465 {
00466   pdev->dev_old_state =  pdev->dev_state;
00467   pdev->dev_state  = USBD_STATE_SUSPENDED;
00468   return USBD_OK;
00469 }
00470 
00471 /**
00472 * @brief  USBD_Resume 
00473 *         Handle Resume event
00474 * @param  pdev: device instance
00475 * @retval status
00476 */
00477 
00478 USBD_StatusTypeDef USBD_LL_Resume(USBD_HandleTypeDef  *pdev)
00479 {
00480   pdev->dev_state = pdev->dev_old_state;  
00481   return USBD_OK;
00482 }
00483 
00484 /**
00485 * @brief  USBD_SOF 
00486 *         Handle SOF event
00487 * @param  pdev: device instance
00488 * @retval status
00489 */
00490 
00491 USBD_StatusTypeDef USBD_LL_SOF(USBD_HandleTypeDef  *pdev)
00492 {
00493   if(pdev->dev_state == USBD_STATE_CONFIGURED)
00494   {
00495     if(pdev->pClass->SOF != NULL)
00496     {
00497       pdev->pClass->SOF(pdev);
00498     }
00499   }
00500   return USBD_OK;
00501 }
00502 
00503 /**
00504 * @brief  USBD_IsoINIncomplete 
00505 *         Handle iso in incomplete event
00506 * @param  pdev: device instance
00507 * @retval status
00508 */
00509 USBD_StatusTypeDef USBD_LL_IsoINIncomplete(USBD_HandleTypeDef  *pdev, uint8_t epnum)
00510 {
00511   return USBD_OK;
00512 }
00513 
00514 /**
00515 * @brief  USBD_IsoOUTIncomplete 
00516 *         Handle iso out incomplete event
00517 * @param  pdev: device instance
00518 * @retval status
00519 */
00520 USBD_StatusTypeDef USBD_LL_IsoOUTIncomplete(USBD_HandleTypeDef  *pdev, uint8_t epnum)
00521 {
00522   return USBD_OK;
00523 }
00524 
00525 /**
00526 * @brief  USBD_DevConnected 
00527 *         Handle device connection event
00528 * @param  pdev: device instance
00529 * @retval status
00530 */
00531 USBD_StatusTypeDef USBD_LL_DevConnected(USBD_HandleTypeDef  *pdev)
00532 {
00533   return USBD_OK;
00534 }
00535 
00536 /**
00537 * @brief  USBD_DevDisconnected 
00538 *         Handle device disconnection event
00539 * @param  pdev: device instance
00540 * @retval status
00541 */
00542 USBD_StatusTypeDef USBD_LL_DevDisconnected(USBD_HandleTypeDef  *pdev)
00543 {
00544   /* Free Class Resources */
00545   pdev->dev_state = USBD_STATE_DEFAULT;
00546   pdev->pClass->DeInit(pdev, pdev->dev_config);  
00547    
00548   return USBD_OK;
00549 }
00550 /**
00551 * @}
00552 */ 
00553 
00554 
00555 /**
00556 * @}
00557 */ 
00558 
00559 
00560 /**
00561 * @}
00562 */ 
00563 
00564 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
00565 
00566