0
mirror of https://gitlab.com/hyperglitch/jellyfish.git synced 2026-01-02 16:21:55 +00:00

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 */
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/