Damian Gabino / picoGW_mcu
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers usbd_cdc.cpp Source File

usbd_cdc.cpp

00001 /**
00002   ******************************************************************************
00003   * @file    usbd_cdc.c
00004   * @author  MCD Application Team
00005   * @version V2.4.2
00006   * @date    11-December-2015
00007   * @brief   This file provides the high layer firmware functions to manage the 
00008   *          following functionalities of the USB CDC Class:
00009   *           - Initialization and Configuration of high and low layer
00010   *           - Enumeration as CDC Device (and enumeration for each implemented memory interface)
00011   *           - OUT/IN data transfer
00012   *           - Command IN transfer (class requests management)
00013   *           - Error management
00014   *           
00015   *  @verbatim
00016   *      
00017   *          ===================================================================      
00018   *                                CDC Class Driver Description
00019   *          =================================================================== 
00020   *           This driver manages the "Universal Serial Bus Class Definitions for Communications Devices
00021   *           Revision 1.2 November 16, 2007" and the sub-protocol specification of "Universal Serial Bus 
00022   *           Communications Class Subclass Specification for PSTN Devices Revision 1.2 February 9, 2007"
00023   *           This driver implements the following aspects of the specification:
00024   *             - Device descriptor management
00025   *             - Configuration descriptor management
00026   *             - Enumeration as CDC device with 2 data endpoints (IN and OUT) and 1 command endpoint (IN)
00027   *             - Requests management (as described in section 6.2 in specification)
00028   *             - Abstract Control Model compliant
00029   *             - Union Functional collection (using 1 IN endpoint for control)
00030   *             - Data interface class
00031   * 
00032   *           These aspects may be enriched or modified for a specific user application.
00033   *          
00034   *            This driver doesn't implement the following aspects of the specification 
00035   *            (but it is possible to manage these features with some modifications on this driver):
00036   *             - Any class-specific aspect relative to communication classes should be managed by user application.
00037   *             - All communication classes other than PSTN are not managed
00038   *      
00039   *  @endverbatim
00040   *                                  
00041   ******************************************************************************
00042   * @attention
00043   *
00044   * <h2><center>&copy; COPYRIGHT 2015 STMicroelectronics</center></h2>
00045   *
00046   * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
00047   * You may not use this file except in compliance with the License.
00048   * You may obtain a copy of the License at:
00049   *
00050   *        http://www.st.com/software_license_agreement_liberty_v2
00051   *
00052   * Unless required by applicable law or agreed to in writing, software 
00053   * distributed under the License is distributed on an "AS IS" BASIS, 
00054   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00055   * See the License for the specific language governing permissions and
00056   * limitations under the License.
00057   *
00058   ******************************************************************************
00059   */ 
00060 
00061 /* Includes ------------------------------------------------------------------*/
00062 #include "usbd_cdc.h"
00063 #include "board.h"
00064 #include "usbd_desc.h"
00065 #include "usbd_ctlreq.h"
00066 
00067 
00068 /** @addtogroup STM32_USB_DEVICE_LIBRARY
00069   * @{
00070   */
00071 
00072 
00073 /** @defgroup USBD_CDC 
00074   * @brief usbd core module
00075   * @{
00076   */ 
00077 
00078 /** @defgroup USBD_CDC_Private_TypesDefinitions
00079   * @{
00080   */ 
00081 /**
00082   * @}
00083   */ 
00084 
00085 
00086 /** @defgroup USBD_CDC_Private_Defines
00087   * @{
00088   */ 
00089 /**
00090   * @}
00091   */ 
00092 
00093 
00094 /** @defgroup USBD_CDC_Private_Macros
00095   * @{
00096   */ 
00097 
00098 /**
00099   * @}
00100   */ 
00101 
00102 
00103 /** @defgroup USBD_CDC_Private_FunctionPrototypes
00104   * @{
00105   */
00106 
00107 
00108 static uint8_t  USBD_CDC_Init (USBD_HandleTypeDef *pdev, 
00109                                uint8_t cfgidx);
00110 
00111 static uint8_t  USBD_CDC_DeInit (USBD_HandleTypeDef *pdev, 
00112                                  uint8_t cfgidx);
00113 
00114 static uint8_t  USBD_CDC_Setup (USBD_HandleTypeDef *pdev, 
00115                                 USBD_SetupReqTypedef *req);
00116 
00117 static uint8_t  USBD_CDC_DataIn (USBD_HandleTypeDef *pdev, 
00118                                  uint8_t epnum);
00119 
00120 static uint8_t  USBD_CDC_DataOut (USBD_HandleTypeDef *pdev, 
00121                                  uint8_t epnum);
00122 
00123 static uint8_t  USBD_CDC_EP0_RxReady (USBD_HandleTypeDef *pdev);
00124 
00125 static uint8_t  *USBD_CDC_GetFSCfgDesc (uint16_t *length);
00126 
00127 static uint8_t  *USBD_CDC_GetHSCfgDesc (uint16_t *length);
00128 
00129 static uint8_t  *USBD_CDC_GetOtherSpeedCfgDesc (uint16_t *length);
00130 
00131 static uint8_t  *USBD_CDC_GetOtherSpeedCfgDesc (uint16_t *length);
00132 
00133 uint8_t  *USBD_CDC_GetDeviceQualifierDescriptor (uint16_t *length);
00134 
00135 /* USB Standard Device Descriptor */
00136 __ALIGN_BEGIN static uint8_t USBD_CDC_DeviceQualifierDesc[USB_LEN_DEV_QUALIFIER_DESC] __ALIGN_END =
00137 {
00138   USB_LEN_DEV_QUALIFIER_DESC,
00139   USB_DESC_TYPE_DEVICE_QUALIFIER,
00140   0x00,
00141   0x02,
00142   0x00,
00143   0x00,
00144   0x00,
00145   0x40,
00146   0x01,
00147   0x00,
00148 };
00149 
00150 /**
00151   * @}
00152   */ 
00153 
00154 /** @defgroup USBD_CDC_Private_Variables
00155   * @{
00156   */ 
00157 
00158 
00159 /* CDC interface class callbacks structure */
00160 USBD_ClassTypeDef  USBD_CDC = 
00161 {
00162   USBD_CDC_Init,
00163   USBD_CDC_DeInit,
00164   USBD_CDC_Setup,
00165   NULL,                 /* EP0_TxSent, */
00166   USBD_CDC_EP0_RxReady,
00167   USBD_CDC_DataIn,
00168   USBD_CDC_DataOut,
00169   NULL,
00170   NULL,
00171   NULL,     
00172   USBD_CDC_GetHSCfgDesc,  
00173   USBD_CDC_GetFSCfgDesc,    
00174   USBD_CDC_GetOtherSpeedCfgDesc, 
00175   USBD_CDC_GetDeviceQualifierDescriptor,
00176 };
00177 
00178 /* USB CDC device Configuration Descriptor */
00179 __ALIGN_BEGIN uint8_t USBD_CDC_CfgHSDesc[USB_CDC_CONFIG_DESC_SIZ] __ALIGN_END =
00180 {
00181   /*Configuration Descriptor*/
00182   0x09,   /* bLength: Configuration Descriptor size */
00183   USB_DESC_TYPE_CONFIGURATION,      /* bDescriptorType: Configuration */
00184   USB_CDC_CONFIG_DESC_SIZ,                /* wTotalLength:no of returned bytes */
00185   0x00,
00186   0x02,   /* bNumInterfaces: 2 interface */
00187   0x01,   /* bConfigurationValue: Configuration value */
00188   0x00,   /* iConfiguration: Index of string descriptor describing the configuration */
00189   0xC0,   /* bmAttributes: self powered */
00190   0x32,   /* MaxPower 0 mA */
00191   
00192   /*---------------------------------------------------------------------------*/
00193   
00194   /*Interface Descriptor */
00195   0x09,   /* bLength: Interface Descriptor size */
00196   USB_DESC_TYPE_INTERFACE,  /* bDescriptorType: Interface */
00197   /* Interface descriptor type */
00198   0x00,   /* bInterfaceNumber: Number of Interface */
00199   0x00,   /* bAlternateSetting: Alternate setting */
00200   0x01,   /* bNumEndpoints: One endpoints used */
00201   0x02,   /* bInterfaceClass: Communication Interface Class */
00202   0x02,   /* bInterfaceSubClass: Abstract Control Model */
00203   0x01,   /* bInterfaceProtocol: Common AT commands */
00204   0x00,   /* iInterface: */
00205   
00206   /*Header Functional Descriptor*/
00207   0x05,   /* bLength: Endpoint Descriptor size */
00208   0x24,   /* bDescriptorType: CS_INTERFACE */
00209   0x00,   /* bDescriptorSubtype: Header Func Desc */
00210   0x10,   /* bcdCDC: spec release number */
00211   0x01,
00212   
00213   /*Call Management Functional Descriptor*/
00214   0x05,   /* bFunctionLength */
00215   0x24,   /* bDescriptorType: CS_INTERFACE */
00216   0x01,   /* bDescriptorSubtype: Call Management Func Desc */
00217   0x00,   /* bmCapabilities: D0+D1 */
00218   0x01,   /* bDataInterface: 1 */
00219   
00220   /*ACM Functional Descriptor*/
00221   0x04,   /* bFunctionLength */
00222   0x24,   /* bDescriptorType: CS_INTERFACE */
00223   0x02,   /* bDescriptorSubtype: Abstract Control Management desc */
00224   0x02,   /* bmCapabilities */
00225   
00226   /*Union Functional Descriptor*/
00227   0x05,   /* bFunctionLength */
00228   0x24,   /* bDescriptorType: CS_INTERFACE */
00229   0x06,   /* bDescriptorSubtype: Union func desc */
00230   0x00,   /* bMasterInterface: Communication class interface */
00231   0x01,   /* bSlaveInterface0: Data Class Interface */
00232   
00233   /*Endpoint 2 Descriptor*/
00234   0x07,                           /* bLength: Endpoint Descriptor size */
00235   USB_DESC_TYPE_ENDPOINT,   /* bDescriptorType: Endpoint */
00236   CDC_CMD_EP,                     /* bEndpointAddress */
00237   0x03,                           /* bmAttributes: Interrupt */
00238   LOBYTE(CDC_CMD_PACKET_SIZE),     /* wMaxPacketSize: */
00239   HIBYTE(CDC_CMD_PACKET_SIZE),
00240   0x10,                           /* bInterval: */ 
00241   /*---------------------------------------------------------------------------*/
00242   
00243   /*Data class interface descriptor*/
00244   0x09,   /* bLength: Endpoint Descriptor size */
00245   USB_DESC_TYPE_INTERFACE,  /* bDescriptorType: */
00246   0x01,   /* bInterfaceNumber: Number of Interface */
00247   0x00,   /* bAlternateSetting: Alternate setting */
00248   0x02,   /* bNumEndpoints: Two endpoints used */
00249   0x0A,   /* bInterfaceClass: CDC */
00250   0x00,   /* bInterfaceSubClass: */
00251   0x00,   /* bInterfaceProtocol: */
00252   0x00,   /* iInterface: */
00253   
00254   /*Endpoint OUT Descriptor*/
00255   0x07,   /* bLength: Endpoint Descriptor size */
00256   USB_DESC_TYPE_ENDPOINT,      /* bDescriptorType: Endpoint */
00257   CDC_OUT_EP,                        /* bEndpointAddress */
00258   0x02,                              /* bmAttributes: Bulk */
00259   LOBYTE(CDC_DATA_HS_MAX_PACKET_SIZE),  /* wMaxPacketSize: */
00260   HIBYTE(CDC_DATA_HS_MAX_PACKET_SIZE),
00261   0x00,                              /* bInterval: ignore for Bulk transfer */
00262   
00263   /*Endpoint IN Descriptor*/
00264   0x07,   /* bLength: Endpoint Descriptor size */
00265   USB_DESC_TYPE_ENDPOINT,      /* bDescriptorType: Endpoint */
00266   CDC_IN_EP,                         /* bEndpointAddress */
00267   0x02,                              /* bmAttributes: Bulk */
00268   LOBYTE(CDC_DATA_HS_MAX_PACKET_SIZE),  /* wMaxPacketSize: */
00269   HIBYTE(CDC_DATA_HS_MAX_PACKET_SIZE),
00270   0x00                               /* bInterval: ignore for Bulk transfer */
00271 } ;
00272 
00273 
00274 /* USB CDC device Configuration Descriptor */
00275 __ALIGN_BEGIN uint8_t USBD_CDC_CfgFSDesc[USB_CDC_CONFIG_DESC_SIZ] __ALIGN_END =
00276 {
00277   /*Configuration Descriptor*/
00278   0x09,   /* bLength: Configuration Descriptor size */
00279   USB_DESC_TYPE_CONFIGURATION,      /* bDescriptorType: Configuration */
00280   USB_CDC_CONFIG_DESC_SIZ,                /* wTotalLength:no of returned bytes */
00281   0x00,
00282   0x02,   /* bNumInterfaces: 2 interface */
00283   0x01,   /* bConfigurationValue: Configuration value */
00284   0x00,   /* iConfiguration: Index of string descriptor describing the configuration */
00285   0xC0,   /* bmAttributes: self powered */
00286   0x32,   /* MaxPower 0 mA */
00287   
00288   /*---------------------------------------------------------------------------*/
00289   
00290   /*Interface Descriptor */
00291   0x09,   /* bLength: Interface Descriptor size */
00292   USB_DESC_TYPE_INTERFACE,  /* bDescriptorType: Interface */
00293   /* Interface descriptor type */
00294   0x00,   /* bInterfaceNumber: Number of Interface */
00295   0x00,   /* bAlternateSetting: Alternate setting */
00296   0x01,   /* bNumEndpoints: One endpoints used */
00297   0x02,   /* bInterfaceClass: Communication Interface Class */
00298   0x02,   /* bInterfaceSubClass: Abstract Control Model */
00299   0x01,   /* bInterfaceProtocol: Common AT commands */
00300   0x00,   /* iInterface: */
00301   
00302   /*Header Functional Descriptor*/
00303   0x05,   /* bLength: Endpoint Descriptor size */
00304   0x24,   /* bDescriptorType: CS_INTERFACE */
00305   0x00,   /* bDescriptorSubtype: Header Func Desc */
00306   0x10,   /* bcdCDC: spec release number */
00307   0x01,
00308   
00309   /*Call Management Functional Descriptor*/
00310   0x05,   /* bFunctionLength */
00311   0x24,   /* bDescriptorType: CS_INTERFACE */
00312   0x01,   /* bDescriptorSubtype: Call Management Func Desc */
00313   0x00,   /* bmCapabilities: D0+D1 */
00314   0x01,   /* bDataInterface: 1 */
00315   
00316   /*ACM Functional Descriptor*/
00317   0x04,   /* bFunctionLength */
00318   0x24,   /* bDescriptorType: CS_INTERFACE */
00319   0x02,   /* bDescriptorSubtype: Abstract Control Management desc */
00320   0x02,   /* bmCapabilities */
00321   
00322   /*Union Functional Descriptor*/
00323   0x05,   /* bFunctionLength */
00324   0x24,   /* bDescriptorType: CS_INTERFACE */
00325   0x06,   /* bDescriptorSubtype: Union func desc */
00326   0x00,   /* bMasterInterface: Communication class interface */
00327   0x01,   /* bSlaveInterface0: Data Class Interface */
00328   
00329   /*Endpoint 2 Descriptor*/
00330   0x07,                           /* bLength: Endpoint Descriptor size */
00331   USB_DESC_TYPE_ENDPOINT,   /* bDescriptorType: Endpoint */
00332   CDC_CMD_EP,                     /* bEndpointAddress */
00333   0x03,                           /* bmAttributes: Interrupt */
00334   LOBYTE(CDC_CMD_PACKET_SIZE),     /* wMaxPacketSize: */
00335   HIBYTE(CDC_CMD_PACKET_SIZE),
00336   0x10,                           /* bInterval: */ 
00337   /*---------------------------------------------------------------------------*/
00338   
00339   /*Data class interface descriptor*/
00340   0x09,   /* bLength: Endpoint Descriptor size */
00341   USB_DESC_TYPE_INTERFACE,  /* bDescriptorType: */
00342   0x01,   /* bInterfaceNumber: Number of Interface */
00343   0x00,   /* bAlternateSetting: Alternate setting */
00344   0x02,   /* bNumEndpoints: Two endpoints used */
00345   0x0A,   /* bInterfaceClass: CDC */
00346   0x00,   /* bInterfaceSubClass: */
00347   0x00,   /* bInterfaceProtocol: */
00348   0x00,   /* iInterface: */
00349   
00350   /*Endpoint OUT Descriptor*/
00351   0x07,   /* bLength: Endpoint Descriptor size */
00352   USB_DESC_TYPE_ENDPOINT,      /* bDescriptorType: Endpoint */
00353   CDC_OUT_EP,                        /* bEndpointAddress */
00354   0x02,                              /* bmAttributes: Bulk */
00355   LOBYTE(CDC_DATA_FS_MAX_PACKET_SIZE),  /* wMaxPacketSize: */
00356   HIBYTE(CDC_DATA_FS_MAX_PACKET_SIZE),
00357   0x00,                              /* bInterval: ignore for Bulk transfer */
00358   
00359   /*Endpoint IN Descriptor*/
00360   0x07,   /* bLength: Endpoint Descriptor size */
00361   USB_DESC_TYPE_ENDPOINT,      /* bDescriptorType: Endpoint */
00362   CDC_IN_EP,                         /* bEndpointAddress */
00363   0x02,                              /* bmAttributes: Bulk */
00364   LOBYTE(CDC_DATA_FS_MAX_PACKET_SIZE),  /* wMaxPacketSize: */
00365   HIBYTE(CDC_DATA_FS_MAX_PACKET_SIZE),
00366   0x00                               /* bInterval: ignore for Bulk transfer */
00367 } ;
00368 
00369 __ALIGN_BEGIN uint8_t USBD_CDC_OtherSpeedCfgDesc[USB_CDC_CONFIG_DESC_SIZ] __ALIGN_END =
00370 { 
00371   0x09,   /* bLength: Configuation Descriptor size */
00372   USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION,   
00373   USB_CDC_CONFIG_DESC_SIZ,
00374   0x00,
00375   0x02,   /* bNumInterfaces: 2 interfaces */
00376   0x01,   /* bConfigurationValue: */
00377   0x04,   /* iConfiguration: */
00378   0xC0,   /* bmAttributes: */
00379   0x32,   /* MaxPower 100 mA */  
00380   
00381   /*Interface Descriptor */
00382   0x09,   /* bLength: Interface Descriptor size */
00383   USB_DESC_TYPE_INTERFACE,  /* bDescriptorType: Interface */
00384   /* Interface descriptor type */
00385   0x00,   /* bInterfaceNumber: Number of Interface */
00386   0x00,   /* bAlternateSetting: Alternate setting */
00387   0x01,   /* bNumEndpoints: One endpoints used */
00388   0x02,   /* bInterfaceClass: Communication Interface Class */
00389   0x02,   /* bInterfaceSubClass: Abstract Control Model */
00390   0x01,   /* bInterfaceProtocol: Common AT commands */
00391   0x00,   /* iInterface: */
00392   
00393   /*Header Functional Descriptor*/
00394   0x05,   /* bLength: Endpoint Descriptor size */
00395   0x24,   /* bDescriptorType: CS_INTERFACE */
00396   0x00,   /* bDescriptorSubtype: Header Func Desc */
00397   0x10,   /* bcdCDC: spec release number */
00398   0x01,
00399   
00400   /*Call Management Functional Descriptor*/
00401   0x05,   /* bFunctionLength */
00402   0x24,   /* bDescriptorType: CS_INTERFACE */
00403   0x01,   /* bDescriptorSubtype: Call Management Func Desc */
00404   0x00,   /* bmCapabilities: D0+D1 */
00405   0x01,   /* bDataInterface: 1 */
00406   
00407   /*ACM Functional Descriptor*/
00408   0x04,   /* bFunctionLength */
00409   0x24,   /* bDescriptorType: CS_INTERFACE */
00410   0x02,   /* bDescriptorSubtype: Abstract Control Management desc */
00411   0x02,   /* bmCapabilities */
00412   
00413   /*Union Functional Descriptor*/
00414   0x05,   /* bFunctionLength */
00415   0x24,   /* bDescriptorType: CS_INTERFACE */
00416   0x06,   /* bDescriptorSubtype: Union func desc */
00417   0x00,   /* bMasterInterface: Communication class interface */
00418   0x01,   /* bSlaveInterface0: Data Class Interface */
00419   
00420   /*Endpoint 2 Descriptor*/
00421   0x07,                           /* bLength: Endpoint Descriptor size */
00422   USB_DESC_TYPE_ENDPOINT      ,   /* bDescriptorType: Endpoint */
00423   CDC_CMD_EP,                     /* bEndpointAddress */
00424   0x03,                           /* bmAttributes: Interrupt */
00425   LOBYTE(CDC_CMD_PACKET_SIZE),     /* wMaxPacketSize: */
00426   HIBYTE(CDC_CMD_PACKET_SIZE),
00427   0xFF,                           /* bInterval: */
00428   
00429   /*---------------------------------------------------------------------------*/
00430   
00431   /*Data class interface descriptor*/
00432   0x09,   /* bLength: Endpoint Descriptor size */
00433   USB_DESC_TYPE_INTERFACE,  /* bDescriptorType: */
00434   0x01,   /* bInterfaceNumber: Number of Interface */
00435   0x00,   /* bAlternateSetting: Alternate setting */
00436   0x02,   /* bNumEndpoints: Two endpoints used */
00437   0x0A,   /* bInterfaceClass: CDC */
00438   0x00,   /* bInterfaceSubClass: */
00439   0x00,   /* bInterfaceProtocol: */
00440   0x00,   /* iInterface: */
00441   
00442   /*Endpoint OUT Descriptor*/
00443   0x07,   /* bLength: Endpoint Descriptor size */
00444   USB_DESC_TYPE_ENDPOINT,      /* bDescriptorType: Endpoint */
00445   CDC_OUT_EP,                        /* bEndpointAddress */
00446   0x02,                              /* bmAttributes: Bulk */
00447   0x40,                              /* wMaxPacketSize: */
00448   0x00,
00449   0x00,                              /* bInterval: ignore for Bulk transfer */
00450   
00451   /*Endpoint IN Descriptor*/
00452   0x07,   /* bLength: Endpoint Descriptor size */
00453   USB_DESC_TYPE_ENDPOINT,     /* bDescriptorType: Endpoint */
00454   CDC_IN_EP,                        /* bEndpointAddress */
00455   0x02,                             /* bmAttributes: Bulk */
00456   0x40,                             /* wMaxPacketSize: */
00457   0x00,
00458   0x00                              /* bInterval */
00459 };
00460 
00461 /**
00462   * @}
00463   */ 
00464 
00465 /** @defgroup USBD_CDC_Private_Functions
00466   * @{
00467   */ 
00468 
00469 /**
00470   * @brief  USBD_CDC_Init
00471   *         Initialize the CDC interface
00472   * @param  pdev: device instance
00473   * @param  cfgidx: Configuration index
00474   * @retval status
00475   */
00476 static uint8_t  USBD_CDC_Init (USBD_HandleTypeDef *pdev, 
00477                                uint8_t cfgidx)
00478 {
00479   uint8_t ret = 0;
00480   USBD_CDC_HandleTypeDef   *hcdc;
00481   
00482   if(pdev->dev_speed == USBD_SPEED_HIGH  ) 
00483   {  
00484     /* Open EP IN */
00485     USBD_LL_OpenEP(pdev,
00486                    CDC_IN_EP,
00487                    USBD_EP_TYPE_BULK,
00488                    CDC_DATA_HS_IN_PACKET_SIZE);
00489     
00490     /* Open EP OUT */
00491     USBD_LL_OpenEP(pdev,
00492                    CDC_OUT_EP,
00493                    USBD_EP_TYPE_BULK,
00494                    CDC_DATA_HS_OUT_PACKET_SIZE);
00495     
00496   }
00497   else
00498   {
00499     /* Open EP IN */
00500     USBD_LL_OpenEP(pdev,
00501                    CDC_IN_EP,
00502                    USBD_EP_TYPE_BULK,
00503                    CDC_DATA_FS_IN_PACKET_SIZE);
00504     
00505     /* Open EP OUT */
00506     USBD_LL_OpenEP(pdev,
00507                    CDC_OUT_EP,
00508                    USBD_EP_TYPE_BULK,
00509                    CDC_DATA_FS_OUT_PACKET_SIZE);
00510   }
00511   /* Open Command IN EP */
00512   USBD_LL_OpenEP(pdev,
00513                  CDC_CMD_EP,
00514                  USBD_EP_TYPE_INTR,
00515                  CDC_CMD_PACKET_SIZE);
00516   
00517     
00518   pdev->pClassData = USBD_malloc(sizeof (USBD_CDC_HandleTypeDef));
00519   
00520   if(pdev->pClassData == NULL)
00521   {
00522     ret = 1; 
00523   }
00524   else
00525   {
00526     hcdc = (USBD_CDC_HandleTypeDef*) pdev->pClassData;
00527     
00528     /* Init  physical Interface components */
00529     ((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Init();
00530     
00531     /* Init Xfer states */
00532     hcdc->TxState =0;
00533     hcdc->RxState =0;
00534        
00535     if(pdev->dev_speed == USBD_SPEED_HIGH  ) 
00536     {      
00537       /* Prepare Out endpoint to receive next packet */
00538       USBD_LL_PrepareReceive(pdev,
00539                              CDC_OUT_EP,
00540                              hcdc->RxBuffer,
00541                              CDC_DATA_HS_OUT_PACKET_SIZE);
00542     }
00543     else
00544     {
00545       /* Prepare Out endpoint to receive next packet */
00546       USBD_LL_PrepareReceive(pdev,
00547                              CDC_OUT_EP,
00548                              hcdc->RxBuffer,
00549                              CDC_DATA_FS_OUT_PACKET_SIZE);
00550     }
00551     
00552     
00553   }
00554   return ret;
00555 }
00556 
00557 /**
00558   * @brief  USBD_CDC_Init
00559   *         DeInitialize the CDC layer
00560   * @param  pdev: device instance
00561   * @param  cfgidx: Configuration index
00562   * @retval status
00563   */
00564 static uint8_t  USBD_CDC_DeInit (USBD_HandleTypeDef *pdev, 
00565                                  uint8_t cfgidx)
00566 {
00567   uint8_t ret = 0;
00568   
00569   /* Open EP IN */
00570   USBD_LL_CloseEP(pdev,
00571               CDC_IN_EP);
00572   
00573   /* Open EP OUT */
00574   USBD_LL_CloseEP(pdev,
00575               CDC_OUT_EP);
00576   
00577   /* Open Command IN EP */
00578   USBD_LL_CloseEP(pdev,
00579               CDC_CMD_EP);
00580   
00581   
00582   /* DeInit  physical Interface components */
00583   if(pdev->pClassData != NULL)
00584   {
00585     ((USBD_CDC_ItfTypeDef *)pdev->pUserData)->DeInit();
00586     USBD_free(pdev->pClassData);
00587     pdev->pClassData = NULL;
00588   }
00589   
00590   return ret;
00591 }
00592 
00593 /**
00594   * @brief  USBD_CDC_Setup
00595   *         Handle the CDC specific requests
00596   * @param  pdev: instance
00597   * @param  req: usb requests
00598   * @retval status
00599   */
00600 static uint8_t  USBD_CDC_Setup (USBD_HandleTypeDef *pdev, 
00601                                 USBD_SetupReqTypedef *req)
00602 {
00603   USBD_CDC_HandleTypeDef   *hcdc = (USBD_CDC_HandleTypeDef*) pdev->pClassData;
00604   static uint8_t ifalt = 0;
00605     
00606   switch (req->bmRequest & USB_REQ_TYPE_MASK)
00607   {
00608   case USB_REQ_TYPE_CLASS :
00609     if (req->wLength)
00610     {
00611       if (req->bmRequest & 0x80)
00612       {
00613         ((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Control(req->bRequest,
00614                                                           (uint8_t *)hcdc->data,
00615                                                           req->wLength);
00616           USBD_CtlSendData (pdev, 
00617                             (uint8_t *)hcdc->data,
00618                             req->wLength);
00619       }
00620       else
00621       {
00622         hcdc->CmdOpCode = req->bRequest;
00623         hcdc->CmdLength = req->wLength;
00624         
00625         USBD_CtlPrepareRx (pdev, 
00626                            (uint8_t *)hcdc->data,
00627                            req->wLength);
00628       }
00629       
00630     }
00631     else
00632     {
00633       ((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Control(req->bRequest,
00634                                                         (uint8_t*)req,
00635                                                         0);
00636     }
00637     break;
00638 
00639   case USB_REQ_TYPE_STANDARD:
00640     switch (req->bRequest)
00641     {      
00642     case USB_REQ_GET_INTERFACE :
00643       USBD_CtlSendData (pdev,
00644                         &ifalt,
00645                         1);
00646       break;
00647       
00648     case USB_REQ_SET_INTERFACE :
00649       break;
00650     }
00651  
00652   default: 
00653     break;
00654   }
00655   return USBD_OK;
00656 }
00657 
00658 /**
00659   * @brief  USBD_CDC_DataIn
00660   *         Data sent on non-control IN endpoint
00661   * @param  pdev: device instance
00662   * @param  epnum: endpoint number
00663   * @retval status
00664   */
00665 static uint8_t  USBD_CDC_DataIn (USBD_HandleTypeDef *pdev, uint8_t epnum)
00666 {
00667   USBD_CDC_HandleTypeDef   *hcdc = (USBD_CDC_HandleTypeDef*) pdev->pClassData;
00668   
00669   if(pdev->pClassData != NULL)
00670   {
00671     
00672     hcdc->TxState = 0;
00673 
00674     return USBD_OK;
00675   }
00676   else
00677   {
00678     return USBD_FAIL;
00679   }
00680 }
00681 
00682 /**
00683   * @brief  USBD_CDC_DataOut
00684   *         Data received on non-control Out endpoint
00685   * @param  pdev: device instance
00686   * @param  epnum: endpoint number
00687   * @retval status
00688   */
00689 static uint8_t  USBD_CDC_DataOut (USBD_HandleTypeDef *pdev, uint8_t epnum)
00690 {      
00691   USBD_CDC_HandleTypeDef   *hcdc = (USBD_CDC_HandleTypeDef*) pdev->pClassData;
00692   
00693   /* Get the received data length */
00694   hcdc->RxLength = USBD_LL_GetRxDataSize (pdev, epnum);
00695   
00696   /* USB data will be immediately processed, this allow next USB traffic being 
00697   NAKed till the end of the application Xfer */
00698   if(pdev->pClassData != NULL)
00699   {
00700     ((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Receive(hcdc->RxBuffer, &hcdc->RxLength);
00701 
00702     return USBD_OK;
00703   }
00704   else
00705   {
00706     return USBD_FAIL;
00707   }
00708 }
00709 
00710 
00711 
00712 /**
00713   * @brief  USBD_CDC_DataOut
00714   *         Data received on non-control Out endpoint
00715   * @param  pdev: device instance
00716   * @param  epnum: endpoint number
00717   * @retval status
00718   */
00719 static uint8_t  USBD_CDC_EP0_RxReady (USBD_HandleTypeDef *pdev)
00720 { 
00721   USBD_CDC_HandleTypeDef   *hcdc = (USBD_CDC_HandleTypeDef*) pdev->pClassData;
00722   
00723   if((pdev->pUserData != NULL) && (hcdc->CmdOpCode != 0xFF))
00724   {
00725     ((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Control(hcdc->CmdOpCode,
00726                                                       (uint8_t *)hcdc->data,
00727                                                       hcdc->CmdLength);
00728       hcdc->CmdOpCode = 0xFF; 
00729       
00730   }
00731   return USBD_OK;
00732 }
00733 
00734 /**
00735   * @brief  USBD_CDC_GetFSCfgDesc 
00736   *         Return configuration descriptor
00737   * @param  speed : current device speed
00738   * @param  length : pointer data length
00739   * @retval pointer to descriptor buffer
00740   */
00741 static uint8_t  *USBD_CDC_GetFSCfgDesc (uint16_t *length)
00742 {
00743   *length = sizeof (USBD_CDC_CfgFSDesc);
00744   return USBD_CDC_CfgFSDesc;
00745 }
00746 
00747 /**
00748   * @brief  USBD_CDC_GetHSCfgDesc 
00749   *         Return configuration descriptor
00750   * @param  speed : current device speed
00751   * @param  length : pointer data length
00752   * @retval pointer to descriptor buffer
00753   */
00754 static uint8_t  *USBD_CDC_GetHSCfgDesc (uint16_t *length)
00755 {
00756   *length = sizeof (USBD_CDC_CfgHSDesc);
00757   return USBD_CDC_CfgHSDesc;
00758 }
00759 
00760 /**
00761   * @brief  USBD_CDC_GetCfgDesc 
00762   *         Return configuration descriptor
00763   * @param  speed : current device speed
00764   * @param  length : pointer data length
00765   * @retval pointer to descriptor buffer
00766   */
00767 static uint8_t  *USBD_CDC_GetOtherSpeedCfgDesc (uint16_t *length)
00768 {
00769   *length = sizeof (USBD_CDC_OtherSpeedCfgDesc);
00770   return USBD_CDC_OtherSpeedCfgDesc;
00771 }
00772 
00773 /**
00774 * @brief  DeviceQualifierDescriptor 
00775 *         return Device Qualifier descriptor
00776 * @param  length : pointer data length
00777 * @retval pointer to descriptor buffer
00778 */
00779 uint8_t  *USBD_CDC_GetDeviceQualifierDescriptor (uint16_t *length)
00780 {
00781   *length = sizeof (USBD_CDC_DeviceQualifierDesc);
00782   return USBD_CDC_DeviceQualifierDesc;
00783 }
00784 
00785 /**
00786 * @brief  USBD_CDC_RegisterInterface
00787   * @param  pdev: device instance
00788   * @param  fops: CD  Interface callback
00789   * @retval status
00790   */
00791 uint8_t  USBD_CDC_RegisterInterface  (USBD_HandleTypeDef   *pdev, 
00792                                       USBD_CDC_ItfTypeDef *fops)
00793 {
00794   uint8_t  ret = USBD_FAIL;
00795   
00796   if(fops != NULL)
00797   {
00798     pdev->pUserData= fops;
00799     ret = USBD_OK;    
00800   }
00801   
00802   return ret;
00803 }
00804 
00805 /**
00806   * @brief  USBD_CDC_SetTxBuffer
00807   * @param  pdev: device instance
00808   * @param  pbuff: Tx Buffer
00809   * @retval status
00810   */
00811 uint8_t  USBD_CDC_SetTxBuffer  (USBD_HandleTypeDef   *pdev,
00812                                 uint8_t  *pbuff,
00813                                 uint16_t length)
00814 {
00815   USBD_CDC_HandleTypeDef   *hcdc = (USBD_CDC_HandleTypeDef*) pdev->pClassData;
00816   
00817   hcdc->TxBuffer = pbuff;
00818   hcdc->TxLength = length;  
00819   
00820   return USBD_OK;  
00821 }
00822 
00823 
00824 /**
00825   * @brief  USBD_CDC_SetRxBuffer
00826   * @param  pdev: device instance
00827   * @param  pbuff: Rx Buffer
00828   * @retval status
00829   */
00830 uint8_t  USBD_CDC_SetRxBuffer  (USBD_HandleTypeDef   *pdev,
00831                                    uint8_t  *pbuff)
00832 {
00833   USBD_CDC_HandleTypeDef   *hcdc = (USBD_CDC_HandleTypeDef*) pdev->pClassData;
00834   
00835   hcdc->RxBuffer = pbuff;
00836   
00837   return USBD_OK;
00838 }
00839 
00840 /**
00841   * @brief  USBD_CDC_DataOut
00842   *         Data received on non-control Out endpoint
00843   * @param  pdev: device instance
00844   * @param  epnum: endpoint number
00845   * @retval status
00846   */
00847 uint8_t  USBD_CDC_TransmitPacket(USBD_HandleTypeDef *pdev)
00848 {      
00849   USBD_CDC_HandleTypeDef   *hcdc = (USBD_CDC_HandleTypeDef*) pdev->pClassData;
00850   
00851   if(pdev->pClassData != NULL)
00852   {
00853     if(hcdc->TxState == 0)
00854     {
00855       /* Tx Transfer in progress */
00856       hcdc->TxState = 1;
00857       
00858       /* Transmit next packet */
00859       USBD_LL_Transmit(pdev,
00860                        CDC_IN_EP,
00861                        hcdc->TxBuffer,
00862                        hcdc->TxLength);
00863       
00864       return USBD_OK;
00865     }
00866     else
00867     {
00868       return USBD_BUSY;
00869     }
00870   }
00871   else
00872   {
00873     return USBD_FAIL;
00874   }
00875 }
00876 
00877 
00878 /**
00879   * @brief  USBD_CDC_ReceivePacket
00880   *         prepare OUT Endpoint for reception
00881   * @param  pdev: device instance
00882   * @retval status
00883   */
00884 
00885 uint8_t  USBD_CDC_ReceivePacket(USBD_HandleTypeDef *pdev)
00886 {      
00887   USBD_CDC_HandleTypeDef   *hcdc = (USBD_CDC_HandleTypeDef*) pdev->pClassData;
00888   
00889   /* Suspend or Resume USB Out process */
00890   if(pdev->pClassData != NULL)
00891   {
00892     if(pdev->dev_speed == USBD_SPEED_HIGH  ) 
00893     {      
00894       /* Prepare Out endpoint to receive next packet */
00895       USBD_LL_PrepareReceive(pdev,
00896                              CDC_OUT_EP,
00897                              hcdc->RxBuffer,
00898                              CDC_DATA_HS_OUT_PACKET_SIZE);
00899     }
00900     else
00901     {
00902       /* Prepare Out endpoint to receive next packet */
00903       USBD_LL_PrepareReceive(pdev,
00904                              CDC_OUT_EP,
00905                              hcdc->RxBuffer,
00906                              CDC_DATA_FS_OUT_PACKET_SIZE);
00907     }
00908     return USBD_OK;
00909   }
00910   else
00911   {
00912     return USBD_FAIL;
00913   }
00914 }
00915 /**
00916   * @}
00917   */ 
00918 
00919 /**
00920   * @}
00921   */ 
00922 
00923 /**
00924   * @}
00925   */ 
00926 
00927 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/