Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
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>© 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****/
Generated on Tue Jul 12 2022 22:19:21 by
