Kleber Silva / IOTON-API

Dependents:   ton_demo ton_template

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers usbd_cdc.c Source File

usbd_cdc.c

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