Subversion Repositories dualCDC

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. /**
  2.   ******************************************************************************
  3.   * @file    usbd_cdc.c
  4.   * @author  MCD Application Team
  5.   * @brief   This file provides the high layer firmware functions to manage the
  6.   *          following functionalities of the USB CDC Class:
  7.   *           - Initialization and Configuration of high and low layer
  8.   *           - Enumeration as CDC Device (and enumeration for each implemented memory interface)
  9.   *           - OUT/IN data transfer
  10.   *           - Command IN transfer (class requests management)
  11.   *           - Error management
  12.   *
  13.   *  @verbatim
  14.   *
  15.   *          ===================================================================
  16.   *                                CDC Class Driver Description
  17.   *          ===================================================================
  18.   *           This driver manages the "Universal Serial Bus Class Definitions for Communications Devices
  19.   *           Revision 1.2 November 16, 2007" and the sub-protocol specification of "Universal Serial Bus
  20.   *           Communications Class Subclass Specification for PSTN Devices Revision 1.2 February 9, 2007"
  21.   *           This driver implements the following aspects of the specification:
  22.   *             - Device descriptor management
  23.   *             - Configuration descriptor management
  24.   *             - Enumeration as CDC device with 2 data endpoints (IN and OUT) and 1 command endpoint (IN)
  25.   *             - Requests management (as described in section 6.2 in specification)
  26.   *             - Abstract Control Model compliant
  27.   *             - Union Functional collection (using 1 IN endpoint for control)
  28.   *             - Data interface class
  29.   *
  30.   *           These aspects may be enriched or modified for a specific user application.
  31.   *
  32.   *            This driver doesn't implement the following aspects of the specification
  33.   *            (but it is possible to manage these features with some modifications on this driver):
  34.   *             - Any class-specific aspect relative to communication classes should be managed by user application.
  35.   *             - All communication classes other than PSTN are not managed
  36.   *
  37.   *  @endverbatim
  38.   *
  39.   ******************************************************************************
  40.   * @attention
  41.   *
  42.   * <h2><center>&copy; Copyright (c) 2015 STMicroelectronics.
  43.   * All rights reserved.</center></h2>
  44.   *
  45.   * This software component is licensed by ST under Ultimate Liberty license
  46.   * SLA0044, the "License"; You may not use this file except in compliance with
  47.   * the License. You may obtain a copy of the License at:
  48.   *                      www.st.com/SLA0044
  49.   *
  50.   ******************************************************************************
  51.   */
  52.  
  53. /* BSPDependencies
  54. - "stm32xxxxx_{eval}{discovery}{nucleo_144}.c"
  55. - "stm32xxxxx_{eval}{discovery}_io.c"
  56. EndBSPDependencies */
  57.  
  58. /* Includes ------------------------------------------------------------------*/
  59. #include "usbd_cdc.h"
  60. #include "usbd_ctlreq.h"
  61.  
  62.  
  63. /** @addtogroup STM32_USB_DEVICE_LIBRARY
  64.   * @{
  65.   */
  66.  
  67.  
  68. /** @defgroup USBD_CDC
  69.   * @brief usbd core module
  70.   * @{
  71.   */
  72.  
  73. /** @defgroup USBD_CDC_Private_TypesDefinitions
  74.   * @{
  75.   */
  76. /**
  77.   * @}
  78.   */
  79.  
  80.  
  81. /** @defgroup USBD_CDC_Private_Defines
  82.   * @{
  83.   */
  84. /**
  85.   * @}
  86.   */
  87.  
  88.  
  89. /** @defgroup USBD_CDC_Private_Macros
  90.   * @{
  91.   */
  92.  
  93. /**
  94.   * @}
  95.   */
  96.  
  97.  
  98. /** @defgroup USBD_CDC_Private_FunctionPrototypes
  99.   * @{
  100.   */
  101.  
  102.  
  103. static uint8_t  USBD_CDC_Init(USBD_HandleTypeDef *pdev,
  104.                               uint8_t cfgidx);
  105.  
  106. static uint8_t  USBD_CDC_DeInit(USBD_HandleTypeDef *pdev,
  107.                                 uint8_t cfgidx);
  108.  
  109. static uint8_t  USBD_CDC_Setup(USBD_HandleTypeDef *pdev,
  110.                                USBD_SetupReqTypedef *req);
  111.  
  112. static uint8_t  USBD_CDC_DataIn(USBD_HandleTypeDef *pdev,
  113.                                 uint8_t epnum);
  114.  
  115. static uint8_t  USBD_CDC_DataOut(USBD_HandleTypeDef *pdev,
  116.                                  uint8_t epnum);
  117.  
  118. static uint8_t  USBD_CDC_EP0_RxReady(USBD_HandleTypeDef *pdev);
  119.  
  120. static uint8_t  *USBD_CDC_GetFSCfgDesc(uint16_t *length);
  121.  
  122. static uint8_t  *USBD_CDC_GetHSCfgDesc(uint16_t *length);
  123.  
  124. static uint8_t  *USBD_CDC_GetOtherSpeedCfgDesc(uint16_t *length);
  125.  
  126. static uint8_t  *USBD_CDC_GetOtherSpeedCfgDesc(uint16_t *length);
  127.  
  128. uint8_t  *USBD_CDC_GetDeviceQualifierDescriptor(uint16_t *length);
  129.  
  130. /* USB Standard Device Descriptor */
  131. __ALIGN_BEGIN static uint8_t USBD_CDC_DeviceQualifierDesc[USB_LEN_DEV_QUALIFIER_DESC] __ALIGN_END =
  132. {
  133.   USB_LEN_DEV_QUALIFIER_DESC,
  134.   USB_DESC_TYPE_DEVICE_QUALIFIER,
  135.   0x00,
  136.   0x02,
  137.   0x00,
  138.   0x00,
  139.   0x00,
  140.   0x40,
  141.   0x01,
  142.   0x00,
  143. };
  144.  
  145. /**
  146.   * @}
  147.   */
  148.  
  149. /** @defgroup USBD_CDC_Private_Variables
  150.   * @{
  151.   */
  152.  
  153.  
  154. /* CDC interface class callbacks structure */
  155. USBD_ClassTypeDef  USBD_CDC =
  156. {
  157.   USBD_CDC_Init,
  158.   USBD_CDC_DeInit,
  159.   USBD_CDC_Setup,
  160.   NULL,                 /* EP0_TxSent, */
  161.   USBD_CDC_EP0_RxReady,
  162.   USBD_CDC_DataIn,
  163.   USBD_CDC_DataOut,
  164.   NULL,
  165.   NULL,
  166.   NULL,
  167.   USBD_CDC_GetHSCfgDesc,
  168.   USBD_CDC_GetFSCfgDesc,
  169.   USBD_CDC_GetOtherSpeedCfgDesc,
  170.   USBD_CDC_GetDeviceQualifierDescriptor,
  171. };
  172.  
  173. /* USB CDC device Configuration Descriptor */
  174. __ALIGN_BEGIN uint8_t USBD_CDC_CfgHSDesc[USB_CDC_CONFIG_DESC_SIZ] __ALIGN_END =
  175. {
  176.   /*Configuration Descriptor*/
  177.   0x09,   /* bLength: Configuration Descriptor size */
  178.   USB_DESC_TYPE_CONFIGURATION,      /* bDescriptorType: Configuration */
  179.   USB_CDC_CONFIG_DESC_SIZ,                /* wTotalLength:no of returned bytes */
  180.   0x00,
  181.   0x02,   /* bNumInterfaces: 2 interface */
  182.   0x01,   /* bConfigurationValue: Configuration value */
  183.   0x00,   /* iConfiguration: Index of string descriptor describing the configuration */
  184.   0xC0,   /* bmAttributes: self powered */
  185.   0x32,   /* MaxPower 0 mA */
  186.  
  187.   /*---------------------------------------------------------------------------*/
  188.  
  189.   /*Interface Descriptor */
  190.   0x09,   /* bLength: Interface Descriptor size */
  191.   USB_DESC_TYPE_INTERFACE,  /* bDescriptorType: Interface */
  192.   /* Interface descriptor type */
  193.   0x00,   /* bInterfaceNumber: Number of Interface */
  194.   0x00,   /* bAlternateSetting: Alternate setting */
  195.   0x01,   /* bNumEndpoints: One endpoints used */
  196.   0x02,   /* bInterfaceClass: Communication Interface Class */
  197.   0x02,   /* bInterfaceSubClass: Abstract Control Model */
  198.   0x01,   /* bInterfaceProtocol: Common AT commands */
  199.   0x00,   /* iInterface: */
  200.  
  201.   /*Header Functional Descriptor*/
  202.   0x05,   /* bLength: Endpoint Descriptor size */
  203.   0x24,   /* bDescriptorType: CS_INTERFACE */
  204.   0x00,   /* bDescriptorSubtype: Header Func Desc */
  205.   0x10,   /* bcdCDC: spec release number */
  206.   0x01,
  207.  
  208.   /*Call Management Functional Descriptor*/
  209.   0x05,   /* bFunctionLength */
  210.   0x24,   /* bDescriptorType: CS_INTERFACE */
  211.   0x01,   /* bDescriptorSubtype: Call Management Func Desc */
  212.   0x00,   /* bmCapabilities: D0+D1 */
  213.   0x01,   /* bDataInterface: 1 */
  214.  
  215.   /*ACM Functional Descriptor*/
  216.   0x04,   /* bFunctionLength */
  217.   0x24,   /* bDescriptorType: CS_INTERFACE */
  218.   0x02,   /* bDescriptorSubtype: Abstract Control Management desc */
  219.   0x02,   /* bmCapabilities */
  220.  
  221.   /*Union Functional Descriptor*/
  222.   0x05,   /* bFunctionLength */
  223.   0x24,   /* bDescriptorType: CS_INTERFACE */
  224.   0x06,   /* bDescriptorSubtype: Union func desc */
  225.   0x00,   /* bMasterInterface: Communication class interface */
  226.   0x01,   /* bSlaveInterface0: Data Class Interface */
  227.  
  228.   /*Endpoint 2 Descriptor*/
  229.   0x07,                           /* bLength: Endpoint Descriptor size */
  230.   USB_DESC_TYPE_ENDPOINT,   /* bDescriptorType: Endpoint */
  231.   CDC_CMD_EP,                     /* bEndpointAddress */
  232.   0x03,                           /* bmAttributes: Interrupt */
  233.   LOBYTE(CDC_CMD_PACKET_SIZE),     /* wMaxPacketSize: */
  234.   HIBYTE(CDC_CMD_PACKET_SIZE),
  235.   CDC_HS_BINTERVAL,                           /* bInterval: */
  236.   /*---------------------------------------------------------------------------*/
  237.  
  238.   /*Data class interface descriptor*/
  239.   0x09,   /* bLength: Endpoint Descriptor size */
  240.   USB_DESC_TYPE_INTERFACE,  /* bDescriptorType: */
  241.   0x01,   /* bInterfaceNumber: Number of Interface */
  242.   0x00,   /* bAlternateSetting: Alternate setting */
  243.   0x02,   /* bNumEndpoints: Two endpoints used */
  244.   0x0A,   /* bInterfaceClass: CDC */
  245.   0x00,   /* bInterfaceSubClass: */
  246.   0x00,   /* bInterfaceProtocol: */
  247.   0x00,   /* iInterface: */
  248.  
  249.   /*Endpoint OUT Descriptor*/
  250.   0x07,   /* bLength: Endpoint Descriptor size */
  251.   USB_DESC_TYPE_ENDPOINT,      /* bDescriptorType: Endpoint */
  252.   CDC_OUT_EP,                        /* bEndpointAddress */
  253.   0x02,                              /* bmAttributes: Bulk */
  254.   LOBYTE(CDC_DATA_HS_MAX_PACKET_SIZE),  /* wMaxPacketSize: */
  255.   HIBYTE(CDC_DATA_HS_MAX_PACKET_SIZE),
  256.   0x00,                              /* bInterval: ignore for Bulk transfer */
  257.  
  258.   /*Endpoint IN Descriptor*/
  259.   0x07,   /* bLength: Endpoint Descriptor size */
  260.   USB_DESC_TYPE_ENDPOINT,      /* bDescriptorType: Endpoint */
  261.   CDC_IN_EP,                         /* bEndpointAddress */
  262.   0x02,                              /* bmAttributes: Bulk */
  263.   LOBYTE(CDC_DATA_HS_MAX_PACKET_SIZE),  /* wMaxPacketSize: */
  264.   HIBYTE(CDC_DATA_HS_MAX_PACKET_SIZE),
  265.   0x00                               /* bInterval: ignore for Bulk transfer */
  266. } ;
  267.  
  268.  
  269. /* USB CDC device Configuration Descriptor */
  270. __ALIGN_BEGIN uint8_t USBD_CDC_CfgFSDesc[USB_CDC_CONFIG_DESC_SIZ] __ALIGN_END =
  271. {
  272.   /*Configuration Descriptor*/
  273.   0x09,   /* bLength: Configuration Descriptor size */
  274.   USB_DESC_TYPE_CONFIGURATION,      /* bDescriptorType: Configuration */
  275.   USB_CDC_CONFIG_DESC_SIZ,                /* wTotalLength:no of returned bytes */
  276.   0x00,
  277.   0x02,   /* bNumInterfaces: 2 interface */
  278.   0x01,   /* bConfigurationValue: Configuration value */
  279.   0x00,   /* iConfiguration: Index of string descriptor describing the configuration */
  280.   0xC0,   /* bmAttributes: self powered */
  281.   0x32,   /* MaxPower 0 mA */
  282.  
  283.   /*---------------------------------------------------------------------------*/
  284.  
  285.   /*Interface Descriptor */
  286.   0x09,   /* bLength: Interface Descriptor size */
  287.   USB_DESC_TYPE_INTERFACE,  /* bDescriptorType: Interface */
  288.   /* Interface descriptor type */
  289.   0x00,   /* bInterfaceNumber: Number of Interface */
  290.   0x00,   /* bAlternateSetting: Alternate setting */
  291.   0x01,   /* bNumEndpoints: One endpoints used */
  292.   0x02,   /* bInterfaceClass: Communication Interface Class */
  293.   0x02,   /* bInterfaceSubClass: Abstract Control Model */
  294.   0x01,   /* bInterfaceProtocol: Common AT commands */
  295.   0x00,   /* iInterface: */
  296.  
  297.   /*Header Functional Descriptor*/
  298.   0x05,   /* bLength: Endpoint Descriptor size */
  299.   0x24,   /* bDescriptorType: CS_INTERFACE */
  300.   0x00,   /* bDescriptorSubtype: Header Func Desc */
  301.   0x10,   /* bcdCDC: spec release number */
  302.   0x01,
  303.  
  304.   /*Call Management Functional Descriptor*/
  305.   0x05,   /* bFunctionLength */
  306.   0x24,   /* bDescriptorType: CS_INTERFACE */
  307.   0x01,   /* bDescriptorSubtype: Call Management Func Desc */
  308.   0x00,   /* bmCapabilities: D0+D1 */
  309.   0x01,   /* bDataInterface: 1 */
  310.  
  311.   /*ACM Functional Descriptor*/
  312.   0x04,   /* bFunctionLength */
  313.   0x24,   /* bDescriptorType: CS_INTERFACE */
  314.   0x02,   /* bDescriptorSubtype: Abstract Control Management desc */
  315.   0x02,   /* bmCapabilities */
  316.  
  317.   /*Union Functional Descriptor*/
  318.   0x05,   /* bFunctionLength */
  319.   0x24,   /* bDescriptorType: CS_INTERFACE */
  320.   0x06,   /* bDescriptorSubtype: Union func desc */
  321.   0x00,   /* bMasterInterface: Communication class interface */
  322.   0x01,   /* bSlaveInterface0: Data Class Interface */
  323.  
  324.   /*Endpoint 2 Descriptor*/
  325.   0x07,                           /* bLength: Endpoint Descriptor size */
  326.   USB_DESC_TYPE_ENDPOINT,   /* bDescriptorType: Endpoint */
  327.   CDC_CMD_EP,                     /* bEndpointAddress */
  328.   0x03,                           /* bmAttributes: Interrupt */
  329.   LOBYTE(CDC_CMD_PACKET_SIZE),     /* wMaxPacketSize: */
  330.   HIBYTE(CDC_CMD_PACKET_SIZE),
  331.   CDC_FS_BINTERVAL,                           /* bInterval: */
  332.   /*---------------------------------------------------------------------------*/
  333.  
  334.   /*Data class interface descriptor*/
  335.   0x09,   /* bLength: Endpoint Descriptor size */
  336.   USB_DESC_TYPE_INTERFACE,  /* bDescriptorType: */
  337.   0x01,   /* bInterfaceNumber: Number of Interface */
  338.   0x00,   /* bAlternateSetting: Alternate setting */
  339.   0x02,   /* bNumEndpoints: Two endpoints used */
  340.   0x0A,   /* bInterfaceClass: CDC */
  341.   0x00,   /* bInterfaceSubClass: */
  342.   0x00,   /* bInterfaceProtocol: */
  343.   0x00,   /* iInterface: */
  344.  
  345.   /*Endpoint OUT Descriptor*/
  346.   0x07,   /* bLength: Endpoint Descriptor size */
  347.   USB_DESC_TYPE_ENDPOINT,      /* bDescriptorType: Endpoint */
  348.   CDC_OUT_EP,                        /* bEndpointAddress */
  349.   0x02,                              /* bmAttributes: Bulk */
  350.   LOBYTE(CDC_DATA_FS_MAX_PACKET_SIZE),  /* wMaxPacketSize: */
  351.   HIBYTE(CDC_DATA_FS_MAX_PACKET_SIZE),
  352.   0x00,                              /* bInterval: ignore for Bulk transfer */
  353.  
  354.   /*Endpoint IN Descriptor*/
  355.   0x07,   /* bLength: Endpoint Descriptor size */
  356.   USB_DESC_TYPE_ENDPOINT,      /* bDescriptorType: Endpoint */
  357.   CDC_IN_EP,                         /* bEndpointAddress */
  358.   0x02,                              /* bmAttributes: Bulk */
  359.   LOBYTE(CDC_DATA_FS_MAX_PACKET_SIZE),  /* wMaxPacketSize: */
  360.   HIBYTE(CDC_DATA_FS_MAX_PACKET_SIZE),
  361.   0x00                               /* bInterval: ignore for Bulk transfer */
  362. } ;
  363.  
  364. __ALIGN_BEGIN uint8_t USBD_CDC_OtherSpeedCfgDesc[USB_CDC_CONFIG_DESC_SIZ] __ALIGN_END =
  365. {
  366.   0x09,   /* bLength: Configuation Descriptor size */
  367.   USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION,
  368.   USB_CDC_CONFIG_DESC_SIZ,
  369.   0x00,
  370.   0x02,   /* bNumInterfaces: 2 interfaces */
  371.   0x01,   /* bConfigurationValue: */
  372.   0x04,   /* iConfiguration: */
  373.   0xC0,   /* bmAttributes: */
  374.   0x32,   /* MaxPower 100 mA */
  375.  
  376.   /*Interface Descriptor */
  377.   0x09,   /* bLength: Interface Descriptor size */
  378.   USB_DESC_TYPE_INTERFACE,  /* bDescriptorType: Interface */
  379.   /* Interface descriptor type */
  380.   0x00,   /* bInterfaceNumber: Number of Interface */
  381.   0x00,   /* bAlternateSetting: Alternate setting */
  382.   0x01,   /* bNumEndpoints: One endpoints used */
  383.   0x02,   /* bInterfaceClass: Communication Interface Class */
  384.   0x02,   /* bInterfaceSubClass: Abstract Control Model */
  385.   0x01,   /* bInterfaceProtocol: Common AT commands */
  386.   0x00,   /* iInterface: */
  387.  
  388.   /*Header Functional Descriptor*/
  389.   0x05,   /* bLength: Endpoint Descriptor size */
  390.   0x24,   /* bDescriptorType: CS_INTERFACE */
  391.   0x00,   /* bDescriptorSubtype: Header Func Desc */
  392.   0x10,   /* bcdCDC: spec release number */
  393.   0x01,
  394.  
  395.   /*Call Management Functional Descriptor*/
  396.   0x05,   /* bFunctionLength */
  397.   0x24,   /* bDescriptorType: CS_INTERFACE */
  398.   0x01,   /* bDescriptorSubtype: Call Management Func Desc */
  399.   0x00,   /* bmCapabilities: D0+D1 */
  400.   0x01,   /* bDataInterface: 1 */
  401.  
  402.   /*ACM Functional Descriptor*/
  403.   0x04,   /* bFunctionLength */
  404.   0x24,   /* bDescriptorType: CS_INTERFACE */
  405.   0x02,   /* bDescriptorSubtype: Abstract Control Management desc */
  406.   0x02,   /* bmCapabilities */
  407.  
  408.   /*Union Functional Descriptor*/
  409.   0x05,   /* bFunctionLength */
  410.   0x24,   /* bDescriptorType: CS_INTERFACE */
  411.   0x06,   /* bDescriptorSubtype: Union func desc */
  412.   0x00,   /* bMasterInterface: Communication class interface */
  413.   0x01,   /* bSlaveInterface0: Data Class Interface */
  414.  
  415.   /*Endpoint 2 Descriptor*/
  416.   0x07,                           /* bLength: Endpoint Descriptor size */
  417.   USB_DESC_TYPE_ENDPOINT,         /* bDescriptorType: Endpoint */
  418.   CDC_CMD_EP,                     /* bEndpointAddress */
  419.   0x03,                           /* bmAttributes: Interrupt */
  420.   LOBYTE(CDC_CMD_PACKET_SIZE),     /* wMaxPacketSize: */
  421.   HIBYTE(CDC_CMD_PACKET_SIZE),
  422.   CDC_FS_BINTERVAL,                           /* bInterval: */
  423.  
  424.   /*---------------------------------------------------------------------------*/
  425.  
  426.   /*Data class interface descriptor*/
  427.   0x09,   /* bLength: Endpoint Descriptor size */
  428.   USB_DESC_TYPE_INTERFACE,  /* bDescriptorType: */
  429.   0x01,   /* bInterfaceNumber: Number of Interface */
  430.   0x00,   /* bAlternateSetting: Alternate setting */
  431.   0x02,   /* bNumEndpoints: Two endpoints used */
  432.   0x0A,   /* bInterfaceClass: CDC */
  433.   0x00,   /* bInterfaceSubClass: */
  434.   0x00,   /* bInterfaceProtocol: */
  435.   0x00,   /* iInterface: */
  436.  
  437.   /*Endpoint OUT Descriptor*/
  438.   0x07,   /* bLength: Endpoint Descriptor size */
  439.   USB_DESC_TYPE_ENDPOINT,      /* bDescriptorType: Endpoint */
  440.   CDC_OUT_EP,                        /* bEndpointAddress */
  441.   0x02,                              /* bmAttributes: Bulk */
  442.   0x40,                              /* wMaxPacketSize: */
  443.   0x00,
  444.   0x00,                              /* bInterval: ignore for Bulk transfer */
  445.  
  446.   /*Endpoint IN Descriptor*/
  447.   0x07,   /* bLength: Endpoint Descriptor size */
  448.   USB_DESC_TYPE_ENDPOINT,     /* bDescriptorType: Endpoint */
  449.   CDC_IN_EP,                        /* bEndpointAddress */
  450.   0x02,                             /* bmAttributes: Bulk */
  451.   0x40,                             /* wMaxPacketSize: */
  452.   0x00,
  453.   0x00                              /* bInterval */
  454. };
  455.  
  456. /**
  457.   * @}
  458.   */
  459.  
  460. /** @defgroup USBD_CDC_Private_Functions
  461.   * @{
  462.   */
  463.  
  464. /**
  465.   * @brief  USBD_CDC_Init
  466.   *         Initialize the CDC interface
  467.   * @param  pdev: device instance
  468.   * @param  cfgidx: Configuration index
  469.   * @retval status
  470.   */
  471. static uint8_t  USBD_CDC_Init(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
  472. {
  473.   uint8_t ret = 0U;
  474.   USBD_CDC_HandleTypeDef   *hcdc;
  475.  
  476.   if (pdev->dev_speed == USBD_SPEED_HIGH)
  477.   {
  478.     /* Open EP IN */
  479.     USBD_LL_OpenEP(pdev, CDC_IN_EP, USBD_EP_TYPE_BULK,
  480.                    CDC_DATA_HS_IN_PACKET_SIZE);
  481.  
  482.     pdev->ep_in[CDC_IN_EP & 0xFU].is_used = 1U;
  483.  
  484.     /* Open EP OUT */
  485.     USBD_LL_OpenEP(pdev, CDC_OUT_EP, USBD_EP_TYPE_BULK,
  486.                    CDC_DATA_HS_OUT_PACKET_SIZE);
  487.  
  488.     pdev->ep_out[CDC_OUT_EP & 0xFU].is_used = 1U;
  489.  
  490.   }
  491.   else
  492.   {
  493.     /* Open EP IN */
  494.     USBD_LL_OpenEP(pdev, CDC_IN_EP, USBD_EP_TYPE_BULK,
  495.                    CDC_DATA_FS_IN_PACKET_SIZE);
  496.  
  497.     pdev->ep_in[CDC_IN_EP & 0xFU].is_used = 1U;
  498.  
  499.     /* Open EP OUT */
  500.     USBD_LL_OpenEP(pdev, CDC_OUT_EP, USBD_EP_TYPE_BULK,
  501.                    CDC_DATA_FS_OUT_PACKET_SIZE);
  502.  
  503.     pdev->ep_out[CDC_OUT_EP & 0xFU].is_used = 1U;
  504.   }
  505.   /* Open Command IN EP */
  506.   USBD_LL_OpenEP(pdev, CDC_CMD_EP, USBD_EP_TYPE_INTR, CDC_CMD_PACKET_SIZE);
  507.   pdev->ep_in[CDC_CMD_EP & 0xFU].is_used = 1U;
  508.  
  509.   pdev->pClassData = USBD_malloc(sizeof(USBD_CDC_HandleTypeDef));
  510.  
  511.   if (pdev->pClassData == NULL)
  512.   {
  513.     ret = 1U;
  514.   }
  515.   else
  516.   {
  517.     hcdc = (USBD_CDC_HandleTypeDef *) pdev->pClassData;
  518.  
  519.     /* Init  physical Interface components */
  520.     ((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Init();
  521.  
  522.     /* Init Xfer states */
  523.     hcdc->TxState = 0U;
  524.     hcdc->RxState = 0U;
  525.  
  526.     if (pdev->dev_speed == USBD_SPEED_HIGH)
  527.     {
  528.       /* Prepare Out endpoint to receive next packet */
  529.       USBD_LL_PrepareReceive(pdev, CDC_OUT_EP, hcdc->RxBuffer,
  530.                              CDC_DATA_HS_OUT_PACKET_SIZE);
  531.     }
  532.     else
  533.     {
  534.       /* Prepare Out endpoint to receive next packet */
  535.       USBD_LL_PrepareReceive(pdev, CDC_OUT_EP, hcdc->RxBuffer,
  536.                              CDC_DATA_FS_OUT_PACKET_SIZE);
  537.     }
  538.   }
  539.   return ret;
  540. }
  541.  
  542. /**
  543.   * @brief  USBD_CDC_Init
  544.   *         DeInitialize the CDC layer
  545.   * @param  pdev: device instance
  546.   * @param  cfgidx: Configuration index
  547.   * @retval status
  548.   */
  549. static uint8_t  USBD_CDC_DeInit(USBD_HandleTypeDef *pdev, uint8_t cfgidx)
  550. {
  551.   uint8_t ret = 0U;
  552.  
  553.   /* Close EP IN */
  554.   USBD_LL_CloseEP(pdev, CDC_IN_EP);
  555.   pdev->ep_in[CDC_IN_EP & 0xFU].is_used = 0U;
  556.  
  557.   /* Close EP OUT */
  558.   USBD_LL_CloseEP(pdev, CDC_OUT_EP);
  559.   pdev->ep_out[CDC_OUT_EP & 0xFU].is_used = 0U;
  560.  
  561.   /* Close Command IN EP */
  562.   USBD_LL_CloseEP(pdev, CDC_CMD_EP);
  563.   pdev->ep_in[CDC_CMD_EP & 0xFU].is_used = 0U;
  564.  
  565.   /* DeInit  physical Interface components */
  566.   if (pdev->pClassData != NULL)
  567.   {
  568.     ((USBD_CDC_ItfTypeDef *)pdev->pUserData)->DeInit();
  569.     USBD_free(pdev->pClassData);
  570.     pdev->pClassData = NULL;
  571.   }
  572.  
  573.   return ret;
  574. }
  575.  
  576. /**
  577.   * @brief  USBD_CDC_Setup
  578.   *         Handle the CDC specific requests
  579.   * @param  pdev: instance
  580.   * @param  req: usb requests
  581.   * @retval status
  582.   */
  583. static uint8_t  USBD_CDC_Setup(USBD_HandleTypeDef *pdev,
  584.                                USBD_SetupReqTypedef *req)
  585. {
  586.   USBD_CDC_HandleTypeDef   *hcdc = (USBD_CDC_HandleTypeDef *) pdev->pClassData;
  587.   uint8_t ifalt = 0U;
  588.   uint16_t status_info = 0U;
  589.   uint8_t ret = USBD_OK;
  590.  
  591.   switch (req->bmRequest & USB_REQ_TYPE_MASK)
  592.   {
  593.     case USB_REQ_TYPE_CLASS :
  594.       if (req->wLength)
  595.       {
  596.         if (req->bmRequest & 0x80U)
  597.         {
  598.           ((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Control(req->bRequest,
  599.                                                             (uint8_t *)(void *)hcdc->data,
  600.                                                             req->wLength);
  601.  
  602.           USBD_CtlSendData(pdev, (uint8_t *)(void *)hcdc->data, req->wLength);
  603.         }
  604.         else
  605.         {
  606.           hcdc->CmdOpCode = req->bRequest;
  607.           hcdc->CmdLength = (uint8_t)req->wLength;
  608.  
  609.           USBD_CtlPrepareRx(pdev, (uint8_t *)(void *)hcdc->data, req->wLength);
  610.         }
  611.       }
  612.       else
  613.       {
  614.         ((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Control(req->bRequest,
  615.                                                           (uint8_t *)(void *)req, 0U);
  616.       }
  617.       break;
  618.  
  619.     case USB_REQ_TYPE_STANDARD:
  620.       switch (req->bRequest)
  621.       {
  622.         case USB_REQ_GET_STATUS:
  623.           if (pdev->dev_state == USBD_STATE_CONFIGURED)
  624.           {
  625.             USBD_CtlSendData(pdev, (uint8_t *)(void *)&status_info, 2U);
  626.           }
  627.           else
  628.           {
  629.             USBD_CtlError(pdev, req);
  630.             ret = USBD_FAIL;
  631.           }
  632.           break;
  633.  
  634.         case USB_REQ_GET_INTERFACE:
  635.           if (pdev->dev_state == USBD_STATE_CONFIGURED)
  636.           {
  637.             USBD_CtlSendData(pdev, &ifalt, 1U);
  638.           }
  639.           else
  640.           {
  641.             USBD_CtlError(pdev, req);
  642.             ret = USBD_FAIL;
  643.           }
  644.           break;
  645.  
  646.         case USB_REQ_SET_INTERFACE:
  647.           if (pdev->dev_state != USBD_STATE_CONFIGURED)
  648.           {
  649.             USBD_CtlError(pdev, req);
  650.             ret = USBD_FAIL;
  651.           }
  652.           break;
  653.  
  654.         default:
  655.           USBD_CtlError(pdev, req);
  656.           ret = USBD_FAIL;
  657.           break;
  658.       }
  659.       break;
  660.  
  661.     default:
  662.       USBD_CtlError(pdev, req);
  663.       ret = USBD_FAIL;
  664.       break;
  665.   }
  666.  
  667.   return ret;
  668. }
  669.  
  670. /**
  671.   * @brief  USBD_CDC_DataIn
  672.   *         Data sent on non-control IN endpoint
  673.   * @param  pdev: device instance
  674.   * @param  epnum: endpoint number
  675.   * @retval status
  676.   */
  677. static uint8_t  USBD_CDC_DataIn(USBD_HandleTypeDef *pdev, uint8_t epnum)
  678. {
  679.   USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef *)pdev->pClassData;
  680.   PCD_HandleTypeDef *hpcd = pdev->pData;
  681.  
  682.   if (pdev->pClassData != NULL)
  683.   {
  684.     if ((pdev->ep_in[epnum].total_length > 0U) && ((pdev->ep_in[epnum].total_length % hpcd->IN_ep[epnum].maxpacket) == 0U))
  685.     {
  686.       /* Update the packet total length */
  687.       pdev->ep_in[epnum].total_length = 0U;
  688.  
  689.       /* Send ZLP */
  690.       USBD_LL_Transmit(pdev, epnum, NULL, 0U);
  691.     }
  692.     else
  693.     {
  694.       hcdc->TxState = 0U;
  695.     }
  696.     return USBD_OK;
  697.   }
  698.   else
  699.   {
  700.     return USBD_FAIL;
  701.   }
  702. }
  703.  
  704. /**
  705.   * @brief  USBD_CDC_DataOut
  706.   *         Data received on non-control Out endpoint
  707.   * @param  pdev: device instance
  708.   * @param  epnum: endpoint number
  709.   * @retval status
  710.   */
  711. static uint8_t  USBD_CDC_DataOut(USBD_HandleTypeDef *pdev, uint8_t epnum)
  712. {
  713.   USBD_CDC_HandleTypeDef   *hcdc = (USBD_CDC_HandleTypeDef *) pdev->pClassData;
  714.  
  715.   /* Get the received data length */
  716.   hcdc->RxLength = USBD_LL_GetRxDataSize(pdev, epnum);
  717.  
  718.   /* USB data will be immediately processed, this allow next USB traffic being
  719.   NAKed till the end of the application Xfer */
  720.   if (pdev->pClassData != NULL)
  721.   {
  722.     ((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Receive(hcdc->RxBuffer, &hcdc->RxLength);
  723.  
  724.     return USBD_OK;
  725.   }
  726.   else
  727.   {
  728.     return USBD_FAIL;
  729.   }
  730. }
  731.  
  732. /**
  733.   * @brief  USBD_CDC_EP0_RxReady
  734.   *         Handle EP0 Rx Ready event
  735.   * @param  pdev: device instance
  736.   * @retval status
  737.   */
  738. static uint8_t  USBD_CDC_EP0_RxReady(USBD_HandleTypeDef *pdev)
  739. {
  740.   USBD_CDC_HandleTypeDef   *hcdc = (USBD_CDC_HandleTypeDef *) pdev->pClassData;
  741.  
  742.   if ((pdev->pUserData != NULL) && (hcdc->CmdOpCode != 0xFFU))
  743.   {
  744.     ((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Control(hcdc->CmdOpCode,
  745.                                                       (uint8_t *)(void *)hcdc->data,
  746.                                                       (uint16_t)hcdc->CmdLength);
  747.     hcdc->CmdOpCode = 0xFFU;
  748.  
  749.   }
  750.   return USBD_OK;
  751. }
  752.  
  753. /**
  754.   * @brief  USBD_CDC_GetFSCfgDesc
  755.   *         Return configuration descriptor
  756.   * @param  speed : current device speed
  757.   * @param  length : pointer data length
  758.   * @retval pointer to descriptor buffer
  759.   */
  760. static uint8_t  *USBD_CDC_GetFSCfgDesc(uint16_t *length)
  761. {
  762.   *length = sizeof(USBD_CDC_CfgFSDesc);
  763.   return USBD_CDC_CfgFSDesc;
  764. }
  765.  
  766. /**
  767.   * @brief  USBD_CDC_GetHSCfgDesc
  768.   *         Return configuration descriptor
  769.   * @param  speed : current device speed
  770.   * @param  length : pointer data length
  771.   * @retval pointer to descriptor buffer
  772.   */
  773. static uint8_t  *USBD_CDC_GetHSCfgDesc(uint16_t *length)
  774. {
  775.   *length = sizeof(USBD_CDC_CfgHSDesc);
  776.   return USBD_CDC_CfgHSDesc;
  777. }
  778.  
  779. /**
  780.   * @brief  USBD_CDC_GetCfgDesc
  781.   *         Return configuration descriptor
  782.   * @param  speed : current device speed
  783.   * @param  length : pointer data length
  784.   * @retval pointer to descriptor buffer
  785.   */
  786. static uint8_t  *USBD_CDC_GetOtherSpeedCfgDesc(uint16_t *length)
  787. {
  788.   *length = sizeof(USBD_CDC_OtherSpeedCfgDesc);
  789.   return USBD_CDC_OtherSpeedCfgDesc;
  790. }
  791.  
  792. /**
  793. * @brief  DeviceQualifierDescriptor
  794. *         return Device Qualifier descriptor
  795. * @param  length : pointer data length
  796. * @retval pointer to descriptor buffer
  797. */
  798. uint8_t  *USBD_CDC_GetDeviceQualifierDescriptor(uint16_t *length)
  799. {
  800.   *length = sizeof(USBD_CDC_DeviceQualifierDesc);
  801.   return USBD_CDC_DeviceQualifierDesc;
  802. }
  803.  
  804. /**
  805. * @brief  USBD_CDC_RegisterInterface
  806.   * @param  pdev: device instance
  807.   * @param  fops: CD  Interface callback
  808.   * @retval status
  809.   */
  810. uint8_t  USBD_CDC_RegisterInterface(USBD_HandleTypeDef   *pdev,
  811.                                     USBD_CDC_ItfTypeDef *fops)
  812. {
  813.   uint8_t  ret = USBD_FAIL;
  814.  
  815.   if (fops != NULL)
  816.   {
  817.     pdev->pUserData = fops;
  818.     ret = USBD_OK;
  819.   }
  820.  
  821.   return ret;
  822. }
  823.  
  824. /**
  825.   * @brief  USBD_CDC_SetTxBuffer
  826.   * @param  pdev: device instance
  827.   * @param  pbuff: Tx Buffer
  828.   * @retval status
  829.   */
  830. uint8_t  USBD_CDC_SetTxBuffer(USBD_HandleTypeDef   *pdev,
  831.                               uint8_t  *pbuff,
  832.                               uint16_t length)
  833. {
  834.   USBD_CDC_HandleTypeDef   *hcdc = (USBD_CDC_HandleTypeDef *) pdev->pClassData;
  835.  
  836.   hcdc->TxBuffer = pbuff;
  837.   hcdc->TxLength = length;
  838.  
  839.   return USBD_OK;
  840. }
  841.  
  842.  
  843. /**
  844.   * @brief  USBD_CDC_SetRxBuffer
  845.   * @param  pdev: device instance
  846.   * @param  pbuff: Rx Buffer
  847.   * @retval status
  848.   */
  849. uint8_t  USBD_CDC_SetRxBuffer(USBD_HandleTypeDef   *pdev,
  850.                               uint8_t  *pbuff)
  851. {
  852.   USBD_CDC_HandleTypeDef   *hcdc = (USBD_CDC_HandleTypeDef *) pdev->pClassData;
  853.  
  854.   hcdc->RxBuffer = pbuff;
  855.  
  856.   return USBD_OK;
  857. }
  858.  
  859. /**
  860.   * @brief  USBD_CDC_TransmitPacket
  861.   *         Transmit packet on IN endpoint
  862.   * @param  pdev: device instance
  863.   * @retval status
  864.   */
  865. uint8_t  USBD_CDC_TransmitPacket(USBD_HandleTypeDef *pdev)
  866. {
  867.   USBD_CDC_HandleTypeDef   *hcdc = (USBD_CDC_HandleTypeDef *) pdev->pClassData;
  868.  
  869.   if (pdev->pClassData != NULL)
  870.   {
  871.     if (hcdc->TxState == 0U)
  872.     {
  873.       /* Tx Transfer in progress */
  874.       hcdc->TxState = 1U;
  875.  
  876.       /* Update the packet total length */
  877.       pdev->ep_in[CDC_IN_EP & 0xFU].total_length = hcdc->TxLength;
  878.  
  879.       /* Transmit next packet */
  880.       USBD_LL_Transmit(pdev, CDC_IN_EP, hcdc->TxBuffer,
  881.                        (uint16_t)hcdc->TxLength);
  882.  
  883.       return USBD_OK;
  884.     }
  885.     else
  886.     {
  887.       return USBD_BUSY;
  888.     }
  889.   }
  890.   else
  891.   {
  892.     return USBD_FAIL;
  893.   }
  894. }
  895.  
  896.  
  897. /**
  898.   * @brief  USBD_CDC_ReceivePacket
  899.   *         prepare OUT Endpoint for reception
  900.   * @param  pdev: device instance
  901.   * @retval status
  902.   */
  903. uint8_t  USBD_CDC_ReceivePacket(USBD_HandleTypeDef *pdev)
  904. {
  905.   USBD_CDC_HandleTypeDef   *hcdc = (USBD_CDC_HandleTypeDef *) pdev->pClassData;
  906.  
  907.   /* Suspend or Resume USB Out process */
  908.   if (pdev->pClassData != NULL)
  909.   {
  910.     if (pdev->dev_speed == USBD_SPEED_HIGH)
  911.     {
  912.       /* Prepare Out endpoint to receive next packet */
  913.       USBD_LL_PrepareReceive(pdev,
  914.                              CDC_OUT_EP,
  915.                              hcdc->RxBuffer,
  916.                              CDC_DATA_HS_OUT_PACKET_SIZE);
  917.     }
  918.     else
  919.     {
  920.       /* Prepare Out endpoint to receive next packet */
  921.       USBD_LL_PrepareReceive(pdev,
  922.                              CDC_OUT_EP,
  923.                              hcdc->RxBuffer,
  924.                              CDC_DATA_FS_OUT_PACKET_SIZE);
  925.     }
  926.     return USBD_OK;
  927.   }
  928.   else
  929.   {
  930.     return USBD_FAIL;
  931.   }
  932. }
  933. /**
  934.   * @}
  935.   */
  936.  
  937. /**
  938.   * @}
  939.   */
  940.  
  941. /**
  942.   * @}
  943.   */
  944.  
  945. /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
  946.