最近看USB方面的协议,从实现USB麦克风、多串口、USB麦克风+扬声器,到目前的USB耳机+多路CDC,对USB的拓扑方式有了更深的理解,本文记录下任意类的USB组合设备的实现方式,以USB Composite 组合设备之耳机+多路CDC为实验对象
USB组合设备中,需要注意增添的类所占用的字节数
,接口数
、端点地址数
、分配相对应的端点地址、设置好USB FIFO
主要关注如下配置:
usbd_conf.h
#define USBD_MAX_NUM_INTERFACES 10U /* 多路CDC最大占用6个接口 */
/* 增加如下配置 */
#define USE_USBD_COMPOSITE 1
#define USBD_COMPOSITE_USE_IAD 1
#define USBD_CMPSIT_ACTIVATE_AUDIO 0
#define USBD_CMPSIT_ACTIVATE_CDC 0
#define USBD_CMPSIT_ACTIVATE_MICROPHONE 0
#define USBD_CMPSIT_ACTIVATE_HEADPHONE 1
#define USBD_CMPSIT_ACTIVATE_MULTI_CDC 1
usbd_def.h
#ifndef USBD_MAX_CLASS_ENDPOINTS
#define USBD_MAX_CLASS_ENDPOINTS 10U /* 每个类最大端点数9: CDC 3端点 * 3接口 */
#endif /* USBD_MAX_CLASS_ENDPOINTS */
#ifndef USBD_MAX_CLASS_INTERFACES
#define USBD_MAX_CLASS_INTERFACES 8U /* 每个类的最大接口数:多路CDC MAX 6 */
#endif /* USBD_MAX_CLASS_INTERFACES */
增加如下类:
typedef enum
{
CLASS_TYPE_NONE = 0,
CLASS_TYPE_HID = 1,
CLASS_TYPE_CDC = 2,
CLASS_TYPE_MSC = 3,
CLASS_TYPE_DFU = 4,
CLASS_TYPE_CHID = 5,
CLASS_TYPE_AUDIO = 6, //扬声器
CLASS_TYPE_ECM = 7,
CLASS_TYPE_RNDIS = 8,
CLASS_TYPE_MTP = 9,
CLASS_TYPE_VIDEO = 10,
CLASS_TYPE_PRINTER = 11,
CLASS_TYPE_CCID = 12,
CLASS_TYPE_MICROPHONE = 13, //麦克风
CLASS_TYPE_HEADPHONE = 14, //耳机
CLASS_TYPE_MULTI_CDC = 15, //多路CDC
} USBD_CompositeClassTypeDef;
usbd_conf.c
/* EP_OUT: 0x00(64) 0x01(CDC 64) 0x02(Speaker 64) 0x03(CDC2 64) 0x04(CDC3 64) 最小64Bytes,HAL_PCDEx_SetRxFiFo每个数值代表4Bytes */
HAL_PCDEx_SetRxFiFo(&hpcd_USB_OTG_FS, 16 + 16 * 7);
/* EP_IN: 0x80(64) 0x81(CDC 64) 0x82(Microphone 64) 0x83(CDC2 64) 0x84(CD3 64) 0x85(CDC 8) 0x86(CDC2 8) 0x87(CDC3 8) */
HAL_PCDEx_SetTxFiFo(&hpcd_USB_OTG_FS, 0, 16);
HAL_PCDEx_SetTxFiFo(&hpcd_USB_OTG_FS, 1, 16);
HAL_PCDEx_SetTxFiFo(&hpcd_USB_OTG_FS, 2, 16);
HAL_PCDEx_SetTxFiFo(&hpcd_USB_OTG_FS, 3, 16);
HAL_PCDEx_SetTxFiFo(&hpcd_USB_OTG_FS, 4, 16);
HAL_PCDEx_SetTxFiFo(&hpcd_USB_OTG_FS, 5, 16);
HAL_PCDEx_SetTxFiFo(&hpcd_USB_OTG_FS, 6, 16);
HAL_PCDEx_SetTxFiFo(&hpcd_USB_OTG_FS, 7, 16);
/* 设备RxFIFO =(5 * 控制端点数 + 8)+((使用的最大USB包 / 4) + 1用于状态信息)+ (2 * OUT端点数) + 1用于全局NAK
例如:周期USB报文的MPS为1024字节,非周期USB报文的MPS为512字节。有三个OUT端点、三个IN端点、一个控制端点和三个主机通道。
设备RxFIFO = (5 * 1 + 8) + ((1024 / 4) + 1) + (2 * 4) + 1 = 279 */
FIFO的设置关乎USB运行稳定性,建议TX设置为该端点地址数据的最大包长Bytes / 4,剩余的可以全部给RX
所以本次最终设置如下:FIFO总大小4096Bytes
/* EP_OUT: 0x00(64) 0x01(CDC 64) 0x02(Speaker 64) 0x03(CDC2 64) 0x04(CDC3 64) 最小64Bytes,HAL_PCDEx_SetRxFiFo每个数值代表4Bytes */
HAL_PCDEx_SetRxFiFo(&hpcd_USB_OTG_FS, 880); // 880 * 4Bytes = 3520Bytes
/* EP_IN: 0x80(64) 0x81(CDC 64) 0x82(Microphone 64) 0x83(CDC2 64) 0x84(CD3 64) 0x85(CDC 8) 0x86(CDC2 8) 0x87(CDC3 8) */
HAL_PCDEx_SetTxFiFo(&hpcd_USB_OTG_FS, 0, 16);
HAL_PCDEx_SetTxFiFo(&hpcd_USB_OTG_FS, 1, 16);
HAL_PCDEx_SetTxFiFo(&hpcd_USB_OTG_FS, 2, AUDIO_OUT_PACKET / 4);
HAL_PCDEx_SetTxFiFo(&hpcd_USB_OTG_FS, 3, 16);
HAL_PCDEx_SetTxFiFo(&hpcd_USB_OTG_FS, 4, 16);
HAL_PCDEx_SetTxFiFo(&hpcd_USB_OTG_FS, 5, 16);
HAL_PCDEx_SetTxFiFo(&hpcd_USB_OTG_FS, 6, 16);
HAL_PCDEx_SetTxFiFo(&hpcd_USB_OTG_FS, 7, 16);
在FIFO设置中已有描述
EP_IN: 0x80(64) 0x81(CDC 64) 0x82(Microphone 64) 0x83(CDC2 64) 0x84(CD3 64) 0x85(CDC 8) 0x86(CDC2 8) 0x87(CDC3 8)
EP_OUT: 0x00(64) 0x01(CDC 64) 0x02(Speaker 64) 0x03(CDC2 64) 0x04(CDC3 64) 最小64Bytes,HAL_PCDEx_SetRxFiFo每个数值代表4Bytes
usbd_desc.c
改为IAD设备类
0xEF, /*bDeviceClass*/
0x02, /*bDeviceSubClass*/
0x01, /*bDeviceProtocol*/
这两个描述符修改我们增加如下文件:
usbd_composite_builder.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 "../inc/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_MSC == 1U
static void USBD_CMPSIT_MSCDesc(USBD_HandleTypeDef *pdev, uint32_t pConf, __IO uint32_t *Sze, uint8_t speed);
#endif /* USBD_CMPSIT_ACTIVATE_MSC == 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 */
#if USBD_CMPSIT_ACTIVATE_MICROPHONE == 1U
static void USBD_CMPSIT_MICROPHONEDesc(USBD_HandleTypeDef *pdev, uint32_t pConf, __IO uint32_t *Sze, uint8_t speed);
#endif /* USBD_CMPSIT_ACTIVATE_MICROPHONE == 1U */
#if USBD_CMPSIT_ACTIVATE_HEADPHONE == 1U
static void USBD_CMPSIT_HEADPHONEDesc(USBD_HandleTypeDef *pdev, uint32_t pConf, __IO uint32_t *Sze, uint8_t speed);
#endif /* USBD_CMPSIT_ACTIVATE_HEADPHONE == 1U */
#if USBD_CMPSIT_ACTIVATE_MULTI_CDC == 1U
static void USBD_CMPSIT_MULTI_CDCDesc(USBD_HandleTypeDef *pdev, uint32_t pConf, __IO uint32_t *Sze, uint8_t speed);
#endif /* USBD_CMPSIT_ACTIVATE_MULTI_CDC == 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_MSC == 1
case CLASS_TYPE_MSC:
/* Setup default Max packet size */
pdev->tclasslist[pdev->classId].CurrPcktSze = MSC_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_MSCDesc(pdev, (uint32_t)pCmpstFSConfDesc, &CurrFSConfDescSz, (uint8_t)USBD_SPEED_FULL);
#ifdef USE_USB_HS
USBD_CMPSIT_MSCDesc(pdev, (uint32_t)pCmpstHSConfDesc, &CurrHSConfDescSz, (uint8_t)USBD_SPEED_HIGH);
#endif /* USE_USB_HS */
break;
#endif /* USBD_CMPSIT_ACTIVATE_MSC */
#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_MULTI_CDC == 1
case CLASS_TYPE_MULTI_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 = 0x02 * USE_CDC_NUM;
for(uint8_t i = 0; i < USE_CDC_NUM; i++)
{
pdev->tclasslist[pdev->classId].Ifs[i * 2] = idxIf;
idxIf++;
pdev->tclasslist[pdev->classId].Ifs[i * 2 + 1] = idxIf;
idxIf++;
}
/* Assign endpoint numbers */
pdev->tclasslist[pdev->classId].NumEps = 3U * USE_CDC_NUM;
for(uint8_t i = 0; i < USE_CDC_NUM; i++)
{
/* Set IN endpoint slot */
iEp = pdev->tclasslist[pdev->classId].EpAdd[i * 3];
USBD_CMPSIT_AssignEp(pdev, iEp, USBD_EP_TYPE_BULK, pdev->tclasslist[pdev->classId].CurrPcktSze);
/* Set OUT endpoint slot */
iEp = pdev->tclasslist[pdev->classId].EpAdd[i * 3 + 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[i * 3 + 2];
USBD_CMPSIT_AssignEp(pdev, iEp, USBD_EP_TYPE_INTR, CDC_CMD_PACKET_SIZE);
}
/* Configure and Append the Descriptor */
USBD_CMPSIT_MULTI_CDCDesc(pdev, (uint32_t)pCmpstFSConfDesc, &CurrFSConfDescSz, (uint8_t)USBD_SPEED_FULL);
#ifdef USE_USB_HS
USBD_CMPSIT_MULTI_CDCDesc(pdev, (uint32_t)pCmpstHSConfDesc, &CurrHSConfDescSz, (uint8_t)USBD_SPEED_HIGH);
#endif /* USE_USB_HS */
break;
#endif /* USBD_CMPSIT_ACTIVATE_MULTI_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_MICROPHONE == 1
case CLASS_TYPE_MICROPHONE:
/* 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; /* EP_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 (only FS mode supported) */
USBD_CMPSIT_MICROPHONEDesc(pdev, (uint32_t)pCmpstFSConfDesc, &CurrFSConfDescSz, (uint8_t)USBD_SPEED_FULL);
break;
#endif /* USBD_CMPSIT_ACTIVATE_MICROPHONE */
#if USBD_CMPSIT_ACTIVATE_HEADPHONE == 1
case CLASS_TYPE_HEADPHONE:
/* 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 = 3U;
pdev->tclasslist[pdev->classId].Ifs[0] = idxIf;
pdev->tclasslist[pdev->classId].Ifs[1] = (uint8_t)(idxIf + 1U);
pdev->tclasslist[pdev->classId].Ifs[2] = (uint8_t)(idxIf + 2U);
/* Assign endpoint numbers */
pdev->tclasslist[pdev->classId].NumEps = 2U; /* EP_IN EP_OUT */
/* 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);
/* Set OUT endpoint slot */
iEp = pdev->tclasslist[pdev->classId].EpAdd[1];
/* 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_HEADPHONEDesc(pdev, (uint32_t)pCmpstFSConfDesc, &CurrFSConfDescSz, (uint8_t)USBD_SPEED_FULL);
break;
#endif /* USBD_CMPSIT_ACTIVATE_HEADPHONE */
#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