mirror of
https://gitlab.com/hyperglitch/jellyfish.git
synced 2026-01-02 16:21:55 +00:00
1885 lines
74 KiB
C
1885 lines
74 KiB
C
/**
|
|
******************************************************************************
|
|
* @file usbd_composite_builder.c
|
|
* @author MCD Application Team
|
|
* @brief This file provides all the composite builder functions.
|
|
******************************************************************************
|
|
* @attention
|
|
*
|
|
* Copyright (c) 2021 STMicroelectronics.
|
|
* All rights reserved.
|
|
*
|
|
* This software is licensed under terms that can be found in the LICENSE file
|
|
* in the root directory of this software component.
|
|
* If no LICENSE file comes with this software, it is provided AS-IS.
|
|
*
|
|
******************************************************************************
|
|
* @verbatim
|
|
*
|
|
* ===================================================================
|
|
* Composite Builder Description
|
|
* ===================================================================
|
|
*
|
|
* The composite builder builds the configuration descriptors based on
|
|
* the selection of classes by user.
|
|
* It includes all USB Device classes in order to instantiate their
|
|
* descriptors, but for better management, it is possible to optimize
|
|
* footprint by removing unused classes. It is possible to do so by
|
|
* commenting the relative define in usbd_conf.h.
|
|
*
|
|
* @endverbatim
|
|
*
|
|
******************************************************************************
|
|
*/
|
|
|
|
/* BSPDependencies
|
|
- None
|
|
EndBSPDependencies */
|
|
|
|
/* Includes ------------------------------------------------------------------*/
|
|
#include "usbd_composite_builder.h"
|
|
|
|
#ifdef USE_USBD_COMPOSITE
|
|
|
|
/** @addtogroup STM32_USB_DEVICE_LIBRARY
|
|
* @{
|
|
*/
|
|
|
|
|
|
/** @defgroup CMPSIT_CORE
|
|
* @brief Mass storage core module
|
|
* @{
|
|
*/
|
|
|
|
/** @defgroup CMPSIT_CORE_Private_TypesDefinitions
|
|
* @{
|
|
*/
|
|
/**
|
|
* @}
|
|
*/
|
|
|
|
|
|
/** @defgroup CMPSIT_CORE_Private_Defines
|
|
* @{
|
|
*/
|
|
|
|
/**
|
|
* @}
|
|
*/
|
|
|
|
|
|
/** @defgroup CMPSIT_CORE_Private_Macros
|
|
* @{
|
|
*/
|
|
/**
|
|
* @}
|
|
*/
|
|
|
|
|
|
/** @defgroup CMPSIT_CORE_Private_FunctionPrototypes
|
|
* @{
|
|
*/
|
|
/* uint8_t USBD_CMPSIT_Init (USBD_HandleTypeDef *pdev,
|
|
uint8_t cfgidx); */ /* Function not used for the moment */
|
|
|
|
/* uint8_t USBD_CMPSIT_DeInit (USBD_HandleTypeDef *pdev,
|
|
uint8_t cfgidx); */ /* Function not used for the moment */
|
|
|
|
uint8_t *USBD_CMPSIT_GetFSCfgDesc(uint16_t *length);
|
|
#ifdef USE_USB_HS
|
|
uint8_t *USBD_CMPSIT_GetHSCfgDesc(uint16_t *length);
|
|
#endif /* USE_USB_HS */
|
|
|
|
uint8_t *USBD_CMPSIT_GetOtherSpeedCfgDesc(uint16_t *length);
|
|
|
|
uint8_t *USBD_CMPSIT_GetDeviceQualifierDescriptor(uint16_t *length);
|
|
|
|
static uint8_t USBD_CMPSIT_FindFreeIFNbr(USBD_HandleTypeDef *pdev);
|
|
|
|
static void USBD_CMPSIT_AddConfDesc(uint32_t Conf, __IO uint32_t *pSze);
|
|
|
|
static void USBD_CMPSIT_AssignEp(USBD_HandleTypeDef *pdev, uint8_t Add, uint8_t Type, uint32_t Sze);
|
|
|
|
|
|
#if USBD_CMPSIT_ACTIVATE_HID == 1U
|
|
static void USBD_CMPSIT_HIDMouseDesc(USBD_HandleTypeDef *pdev, uint32_t pConf, __IO uint32_t *Sze, uint8_t speed);
|
|
#endif /* USBD_CMPSIT_ACTIVATE_HID == 1U */
|
|
|
|
#if USBD_CMPSIT_ACTIVATE_BULK == 1U
|
|
static void USBD_CMPSIT_BULKDesc(USBD_HandleTypeDef *pdev, uint32_t pConf, __IO uint32_t *Sze, uint8_t speed);
|
|
#endif /* USBD_CMPSIT_ACTIVATE_BULK == 1U */
|
|
|
|
#if USBD_CMPSIT_ACTIVATE_CDC == 1U
|
|
static void USBD_CMPSIT_CDCDesc(USBD_HandleTypeDef *pdev, uint32_t pConf, __IO uint32_t *Sze, uint8_t speed);
|
|
#endif /* USBD_CMPSIT_ACTIVATE_CDC == 1U */
|
|
|
|
#if USBD_CMPSIT_ACTIVATE_DFU == 1U
|
|
static void USBD_CMPSIT_DFUDesc(USBD_HandleTypeDef *pdev, uint32_t pConf, __IO uint32_t *Sze, uint8_t speed);
|
|
#endif /* USBD_CMPSIT_ACTIVATE_DFU == 1U */
|
|
|
|
#if USBD_CMPSIT_ACTIVATE_RNDIS == 1U
|
|
static void USBD_CMPSIT_RNDISDesc(USBD_HandleTypeDef *pdev, uint32_t pConf, __IO uint32_t *Sze, uint8_t speed);
|
|
#endif /* USBD_CMPSIT_ACTIVATE_RNDIS == 1U */
|
|
|
|
#if USBD_CMPSIT_ACTIVATE_CDC_ECM == 1U
|
|
static void USBD_CMPSIT_CDC_ECMDesc(USBD_HandleTypeDef *pdev, uint32_t pConf, __IO uint32_t *Sze, uint8_t speed);
|
|
#endif /* USBD_CMPSIT_ACTIVATE_CDC_ECM == 1U */
|
|
|
|
#if USBD_CMPSIT_ACTIVATE_AUDIO == 1U
|
|
static void USBD_CMPSIT_AUDIODesc(USBD_HandleTypeDef *pdev, uint32_t pConf, __IO uint32_t *Sze, uint8_t speed);
|
|
#endif /* USBD_CMPSIT_ACTIVATE_AUDIO == 1U */
|
|
|
|
#if USBD_CMPSIT_ACTIVATE_CUSTOMHID == 1
|
|
static void USBD_CMPSIT_CUSTOMHIDDesc(USBD_HandleTypeDef *pdev, uint32_t pConf, __IO uint32_t *Sze, uint8_t speed);
|
|
#endif /* USBD_CMPSIT_ACTIVATE_CUSTOMHID == 1U */
|
|
|
|
#if USBD_CMPSIT_ACTIVATE_VIDEO == 1U
|
|
static void USBD_CMPSIT_VIDEODesc(USBD_HandleTypeDef *pdev, uint32_t pConf, __IO uint32_t *Sze, uint8_t speed);
|
|
#endif /* USBD_CMPSIT_ACTIVATE_VIDEO == 1U */
|
|
|
|
#if USBD_CMPSIT_ACTIVATE_PRINTER == 1U
|
|
static void USBD_CMPSIT_PRNTDesc(USBD_HandleTypeDef *pdev, uint32_t pConf, __IO uint32_t *Sze, uint8_t speed);
|
|
#endif /* USBD_CMPSIT_ACTIVATE_PRINTER == 1U */
|
|
|
|
#if USBD_CMPSIT_ACTIVATE_CCID == 1U
|
|
static void USBD_CMPSIT_CCIDDesc(USBD_HandleTypeDef *pdev, uint32_t pConf, __IO uint32_t *Sze, uint8_t speed);
|
|
#endif /* USBD_CMPSIT_ACTIVATE_CCID == 1U */
|
|
|
|
#if USBD_CMPSIT_ACTIVATE_MTP == 1U
|
|
static void USBD_CMPSIT_MTPDesc(USBD_HandleTypeDef *pdev, uint32_t pConf, __IO uint32_t *Sze, uint8_t speed);
|
|
#endif /* USBD_CMPSIT_ACTIVATE_MTP == 1U */
|
|
|
|
/**
|
|
* @}
|
|
*/
|
|
|
|
|
|
/** @defgroup CMPSIT_CORE_Private_Variables
|
|
* @{
|
|
*/
|
|
/* This structure is used only for the Configuration descriptors and Device Qualifier */
|
|
USBD_ClassTypeDef USBD_CMPSIT =
|
|
{
|
|
NULL, /* Init, */
|
|
NULL, /* DeInit, */
|
|
NULL, /* Setup, */
|
|
NULL, /* EP0_TxSent, */
|
|
NULL, /* EP0_RxReady, */
|
|
NULL, /* DataIn, */
|
|
NULL, /* DataOut, */
|
|
NULL, /* SOF, */
|
|
NULL,
|
|
NULL,
|
|
#ifdef USE_USB_HS
|
|
USBD_CMPSIT_GetHSCfgDesc,
|
|
#else
|
|
NULL,
|
|
#endif /* USE_USB_HS */
|
|
USBD_CMPSIT_GetFSCfgDesc,
|
|
USBD_CMPSIT_GetOtherSpeedCfgDesc,
|
|
USBD_CMPSIT_GetDeviceQualifierDescriptor,
|
|
#if (USBD_SUPPORT_USER_STRING_DESC == 1U)
|
|
NULL,
|
|
#endif /* USBD_SUPPORT_USER_STRING_DESC */
|
|
};
|
|
|
|
/* The generic configuration descriptor buffer that will be filled by builder
|
|
Size of the buffer is the maximum possible configuration descriptor size. */
|
|
__ALIGN_BEGIN static uint8_t USBD_CMPSIT_FSCfgDesc[USBD_CMPST_MAX_CONFDESC_SZ] __ALIGN_END = {0};
|
|
static uint8_t *pCmpstFSConfDesc = USBD_CMPSIT_FSCfgDesc;
|
|
/* Variable that dynamically holds the current size of the configuration descriptor */
|
|
static __IO uint32_t CurrFSConfDescSz = 0U;
|
|
|
|
#ifdef USE_USB_HS
|
|
__ALIGN_BEGIN static uint8_t USBD_CMPSIT_HSCfgDesc[USBD_CMPST_MAX_CONFDESC_SZ] __ALIGN_END = {0};
|
|
static uint8_t *pCmpstHSConfDesc = USBD_CMPSIT_HSCfgDesc;
|
|
/* Variable that dynamically holds the current size of the configuration descriptor */
|
|
static __IO uint32_t CurrHSConfDescSz = 0U;
|
|
#endif /* USE_USB_HS */
|
|
|
|
/* USB Standard Device Descriptor */
|
|
__ALIGN_BEGIN static uint8_t USBD_CMPSIT_DeviceQualifierDesc[USB_LEN_DEV_QUALIFIER_DESC] __ALIGN_END =
|
|
{
|
|
USB_LEN_DEV_QUALIFIER_DESC, /* bLength */
|
|
USB_DESC_TYPE_DEVICE_QUALIFIER, /* bDescriptorType */
|
|
0x00, /* bcdDevice low */
|
|
0x02, /* bcdDevice high */
|
|
0xEF, /* Class */
|
|
0x02, /* SubClass */
|
|
0x01, /* Protocol */
|
|
0x40, /* bMaxPacketSize0 */
|
|
0x01, /* bNumConfigurations */
|
|
0x00, /* bReserved */
|
|
};
|
|
|
|
/**
|
|
* @}
|
|
*/
|
|
|
|
|
|
/** @defgroup CMPSIT_CORE_Private_Functions
|
|
* @{
|
|
*/
|
|
|
|
/**
|
|
* @brief USBD_CMPSIT_AddClass
|
|
* Register a class in the class builder
|
|
* @param pdev: device instance
|
|
* @param pclass: pointer to the class structure to be added
|
|
* @param class: type of the class to be added (from USBD_CompositeClassTypeDef)
|
|
* @param cfgidx: configuration index
|
|
* @retval status
|
|
*/
|
|
uint8_t USBD_CMPSIT_AddClass(USBD_HandleTypeDef *pdev,
|
|
USBD_ClassTypeDef *pclass,
|
|
USBD_CompositeClassTypeDef class,
|
|
uint8_t cfgidx)
|
|
{
|
|
if ((pdev->classId < USBD_MAX_SUPPORTED_CLASS) && (pdev->tclasslist[pdev->classId].Active == 0U))
|
|
{
|
|
/* Store the class parameters in the global tab */
|
|
pdev->pClass[pdev->classId] = pclass;
|
|
pdev->tclasslist[pdev->classId].ClassId = pdev->classId;
|
|
pdev->tclasslist[pdev->classId].Active = 1U;
|
|
pdev->tclasslist[pdev->classId].ClassType = class;
|
|
|
|
/* Call configuration descriptor builder and endpoint configuration builder */
|
|
if (USBD_CMPSIT_AddToConfDesc(pdev) != (uint8_t)USBD_OK)
|
|
{
|
|
return (uint8_t)USBD_FAIL;
|
|
}
|
|
}
|
|
|
|
UNUSED(cfgidx);
|
|
|
|
return (uint8_t)USBD_OK;
|
|
}
|
|
|
|
|
|
/**
|
|
* @brief USBD_CMPSIT_AddToConfDesc
|
|
* Add a new class to the configuration descriptor
|
|
* @param pdev: device instance
|
|
* @retval status
|
|
*/
|
|
uint8_t USBD_CMPSIT_AddToConfDesc(USBD_HandleTypeDef *pdev)
|
|
{
|
|
uint8_t idxIf = 0U;
|
|
uint8_t iEp = 0U;
|
|
|
|
/* For the first class instance, start building the config descriptor common part */
|
|
if (pdev->classId == 0U)
|
|
{
|
|
/* Add configuration and IAD descriptors */
|
|
USBD_CMPSIT_AddConfDesc((uint32_t)pCmpstFSConfDesc, &CurrFSConfDescSz);
|
|
#ifdef USE_USB_HS
|
|
USBD_CMPSIT_AddConfDesc((uint32_t)pCmpstHSConfDesc, &CurrHSConfDescSz);
|
|
#endif /* USE_USB_HS */
|
|
}
|
|
|
|
switch (pdev->tclasslist[pdev->classId].ClassType)
|
|
{
|
|
#if USBD_CMPSIT_ACTIVATE_HID == 1
|
|
case CLASS_TYPE_HID:
|
|
/* Setup Max packet sizes (for HID, no dependency on USB Speed, both HS/FS have same packet size) */
|
|
pdev->tclasslist[pdev->classId].CurrPcktSze = HID_EPIN_SIZE;
|
|
|
|
/* Find the first available interface slot and Assign number of interfaces */
|
|
idxIf = USBD_CMPSIT_FindFreeIFNbr(pdev);
|
|
pdev->tclasslist[pdev->classId].NumIf = 1U;
|
|
pdev->tclasslist[pdev->classId].Ifs[0] = idxIf;
|
|
|
|
/* Assign endpoint numbers */
|
|
pdev->tclasslist[pdev->classId].NumEps = 1U; /* EP1_IN */
|
|
|
|
/* Set IN endpoint slot */
|
|
iEp = pdev->tclasslist[pdev->classId].EpAdd[0];
|
|
|
|
/* Assign IN Endpoint */
|
|
USBD_CMPSIT_AssignEp(pdev, iEp, USBD_EP_TYPE_INTR, pdev->tclasslist[pdev->classId].CurrPcktSze);
|
|
|
|
/* Configure and Append the Descriptor */
|
|
USBD_CMPSIT_HIDMouseDesc(pdev, (uint32_t)pCmpstFSConfDesc, &CurrFSConfDescSz, (uint8_t)USBD_SPEED_FULL);
|
|
|
|
#ifdef USE_USB_HS
|
|
USBD_CMPSIT_HIDMouseDesc(pdev, (uint32_t)pCmpstHSConfDesc, &CurrHSConfDescSz, (uint8_t)USBD_SPEED_HIGH);
|
|
#endif /* USE_USB_HS */
|
|
|
|
break;
|
|
#endif /* USBD_CMPSIT_ACTIVATE_HID */
|
|
|
|
#if USBD_CMPSIT_ACTIVATE_BULK == 1
|
|
case 3:
|
|
/* Setup default Max packet size */
|
|
pdev->tclasslist[pdev->classId].CurrPcktSze = BULK_MAX_FS_PACKET;
|
|
|
|
/* Find the first available interface slot and Assign number of interfaces */
|
|
idxIf = USBD_CMPSIT_FindFreeIFNbr(pdev);
|
|
pdev->tclasslist[pdev->classId].NumIf = 1U;
|
|
pdev->tclasslist[pdev->classId].Ifs[0] = idxIf;
|
|
|
|
/* Assign endpoint numbers */
|
|
pdev->tclasslist[pdev->classId].NumEps = 2U; /* EP1_IN, EP1_OUT */
|
|
|
|
/* Set IN endpoint slot */
|
|
iEp = pdev->tclasslist[pdev->classId].EpAdd[0];
|
|
USBD_CMPSIT_AssignEp(pdev, iEp, USBD_EP_TYPE_BULK, pdev->tclasslist[pdev->classId].CurrPcktSze);
|
|
|
|
/* Set OUT endpoint slot */
|
|
iEp = pdev->tclasslist[pdev->classId].EpAdd[1];
|
|
USBD_CMPSIT_AssignEp(pdev, iEp, USBD_EP_TYPE_BULK, pdev->tclasslist[pdev->classId].CurrPcktSze);
|
|
|
|
/* Configure and Append the Descriptor */
|
|
USBD_CMPSIT_BULKDesc(pdev, (uint32_t)pCmpstFSConfDesc, &CurrFSConfDescSz, (uint8_t)USBD_SPEED_FULL);
|
|
|
|
#ifdef USE_USB_HS
|
|
USBD_CMPSIT_BULKDesc(pdev, (uint32_t)pCmpstHSConfDesc, &CurrHSConfDescSz, (uint8_t)USBD_SPEED_HIGH);
|
|
#endif /* USE_USB_HS */
|
|
|
|
break;
|
|
#endif /* USBD_CMPSIT_ACTIVATE_BULK */
|
|
|
|
#if USBD_CMPSIT_ACTIVATE_CDC == 1
|
|
case CLASS_TYPE_CDC:
|
|
/* Setup default Max packet size for FS device */
|
|
pdev->tclasslist[pdev->classId].CurrPcktSze = CDC_DATA_FS_MAX_PACKET_SIZE;
|
|
|
|
/* Find the first available interface slot and Assign number of interfaces */
|
|
idxIf = USBD_CMPSIT_FindFreeIFNbr(pdev);
|
|
pdev->tclasslist[pdev->classId].NumIf = 2U;
|
|
pdev->tclasslist[pdev->classId].Ifs[0] = idxIf;
|
|
pdev->tclasslist[pdev->classId].Ifs[1] = (uint8_t)(idxIf + 1U);
|
|
|
|
/* Assign endpoint numbers */
|
|
pdev->tclasslist[pdev->classId].NumEps = 3U;
|
|
|
|
/* Set IN endpoint slot */
|
|
iEp = pdev->tclasslist[pdev->classId].EpAdd[0];
|
|
USBD_CMPSIT_AssignEp(pdev, iEp, USBD_EP_TYPE_BULK, pdev->tclasslist[pdev->classId].CurrPcktSze);
|
|
|
|
/* Set OUT endpoint slot */
|
|
iEp = pdev->tclasslist[pdev->classId].EpAdd[1];
|
|
USBD_CMPSIT_AssignEp(pdev, iEp, USBD_EP_TYPE_BULK, pdev->tclasslist[pdev->classId].CurrPcktSze);
|
|
|
|
/* Set the second IN endpoint slot */
|
|
iEp = pdev->tclasslist[pdev->classId].EpAdd[2];
|
|
USBD_CMPSIT_AssignEp(pdev, iEp, USBD_EP_TYPE_INTR, CDC_CMD_PACKET_SIZE);
|
|
|
|
/* Configure and Append the Descriptor */
|
|
USBD_CMPSIT_CDCDesc(pdev, (uint32_t)pCmpstFSConfDesc, &CurrFSConfDescSz, (uint8_t)USBD_SPEED_FULL);
|
|
|
|
#ifdef USE_USB_HS
|
|
USBD_CMPSIT_CDCDesc(pdev, (uint32_t)pCmpstHSConfDesc, &CurrHSConfDescSz, (uint8_t)USBD_SPEED_HIGH);
|
|
#endif /* USE_USB_HS */
|
|
|
|
break;
|
|
#endif /* USBD_CMPSIT_ACTIVATE_CDC */
|
|
|
|
#if USBD_CMPSIT_ACTIVATE_DFU == 1
|
|
case CLASS_TYPE_DFU:
|
|
/* Setup Max packet sizes (for DFU, no dependency on USB Speed, both HS/FS have same packet size) */
|
|
pdev->tclasslist[pdev->classId].CurrPcktSze = 64U;
|
|
|
|
/* Find the first available interface slot and Assign number of interfaces */
|
|
idxIf = USBD_CMPSIT_FindFreeIFNbr(pdev);
|
|
pdev->tclasslist[pdev->classId].NumIf = 1U;
|
|
pdev->tclasslist[pdev->classId].Ifs[0] = idxIf;
|
|
|
|
/* Assign endpoint numbers */
|
|
pdev->tclasslist[pdev->classId].NumEps = 0U; /* only EP0 is used */
|
|
|
|
/* Configure and Append the Descriptor */
|
|
USBD_CMPSIT_DFUDesc(pdev, (uint32_t)pCmpstFSConfDesc, &CurrFSConfDescSz, (uint8_t)USBD_SPEED_FULL);
|
|
|
|
#ifdef USE_USB_HS
|
|
USBD_CMPSIT_DFUDesc(pdev, (uint32_t)pCmpstHSConfDesc, &CurrHSConfDescSz, (uint8_t)USBD_SPEED_HIGH);
|
|
#endif /* USE_USB_HS */
|
|
|
|
break;
|
|
#endif /* USBD_CMPSIT_ACTIVATE_DFU */
|
|
|
|
#if USBD_CMPSIT_ACTIVATE_RNDIS == 1
|
|
case CLASS_TYPE_RNDIS:
|
|
/* Setup default Max packet size */
|
|
pdev->tclasslist[pdev->classId].CurrPcktSze = CDC_RNDIS_DATA_FS_MAX_PACKET_SIZE;
|
|
|
|
/* Find the first available interface slot and Assign number of interfaces */
|
|
idxIf = USBD_CMPSIT_FindFreeIFNbr(pdev);
|
|
pdev->tclasslist[pdev->classId].NumIf = 2U;
|
|
pdev->tclasslist[pdev->classId].Ifs[0] = idxIf;
|
|
pdev->tclasslist[pdev->classId].Ifs[1] = (uint8_t)(idxIf + 1U);
|
|
|
|
/* Assign endpoint numbers */
|
|
pdev->tclasslist[pdev->classId].NumEps = 3U;
|
|
|
|
/* Set IN endpoint slot */
|
|
iEp = pdev->tclasslist[pdev->classId].EpAdd[0];
|
|
USBD_CMPSIT_AssignEp(pdev, iEp, USBD_EP_TYPE_BULK, pdev->tclasslist[pdev->classId].CurrPcktSze);
|
|
|
|
/* Set OUT endpoint slot */
|
|
iEp = pdev->tclasslist[pdev->classId].EpAdd[1];
|
|
USBD_CMPSIT_AssignEp(pdev, iEp, USBD_EP_TYPE_BULK, pdev->tclasslist[pdev->classId].CurrPcktSze);
|
|
|
|
/* Set the second IN endpoint slot */
|
|
iEp = pdev->tclasslist[pdev->classId].EpAdd[2];
|
|
USBD_CMPSIT_AssignEp(pdev, iEp, USBD_EP_TYPE_INTR, CDC_RNDIS_CMD_PACKET_SIZE);
|
|
|
|
/* Configure and Append the Descriptor */
|
|
USBD_CMPSIT_RNDISDesc(pdev, (uint32_t)pCmpstFSConfDesc, &CurrFSConfDescSz, (uint8_t)USBD_SPEED_FULL);
|
|
|
|
#ifdef USE_USB_HS
|
|
USBD_CMPSIT_RNDISDesc(pdev, (uint32_t)pCmpstHSConfDesc, &CurrHSConfDescSz, (uint8_t)USBD_SPEED_HIGH);
|
|
#endif /* USE_USB_HS */
|
|
|
|
break;
|
|
#endif /* USBD_CMPSIT_ACTIVATE_RNDIS */
|
|
|
|
#if USBD_CMPSIT_ACTIVATE_CDC_ECM == 1
|
|
case CLASS_TYPE_ECM:
|
|
/* Setup default Max packet size */
|
|
pdev->tclasslist[pdev->classId].CurrPcktSze = CDC_ECM_DATA_FS_MAX_PACKET_SIZE;
|
|
|
|
/* Find the first available interface slot and Assign number of interfaces */
|
|
idxIf = USBD_CMPSIT_FindFreeIFNbr(pdev);
|
|
pdev->tclasslist[pdev->classId].NumIf = 2U;
|
|
pdev->tclasslist[pdev->classId].Ifs[0] = idxIf;
|
|
pdev->tclasslist[pdev->classId].Ifs[1] = (uint8_t)(idxIf + 1U);
|
|
|
|
/* Assign endpoint numbers */
|
|
pdev->tclasslist[pdev->classId].NumEps = 3U; /* EP1_IN, EP1_OUT,CMD_EP2 */
|
|
|
|
/* Set IN endpoint slot */
|
|
iEp = pdev->tclasslist[pdev->classId].EpAdd[0];
|
|
USBD_CMPSIT_AssignEp(pdev, iEp, USBD_EP_TYPE_BULK, pdev->tclasslist[pdev->classId].CurrPcktSze);
|
|
|
|
/* Set OUT endpoint slot */
|
|
iEp = pdev->tclasslist[pdev->classId].EpAdd[1];
|
|
USBD_CMPSIT_AssignEp(pdev, iEp, USBD_EP_TYPE_BULK, pdev->tclasslist[pdev->classId].CurrPcktSze);
|
|
|
|
/* Set the second IN endpoint slot */
|
|
iEp = pdev->tclasslist[pdev->classId].EpAdd[2];
|
|
USBD_CMPSIT_AssignEp(pdev, iEp, USBD_EP_TYPE_INTR, CDC_ECM_CMD_PACKET_SIZE);
|
|
|
|
/* Configure and Append the Descriptor */
|
|
USBD_CMPSIT_CDC_ECMDesc(pdev, (uint32_t)pCmpstFSConfDesc, &CurrFSConfDescSz, (uint8_t)USBD_SPEED_FULL);
|
|
|
|
#ifdef USE_USB_HS
|
|
USBD_CMPSIT_CDC_ECMDesc(pdev, (uint32_t)pCmpstHSConfDesc, &CurrHSConfDescSz, (uint8_t)USBD_SPEED_HIGH);
|
|
#endif /* USE_USB_HS */
|
|
|
|
break;
|
|
#endif /* USBD_CMPSIT_ACTIVATE_CDC_ECM */
|
|
|
|
#if USBD_CMPSIT_ACTIVATE_AUDIO == 1
|
|
case CLASS_TYPE_AUDIO:
|
|
/* Setup Max packet sizes*/
|
|
pdev->tclasslist[pdev->classId].CurrPcktSze = USBD_AUDIO_GetEpPcktSze(pdev, 0U, 0U);
|
|
|
|
/* Find the first available interface slot and Assign number of interfaces */
|
|
idxIf = USBD_CMPSIT_FindFreeIFNbr(pdev);
|
|
pdev->tclasslist[pdev->classId].NumIf = 2U;
|
|
pdev->tclasslist[pdev->classId].Ifs[0] = idxIf;
|
|
pdev->tclasslist[pdev->classId].Ifs[1] = (uint8_t)(idxIf + 1U);
|
|
|
|
/* Assign endpoint numbers */
|
|
pdev->tclasslist[pdev->classId].NumEps = 1U; /* EP1_OUT*/
|
|
|
|
/* Set OUT endpoint slot */
|
|
iEp = pdev->tclasslist[pdev->classId].EpAdd[0];
|
|
|
|
/* Assign OUT Endpoint */
|
|
USBD_CMPSIT_AssignEp(pdev, iEp, USBD_EP_TYPE_ISOC, pdev->tclasslist[pdev->classId].CurrPcktSze);
|
|
|
|
/* Configure and Append the Descriptor (only FS mode supported) */
|
|
USBD_CMPSIT_AUDIODesc(pdev, (uint32_t)pCmpstFSConfDesc, &CurrFSConfDescSz, (uint8_t)USBD_SPEED_FULL);
|
|
|
|
break;
|
|
#endif /* USBD_CMPSIT_ACTIVATE_AUDIO */
|
|
|
|
#if USBD_CMPSIT_ACTIVATE_CUSTOMHID == 1
|
|
case CLASS_TYPE_CHID:
|
|
/* Setup Max packet sizes */
|
|
pdev->tclasslist[pdev->classId].CurrPcktSze = CUSTOM_HID_EPOUT_SIZE;
|
|
|
|
/* Find the first available interface slot and Assign number of interfaces */
|
|
idxIf = USBD_CMPSIT_FindFreeIFNbr(pdev);
|
|
pdev->tclasslist[pdev->classId].NumIf = 1U;
|
|
pdev->tclasslist[pdev->classId].Ifs[0] = idxIf;
|
|
|
|
/* Assign endpoint numbers */
|
|
pdev->tclasslist[pdev->classId].NumEps = 2U; /* EP1_IN, EP1_OUT */
|
|
|
|
/* Set IN endpoint slot */
|
|
iEp = pdev->tclasslist[pdev->classId].EpAdd[0];
|
|
USBD_CMPSIT_AssignEp(pdev, iEp, USBD_EP_TYPE_INTR, pdev->tclasslist[pdev->classId].CurrPcktSze);
|
|
|
|
/* Set OUT endpoint slot */
|
|
iEp = pdev->tclasslist[pdev->classId].EpAdd[1];
|
|
USBD_CMPSIT_AssignEp(pdev, iEp, USBD_EP_TYPE_INTR, pdev->tclasslist[pdev->classId].CurrPcktSze);
|
|
|
|
/* Configure and Append the Descriptor */
|
|
USBD_CMPSIT_CUSTOMHIDDesc(pdev, (uint32_t)pCmpstFSConfDesc, &CurrFSConfDescSz, (uint8_t)USBD_SPEED_FULL);
|
|
|
|
#ifdef USE_USB_HS
|
|
USBD_CMPSIT_CUSTOMHIDDesc(pdev, (uint32_t)pCmpstHSConfDesc, &CurrHSConfDescSz, (uint8_t)USBD_SPEED_HIGH);
|
|
#endif /* USE_USB_HS */
|
|
|
|
break;
|
|
#endif /* USBD_CMPSIT_ACTIVATE_CUSTOMHID */
|
|
|
|
#if USBD_CMPSIT_ACTIVATE_VIDEO == 1
|
|
case CLASS_TYPE_VIDEO:
|
|
/* Setup default Max packet size */
|
|
pdev->tclasslist[pdev->classId].CurrPcktSze = UVC_ISO_FS_MPS;
|
|
|
|
/* Find the first available interface slot and Assign number of interfaces */
|
|
idxIf = USBD_CMPSIT_FindFreeIFNbr(pdev);
|
|
pdev->tclasslist[pdev->classId].NumIf = 2U;
|
|
pdev->tclasslist[pdev->classId].Ifs[0] = idxIf;
|
|
pdev->tclasslist[pdev->classId].Ifs[1] = (uint8_t)(idxIf + 1U);
|
|
|
|
/* Assign endpoint numbers */
|
|
pdev->tclasslist[pdev->classId].NumEps = 1U; /* EP1_IN */
|
|
|
|
/* Set IN endpoint slot */
|
|
iEp = pdev->tclasslist[pdev->classId].EpAdd[0];
|
|
|
|
/* Assign IN Endpoint */
|
|
USBD_CMPSIT_AssignEp(pdev, iEp, USBD_EP_TYPE_ISOC, pdev->tclasslist[pdev->classId].CurrPcktSze);
|
|
|
|
/* Configure and Append the Descriptor */
|
|
USBD_CMPSIT_VIDEODesc(pdev, (uint32_t)pCmpstFSConfDesc, &CurrFSConfDescSz, (uint8_t)USBD_SPEED_FULL);
|
|
|
|
#ifdef USE_USB_HS
|
|
USBD_CMPSIT_VIDEODesc(pdev, (uint32_t)pCmpstHSConfDesc, &CurrHSConfDescSz, (uint8_t)USBD_SPEED_HIGH);
|
|
#endif /* USE_USB_HS */
|
|
|
|
break;
|
|
#endif /* USBD_CMPSIT_ACTIVATE_VIDEO */
|
|
|
|
#if USBD_CMPSIT_ACTIVATE_PRINTER == 1
|
|
case CLASS_TYPE_PRINTER:
|
|
|
|
/* Setup default Max packet size */
|
|
pdev->tclasslist[pdev->classId].CurrPcktSze = PRNT_DATA_FS_MAX_PACKET_SIZE;
|
|
|
|
/* Find the first available interface slot and Assign number of interfaces */
|
|
idxIf = USBD_CMPSIT_FindFreeIFNbr(pdev);
|
|
pdev->tclasslist[pdev->classId].NumIf = 1U;
|
|
pdev->tclasslist[pdev->classId].Ifs[0] = idxIf;
|
|
|
|
/* Assign endpoint numbers */
|
|
pdev->tclasslist[pdev->classId].NumEps = 2U;
|
|
|
|
/* Set IN endpoint slot */
|
|
iEp = pdev->tclasslist[pdev->classId].EpAdd[0];
|
|
USBD_CMPSIT_AssignEp(pdev, iEp, USBD_EP_TYPE_BULK, pdev->tclasslist[pdev->classId].CurrPcktSze);
|
|
|
|
/* Set OUT endpoint slot */
|
|
iEp = pdev->tclasslist[pdev->classId].EpAdd[1];
|
|
USBD_CMPSIT_AssignEp(pdev, iEp, USBD_EP_TYPE_BULK, pdev->tclasslist[pdev->classId].CurrPcktSze);
|
|
|
|
/* Configure and Append the Descriptor */
|
|
USBD_CMPSIT_PRNTDesc(pdev, (uint32_t)pCmpstFSConfDesc, &CurrFSConfDescSz, (uint8_t)USBD_SPEED_FULL);
|
|
|
|
#ifdef USE_USB_HS
|
|
USBD_CMPSIT_PRNTDesc(pdev, (uint32_t)pCmpstHSConfDesc, &CurrHSConfDescSz, (uint8_t)USBD_SPEED_HIGH);
|
|
#endif /* USE_USB_HS */
|
|
|
|
break;
|
|
#endif /* USBD_CMPSIT_ACTIVATE_PRINTER */
|
|
|
|
#if USBD_CMPSIT_ACTIVATE_CCID == 1
|
|
|
|
case CLASS_TYPE_CCID:
|
|
/* Setup default Max packet size */
|
|
pdev->tclasslist[pdev->classId].CurrPcktSze = CCID_DATA_FS_MAX_PACKET_SIZE;
|
|
|
|
/* Find the first available interface slot and Assign number of interfaces */
|
|
idxIf = USBD_CMPSIT_FindFreeIFNbr(pdev);
|
|
pdev->tclasslist[pdev->classId].NumIf = 1U;
|
|
pdev->tclasslist[pdev->classId].Ifs[0] = idxIf;
|
|
|
|
/* Assign endpoint numbers */
|
|
pdev->tclasslist[pdev->classId].NumEps = 3U;
|
|
|
|
/* Set IN endpoint slot */
|
|
iEp = pdev->tclasslist[pdev->classId].EpAdd[0];
|
|
USBD_CMPSIT_AssignEp(pdev, iEp, USBD_EP_TYPE_BULK, pdev->tclasslist[pdev->classId].CurrPcktSze);
|
|
|
|
/* Set OUT endpoint slot */
|
|
iEp = pdev->tclasslist[pdev->classId].EpAdd[1];
|
|
USBD_CMPSIT_AssignEp(pdev, iEp, USBD_EP_TYPE_BULK, pdev->tclasslist[pdev->classId].CurrPcktSze);
|
|
|
|
/* Set the second IN endpoint slot */
|
|
iEp = pdev->tclasslist[pdev->classId].EpAdd[2];
|
|
USBD_CMPSIT_AssignEp(pdev, iEp, USBD_EP_TYPE_INTR, CCID_CMD_PACKET_SIZE);
|
|
|
|
/* Configure and Append the Descriptor */
|
|
USBD_CMPSIT_CCIDDesc(pdev, (uint32_t)pCmpstFSConfDesc, &CurrFSConfDescSz, (uint8_t)USBD_SPEED_FULL);
|
|
|
|
#ifdef USE_USB_HS
|
|
USBD_CMPSIT_CCIDDesc(pdev, (uint32_t)pCmpstHSConfDesc, &CurrHSConfDescSz, (uint8_t)USBD_SPEED_HIGH);
|
|
#endif /* USE_USB_HS */
|
|
|
|
break;
|
|
#endif /* USBD_CMPSIT_ACTIVATE_CCID */
|
|
|
|
#if USBD_CMPSIT_ACTIVATE_MTP == 1
|
|
|
|
case CLASS_TYPE_MTP:
|
|
/* Setup default Max packet sizes */
|
|
pdev->tclasslist[pdev->classId].CurrPcktSze = MTP_DATA_MAX_FS_PACKET_SIZE;
|
|
|
|
/* Find the first available interface slot and Assign number of interfaces */
|
|
idxIf = USBD_CMPSIT_FindFreeIFNbr(pdev);
|
|
pdev->tclasslist[pdev->classId].NumIf = 1U;
|
|
pdev->tclasslist[pdev->classId].Ifs[0] = idxIf;
|
|
|
|
/* Assign endpoint numbers */
|
|
pdev->tclasslist[pdev->classId].NumEps = 3U;
|
|
|
|
/* Set IN endpoint slot */
|
|
iEp = pdev->tclasslist[pdev->classId].EpAdd[0];
|
|
USBD_CMPSIT_AssignEp(pdev, iEp, USBD_EP_TYPE_BULK, pdev->tclasslist[pdev->classId].CurrPcktSze);
|
|
|
|
/* Set OUT endpoint slot */
|
|
iEp = pdev->tclasslist[pdev->classId].EpAdd[1];
|
|
USBD_CMPSIT_AssignEp(pdev, iEp, USBD_EP_TYPE_BULK, pdev->tclasslist[pdev->classId].CurrPcktSze);
|
|
|
|
/* Set the second IN endpoint slot */
|
|
iEp = pdev->tclasslist[pdev->classId].EpAdd[2];
|
|
USBD_CMPSIT_AssignEp(pdev, iEp, USBD_EP_TYPE_INTR, MTP_CMD_PACKET_SIZE);
|
|
|
|
/* Configure and Append the Descriptor */
|
|
USBD_CMPSIT_MTPDesc(pdev, (uint32_t)pCmpstFSConfDesc, &CurrFSConfDescSz, (uint8_t)USBD_SPEED_FULL);
|
|
|
|
#ifdef USE_USB_HS
|
|
USBD_CMPSIT_MTPDesc(pdev, (uint32_t)pCmpstHSConfDesc, &CurrHSConfDescSz, (uint8_t)USBD_SPEED_HIGH);
|
|
#endif /* USE_USB_HS */
|
|
|
|
break;
|
|
#endif /* USBD_CMPSIT_ACTIVATE_MTP */
|
|
|
|
default:
|
|
UNUSED(idxIf);
|
|
UNUSED(iEp);
|
|
UNUSED(USBD_CMPSIT_FindFreeIFNbr);
|
|
UNUSED(USBD_CMPSIT_AssignEp);
|
|
break;
|
|
}
|
|
|
|
return (uint8_t)USBD_OK;
|
|
}
|
|
|
|
/**
|
|
* @brief USBD_CMPSIT_GetFSCfgDesc
|
|
* return configuration descriptor for both FS and HS modes
|
|
* @param length : pointer data length
|
|
* @retval pointer to descriptor buffer
|
|
*/
|
|
uint8_t *USBD_CMPSIT_GetFSCfgDesc(uint16_t *length)
|
|
{
|
|
*length = (uint16_t)CurrFSConfDescSz;
|
|
|
|
return USBD_CMPSIT_FSCfgDesc;
|
|
}
|
|
|
|
#ifdef USE_USB_HS
|
|
/**
|
|
* @brief USBD_CMPSIT_GetHSCfgDesc
|
|
* return configuration descriptor for both FS and HS modes
|
|
* @param length : pointer data length
|
|
* @retval pointer to descriptor buffer
|
|
*/
|
|
uint8_t *USBD_CMPSIT_GetHSCfgDesc(uint16_t *length)
|
|
{
|
|
*length = (uint16_t)CurrHSConfDescSz;
|
|
|
|
return USBD_CMPSIT_HSCfgDesc;
|
|
}
|
|
#endif /* USE_USB_HS */
|
|
|
|
/**
|
|
* @brief USBD_CMPSIT_GetOtherSpeedCfgDesc
|
|
* return other speed configuration descriptor
|
|
* @param length : pointer data length
|
|
* @retval pointer to descriptor buffer
|
|
*/
|
|
uint8_t *USBD_CMPSIT_GetOtherSpeedCfgDesc(uint16_t *length)
|
|
{
|
|
*length = (uint16_t)CurrFSConfDescSz;
|
|
|
|
return USBD_CMPSIT_FSCfgDesc;
|
|
}
|
|
|
|
/**
|
|
* @brief DeviceQualifierDescriptor
|
|
* return Device Qualifier descriptor
|
|
* @param length : pointer data length
|
|
* @retval pointer to descriptor buffer
|
|
*/
|
|
uint8_t *USBD_CMPSIT_GetDeviceQualifierDescriptor(uint16_t *length)
|
|
{
|
|
*length = (uint16_t)(sizeof(USBD_CMPSIT_DeviceQualifierDesc));
|
|
return USBD_CMPSIT_DeviceQualifierDesc;
|
|
}
|
|
|
|
/**
|
|
* @brief USBD_CMPSIT_FindFreeIFNbr
|
|
* Find the first interface available slot
|
|
* @param pdev: device instance
|
|
* @retval The interface number to be used
|
|
*/
|
|
static uint8_t USBD_CMPSIT_FindFreeIFNbr(USBD_HandleTypeDef *pdev)
|
|
{
|
|
uint32_t idx = 0U;
|
|
|
|
/* Unroll all already activated classes */
|
|
for (uint32_t i = 0U; i < pdev->NumClasses; i++)
|
|
{
|
|
/* Unroll each class interfaces */
|
|
for (uint32_t j = 0U; j < pdev->tclasslist[i].NumIf; j++)
|
|
{
|
|
/* Increment the interface counter index */
|
|
idx++;
|
|
}
|
|
}
|
|
|
|
/* Return the first available interface slot */
|
|
return (uint8_t)idx;
|
|
}
|
|
|
|
/**
|
|
* @brief USBD_CMPSIT_AddToConfDesc
|
|
* Add a new class to the configuration descriptor
|
|
* @param pdev: device instance
|
|
* @retval none
|
|
*/
|
|
static void USBD_CMPSIT_AddConfDesc(uint32_t Conf, __IO uint32_t *pSze)
|
|
{
|
|
/* Intermediate variable to comply with MISRA-C Rule 11.3 */
|
|
USBD_ConfigDescTypeDef *ptr = (USBD_ConfigDescTypeDef *)Conf;
|
|
|
|
ptr->bLength = (uint8_t)sizeof(USBD_ConfigDescTypeDef);
|
|
ptr->bDescriptorType = USB_DESC_TYPE_CONFIGURATION;
|
|
ptr->wTotalLength = 0U;
|
|
ptr->bNumInterfaces = 0U;
|
|
ptr->bConfigurationValue = 1U;
|
|
ptr->iConfiguration = USBD_CONFIG_STR_DESC_IDX;
|
|
|
|
#if (USBD_SELF_POWERED == 1U)
|
|
ptr->bmAttributes = 0xC0U; /* bmAttributes: Self Powered according to user configuration */
|
|
#else
|
|
ptr->bmAttributes = 0x80U; /* bmAttributes: Bus Powered according to user configuration */
|
|
#endif /* USBD_SELF_POWERED */
|
|
|
|
ptr->bMaxPower = USBD_MAX_POWER;
|
|
|
|
*pSze += sizeof(USBD_ConfigDescTypeDef);
|
|
}
|
|
|
|
/**
|
|
* @brief USBD_CMPSIT_AssignEp
|
|
* Assign and endpoint
|
|
* @param pdev: device instance
|
|
* @param Add: Endpoint address
|
|
* @param Type: Endpoint type
|
|
* @param Sze: Endpoint max packet size
|
|
* @retval none
|
|
*/
|
|
static void USBD_CMPSIT_AssignEp(USBD_HandleTypeDef *pdev, uint8_t Add, uint8_t Type, uint32_t Sze)
|
|
{
|
|
uint32_t idx = 0U;
|
|
|
|
/* Find the first available endpoint slot */
|
|
while (((idx < (pdev->tclasslist[pdev->classId]).NumEps) && \
|
|
((pdev->tclasslist[pdev->classId].Eps[idx].is_used) != 0U)))
|
|
{
|
|
/* Increment the index */
|
|
idx++;
|
|
}
|
|
|
|
/* Configure the endpoint */
|
|
pdev->tclasslist[pdev->classId].Eps[idx].add = Add;
|
|
pdev->tclasslist[pdev->classId].Eps[idx].type = Type;
|
|
pdev->tclasslist[pdev->classId].Eps[idx].size = (uint8_t)Sze;
|
|
pdev->tclasslist[pdev->classId].Eps[idx].is_used = 1U;
|
|
}
|
|
|
|
#if USBD_CMPSIT_ACTIVATE_HID == 1
|
|
/**
|
|
* @brief USBD_CMPSIT_HIDMouseDesc
|
|
* Configure and Append the HID Mouse Descriptor
|
|
* @param pdev: device instance
|
|
* @param pConf: Configuration descriptor pointer
|
|
* @param Sze: pointer to the current configuration descriptor size
|
|
* @retval None
|
|
*/
|
|
static void USBD_CMPSIT_HIDMouseDesc(USBD_HandleTypeDef *pdev, uint32_t pConf,
|
|
__IO uint32_t *Sze, uint8_t speed)
|
|
{
|
|
static USBD_IfDescTypeDef *pIfDesc;
|
|
static USBD_EpDescTypeDef *pEpDesc;
|
|
static USBD_HIDDescTypeDef *pHidMouseDesc;
|
|
|
|
/* Append HID Interface descriptor to Configuration descriptor */
|
|
__USBD_CMPSIT_SET_IF(pdev->tclasslist[pdev->classId].Ifs[0], 0U, \
|
|
(uint8_t)(pdev->tclasslist[pdev->classId].NumEps), 0x03U, 0x01U, 0x02U, 0U);
|
|
|
|
/* Append HID Functional descriptor to Configuration descriptor */
|
|
pHidMouseDesc = ((USBD_HIDDescTypeDef *)(pConf + *Sze));
|
|
pHidMouseDesc->bLength = (uint8_t)sizeof(USBD_HIDDescTypeDef);
|
|
pHidMouseDesc->bDescriptorType = HID_DESCRIPTOR_TYPE;
|
|
pHidMouseDesc->bcdHID = 0x0111U;
|
|
pHidMouseDesc->bCountryCode = 0x00U;
|
|
pHidMouseDesc->bNumDescriptors = 0x01U;
|
|
pHidMouseDesc->bHIDDescriptorType = 0x22U;
|
|
pHidMouseDesc->wItemLength = HID_MOUSE_REPORT_DESC_SIZE;
|
|
*Sze += (uint32_t)sizeof(USBD_HIDDescTypeDef);
|
|
|
|
/* Append Endpoint descriptor to Configuration descriptor */
|
|
__USBD_CMPSIT_SET_EP(pdev->tclasslist[pdev->classId].Eps[0].add, USBD_EP_TYPE_INTR, HID_EPIN_SIZE, \
|
|
HID_HS_BINTERVAL, HID_FS_BINTERVAL);
|
|
|
|
/* Update Config Descriptor and IAD descriptor */
|
|
((USBD_ConfigDescTypeDef *)pConf)->bNumInterfaces += 1U;
|
|
((USBD_ConfigDescTypeDef *)pConf)->wTotalLength = (uint16_t)(*Sze);
|
|
}
|
|
#endif /* USBD_CMPSIT_ACTIVATE_HID == 1 */
|
|
|
|
#if USBD_CMPSIT_ACTIVATE_BULK == 1
|
|
/**
|
|
* @brief USBD_CMPSIT_BULKDesc
|
|
* Configure and Append the BULK Descriptor
|
|
* @param pdev: device instance
|
|
* @param pConf: Configuration descriptor pointer
|
|
* @param Sze: pointer to the current configuration descriptor size
|
|
* @retval None
|
|
*/
|
|
static void USBD_CMPSIT_BULKDesc(USBD_HandleTypeDef *pdev, uint32_t pConf, __IO uint32_t *Sze, uint8_t speed)
|
|
{
|
|
USBD_IfDescTypeDef *pIfDesc;
|
|
USBD_EpDescTypeDef *pEpDesc;
|
|
|
|
/* Append BULK Interface descriptor */
|
|
__USBD_CMPSIT_SET_IF((pdev->tclasslist[pdev->classId].Ifs[0]),
|
|
(0U), // Interface number
|
|
(uint8_t)(pdev->tclasslist[pdev->classId].NumEps),
|
|
(0xFFU), // bInterfaceClass: 0xFF = Vendor Specific
|
|
(0x00U), // bInterfaceSubClass: 0x00 = Custom
|
|
(0x00U), // bInterfaceProtocol: 0x00 = Custom
|
|
(0U));
|
|
|
|
if (speed == (uint8_t)USBD_SPEED_HIGH)
|
|
{
|
|
pdev->tclasslist[pdev->classId].CurrPcktSze = BULK_MAX_HS_PACKET;
|
|
}
|
|
|
|
/* Append Endpoint descriptor to Configuration descriptor */
|
|
__USBD_CMPSIT_SET_EP((pdev->tclasslist[pdev->classId].Eps[0].add), (USBD_EP_TYPE_BULK), \
|
|
(pdev->tclasslist[pdev->classId].CurrPcktSze), (0U), (0U));
|
|
|
|
/* Append Endpoint descriptor to Configuration descriptor */
|
|
__USBD_CMPSIT_SET_EP((pdev->tclasslist[pdev->classId].Eps[1].add), (USBD_EP_TYPE_BULK), \
|
|
(pdev->tclasslist[pdev->classId].CurrPcktSze), (0U), (0U));
|
|
|
|
/* Update Config Descriptor and IAD descriptor */
|
|
((USBD_ConfigDescTypeDef *)pConf)->bNumInterfaces += 1U;
|
|
((USBD_ConfigDescTypeDef *)pConf)->wTotalLength = (uint16_t)(*Sze);
|
|
}
|
|
#endif /* USBD_CMPSIT_ACTIVATE_BULK == 1 */
|
|
|
|
#if USBD_CMPSIT_ACTIVATE_CDC == 1
|
|
/**
|
|
* @brief USBD_CMPSIT_BULKDesc
|
|
* Configure and Append the HID Mouse Descriptor
|
|
* @param pdev: device instance
|
|
* @param pConf: Configuration descriptor pointer
|
|
* @param Sze: pointer to the current configuration descriptor size
|
|
* @retval None
|
|
*/
|
|
static void USBD_CMPSIT_CDCDesc(USBD_HandleTypeDef *pdev, uint32_t pConf, __IO uint32_t *Sze, uint8_t speed)
|
|
{
|
|
static USBD_IfDescTypeDef *pIfDesc;
|
|
static USBD_EpDescTypeDef *pEpDesc;
|
|
static USBD_CDCHeaderFuncDescTypeDef *pHeadDesc;
|
|
static USBD_CDCCallMgmFuncDescTypeDef *pCallMgmDesc;
|
|
static USBD_CDCACMFuncDescTypeDef *pACMDesc;
|
|
static USBD_CDCUnionFuncDescTypeDef *pUnionDesc;
|
|
#if USBD_COMPOSITE_USE_IAD == 1
|
|
static USBD_IadDescTypeDef *pIadDesc;
|
|
#endif /* USBD_COMPOSITE_USE_IAD == 1 */
|
|
|
|
#if USBD_COMPOSITE_USE_IAD == 1
|
|
pIadDesc = ((USBD_IadDescTypeDef *)(pConf + *Sze));
|
|
pIadDesc->bLength = (uint8_t)sizeof(USBD_IadDescTypeDef);
|
|
pIadDesc->bDescriptorType = USB_DESC_TYPE_IAD; /* IAD descriptor */
|
|
pIadDesc->bFirstInterface = pdev->tclasslist[pdev->classId].Ifs[0];
|
|
pIadDesc->bInterfaceCount = 2U; /* 2 interfaces */
|
|
pIadDesc->bFunctionClass = 0x02U;
|
|
pIadDesc->bFunctionSubClass = 0x02U;
|
|
pIadDesc->bFunctionProtocol = 0x01U;
|
|
pIadDesc->iFunction = 0U; /* String Index */
|
|
*Sze += (uint32_t)sizeof(USBD_IadDescTypeDef);
|
|
#endif /* USBD_COMPOSITE_USE_IAD == 1 */
|
|
|
|
/* Control Interface Descriptor */
|
|
__USBD_CMPSIT_SET_IF(pdev->tclasslist[pdev->classId].Ifs[0], 0U, 1U, 0x02, 0x02U, 0x01U, 0U);
|
|
|
|
/* Control interface headers */
|
|
pHeadDesc = ((USBD_CDCHeaderFuncDescTypeDef *)((uint32_t)pConf + *Sze));
|
|
/* Header Functional Descriptor*/
|
|
pHeadDesc->bLength = 0x05U;
|
|
pHeadDesc->bDescriptorType = 0x24U;
|
|
pHeadDesc->bDescriptorSubtype = 0x00U;
|
|
pHeadDesc->bcdCDC = 0x0110U;
|
|
*Sze += (uint32_t)sizeof(USBD_CDCHeaderFuncDescTypeDef);
|
|
|
|
/* Call Management Functional Descriptor */
|
|
pCallMgmDesc = ((USBD_CDCCallMgmFuncDescTypeDef *)((uint32_t)pConf + *Sze));
|
|
pCallMgmDesc->bLength = 0x05U;
|
|
pCallMgmDesc->bDescriptorType = 0x24U;
|
|
pCallMgmDesc->bDescriptorSubtype = 0x01U;
|
|
pCallMgmDesc->bmCapabilities = 0x00U;
|
|
pCallMgmDesc->bDataInterface = pdev->tclasslist[pdev->classId].Ifs[1];
|
|
*Sze += (uint32_t)sizeof(USBD_CDCCallMgmFuncDescTypeDef);
|
|
|
|
/* ACM Functional Descriptor*/
|
|
pACMDesc = ((USBD_CDCACMFuncDescTypeDef *)((uint32_t)pConf + *Sze));
|
|
pACMDesc->bLength = 0x04U;
|
|
pACMDesc->bDescriptorType = 0x24U;
|
|
pACMDesc->bDescriptorSubtype = 0x02U;
|
|
pACMDesc->bmCapabilities = 0x02U;
|
|
*Sze += (uint32_t)sizeof(USBD_CDCACMFuncDescTypeDef);
|
|
|
|
/* Union Functional Descriptor*/
|
|
pUnionDesc = ((USBD_CDCUnionFuncDescTypeDef *)((uint32_t)pConf + *Sze));
|
|
pUnionDesc->bLength = 0x05U;
|
|
pUnionDesc->bDescriptorType = 0x24U;
|
|
pUnionDesc->bDescriptorSubtype = 0x06U;
|
|
pUnionDesc->bMasterInterface = pdev->tclasslist[pdev->classId].Ifs[0];
|
|
pUnionDesc->bSlaveInterface = pdev->tclasslist[pdev->classId].Ifs[1];
|
|
*Sze += (uint32_t)sizeof(USBD_CDCUnionFuncDescTypeDef);
|
|
|
|
/* Append Endpoint descriptor to Configuration descriptor */
|
|
__USBD_CMPSIT_SET_EP(pdev->tclasslist[pdev->classId].Eps[2].add, \
|
|
USBD_EP_TYPE_INTR, CDC_CMD_PACKET_SIZE, CDC_HS_BINTERVAL, CDC_FS_BINTERVAL);
|
|
|
|
/* Data Interface Descriptor */
|
|
__USBD_CMPSIT_SET_IF(pdev->tclasslist[pdev->classId].Ifs[1], 0U, 2U, 0x0A, 0U, 0U, 0U);
|
|
|
|
if (speed == (uint8_t)USBD_SPEED_HIGH)
|
|
{
|
|
pdev->tclasslist[pdev->classId].CurrPcktSze = CDC_DATA_HS_MAX_PACKET_SIZE;
|
|
}
|
|
|
|
/* Append Endpoint descriptor to Configuration descriptor */
|
|
__USBD_CMPSIT_SET_EP((pdev->tclasslist[pdev->classId].Eps[0].add), \
|
|
(USBD_EP_TYPE_BULK), (pdev->tclasslist[pdev->classId].CurrPcktSze), (0U), (0U));
|
|
|
|
/* Append Endpoint descriptor to Configuration descriptor */
|
|
__USBD_CMPSIT_SET_EP((pdev->tclasslist[pdev->classId].Eps[1].add), \
|
|
(USBD_EP_TYPE_BULK), (pdev->tclasslist[pdev->classId].CurrPcktSze), (0U), (0U));
|
|
|
|
/* Update Config Descriptor and IAD descriptor */
|
|
((USBD_ConfigDescTypeDef *)pConf)->bNumInterfaces += 2U;
|
|
((USBD_ConfigDescTypeDef *)pConf)->wTotalLength = (uint16_t)(*Sze);
|
|
}
|
|
#endif /* USBD_CMPSIT_ACTIVATE_CDC == 1 */
|
|
|
|
#if USBD_CMPSIT_ACTIVATE_DFU == 1
|
|
/**
|
|
* @brief USBD_CMPSIT_DFUDesc
|
|
* Configure and Append the DFU Descriptor
|
|
* @param pdev: device instance
|
|
* @param pConf: Configuration descriptor pointer
|
|
* @param Sze: pointer to the current configuration descriptor size
|
|
* @retval None
|
|
*/
|
|
static void USBD_CMPSIT_DFUDesc(USBD_HandleTypeDef *pdev, uint32_t pConf, __IO uint32_t *Sze, uint8_t speed)
|
|
{
|
|
static USBD_IfDescTypeDef *pIfDesc;
|
|
static USBD_DFUFuncDescTypeDef *pDFUFuncDesc;
|
|
uint32_t idx;
|
|
UNUSED(speed);
|
|
|
|
for (idx = 0U; idx < USBD_DFU_MAX_ITF_NUM; idx++)
|
|
{
|
|
/* Append DFU Interface descriptor to Configuration descriptor */
|
|
__USBD_CMPSIT_SET_IF(pdev->tclasslist[pdev->classId].Ifs[0], (uint8_t)idx, 0U, 0xFEU, 0x01U, 0x02U, \
|
|
(uint8_t)USBD_IDX_INTERFACE_STR + 1U + (uint8_t)idx);
|
|
}
|
|
|
|
/* Append DFU Functional descriptor to Configuration descriptor */
|
|
pDFUFuncDesc = ((USBD_DFUFuncDescTypeDef *)(pConf + *Sze));
|
|
pDFUFuncDesc->bLength = (uint8_t)sizeof(USBD_DFUFuncDescTypeDef);
|
|
pDFUFuncDesc->bDescriptorType = DFU_DESCRIPTOR_TYPE;
|
|
pDFUFuncDesc->bmAttributes = USBD_DFU_BM_ATTRIBUTES;
|
|
pDFUFuncDesc->wDetachTimeout = USBD_DFU_DETACH_TIMEOUT;
|
|
pDFUFuncDesc->wTransferSze = USBD_DFU_XFER_SIZE;
|
|
pDFUFuncDesc->bcdDFUVersion = 0x011AU;
|
|
*Sze += (uint32_t)sizeof(USBD_DFUFuncDescTypeDef);
|
|
|
|
/* Update Config Descriptor and IAD descriptor */
|
|
((USBD_ConfigDescTypeDef *)pConf)->bNumInterfaces += 1U;
|
|
((USBD_ConfigDescTypeDef *)pConf)->wTotalLength = (uint16_t)(*Sze);
|
|
|
|
UNUSED(idx);
|
|
}
|
|
#endif /* USBD_CMPSIT_ACTIVATE_DFU == 1 */
|
|
|
|
#if USBD_CMPSIT_ACTIVATE_CDC_ECM == 1
|
|
/**
|
|
* @brief USBD_CMPSIT_CDC_ECMDesc
|
|
* Configure and Append the CDC_ECM Descriptor
|
|
* @param pdev: device instance
|
|
* @param pConf: Configuration descriptor pointer
|
|
* @param Sze: pointer to the current configuration descriptor size
|
|
* @retval None
|
|
*/
|
|
static void USBD_CMPSIT_CDC_ECMDesc(USBD_HandleTypeDef *pdev, uint32_t pConf, __IO uint32_t *Sze, uint8_t speed)
|
|
{
|
|
static USBD_IfDescTypeDef *pIfDesc;
|
|
static USBD_EpDescTypeDef *pEpDesc;
|
|
static USBD_ECMFuncDescTypeDef *pFuncDesc;
|
|
static USBD_IadDescTypeDef *pIadDesc;
|
|
|
|
static USBD_CDCHeaderFuncDescTypeDef *pHeadDesc;
|
|
static USBD_CDCUnionFuncDescTypeDef *pUnionDesc;
|
|
|
|
#if USBD_COMPOSITE_USE_IAD == 1
|
|
pIadDesc = ((USBD_IadDescTypeDef *)(pConf + *Sze));
|
|
pIadDesc->bLength = (uint8_t)sizeof(USBD_IadDescTypeDef);
|
|
pIadDesc->bDescriptorType = USB_DESC_TYPE_IAD; /* IAD descriptor */
|
|
pIadDesc->bFirstInterface = pdev->tclasslist[pdev->classId].Ifs[0];
|
|
pIadDesc->bInterfaceCount = 2U; /* 2 interfaces */
|
|
pIadDesc->bFunctionClass = 0x02U;
|
|
pIadDesc->bFunctionSubClass = 0x06U;
|
|
pIadDesc->bFunctionProtocol = 0x00U;
|
|
pIadDesc->iFunction = 0U; /* String Index */
|
|
*Sze += (uint32_t)sizeof(USBD_IadDescTypeDef);
|
|
#endif /* USBD_COMPOSITE_USE_IAD == 1 */
|
|
|
|
/* Append ECM Interface descriptor to Configuration descriptor */
|
|
__USBD_CMPSIT_SET_IF(pdev->tclasslist[pdev->classId].Ifs[0], 0U, 1U, 0x02U, 0x06U, 0U, 0U);
|
|
|
|
/* Append ECM header functional descriptor to Configuration descriptor */
|
|
pHeadDesc = ((USBD_CDCHeaderFuncDescTypeDef *)(pConf + *Sze));
|
|
pHeadDesc->bLength = (uint8_t)sizeof(USBD_CDCHeaderFuncDescTypeDef);
|
|
pHeadDesc->bDescriptorType = USBD_FUNC_DESCRIPTOR_TYPE;
|
|
pHeadDesc->bDescriptorSubtype = 0x00U;
|
|
pHeadDesc->bcdCDC = 0x1000U;
|
|
*Sze += (uint32_t)sizeof(USBD_CDCHeaderFuncDescTypeDef);
|
|
|
|
/* Append ECM functional descriptor to Configuration descriptor */
|
|
pFuncDesc = ((USBD_ECMFuncDescTypeDef *)(pConf + *Sze));
|
|
pFuncDesc->bFunctionLength = (uint8_t)sizeof(USBD_ECMFuncDescTypeDef);
|
|
pFuncDesc->bDescriptorType = USBD_FUNC_DESCRIPTOR_TYPE;
|
|
pFuncDesc->bDescriptorSubType = USBD_DESC_SUBTYPE_ACM;
|
|
pFuncDesc->iMacAddress = CDC_ECM_MAC_STRING_INDEX;
|
|
pFuncDesc->bEthernetStatistics3 = CDC_ECM_ETH_STATS_BYTE3;
|
|
pFuncDesc->bEthernetStatistics2 = CDC_ECM_ETH_STATS_BYTE2;
|
|
pFuncDesc->bEthernetStatistics1 = CDC_ECM_ETH_STATS_BYTE1;
|
|
pFuncDesc->bEthernetStatistics0 = CDC_ECM_ETH_STATS_BYTE0;
|
|
pFuncDesc->wMaxSegmentSize = CDC_ECM_ETH_MAX_SEGSZE;
|
|
pFuncDesc->bNumberMCFiltes = CDC_ECM_ETH_NBR_MACFILTERS;
|
|
pFuncDesc->bNumberPowerFiltes = CDC_ECM_ETH_NBR_PWRFILTERS;
|
|
*Sze += (uint32_t)sizeof(USBD_ECMFuncDescTypeDef);
|
|
|
|
/* Append ECM Union functional descriptor to Configuration descriptor */
|
|
pUnionDesc = ((USBD_CDCUnionFuncDescTypeDef *)(pConf + *Sze));
|
|
pUnionDesc->bLength = (uint8_t)sizeof(USBD_CDCUnionFuncDescTypeDef);
|
|
pUnionDesc->bDescriptorType = 0x24U;
|
|
pUnionDesc->bDescriptorSubtype = 0x06U;
|
|
pUnionDesc->bMasterInterface = pdev->tclasslist[pdev->classId].Ifs[0];
|
|
pUnionDesc->bSlaveInterface = pdev->tclasslist[pdev->classId].Ifs[1];
|
|
*Sze += (uint32_t)sizeof(USBD_CDCUnionFuncDescTypeDef);
|
|
|
|
/* Append ECM Communication IN Endpoint Descriptor to Configuration descriptor */
|
|
__USBD_CMPSIT_SET_EP(pdev->tclasslist[pdev->classId].Eps[2].add, USBD_EP_TYPE_INTR, CDC_ECM_CMD_PACKET_SIZE, \
|
|
CDC_ECM_HS_BINTERVAL, CDC_ECM_FS_BINTERVAL);
|
|
|
|
/* Append ECM Data class interface descriptor to Configuration descriptor */
|
|
__USBD_CMPSIT_SET_IF(pdev->tclasslist[pdev->classId].Ifs[1], 0U, 2U, 0x0AU, 0U, 0U, 0U);
|
|
|
|
if (speed == (uint8_t)USBD_SPEED_HIGH)
|
|
{
|
|
pdev->tclasslist[pdev->classId].CurrPcktSze = CDC_ECM_DATA_HS_MAX_PACKET_SIZE;
|
|
}
|
|
|
|
/* Append ECM OUT Endpoint Descriptor to Configuration descriptor */
|
|
__USBD_CMPSIT_SET_EP((pdev->tclasslist[pdev->classId].Eps[0].add), (USBD_EP_TYPE_BULK), \
|
|
(pdev->tclasslist[pdev->classId].CurrPcktSze), (CDC_ECM_HS_BINTERVAL), (CDC_ECM_FS_BINTERVAL));
|
|
|
|
/* Append ECM IN Endpoint Descriptor to Configuration descriptor */
|
|
__USBD_CMPSIT_SET_EP((pdev->tclasslist[pdev->classId].Eps[1].add), (USBD_EP_TYPE_BULK), \
|
|
(pdev->tclasslist[pdev->classId].CurrPcktSze), (CDC_ECM_HS_BINTERVAL), (CDC_ECM_FS_BINTERVAL));
|
|
|
|
/* Update Config Descriptor and IAD descriptor */
|
|
((USBD_ConfigDescTypeDef *)pConf)->bNumInterfaces += 2U;
|
|
((USBD_ConfigDescTypeDef *)pConf)->wTotalLength = (uint16_t)(*Sze);
|
|
}
|
|
#endif /* USBD_CMPSIT_ACTIVATE_CDC_ECM */
|
|
|
|
#if USBD_CMPSIT_ACTIVATE_AUDIO == 1
|
|
/**
|
|
* @brief USBD_CMPSIT_AUDIODesc
|
|
* Configure and Append the AUDIO Descriptor
|
|
* @param pdev: device instance
|
|
* @param pConf: Configuration descriptor pointer
|
|
* @param Sze: pointer to the current configuration descriptor size
|
|
* @retval None
|
|
*/
|
|
static void USBD_CMPSIT_AUDIODesc(USBD_HandleTypeDef *pdev, uint32_t pConf, __IO uint32_t *Sze, uint8_t speed)
|
|
{
|
|
static USBD_IfDescTypeDef *pIfDesc;
|
|
static USBD_IadDescTypeDef *pIadDesc;
|
|
UNUSED(speed);
|
|
|
|
/* Append AUDIO Interface descriptor to Configuration descriptor */
|
|
USBD_SpeakerIfDescTypeDef *pSpIfDesc;
|
|
USBD_SpeakerInDescTypeDef *pSpInDesc;
|
|
USBD_SpeakerFeatureDescTypeDef *pSpFDesc;
|
|
USBD_SpeakerOutDescTypeDef *pSpOutDesc;
|
|
USBD_SpeakerStreamIfDescTypeDef *pSpStrDesc;
|
|
USBD_SpeakerIIIFormatIfDescTypeDef *pSpIIIDesc;
|
|
USBD_SpeakerEndDescTypeDef *pSpEpDesc;
|
|
USBD_SpeakerEndStDescTypeDef *pSpEpStDesc;
|
|
|
|
#if USBD_COMPOSITE_USE_IAD == 1
|
|
pIadDesc = ((USBD_IadDescTypeDef *)(pConf + *Sze));
|
|
pIadDesc->bLength = (uint8_t)sizeof(USBD_IadDescTypeDef);
|
|
pIadDesc->bDescriptorType = USB_DESC_TYPE_IAD; /* IAD descriptor */
|
|
pIadDesc->bFirstInterface = pdev->tclasslist[pdev->classId].Ifs[0];
|
|
pIadDesc->bInterfaceCount = 2U; /* 2 interfaces */
|
|
pIadDesc->bFunctionClass = USB_DEVICE_CLASS_AUDIO;
|
|
pIadDesc->bFunctionSubClass = AUDIO_SUBCLASS_AUDIOCONTROL;
|
|
pIadDesc->bFunctionProtocol = AUDIO_PROTOCOL_UNDEFINED;
|
|
pIadDesc->iFunction = 0U; /* String Index */
|
|
*Sze += (uint32_t)sizeof(USBD_IadDescTypeDef);
|
|
#endif /* USBD_COMPOSITE_USE_IAD == 1 */
|
|
|
|
/* Append AUDIO Interface descriptor to Configuration descriptor */
|
|
__USBD_CMPSIT_SET_IF(pdev->tclasslist[pdev->classId].Ifs[0], 0U, 0U, USB_DEVICE_CLASS_AUDIO, \
|
|
AUDIO_SUBCLASS_AUDIOCONTROL, AUDIO_PROTOCOL_UNDEFINED, 0U);
|
|
|
|
/* Append AUDIO USB Speaker Class-specific AC Interface descriptor to Configuration descriptor */
|
|
pSpIfDesc = ((USBD_SpeakerIfDescTypeDef *)(pConf + *Sze));
|
|
pSpIfDesc->bLength = (uint8_t)sizeof(USBD_IfDescTypeDef);
|
|
pSpIfDesc->bDescriptorType = AUDIO_INTERFACE_DESCRIPTOR_TYPE;
|
|
pSpIfDesc->bDescriptorSubtype = AUDIO_CONTROL_HEADER;
|
|
pSpIfDesc->bcdADC = 0x0100U;
|
|
pSpIfDesc->wTotalLength = 0x0027U;
|
|
pSpIfDesc->bInCollection = 0x01U;
|
|
pSpIfDesc->baInterfaceNr = 0x01U;
|
|
*Sze += (uint32_t)sizeof(USBD_IfDescTypeDef);
|
|
|
|
/* Append USB Speaker Input Terminal Descriptor to Configuration descriptor*/
|
|
pSpInDesc = ((USBD_SpeakerInDescTypeDef *)(pConf + *Sze));
|
|
pSpInDesc->bLength = (uint8_t)sizeof(USBD_SpeakerInDescTypeDef);
|
|
pSpInDesc->bDescriptorType = AUDIO_INTERFACE_DESCRIPTOR_TYPE;
|
|
pSpInDesc->bDescriptorSubtype = AUDIO_CONTROL_INPUT_TERMINAL;
|
|
pSpInDesc->bTerminalID = 0x01U;
|
|
pSpInDesc->wTerminalType = 0x0101U;
|
|
pSpInDesc->bAssocTerminal = 0x00U;
|
|
pSpInDesc->bNrChannels = 0x01U;
|
|
pSpInDesc->wChannelConfig = 0x0000U;
|
|
pSpInDesc->iChannelNames = 0x00U;
|
|
pSpInDesc->iTerminal = 0x00U;
|
|
*Sze += (uint32_t)sizeof(USBD_SpeakerInDescTypeDef);
|
|
|
|
/*Append USB Speaker Audio Feature Unit Descriptor to Configuration descriptor */
|
|
pSpFDesc = ((USBD_SpeakerFeatureDescTypeDef *)(pConf + *Sze));
|
|
pSpFDesc->bLength = (uint8_t)sizeof(USBD_SpeakerFeatureDescTypeDef);
|
|
pSpFDesc->bDescriptorType = AUDIO_INTERFACE_DESCRIPTOR_TYPE;
|
|
pSpFDesc->bDescriptorSubtype = AUDIO_CONTROL_FEATURE_UNIT;
|
|
pSpFDesc->bUnitID = AUDIO_OUT_STREAMING_CTRL;
|
|
pSpFDesc->bSourceID = 0x01U;
|
|
pSpFDesc->bControlSize = 0x01U;
|
|
pSpFDesc->bmaControls = AUDIO_CONTROL_MUTE;
|
|
pSpFDesc->iTerminal = 0x00U;
|
|
*Sze += (uint32_t)sizeof(USBD_SpeakerFeatureDescTypeDef);
|
|
|
|
/*Append USB Speaker Output Terminal Descriptor to Configuration descriptor*/
|
|
pSpOutDesc = ((USBD_SpeakerOutDescTypeDef *)(pConf + *Sze));
|
|
pSpOutDesc->bLength = (uint8_t)sizeof(USBD_SpeakerOutDescTypeDef);
|
|
pSpOutDesc->bDescriptorType = AUDIO_INTERFACE_DESCRIPTOR_TYPE;
|
|
pSpOutDesc->bDescriptorSubtype = AUDIO_CONTROL_OUTPUT_TERMINAL;
|
|
pSpOutDesc->bTerminalID = 0x03U;
|
|
pSpOutDesc->wTerminalType = 0x0301U;
|
|
pSpOutDesc->bAssocTerminal = 0x00U;
|
|
pSpOutDesc->bSourceID = 0x02U;
|
|
pSpOutDesc->iTerminal = 0x00U;
|
|
*Sze += (uint32_t)sizeof(USBD_SpeakerOutDescTypeDef);
|
|
|
|
/* USB Speaker Standard AS Interface Descriptor - Audio Streaming Zero Bandwidth */
|
|
/* Interface 1, Alternate Setting 0*/
|
|
__USBD_CMPSIT_SET_IF(pdev->tclasslist[pdev->classId].Ifs[1], 0U, 0U, USB_DEVICE_CLASS_AUDIO, \
|
|
AUDIO_SUBCLASS_AUDIOSTREAMING, AUDIO_PROTOCOL_UNDEFINED, 0U);
|
|
|
|
/* USB Speaker Standard AS Interface Descriptor -Audio Streaming Operational */
|
|
/* Interface 1, Alternate Setting 1*/
|
|
__USBD_CMPSIT_SET_IF(pdev->tclasslist[pdev->classId].Ifs[1], 0x01U, 0x01U, USB_DEVICE_CLASS_AUDIO, \
|
|
AUDIO_SUBCLASS_AUDIOSTREAMING, AUDIO_PROTOCOL_UNDEFINED, 0U);
|
|
|
|
/* USB Speaker Audio Streaming Interface Descriptor */
|
|
pSpStrDesc = ((USBD_SpeakerStreamIfDescTypeDef *)(pConf + *Sze));
|
|
pSpStrDesc->bLength = (uint8_t)sizeof(USBD_SpeakerStreamIfDescTypeDef);
|
|
pSpStrDesc->bDescriptorType = AUDIO_INTERFACE_DESCRIPTOR_TYPE;
|
|
pSpStrDesc->bDescriptorSubtype = AUDIO_STREAMING_GENERAL;
|
|
pSpStrDesc->bTerminalLink = 0x01U;
|
|
pSpStrDesc->bDelay = 0x01U;
|
|
pSpStrDesc->wFormatTag = 0x0001U;
|
|
*Sze += (uint32_t)sizeof(USBD_SpeakerStreamIfDescTypeDef);
|
|
|
|
/* USB Speaker Audio Type III Format Interface Descriptor */
|
|
pSpIIIDesc = ((USBD_SpeakerIIIFormatIfDescTypeDef *)(pConf + *Sze));
|
|
pSpIIIDesc->bLength = (uint8_t)sizeof(USBD_SpeakerIIIFormatIfDescTypeDef);
|
|
pSpIIIDesc->bDescriptorType = AUDIO_INTERFACE_DESCRIPTOR_TYPE;
|
|
pSpIIIDesc->bDescriptorSubtype = AUDIO_STREAMING_FORMAT_TYPE;
|
|
pSpIIIDesc->bFormatType = AUDIO_FORMAT_TYPE_I;
|
|
pSpIIIDesc->bNrChannels = 0x02U;
|
|
pSpIIIDesc->bSubFrameSize = 0x02U;
|
|
pSpIIIDesc->bBitResolution = 16U;
|
|
pSpIIIDesc->bSamFreqType = 1U;
|
|
pSpIIIDesc->tSamFreq2 = 0x80U;
|
|
pSpIIIDesc->tSamFreq1 = 0xBBU;
|
|
pSpIIIDesc->tSamFreq0 = 0x00U;
|
|
*Sze += (uint32_t)sizeof(USBD_SpeakerIIIFormatIfDescTypeDef);
|
|
|
|
/* Endpoint 1 - Standard Descriptor */
|
|
pSpEpDesc = ((USBD_SpeakerEndDescTypeDef *)(pConf + *Sze));
|
|
pSpEpDesc->bLength = 0x09U;
|
|
pSpEpDesc->bDescriptorType = USB_DESC_TYPE_ENDPOINT;
|
|
pSpEpDesc->bEndpointAddress = pdev->tclasslist[pdev->classId].Eps[0].add;
|
|
pSpEpDesc->bmAttributes = USBD_EP_TYPE_ISOC;
|
|
pSpEpDesc->wMaxPacketSize = (uint16_t)USBD_AUDIO_GetEpPcktSze(pdev, 0U, 0U);
|
|
pSpEpDesc->bInterval = 0x01U;
|
|
pSpEpDesc->bRefresh = 0x00U;
|
|
pSpEpDesc->bSynchAddress = 0x00U;
|
|
*Sze += 0x09U;
|
|
|
|
/* Endpoint - Audio Streaming Descriptor*/
|
|
pSpEpStDesc = ((USBD_SpeakerEndStDescTypeDef *)(pConf + *Sze));
|
|
pSpEpStDesc->bLength = (uint8_t)sizeof(USBD_SpeakerEndStDescTypeDef);
|
|
pSpEpStDesc->bDescriptorType = AUDIO_ENDPOINT_DESCRIPTOR_TYPE;
|
|
pSpEpStDesc->bDescriptor = AUDIO_ENDPOINT_GENERAL;
|
|
pSpEpStDesc->bmAttributes = 0x00U;
|
|
pSpEpStDesc->bLockDelayUnits = 0x00U;
|
|
pSpEpStDesc->wLockDelay = 0x0000U;
|
|
*Sze += (uint32_t)sizeof(USBD_SpeakerEndStDescTypeDef);
|
|
|
|
/* Update Config Descriptor and IAD descriptor */
|
|
((USBD_ConfigDescTypeDef *)pConf)->bNumInterfaces += 2U;
|
|
((USBD_ConfigDescTypeDef *)pConf)->wTotalLength = (uint16_t)(*Sze);
|
|
}
|
|
#endif /* USBD_CMPSIT_ACTIVATE_AUDIO */
|
|
|
|
#if USBD_CMPSIT_ACTIVATE_RNDIS == 1
|
|
/**
|
|
* @brief USBD_CMPSIT_BULKDesc
|
|
* Configure and Append the CDC_RNDIS Descriptor
|
|
* @param pdev: device instance
|
|
* @param pConf: Configuration descriptor pointer
|
|
* @param Sze: pointer to the current configuration descriptor size
|
|
* @retval None
|
|
*/
|
|
static void USBD_CMPSIT_RNDISDesc(USBD_HandleTypeDef *pdev, uint32_t pConf, __IO uint32_t *Sze, uint8_t speed)
|
|
{
|
|
static USBD_IfDescTypeDef *pIfDesc;
|
|
static USBD_EpDescTypeDef *pEpDesc;
|
|
static USBD_CDCHeaderFuncDescTypeDef *pHeadDesc;
|
|
static USBD_CDCCallMgmFuncDescTypeDef *pCallMgmDesc;
|
|
static USBD_CDCACMFuncDescTypeDef *pACMDesc;
|
|
static USBD_CDCUnionFuncDescTypeDef *pUnionDesc;
|
|
static USBD_IadDescTypeDef *pIadDesc;
|
|
|
|
#if USBD_COMPOSITE_USE_IAD == 1
|
|
pIadDesc = ((USBD_IadDescTypeDef *)(pConf + *Sze));
|
|
pIadDesc->bLength = (uint8_t)sizeof(USBD_IadDescTypeDef);
|
|
pIadDesc->bDescriptorType = USB_DESC_TYPE_IAD; /* IAD descriptor */
|
|
pIadDesc->bFirstInterface = pdev->tclasslist[pdev->classId].Ifs[0];
|
|
pIadDesc->bInterfaceCount = 2U; /* 2 interfaces */
|
|
pIadDesc->bFunctionClass = 0xE0U;
|
|
pIadDesc->bFunctionSubClass = 0x01U;
|
|
pIadDesc->bFunctionProtocol = 0x03U;
|
|
pIadDesc->iFunction = 0U; /* String Index */
|
|
*Sze += (uint32_t)sizeof(USBD_IadDescTypeDef);
|
|
#endif /* USBD_COMPOSITE_USE_IAD == 1 */
|
|
|
|
/* Control Interface Descriptor */
|
|
__USBD_CMPSIT_SET_IF(pdev->tclasslist[pdev->classId].Ifs[0], 0U, 1U, 0x02, 0x02, 0xFF, 0U);
|
|
|
|
/* Control interface headers */
|
|
pHeadDesc = ((USBD_CDCHeaderFuncDescTypeDef *)(pConf + *Sze));
|
|
/* Header Functional Descriptor*/
|
|
pHeadDesc->bLength = (uint8_t)sizeof(USBD_CDCHeaderFuncDescTypeDef);
|
|
pHeadDesc->bDescriptorType = 0x24U;
|
|
pHeadDesc->bDescriptorSubtype = 0x00U;
|
|
pHeadDesc->bcdCDC = 0x0110U;
|
|
*Sze += (uint32_t)sizeof(USBD_CDCHeaderFuncDescTypeDef);
|
|
|
|
/* Call Management Functional Descriptor*/
|
|
pCallMgmDesc = ((USBD_CDCCallMgmFuncDescTypeDef *)(pConf + *Sze));
|
|
pCallMgmDesc->bLength = (uint8_t)sizeof(USBD_CDCCallMgmFuncDescTypeDef);
|
|
pCallMgmDesc->bDescriptorType = 0x24U;
|
|
pCallMgmDesc->bDescriptorSubtype = 0x01U;
|
|
pCallMgmDesc->bmCapabilities = 0x00U;
|
|
pCallMgmDesc->bDataInterface = pdev->tclasslist[pdev->classId].Ifs[1];
|
|
*Sze += (uint32_t)sizeof(USBD_CDCCallMgmFuncDescTypeDef);
|
|
|
|
/* ACM Functional Descriptor*/
|
|
pACMDesc = ((USBD_CDCACMFuncDescTypeDef *)(pConf + *Sze));
|
|
pACMDesc->bLength = (uint8_t)sizeof(USBD_CDCACMFuncDescTypeDef);
|
|
pACMDesc->bDescriptorType = 0x24U;
|
|
pACMDesc->bDescriptorSubtype = 0x02U;
|
|
pACMDesc->bmCapabilities = 0x00U;
|
|
*Sze += (uint32_t)sizeof(USBD_CDCACMFuncDescTypeDef);
|
|
|
|
/* Union Functional Descriptor*/
|
|
pUnionDesc = ((USBD_CDCUnionFuncDescTypeDef *)(pConf + *Sze));
|
|
pUnionDesc->bLength = (uint8_t)sizeof(USBD_CDCUnionFuncDescTypeDef);
|
|
pUnionDesc->bDescriptorType = 0x24U;
|
|
pUnionDesc->bDescriptorSubtype = 0x06U;
|
|
pUnionDesc->bMasterInterface = pdev->tclasslist[pdev->classId].Ifs[0];
|
|
pUnionDesc->bSlaveInterface = pdev->tclasslist[pdev->classId].Ifs[1];
|
|
*Sze += (uint32_t)sizeof(USBD_CDCUnionFuncDescTypeDef);
|
|
|
|
/* Append Endpoint descriptor to Configuration descriptor */
|
|
__USBD_CMPSIT_SET_EP(pdev->tclasslist[pdev->classId].Eps[2].add, USBD_EP_TYPE_INTR, \
|
|
CDC_RNDIS_CMD_PACKET_SIZE, CDC_RNDIS_HS_BINTERVAL, CDC_RNDIS_FS_BINTERVAL);
|
|
|
|
/* Data Interface Descriptor */
|
|
__USBD_CMPSIT_SET_IF(pdev->tclasslist[pdev->classId].Ifs[1], 0U, 2U, 0x0AU, 0x00U, 0x00U, 0U);
|
|
|
|
if (speed == (uint8_t)USBD_SPEED_HIGH)
|
|
{
|
|
pdev->tclasslist[pdev->classId].CurrPcktSze = CDC_RNDIS_DATA_HS_MAX_PACKET_SIZE;
|
|
}
|
|
|
|
/* Append Endpoint descriptor to Configuration descriptor */
|
|
__USBD_CMPSIT_SET_EP((pdev->tclasslist[pdev->classId].Eps[0].add), (USBD_EP_TYPE_BULK), \
|
|
(pdev->tclasslist[pdev->classId].CurrPcktSze), (0U), (0U));
|
|
|
|
/* Append Endpoint descriptor to Configuration descriptor */
|
|
__USBD_CMPSIT_SET_EP((pdev->tclasslist[pdev->classId].Eps[1].add), (USBD_EP_TYPE_BULK), \
|
|
(pdev->tclasslist[pdev->classId].CurrPcktSze), (0U), (0U));
|
|
|
|
/* Update Config Descriptor and IAD descriptor */
|
|
((USBD_ConfigDescTypeDef *)pConf)->bNumInterfaces += 2U;
|
|
((USBD_ConfigDescTypeDef *)pConf)->wTotalLength = (uint16_t)(*Sze);
|
|
}
|
|
#endif /* USBD_CMPSIT_ACTIVATE_RNDIS == 1 */
|
|
|
|
#if USBD_CMPSIT_ACTIVATE_CUSTOMHID == 1
|
|
/**
|
|
* @brief USBD_CMPSIT_CUSTOMHIDDesc
|
|
* Configure and Append the BULK Descriptor
|
|
* @param pdev: device instance
|
|
* @param pConf: Configuration descriptor pointer
|
|
* @param Sze: pointer to the current configuration descriptor size
|
|
* @retval None
|
|
*/
|
|
static void USBD_CMPSIT_CUSTOMHIDDesc(USBD_HandleTypeDef *pdev, uint32_t pConf, __IO uint32_t *Sze, uint8_t speed)
|
|
{
|
|
static USBD_IfDescTypeDef *pIfDesc;
|
|
static USBD_EpDescTypeDef *pEpDesc;
|
|
static USBD_DescTypeDef *pDesc;
|
|
|
|
/* Control Interface Descriptor */
|
|
__USBD_CMPSIT_SET_IF(pdev->tclasslist[pdev->classId].Ifs[0], 0U, 2U, 3U, 0U, 0U, 0U);
|
|
|
|
/* Descriptor of CUSTOM_HID */
|
|
pDesc = ((USBD_DescTypeDef *)((uint32_t)pConf + *Sze));
|
|
pDesc->bLength = 0x09U;
|
|
pDesc->bDescriptorTypeCHID = CUSTOM_HID_DESCRIPTOR_TYPE;
|
|
pDesc->bcdCUSTOM_HID = 0x0111U;
|
|
pDesc->bCountryCode = 0x00U;
|
|
pDesc->bNumDescriptors = 0x01U;
|
|
pDesc->bDescriptorType = 0x22U;
|
|
pDesc->wItemLength = USBD_CUSTOM_HID_REPORT_DESC_SIZE;
|
|
*Sze += (uint32_t)sizeof(USBD_DescTypeDef);
|
|
|
|
/* Descriptor of Custom HID endpoints */
|
|
/* Append Endpoint descriptor to Configuration descriptor */
|
|
__USBD_CMPSIT_SET_EP(pdev->tclasslist[pdev->classId].Eps[0].add, \
|
|
USBD_EP_TYPE_INTR, CUSTOM_HID_EPIN_SIZE, CUSTOM_HID_HS_BINTERVAL, CUSTOM_HID_FS_BINTERVAL);
|
|
|
|
/* Append Endpoint descriptor to Configuration descriptor */
|
|
__USBD_CMPSIT_SET_EP(pdev->tclasslist[pdev->classId].Eps[1].add, \
|
|
USBD_EP_TYPE_INTR, CUSTOM_HID_EPIN_SIZE, CUSTOM_HID_HS_BINTERVAL, CUSTOM_HID_FS_BINTERVAL);
|
|
|
|
/* Update Config Descriptor and IAD descriptor */
|
|
((USBD_ConfigDescTypeDef *)pConf)->bNumInterfaces += 1U;
|
|
((USBD_ConfigDescTypeDef *)pConf)->wTotalLength = (uint16_t)(*Sze);
|
|
}
|
|
#endif /* USBD_CMPSIT_ACTIVATE_CUSTOMHID == 1U */
|
|
|
|
#if USBD_CMPSIT_ACTIVATE_VIDEO == 1
|
|
/**
|
|
* @brief USBD_CMPSIT_VIDEODesc
|
|
* Configure and Append the VIDEO Descriptor
|
|
* @param pdev: device instance
|
|
* @param pConf: Configuration descriptor pointer
|
|
* @param Sze: pointer to the current configuration descriptor size
|
|
* @retval None
|
|
*/
|
|
static void USBD_CMPSIT_VIDEODesc(USBD_HandleTypeDef *pdev, uint32_t pConf, __IO uint32_t *Sze, uint8_t speed)
|
|
{
|
|
#ifdef USBD_UVC_FORMAT_UNCOMPRESSED
|
|
__ALIGN_BEGIN static uint8_t usbd_uvc_guid[16] __ALIGN_END = {DBVAL(UVC_UNCOMPRESSED_GUID), 0x00, 0x00, 0x10,
|
|
0x00, 0x80, 0x00, 0x00, 0xAA, 0x00, 0x38, 0x9B, 0x71
|
|
};
|
|
#endif /* USBD_UVC_FORMAT_UNCOMPRESSED */
|
|
static USBD_IfDescTypeDef *pIfDesc;
|
|
static USBD_IadDescTypeDef *pIadDesc;
|
|
|
|
/* Append AUDIO Interface descriptor to Configuration descriptor */
|
|
USBD_specificVCInDescTypeDef *pSVCInDesc;
|
|
USBD_InputTerminalDescTypeDef *pInTerDesc;
|
|
USBD_OutputTerminalDescTypeDef *pOuTerDesc;
|
|
USBD_ClassSpecificVsHeaderDescTypeDef *pSpHeaDesc;
|
|
USBD_PayloadFormatDescTypeDef *pPayForDesc;
|
|
#ifdef USBD_UVC_FORMAT_UNCOMPRESSED
|
|
USBD_ColorMatchingDescTypeDef *pColMaDesc;
|
|
#endif /* USBD_UVC_FORMAT_UNCOMPRESSED */
|
|
USBD_StandardVCDataEPDescTypeDef *pSVCDEP;
|
|
USBD_VIDEO_VSFrameDescTypeDef *pClassSpecVS;
|
|
|
|
#if USBD_COMPOSITE_USE_IAD == 1
|
|
pIadDesc = ((USBD_IadDescTypeDef *)(pConf + *Sze));
|
|
pIadDesc->bLength = (uint8_t)sizeof(USBD_IadDescTypeDef);
|
|
pIadDesc->bDescriptorType = USB_DESC_TYPE_IAD; /* IAD descriptor */
|
|
pIadDesc->bFirstInterface = pdev->tclasslist[pdev->classId].Ifs[0];
|
|
pIadDesc->bInterfaceCount = 2U; /* 2 interfaces */
|
|
pIadDesc->bFunctionClass = UVC_CC_VIDEO;
|
|
pIadDesc->bFunctionSubClass = SC_VIDEO_INTERFACE_COLLECTION;
|
|
pIadDesc->bFunctionProtocol = PC_PROTOCOL_UNDEFINED;
|
|
pIadDesc->iFunction = 0U; /* String Index */
|
|
*Sze += (uint32_t)sizeof(USBD_IadDescTypeDef);
|
|
#endif /* USBD_COMPOSITE_USE_IAD == 1 */
|
|
|
|
/* Append VIDEO Interface descriptor to Configuration descriptor */
|
|
__USBD_CMPSIT_SET_IF(pdev->tclasslist[pdev->classId].Ifs[0], 0U, 0U, UVC_CC_VIDEO, 1U, PC_PROTOCOL_UNDEFINED, 0U);
|
|
|
|
/* Append Class-specific VC Interface Descriptor to Configuration descriptor*/
|
|
pSVCInDesc = ((USBD_specificVCInDescTypeDef *)(pConf + *Sze));
|
|
pSVCInDesc->bLength = (uint8_t)sizeof(USBD_specificVCInDescTypeDef);
|
|
pSVCInDesc->bDescriptorType = CS_INTERFACE;
|
|
pSVCInDesc->bDescriptorSubtype = VC_HEADER;
|
|
pSVCInDesc->bcdUVC = UVC_VERSION;
|
|
pSVCInDesc->wTotalLength = 0x001EU;
|
|
pSVCInDesc->dwClockFrequency = 0x02DC6C00U;
|
|
pSVCInDesc->baInterfaceNr = 0x01U;
|
|
pSVCInDesc->iTerminal = 0x01U;
|
|
*Sze += (uint32_t)sizeof(USBD_specificVCInDescTypeDef);
|
|
|
|
/*Append Input Terminal Descriptor to Configuration descriptor */
|
|
pInTerDesc = ((USBD_InputTerminalDescTypeDef *)(pConf + *Sze));
|
|
pInTerDesc->bLength = (uint8_t)sizeof(USBD_InputTerminalDescTypeDef);
|
|
pInTerDesc->bDescriptorType = CS_INTERFACE;
|
|
pInTerDesc->bDescriptorSubtype = VC_INPUT_TERMINAL;
|
|
pInTerDesc->bTerminalID = 0x01U;
|
|
pInTerDesc->wTerminalType = ITT_VENDOR_SPECIFIC;
|
|
pInTerDesc->bAssocTerminal = 0x00U;
|
|
pInTerDesc->iTerminal = 0x00U;
|
|
*Sze += (uint32_t)sizeof(USBD_InputTerminalDescTypeDef);
|
|
|
|
/* Append Output Terminal Descriptor to Configuration descriptor */
|
|
pOuTerDesc = ((USBD_OutputTerminalDescTypeDef *)(pConf + *Sze));
|
|
pOuTerDesc->bLength = (uint8_t)sizeof(USBD_OutputTerminalDescTypeDef);
|
|
pOuTerDesc->bDescriptorType = CS_INTERFACE;
|
|
pOuTerDesc->bDescriptorSubtype = VC_OUTPUT_TERMINAL;
|
|
pOuTerDesc->bTerminalID = 0x02U;
|
|
pOuTerDesc->wTerminalType = TT_STREAMING;
|
|
pOuTerDesc->bAssocTerminal = 0x00U;
|
|
pOuTerDesc->bSourceID = 0x01U;
|
|
pOuTerDesc->iTerminal = 0x00U;
|
|
*Sze += (uint32_t)sizeof(USBD_OutputTerminalDescTypeDef);
|
|
|
|
/* Standard VS (Video Streaming) Interface Descriptor */
|
|
/* Interface 1, Alternate Setting 0 = Zero Bandwidth*/
|
|
__USBD_CMPSIT_SET_IF(pdev->tclasslist[pdev->classId].Ifs[1], 0U, 0U, UVC_CC_VIDEO, \
|
|
SC_VIDEOSTREAMING, PC_PROTOCOL_UNDEFINED, 0U);
|
|
|
|
/* Append Class-specific VS Header Descriptor (Input) to Configuration descriptor */
|
|
pSpHeaDesc = ((USBD_ClassSpecificVsHeaderDescTypeDef *)(pConf + *Sze));
|
|
pSpHeaDesc->bLength = (uint8_t)sizeof(USBD_ClassSpecificVsHeaderDescTypeDef);
|
|
pSpHeaDesc->bDescriptorType = CS_INTERFACE;
|
|
pSpHeaDesc->bDescriptorSubtype = VS_INPUT_HEADER;
|
|
pSpHeaDesc->bNumFormats = 0x4D01U;
|
|
pSpHeaDesc->bVideoControlSize = 0x00U;
|
|
pSpHeaDesc->bEndPointAddress = UVC_IN_EP;
|
|
pSpHeaDesc->bmInfo = 0x00U;
|
|
pSpHeaDesc->bTerminalLink = 0x02U;
|
|
pSpHeaDesc->bStillCaptureMethod = 0x00U;
|
|
pSpHeaDesc->bTriggerSupport = 0x00U;
|
|
pSpHeaDesc->bTriggerUsage = 0x00U;
|
|
pSpHeaDesc->bControlSize = 0x01U;
|
|
pSpHeaDesc->bmaControls = 0x00U;
|
|
*Sze += (uint32_t)sizeof(USBD_ClassSpecificVsHeaderDescTypeDef);
|
|
|
|
/* Append Payload Format Descriptor to Configuration descriptor */
|
|
pPayForDesc = ((USBD_PayloadFormatDescTypeDef *)(pConf + *Sze));
|
|
pPayForDesc->bLength = (uint8_t)sizeof(USBD_PayloadFormatDescTypeDef);
|
|
pPayForDesc->bDescriptorType = CS_INTERFACE;
|
|
pPayForDesc->bDescriptorSubType = VS_FORMAT_SUBTYPE;
|
|
pPayForDesc->bFormatIndex = 0x01U;
|
|
pPayForDesc->bNumFrameDescriptor = 0x01U;
|
|
#ifdef USBD_UVC_FORMAT_UNCOMPRESSED
|
|
(void)USBD_memcpy(pPayForDesc->pGiudFormat, usbd_uvc_guid, 16);
|
|
pPayForDesc->bBitsPerPixel = UVC_BITS_PER_PIXEL;
|
|
#else
|
|
pPayForDesc->bmFlags = 0x01U;
|
|
#endif /* USBD_UVC_FORMAT_UNCOMPRESSED */
|
|
pPayForDesc->bDefaultFrameIndex = 0x01U;
|
|
pPayForDesc->bAspectRatioX = 0x00U;
|
|
pPayForDesc->bAspectRatioY = 0x00U;
|
|
pPayForDesc->bInterlaceFlags = 0x00U;
|
|
pPayForDesc->bCopyProtect = 0x00U;
|
|
*Sze += (uint32_t)sizeof(USBD_PayloadFormatDescTypeDef);
|
|
|
|
/* Append Class-specific VS (Video Streaming) Frame Descriptor to Configuration descriptor */
|
|
pClassSpecVS = ((USBD_VIDEO_VSFrameDescTypeDef *)(pConf + *Sze));
|
|
pClassSpecVS->bLength = (uint8_t)sizeof(USBD_VIDEO_VSFrameDescTypeDef);
|
|
pClassSpecVS->bDescriptorType = CS_INTERFACE;
|
|
pClassSpecVS->bDescriptorSubType = VS_FRAME_SUBTYPE;
|
|
pClassSpecVS->bFrameIndex = 0x01U;
|
|
|
|
#ifdef USBD_UVC_FORMAT_UNCOMPRESSED
|
|
pClassSpecVS->bmCapabilities = 0x00U;
|
|
#else
|
|
pClassSpecVS->bmCapabilities = 0x02U;
|
|
#endif /* USBD_UVC_FORMAT_UNCOMPRESSED */
|
|
|
|
pClassSpecVS->wWidth = UVC_WIDTH;
|
|
pClassSpecVS->wHeight = UVC_HEIGHT;
|
|
|
|
if (speed == (uint8_t)USBD_SPEED_HIGH)
|
|
{
|
|
pClassSpecVS->dwMinBitRate = UVC_MIN_BIT_RATE(UVC_CAM_FPS_HS);
|
|
pClassSpecVS->dwMaxBitRate = UVC_MAX_BIT_RATE(UVC_CAM_FPS_HS);
|
|
pClassSpecVS->dwDefaultFrameInterval = UVC_INTERVAL(UVC_CAM_FPS_HS);
|
|
pClassSpecVS->dwMinFrameInterval = UVC_INTERVAL(UVC_CAM_FPS_HS);
|
|
}
|
|
else
|
|
{
|
|
pClassSpecVS->dwMinBitRate = UVC_MIN_BIT_RATE(UVC_CAM_FPS_FS);
|
|
pClassSpecVS->dwMaxBitRate = UVC_MAX_BIT_RATE(UVC_CAM_FPS_FS);
|
|
pClassSpecVS->dwDefaultFrameInterval = UVC_INTERVAL(UVC_CAM_FPS_FS);
|
|
pClassSpecVS->dwMinFrameInterval = UVC_INTERVAL(UVC_CAM_FPS_FS);
|
|
}
|
|
|
|
pClassSpecVS->dwMaxVideoFrameBufSize = UVC_MAX_FRAME_SIZE;
|
|
pClassSpecVS->bFrameIntervalType = 0x01U;
|
|
|
|
*Sze += (uint32_t)sizeof(USBD_VIDEO_VSFrameDescTypeDef);
|
|
|
|
#ifdef USBD_UVC_FORMAT_UNCOMPRESSED
|
|
/* Append Color Matching Descriptor to Configuration descriptor */
|
|
pColMaDesc = ((USBD_ColorMatchingDescTypeDef *)(pConf + *Sze));
|
|
pColMaDesc->bLength = (uint8_t)sizeof(USBD_ColorMatchingDescTypeDef);
|
|
pColMaDesc->bDescriptorType = CS_INTERFACE;
|
|
pColMaDesc->bDescriptorSubType = VS_COLORFORMAT;
|
|
pColMaDesc->bColorPrimarie = UVC_COLOR_PRIMARIE;
|
|
pColMaDesc->bTransferCharacteristics = UVC_TFR_CHARACTERISTICS;
|
|
pColMaDesc->bMatrixCoefficients = UVC_MATRIX_COEFFICIENTS;
|
|
*Sze += (uint32_t)sizeof(USBD_ColorMatchingDescTypeDef);
|
|
#endif /* USBD_UVC_FORMAT_UNCOMPRESSED */
|
|
|
|
/* USB Standard VS Interface Descriptor - data transfer mode */
|
|
/* Interface 1, Alternate Setting 1*/
|
|
__USBD_CMPSIT_SET_IF(1U, 1U, 1U, UVC_CC_VIDEO, SC_VIDEOSTREAMING, PC_PROTOCOL_UNDEFINED, 0U);
|
|
|
|
/* Standard VS (Video Streaming) data Endpoint */
|
|
pSVCDEP = ((USBD_StandardVCDataEPDescTypeDef *)(pConf + *Sze));
|
|
pSVCDEP->bLength = (uint8_t)sizeof(USBD_StandardVCDataEPDescTypeDef);
|
|
pSVCDEP->bDescriptorType = USB_DESC_TYPE_ENDPOINT;
|
|
pSVCDEP->bEndpointAddress = UVC_IN_EP;
|
|
pSVCDEP->bmAttributes = 0x05U;
|
|
pSVCDEP->bInterval = 0x01U;
|
|
|
|
if (speed == (uint8_t)USBD_SPEED_HIGH)
|
|
{
|
|
pSVCDEP->wMaxPacketSize = UVC_ISO_HS_MPS;
|
|
}
|
|
else
|
|
{
|
|
pSVCDEP->wMaxPacketSize = UVC_ISO_FS_MPS;
|
|
}
|
|
|
|
*Sze += (uint32_t)sizeof(USBD_StandardVCDataEPDescTypeDef);
|
|
|
|
/* Update Config Descriptor and IAD descriptor */
|
|
((USBD_ConfigDescTypeDef *)pConf)->bNumInterfaces += 2U;
|
|
((USBD_ConfigDescTypeDef *)pConf)->wTotalLength = (uint16_t)(*Sze);
|
|
}
|
|
#endif /* USBD_CMPSIT_ACTIVATE_VIDEO == 1 */
|
|
|
|
#if USBD_CMPSIT_ACTIVATE_PRINTER == 1
|
|
/**
|
|
* @brief USBD_CMPSIT_PRINTERDesc
|
|
* Configure and Append the PRINTER Descriptor
|
|
* @param pdev: device instance
|
|
* @param pConf: Configuration descriptor pointer
|
|
* @param Sze: pointer to the current configuration descriptor size
|
|
* @retval None
|
|
*/
|
|
static void USBD_CMPSIT_PRNTDesc(USBD_HandleTypeDef *pdev, uint32_t pConf, __IO uint32_t *Sze, uint8_t speed)
|
|
{
|
|
static USBD_IfDescTypeDef *pIfDesc;
|
|
static USBD_EpDescTypeDef *pEpDesc;
|
|
|
|
/* Control Interface Descriptor */
|
|
__USBD_CMPSIT_SET_IF(pdev->tclasslist[pdev->classId].Ifs[0], 0U, 0x02, 0x07, 0x01U, USB_PRNT_BIDIRECTIONAL, 0U);
|
|
|
|
if (speed == (uint8_t)USBD_SPEED_HIGH)
|
|
{
|
|
pdev->tclasslist[pdev->classId].CurrPcktSze = PRNT_DATA_HS_MAX_PACKET_SIZE;
|
|
}
|
|
|
|
/* Append Endpoint descriptor to Configuration descriptor */
|
|
__USBD_CMPSIT_SET_EP((pdev->tclasslist[pdev->classId].Eps[1].add), \
|
|
(USBD_EP_TYPE_BULK), (pdev->tclasslist[pdev->classId].CurrPcktSze), (0U), (0U));
|
|
|
|
/* Append Endpoint descriptor to Configuration descriptor */
|
|
__USBD_CMPSIT_SET_EP((pdev->tclasslist[pdev->classId].Eps[0].add), \
|
|
(USBD_EP_TYPE_BULK), (pdev->tclasslist[pdev->classId].CurrPcktSze), (0U), (0U));
|
|
|
|
/* Update Config Descriptor and IAD descriptor */
|
|
((USBD_ConfigDescTypeDef *)pConf)->bNumInterfaces += 1U;
|
|
((USBD_ConfigDescTypeDef *)pConf)->wTotalLength = (uint16_t)(*Sze);
|
|
}
|
|
#endif /* USBD_CMPSIT_ACTIVATE_PRINTER == 1 */
|
|
|
|
#if USBD_CMPSIT_ACTIVATE_CCID == 1
|
|
/**
|
|
* @brief USBD_CMPSIT_CCIDDesc
|
|
* Configure and Append the CCID Descriptor
|
|
* @param pdev: device instance
|
|
* @param pConf: Configuration descriptor pointer
|
|
* @param Sze: pointer to the current configuration descriptor size
|
|
* @retval None
|
|
*/
|
|
static void USBD_CMPSIT_CCIDDesc(USBD_HandleTypeDef *pdev, uint32_t pConf, __IO uint32_t *Sze, uint8_t speed)
|
|
{
|
|
static USBD_IfDescTypeDef *pIfDesc;
|
|
static USBD_EpDescTypeDef *pEpDesc;
|
|
static USBD_CCID_DescTypeDef *pDesc;
|
|
|
|
/* Control Interface Descriptor */
|
|
__USBD_CMPSIT_SET_IF(pdev->tclasslist[pdev->classId].Ifs[0], 0U, 0x03, 0x0BU, 0U, 0U, 0U);
|
|
|
|
/* Control interface headers */
|
|
pDesc = ((USBD_CCID_DescTypeDef *)((uint32_t)pConf + *Sze));
|
|
|
|
/* Device Descriptor */
|
|
pDesc->bLength = 0x36U;
|
|
pDesc->bDescriptorType = 0x21U;
|
|
pDesc->bcdCCID = 0x0110U;
|
|
pDesc->bMaxSlotIndex = 0x00U;
|
|
pDesc->bVoltageSupport = CCID_VOLTAGE_SUPP;
|
|
pDesc->dwProtocols = USBD_CCID_PROTOCOL;
|
|
pDesc->dwDefaultClock = USBD_CCID_DEFAULT_CLOCK_FREQ;
|
|
pDesc->dwMaximumClock = USBD_CCID_MAX_CLOCK_FREQ;
|
|
pDesc->bNumClockSupported = 0x00U;
|
|
pDesc->dwDataRate = USBD_CCID_DEFAULT_DATA_RATE;
|
|
pDesc->dwMaxDataRate = USBD_CCID_MAX_DATA_RATE;
|
|
pDesc->bNumDataRatesSupported = 0x35U;
|
|
pDesc->dwMaxIFSD = USBD_CCID_MAX_INF_FIELD_SIZE;
|
|
pDesc->dwSynchProtocols = 0U;
|
|
pDesc->dwMechanical = 0U;
|
|
pDesc->dwFeatures = 0x000104BAU;
|
|
pDesc->dwMaxCCIDMessageLength = CCID_MAX_BLOCK_SIZE_HEADER;
|
|
pDesc->bClassGetResponse = 0U;
|
|
pDesc->bClassEnvelope = 0U;
|
|
pDesc->wLcdLayout = 0U;
|
|
pDesc->bPINSupport = 0x03U;
|
|
pDesc->bMaxCCIDBusySlots = 0x01U;
|
|
|
|
*Sze += (uint32_t)sizeof(USBD_CCID_DescTypeDef);
|
|
|
|
if (speed == (uint8_t)USBD_SPEED_HIGH)
|
|
{
|
|
pdev->tclasslist[pdev->classId].CurrPcktSze = CCID_DATA_HS_MAX_PACKET_SIZE;
|
|
}
|
|
|
|
/* Append Endpoint descriptor to Configuration descriptor */
|
|
__USBD_CMPSIT_SET_EP((pdev->tclasslist[pdev->classId].Eps[0].add), \
|
|
(USBD_EP_TYPE_BULK), (pdev->tclasslist[pdev->classId].CurrPcktSze), (0U), (0U));
|
|
|
|
/* Append Endpoint descriptor to Configuration descriptor */
|
|
__USBD_CMPSIT_SET_EP((pdev->tclasslist[pdev->classId].Eps[1].add), \
|
|
(USBD_EP_TYPE_BULK), (pdev->tclasslist[pdev->classId].CurrPcktSze), (0U), (0U));
|
|
|
|
/* Append Endpoint descriptor to Configuration descriptor */
|
|
__USBD_CMPSIT_SET_EP(pdev->tclasslist[pdev->classId].Eps[2].add, \
|
|
USBD_EP_TYPE_INTR, CCID_CMD_PACKET_SIZE, CCID_CMD_HS_BINTERVAL, CCID_CMD_FS_BINTERVAL);
|
|
|
|
/* Update Config Descriptor and IAD descriptor */
|
|
((USBD_ConfigDescTypeDef *)pConf)->bNumInterfaces += 1U;
|
|
((USBD_ConfigDescTypeDef *)pConf)->wTotalLength = (uint16_t)(*Sze);
|
|
}
|
|
#endif /* USBD_CMPSIT_ACTIVATE_CCID == 1 */
|
|
|
|
#if USBD_CMPSIT_ACTIVATE_MTP == 1
|
|
/**
|
|
* @brief USBD_CMPSIT_MTPDesc
|
|
* Configure and Append the MTP Descriptor
|
|
* @param pdev: device instance
|
|
* @param pConf: Configuration descriptor pointer
|
|
* @param Sze: pointer to the current configuration descriptor size
|
|
* @retval None
|
|
*/
|
|
static void USBD_CMPSIT_MTPDesc(USBD_HandleTypeDef *pdev, uint32_t pConf, __IO uint32_t *Sze, uint8_t speed)
|
|
{
|
|
USBD_IfDescTypeDef *pIfDesc;
|
|
USBD_EpDescTypeDef *pEpDesc;
|
|
|
|
/* Append MTP Interface descriptor */
|
|
__USBD_CMPSIT_SET_IF((pdev->tclasslist[pdev->classId].Ifs[0]), (0U), \
|
|
(uint8_t)(pdev->tclasslist[pdev->classId].NumEps), USB_MTP_INTRERFACE_CLASS, \
|
|
USB_MTP_INTRERFACE_SUB_CLASS, USB_MTP_INTRERFACE_PROTOCOL, (0U));
|
|
|
|
if (speed == (uint8_t)USBD_SPEED_HIGH)
|
|
{
|
|
pdev->tclasslist[pdev->classId].CurrPcktSze = MTP_DATA_MAX_HS_PACKET_SIZE;
|
|
}
|
|
|
|
/* Append Endpoint descriptor to Configuration descriptor */
|
|
__USBD_CMPSIT_SET_EP((pdev->tclasslist[pdev->classId].Eps[0].add), (USBD_EP_TYPE_BULK), \
|
|
(pdev->tclasslist[pdev->classId].CurrPcktSze), (0U), (0U));
|
|
|
|
/* Append Endpoint descriptor to Configuration descriptor */
|
|
__USBD_CMPSIT_SET_EP((pdev->tclasslist[pdev->classId].Eps[1].add), (USBD_EP_TYPE_BULK), \
|
|
(pdev->tclasslist[pdev->classId].CurrPcktSze), (0U), (0U));
|
|
|
|
/* Append Endpoint descriptor to Configuration descriptor */
|
|
__USBD_CMPSIT_SET_EP(pdev->tclasslist[pdev->classId].Eps[2].add, \
|
|
USBD_EP_TYPE_INTR, MTP_CMD_PACKET_SIZE, MTP_HS_BINTERVAL, MTP_FS_BINTERVAL);
|
|
|
|
/* Update Config Descriptor and IAD descriptor */
|
|
((USBD_ConfigDescTypeDef *)pConf)->bNumInterfaces += 1U;
|
|
((USBD_ConfigDescTypeDef *)pConf)->wTotalLength = (uint16_t)(*Sze);
|
|
}
|
|
#endif /* USBD_CMPSIT_ACTIVATE_MTP == 1 */
|
|
|
|
/**
|
|
* @brief USBD_CMPSIT_SetClassID
|
|
* Find and set the class ID relative to selected class type and instance
|
|
* @param pdev: device instance
|
|
* @param Class: Class type, can be CLASS_TYPE_NONE if requested to find class from setup request
|
|
* @param Instance: Instance number of the class (0 if first/unique instance, >0 otherwise)
|
|
* @retval The Class ID, The pdev->classId is set with the value of the selected class ID.
|
|
*/
|
|
uint32_t USBD_CMPSIT_SetClassID(USBD_HandleTypeDef *pdev, USBD_CompositeClassTypeDef Class, uint32_t Instance)
|
|
{
|
|
uint32_t idx;
|
|
uint32_t inst = 0U;
|
|
|
|
/* Unroll all already activated classes */
|
|
for (idx = 0U; idx < pdev->NumClasses; idx++)
|
|
{
|
|
/* Check if the class correspond to the requested type and if it is active */
|
|
if (((USBD_CompositeClassTypeDef)(pdev->tclasslist[idx].ClassType) == Class) &&
|
|
((pdev->tclasslist[idx].Active) == 1U))
|
|
{
|
|
if (inst == Instance)
|
|
{
|
|
/* Set the new class ID */
|
|
pdev->classId = idx;
|
|
|
|
/* Return the class ID value */
|
|
return (idx);
|
|
}
|
|
else
|
|
{
|
|
/* Increment instance index and look for next instance */
|
|
inst++;
|
|
}
|
|
}
|
|
}
|
|
|
|
/* No class found, return 0xFF */
|
|
return 0xFFU;
|
|
}
|
|
|
|
/**
|
|
* @brief USBD_CMPSIT_GetClassID
|
|
* Returns the class ID relative to selected class type and instance
|
|
* @param pdev: device instance
|
|
* @param Class: Class type, can be CLASS_TYPE_NONE if requested to find class from setup request
|
|
* @param Instance: Instance number of the class (0 if first/unique instance, >0 otherwise)
|
|
* @retval The Class ID (this function does not set the pdev->classId field.
|
|
*/
|
|
uint32_t USBD_CMPSIT_GetClassID(USBD_HandleTypeDef *pdev, USBD_CompositeClassTypeDef Class, uint32_t Instance)
|
|
{
|
|
uint32_t idx;
|
|
uint32_t inst = 0U;
|
|
|
|
/* Unroll all already activated classes */
|
|
for (idx = 0U; idx < pdev->NumClasses; idx++)
|
|
{
|
|
/* Check if the class correspond to the requested type and if it is active */
|
|
if (((USBD_CompositeClassTypeDef)(pdev->tclasslist[idx].ClassType) == Class) &&
|
|
((pdev->tclasslist[idx].Active) == 1U))
|
|
{
|
|
if (inst == Instance)
|
|
{
|
|
/* Return the class ID value */
|
|
return (idx);
|
|
}
|
|
else
|
|
{
|
|
/* Increment instance index and look for next instance */
|
|
inst++;
|
|
}
|
|
}
|
|
}
|
|
|
|
/* No class found, return 0xFF */
|
|
return 0xFFU;
|
|
}
|
|
|
|
/**
|
|
* @brief USBD_CMPST_ClearConfDesc
|
|
* Reset the configuration descriptor
|
|
* @param pdev: device instance (reserved for future use)
|
|
* @retval Status.
|
|
*/
|
|
uint8_t USBD_CMPST_ClearConfDesc(USBD_HandleTypeDef *pdev)
|
|
{
|
|
UNUSED(pdev);
|
|
|
|
/* Reset the configuration descriptor pointer to default value and its size to zero */
|
|
pCmpstFSConfDesc = USBD_CMPSIT_FSCfgDesc;
|
|
CurrFSConfDescSz = 0U;
|
|
|
|
#ifdef USE_USB_HS
|
|
pCmpstHSConfDesc = USBD_CMPSIT_HSCfgDesc;
|
|
CurrHSConfDescSz = 0U;
|
|
#endif /* USE_USB_HS */
|
|
|
|
/* All done, can't fail */
|
|
return (uint8_t)USBD_OK;
|
|
}
|
|
|
|
#endif /* USE_USBD_COMPOSITE */
|
|
|
|
/**
|
|
* @}
|
|
*/
|
|
|
|
|
|
/**
|
|
* @}
|
|
*/
|
|
|
|
|
|
/**
|
|
* @}
|
|
*/
|
|
|
|
|