From 8b1b494232543c092c851743df55838cd666ef22 Mon Sep 17 00:00:00 2001 From: esea_info Date: Tue, 9 Apr 2024 04:03:03 +0000 Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=96=B0=20'DOC/22=5FMSC=5FCDC=5FCMPS?= =?UTF-8?q?T.md'?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- DOC/22_MSC_CDC_CMPST.md | 725 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 725 insertions(+) diff --git a/DOC/22_MSC_CDC_CMPST.md b/DOC/22_MSC_CDC_CMPST.md index e69de29..cfc5b19 100644 --- a/DOC/22_MSC_CDC_CMPST.md +++ b/DOC/22_MSC_CDC_CMPST.md @@ -0,0 +1,725 @@ +usb官网:https://usb.org/ +利用 USE_USBD_COMPOSITE 宏, + +#define USE_USBD_COMPOSITE 1 + +新增复合设备类(composite)代码 usbd_composite_builder.c +含 配置描述符 IAD ,多设备 接口偶联描述符 + +void USBD_CMPSIT_AddClass(USBD_HandleTypeDef *pdev, USBD_ClassTypeDef *pclass, USBD_CompositeClassTypeDef classtype, uint8_t *EpAddr) +{} + +USB MX_USB_DEVICE_Init(void) 初始化 , 调用 USBD_RegisterClassComposite 函数, USBD_RegisterClassComposite 调用函数 USBD_CMPSIT_AddClass + + + + +配置主要信息内容:使用了几个接口,每个接口实现什么设备功能(CDC、HID、MSC...),使用了什么样的端点等, +本例程主要用了三个接口,CDC使用了两个,index为0和1,MSC使用了一个,index为2。配置描述符如下: + + + + +usbd_conf.h修改部分 +CDC使用了0x81、0x01、0x82,MSC使用了0x83、0x03 + +#ifndef CDC_IN_EP +#define CDC_IN_EP 0x81U /* EP1 for data IN */ +#endif /* CDC_IN_EP */ +#ifndef CDC_OUT_EP +#define CDC_OUT_EP 0x01U /* EP1 for data OUT */ +#endif /* CDC_OUT_EP */ +#ifndef CDC_CMD_EP +#define CDC_CMD_EP 0x82U /* EP2 for CDC commands */ +#endif /* CDC_CMD_EP */ + + +#ifndef MSC_EPIN_ADDR +#define MSC_EPIN_ADDR 0x83U +#endif /* MSC_EPIN_ADDR */ + +#ifndef MSC_EPOUT_ADDR +#define MSC_EPOUT_ADDR 0x03U +#endif /* MSC_EPOUT_ADDR */ + + + +底层初始化部分修改,usbd_conf.c中USBD_LL_Init + + +配置端点数目, 上面五个+系统1个 + hpcd_USB_OTG_FS.Init.dev_endpoints = 6; + +配置FIFO + HAL_PCDEx_SetRxFiFo(&hpcd_USB_OTG_FS, 0x80); // 接收端点 + HAL_PCDEx_SetTxFiFo(&hpcd_USB_OTG_FS, 0, 0x40); // 系统默认发送端点 + // HAL_PCDEx_SetTxFiFo(&hpcd_USB_OTG_FS, 1, 0x80); + HAL_PCDEx_SetTxFiFo(&hpcd_USB_OTG_FS, 1, 0x40); // CDC 发送端点, CDC命令端点用系统默认发送 + HAL_PCDEx_SetTxFiFo(&hpcd_USB_OTG_FS, 3, 0x40); // MSC 发送端点 + +管理 pdev->ClassID +usbd_cdc.c USBD_CDC_RegisterInterface pdev->ClassID--; *** =fops; pdev->ClassID--; +usbd_msc.c USBD_MSC_RegisterStorage pdev->ClassID--; *** =fops; pdev->ClassID--; + + + +```C +void MX_USB_DEVICE_Init(void) +{ + /* USER CODE BEGIN USB_DEVICE_Init_PreTreatment */ + /* USER CODE END USB_DEVICE_Init_PreTreatment */ + + /* Init Device Library, add supported class and start the library. */ + if (USBD_Init(&hUsbDeviceFS, &usbCmpsitFS_Desc, DEVICE_FS) != USBD_OK) + { + Error_Handler(); + } + /* if (USBD_RegisterClass(&hUsbDeviceFS, &USBD_MSC) != USBD_OK) + { + Error_Handler(); + } */ + + if(USBD_RegisterClassComposite(&hUsbDeviceFS, &USBD_CDC,CLASS_TYPE_CDC,0) != USBD_OK) + { + Error_Handler(); + } + + if(USBD_CDC_RegisterInterface(&hUsbDeviceFS, &USBD_Interface_fops_FS) != USBD_OK) + { + Error_Handler(); + } + if(USBD_RegisterClassComposite(&hUsbDeviceFS, &USBD_MSC,CLASS_TYPE_MSC,0) != USBD_OK) + { + Error_Handler(); + } + if (USBD_MSC_RegisterStorage(&hUsbDeviceFS, &USBD_Storage_Interface_fops_FS) != USBD_OK) + { + Error_Handler(); + } + if (USBD_Start(&hUsbDeviceFS) != USBD_OK) + { + Error_Handler(); + } + + +} +``` + + + +```C +#ifdef USE_USBD_COMPOSITE +void USBD_CMPSIT_AddClass(USBD_HandleTypeDef *pdev, USBD_ClassTypeDef *pclass, USBD_CompositeClassTypeDef classtype, uint8_t *EpAddr) +{ + //printf("classId=%d : %d\r\n",pdev->classId,classtype); + switch(classtype) + { + case CLASS_TYPE_CDC:{ + pdev->tclasslist[pdev->classId].ClassType = CLASS_TYPE_CDC; + + pdev->tclasslist[pdev->classId].Active = 1U; + pdev->tclasslist[pdev->classId].NumEps = 3; + + pdev->tclasslist[pdev->classId].Eps[0].add = CDC_CMD_EP; + pdev->tclasslist[pdev->classId].Eps[0].type = USBD_EP_TYPE_INTR; + pdev->tclasslist[pdev->classId].Eps[0].size = CDC_CMD_PACKET_SIZE; + pdev->tclasslist[pdev->classId].Eps[0].is_used = 1U; + + pdev->tclasslist[pdev->classId].Eps[1].add = CDC_OUT_EP; + pdev->tclasslist[pdev->classId].Eps[1].type = USBD_EP_TYPE_BULK; + pdev->tclasslist[pdev->classId].Eps[1].size = CDC_DATA_FS_MAX_PACKET_SIZE; + pdev->tclasslist[pdev->classId].Eps[1].is_used = 1U; + + pdev->tclasslist[pdev->classId].Eps[2].add = CDC_IN_EP; + pdev->tclasslist[pdev->classId].Eps[2].type = USBD_EP_TYPE_BULK; + pdev->tclasslist[pdev->classId].Eps[2].size = CDC_DATA_FS_MAX_PACKET_SIZE; + pdev->tclasslist[pdev->classId].Eps[2].is_used = 1U; + + pdev->tclasslist[pdev->classId].NumIf = 2; + pdev->tclasslist[pdev->classId].Ifs[0] = 0; + pdev->tclasslist[pdev->classId].Ifs[1] = 1; + + }break; + + case CLASS_TYPE_MSC:{ + pdev->tclasslist[pdev->classId].ClassType = CLASS_TYPE_MSC; + + pdev->tclasslist[pdev->classId].Active = 1U; + pdev->tclasslist[pdev->classId].NumEps = 2; + + pdev->tclasslist[pdev->classId].Eps[0].add = MSC_EPIN_ADDR; + pdev->tclasslist[pdev->classId].Eps[0].type = USBD_EP_TYPE_BULK; + pdev->tclasslist[pdev->classId].Eps[0].size = MSC_MAX_FS_PACKET; + pdev->tclasslist[pdev->classId].Eps[0].is_used = 1U; + + pdev->tclasslist[pdev->classId].Eps[1].add = MSC_EPOUT_ADDR; + pdev->tclasslist[pdev->classId].Eps[1].type = USBD_EP_TYPE_BULK; + pdev->tclasslist[pdev->classId].Eps[1].size = MSC_MAX_FS_PACKET; + pdev->tclasslist[pdev->classId].Eps[1].is_used = 1U; + + + pdev->tclasslist[pdev->classId].NumIf = 1; + pdev->tclasslist[pdev->classId].Ifs[0] = 2; + + }break; + default:break; + } + pdev->tclasslist[pdev->classId].CurrPcktSze = 0U; + +} + +#endif +``` + + +usbd_cmpst.c +```C +#include "usbd_composite.h" +#include "usbd_def.h" +#include "usbd_cdc.h" +#include "usbd_msc.h" + +#include "usbd_core.h" +#include "usbd_desc.h" +#include "usbd_conf.h" +#include + +#define USBD_PRODUCT_XSTR(s) USBD_PRODUCT_STR(s) +#define USBD_PRODUCT_STR(s) #s + +#if 1 +#define USBD_CMPSIT_VID 1155 +#define USBD_CMPSIT_LANGID_STRING 1033 +#define USBD_CMPSIT_MANUFACTURER_STRING "wenyz@wolfGroup" +#define USBD_CMPSIT_PID_FS 22336 +#define USBD_CMPSIT_PRODUCT_STRING_FS "STM32 composite product" +#define USBD_CMPSIT_CONFIGURATION_STRING_FS "Composite Config" +#define USBD_CMPSIT_INTERFACE_STRING_FS "Composite Interface" +#else +#define USBD_CMPSIT_VID 1155 +#define USBD_CMPSIT_LANGID_STRING 1033 +#define USBD_CMPSIT_MANUFACTURER_STRING "STMicroelectronics" +#define USBD_CMPSIT_PID_FS 22336 +#define USBD_CMPSIT_PRODUCT_STRING_FS "STM32 Virtual ComPort" +#define USBD_CMPSIT_CONFIGURATION_STRING_FS "CDC Config" +#define USBD_CMPSIT_INTERFACE_STRING_FS "CDC Interface" +#endif + +#define USBD_CDC_INTERFACE_STRING_FS "CDC Interface" +#define USBD_MSC_INTERFACE_STRING_FS "MSC Interface" + + +uint8_t * USBD_CMPSIT_FS_DeviceDescriptor(USBD_SpeedTypeDef speed, uint16_t *length); +uint8_t * USBD_CMPSIT_FS_LangIDStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length); +uint8_t * USBD_CMPSIT_FS_ManufacturerStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length); +uint8_t * USBD_CMPSIT_FS_ProductStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length); +uint8_t * USBD_CMPSIT_FS_SerialStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length); +uint8_t * USBD_CMPSIT_FS_ConfigStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length); +uint8_t * USBD_CMPSIT_FS_InterfaceStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length); +#if (USBD_LPM_ENABLED == 1) +uint8_t * USBD_CMPSIT_FS_USR_BOSDescriptor(USBD_SpeedTypeDef speed, uint16_t *length); +#endif /* (USBD_LPM_ENABLED == 1) */ + + +USBD_DescriptorsTypeDef usbCmpsitFS_Desc = +{ + USBD_CMPSIT_FS_DeviceDescriptor +, USBD_CMPSIT_FS_LangIDStrDescriptor +, USBD_CMPSIT_FS_ManufacturerStrDescriptor +, USBD_CMPSIT_FS_ProductStrDescriptor +, USBD_CMPSIT_FS_SerialStrDescriptor +, USBD_CMPSIT_FS_ConfigStrDescriptor +, USBD_CMPSIT_FS_InterfaceStrDescriptor +#if (USBD_LPM_ENABLED == 1) +, USBD_CMPSIT_FS_USR_BOSDescriptor +#endif /* (USBD_LPM_ENABLED == 1) */ +}; + +__ALIGN_BEGIN uint8_t USBD_CMPSIT_FS_DeviceDesc[USB_LEN_DEV_DESC] __ALIGN_END = +{ + 0x12, /*bLength */ + USB_DESC_TYPE_DEVICE, /*bDescriptorType*/ +#if (USBD_LPM_ENABLED == 1) + 0x01, /*bcdUSB */ /* changed to USB version 2.01 + in order to support LPM L1 suspend + resume test of USBCV3.0*/ +#else + 0x00, /*bcdUSB */ +#endif /* (USBD_LPM_ENABLED == 1) */ + 0x02, + // Notify OS that this is a composite device + 0xEF, /*bDeviceClass*/ + 0x02, /*bDeviceSubClass*/ + 0x01, /*bDeviceProtocol*/ + USB_MAX_EP0_SIZE, /*bMaxPacketSize*/ + LOBYTE(USBD_CMPSIT_VID), /*idVendor*/ + HIBYTE(USBD_CMPSIT_VID), /*idVendor*/ + LOBYTE(USBD_CMPSIT_PID_FS), /*idProduct*/ + HIBYTE(USBD_CMPSIT_PID_FS), /*idProduct*/ + 0x00, /*bcdDevice rel. 2.00*/ + 0x02, /* bNumInterfaces */ + USBD_IDX_MFC_STR, /*Index of manufacturer string*/ + USBD_IDX_PRODUCT_STR, /*Index of product string*/ + USBD_IDX_SERIAL_STR, /*Index of serial number string*/ + USBD_MAX_NUM_CONFIGURATION /*bNumConfigurations*/ + +}; + +#if (USBD_LPM_ENABLED == 1) +__ALIGN_BEGIN uint8_t USBD_CMPSIT_FS_BOSDesc[USB_SIZ_BOS_DESC] __ALIGN_END = +{ + 0x5, + USB_DESC_TYPE_BOS, + 0xC, + 0x0, + 0x1, /* 1 device capability*/ + /* device capability*/ + 0x7, + USB_DEVICE_CAPABITY_TYPE, + 0x2, + 0x2, /* LPM capability bit set*/ + 0x0, + 0x0, + 0x0 +}; +#endif /* (USBD_LPM_ENABLED == 1) */ + +/** USB lang identifier descriptor. */ +__ALIGN_BEGIN uint8_t USBD_CMPSIT_LangIDDesc[USB_LEN_LANGID_STR_DESC] __ALIGN_END = +{ + USB_LEN_LANGID_STR_DESC, + USB_DESC_TYPE_STRING, + LOBYTE(USBD_CMPSIT_LANGID_STRING), + HIBYTE(USBD_CMPSIT_LANGID_STRING) +}; + + +/* Internal string descriptor. */ +__ALIGN_BEGIN uint8_t USBD_CMPSIT_StrDesc[USBD_MAX_STR_DESC_SIZ] __ALIGN_END; + + +__ALIGN_BEGIN uint8_t USBD_CMPSIT_StringSerial[USB_SIZ_STRING_SERIAL] __ALIGN_END = { + USB_SIZ_STRING_SERIAL, + USB_DESC_TYPE_STRING, +}; + + +uint8_t * USBD_CMPSIT_FS_DeviceDescriptor(USBD_SpeedTypeDef speed, uint16_t *length) +{ + UNUSED(speed); + *length = sizeof(USBD_CMPSIT_FS_DeviceDesc); + return USBD_CMPSIT_FS_DeviceDesc; +} + +uint8_t * USBD_CMPSIT_FS_LangIDStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length) +{ + UNUSED(speed); + *length = sizeof(USBD_CMPSIT_LangIDDesc); + return USBD_CMPSIT_LangIDDesc; +} +uint8_t * USBD_CMPSIT_FS_ManufacturerStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length) +{ + UNUSED(speed); + USBD_GetString((uint8_t *)USBD_CMPSIT_MANUFACTURER_STRING, USBD_CMPSIT_StrDesc, length); + return USBD_CMPSIT_StrDesc; +} + +uint8_t * USBD_CMPSIT_FS_ProductStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length) +{ + if(speed == 0) + { + USBD_GetString((uint8_t *)USBD_CMPSIT_PRODUCT_STRING_FS, USBD_CMPSIT_StrDesc, length); + } + else + { + USBD_GetString((uint8_t *)USBD_CMPSIT_PRODUCT_STRING_FS, USBD_CMPSIT_StrDesc, length); + } + return USBD_CMPSIT_StrDesc; +} + +static void IntToUnicode(uint32_t value, uint8_t * pbuf, uint8_t len) +{ + uint8_t idx = 0; + + for (idx = 0; idx < len; idx++) + { + if (((value >> 28)) < 0xA) + { + pbuf[2 * idx] = (value >> 28) + '0'; + } + else + { + pbuf[2 * idx] = (value >> 28) + 'A' - 10; + } + + value = value << 4; + + pbuf[2 * idx + 1] = 0; + } +} +static void Get_CMPSIT_SerialNum(void) +{ + uint32_t deviceserial0, deviceserial1, deviceserial2; + + deviceserial0 = *(uint32_t *) DEVICE_ID1; + deviceserial1 = *(uint32_t *) DEVICE_ID2; + deviceserial2 = *(uint32_t *) DEVICE_ID3; + + deviceserial0 += deviceserial2; + + if (deviceserial0 != 0) + { + IntToUnicode(deviceserial0, &USBD_CMPSIT_StringSerial[2], 8); + IntToUnicode(deviceserial1, &USBD_CMPSIT_StringSerial[18], 4); + } +} +uint8_t * USBD_CMPSIT_FS_SerialStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length) +{ + UNUSED(speed); + *length = USB_SIZ_STRING_SERIAL; + + /* Update the serial number string descriptor with the data from the unique + * ID */ + Get_CMPSIT_SerialNum(); + /* USER CODE BEGIN USBD_FS_SerialStrDescriptor */ + + /* USER CODE END USBD_FS_SerialStrDescriptor */ + return (uint8_t *) USBD_CMPSIT_StringSerial; +} + +uint8_t * USBD_CMPSIT_FS_InterfaceStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length) +{ + if(speed == 0) + { + USBD_GetString((uint8_t *)USBD_CMPSIT_INTERFACE_STRING_FS, USBD_CMPSIT_StrDesc, length); + } + else + { + USBD_GetString((uint8_t *)USBD_CMPSIT_INTERFACE_STRING_FS, USBD_CMPSIT_StrDesc, length); + } + return USBD_CMPSIT_StrDesc; +} + + +uint8_t * USBD_CMPSIT_FS_ConfigStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length) +{ + if(speed == USBD_SPEED_HIGH) + { + USBD_GetString((uint8_t *)USBD_CMPSIT_CONFIGURATION_STRING_FS, USBD_CMPSIT_StrDesc, length); + } + else + { + USBD_GetString((uint8_t *)USBD_CMPSIT_CONFIGURATION_STRING_FS, USBD_CMPSIT_StrDesc, length); + } + return USBD_CMPSIT_StrDesc; +} + + +#if (USBD_LPM_ENABLED == 1) +/** + * @brief Return the BOS descriptor + * @param speed : Current device speed + * @param length : Pointer to data length variable + * @retval Pointer to descriptor buffer + */ +uint8_t * USBD_CMPSIT_FS_USR_BOSDescriptor(USBD_SpeedTypeDef speed, uint16_t *length) +{ + UNUSED(speed); + *length = sizeof(USBD_CMPSIT_FS_BOSDesc); + return (uint8_t*)USBD_CMPSIT_FS_BOSDesc; +} +#endif /* (USBD_LPM_ENABLED == 1) */ + + +__ALIGN_BEGIN static uint8_t USBD_CMPSIT_CfgDesc[USB_CMPSIT_CONFIG_DESC_SIZ] __ALIGN_END = +{ + /* Configuration Descriptor */ + //0 + 0x09, /* bLength: Configuration Descriptor size */ + USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */ + USB_CMPSIT_CONFIG_DESC_SIZ, /* wTotalLength */ + 0x00, + 0x03, /* bNumInterfaces: 2 interfaces */ + 0x01, /* bConfigurationValue: Configuration value */ + 0x00, /* iConfiguration: Index of string descriptor + describing the configuration */ +#if (USBD_SELF_POWERED == 1U) + 0xC0, /* bmAttributes: Bus Powered according to user configuration */ +#else + 0x80, /* bmAttributes: Bus Powered according to user configuration */ +#endif /* USBD_SELF_POWERED */ + USBD_MAX_POWER, /* MaxPower (mA) */ + + /*---------------------------------------------------------------------------*/ + //9 + /* Interface Association Descriptor: CDC device (virtual com port) */ + 0x08, /* bLength: IAD size */ + 0x0B, /* bDescriptorType: Interface Association Descriptor */ + 0x00, /* bFirstInterface */ + 0x02, /* bInterfaceCount */ + 0x02, /* bFunctionClass: Communication Interface Class */ + 0x02, /* bFunctionSubClass: Abstract Control Model */ + 0x01, /* bFunctionProtocol: Common AT commands */ + 0x06, /* iFunction */ + //17 + /* Interface Descriptor */ + 0x09, /* bLength: Interface Descriptor size */ + USB_DESC_TYPE_INTERFACE, /* bDescriptorType: Interface */ + /* Interface descriptor type */ + 0x00, /* bInterfaceNumber: Number of Interface */ + 0x00, /* bAlternateSetting: Alternate setting */ + 0x01, /* bNumEndpoints: One endpoint used */ + 0x02, /* bInterfaceClass: Communication Interface Class */ + 0x02, /* bInterfaceSubClass: Abstract Control Model */ + 0x01, /* bInterfaceProtocol: Common AT commands */ + 0x06, /* iInterface */ + //26 + /* Header Functional Descriptor */ + 0x05, /* bLength: Endpoint Descriptor size */ + 0x24, /* bDescriptorType: CS_INTERFACE */ + 0x00, /* bDescriptorSubtype: Header Func Desc */ + 0x10, /* bcdCDC: spec release number */ + 0x01, + //31 + /* Call Management Functional Descriptor */ + 0x05, /* bFunctionLength */ + 0x24, /* bDescriptorType: CS_INTERFACE */ + 0x01, /* bDescriptorSubtype: Call Management Func Desc */ + 0x00, /* bmCapabilities: D0+D1 */ + 0x01, /* bDataInterface */ + //36 + /* ACM Functional Descriptor */ + 0x04, /* bFunctionLength */ + 0x24, /* bDescriptorType: CS_INTERFACE */ + 0x02, /* bDescriptorSubtype: Abstract Control Management desc */ + 0x02, /* bmCapabilities */ + //40 + /* Union Functional Descriptor */ + 0x05, /* bFunctionLength */ + 0x24, /* bDescriptorType: CS_INTERFACE */ + 0x06, /* bDescriptorSubtype: Union func desc */ + 0x00, /* bMasterInterface: Communication class interface */ + 0x01, /* bSlaveInterface0: Data Class Interface */ + //45 + /* Endpoint 2 Descriptor */ + 0x07, /* bLength: Endpoint Descriptor size */ + USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */ + CDC_CMD_EP, /* bEndpointAddress */ + 0x03, /* bmAttributes: Interrupt */ + LOBYTE(CDC_CMD_PACKET_SIZE), /* wMaxPacketSize */ + HIBYTE(CDC_CMD_PACKET_SIZE), + CDC_FS_BINTERVAL, /* bInterval */ + /*---------------------------------------------------------------------------*/ + //52 + /* Data class interface descriptor */ + 0x09, /* bLength: Endpoint Descriptor size */ + USB_DESC_TYPE_INTERFACE, /* bDescriptorType: */ + 0x01, /* bInterfaceNumber: Number of Interface */ + 0x00, /* bAlternateSetting: Alternate setting */ + 0x02, /* bNumEndpoints: Two endpoints used */ + 0x0A, /* bInterfaceClass: CDC */ + 0x00, /* bInterfaceSubClass */ + 0x00, /* bInterfaceProtocol */ + 0x06, /* iInterface */ + //61 + /* Endpoint OUT Descriptor */ + 0x07, /* bLength: Endpoint Descriptor size */ + USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */ + CDC_OUT_EP, /* bEndpointAddress */ + 0x02, /* bmAttributes: Bulk */ + LOBYTE(CDC_DATA_FS_MAX_PACKET_SIZE), /* wMaxPacketSize */ + HIBYTE(CDC_DATA_FS_MAX_PACKET_SIZE), + 0x00, /* bInterval */ + //68 + /* Endpoint IN Descriptor */ + 0x07, /* bLength: Endpoint Descriptor size */ + USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */ + CDC_IN_EP, /* bEndpointAddress */ + 0x02, /* bmAttributes: Bulk */ + LOBYTE(CDC_DATA_FS_MAX_PACKET_SIZE), /* wMaxPacketSize */ + HIBYTE(CDC_DATA_FS_MAX_PACKET_SIZE), + 0x00, /* bInterval */ + //75 + /* Interface Association Descriptor: Mass Storage device */ + 0x08, /* bLength: IAD size */ + 0x0B, /* bDescriptorType: Interface Association Descriptor */ + 0x02, /* bFirstInterface */ + 0x01, /* bInterfaceCount */ + 0x08, /* bFunctionClass: */ + 0x06, /* bFunctionSubClass: */ + 0x50, /* bFunctionProtocol: */ + 0x07, /* iFunction */ + //83 + /******************** Mass Storage interface ********************/ + 0x09, /* bLength: Interface Descriptor size */ + 0x04, /* bDescriptorType: */ + 0x02, /* bInterfaceNumber: Number of Interface */ + 0x00, /* bAlternateSetting: Alternate setting */ + 0x02, /* bNumEndpoints */ + 0x08, /* bInterfaceClass: MSC Class */ + 0x06, /* bInterfaceSubClass : SCSI transparent*/ + 0x50, /* nInterfaceProtocol */ + 0x07, /* iInterface: */ + /******************** Mass Storage Endpoints ********************/ + //92 + 0x07, /* Endpoint descriptor length = 7 */ + 0x05, /* Endpoint descriptor type */ + MSC_EPIN_ADDR, /* Endpoint address (IN, address 1) */ + 0x02, /* Bulk endpoint type */ + LOBYTE(MSC_MAX_FS_PACKET), + HIBYTE(MSC_MAX_FS_PACKET), + 0x00, /* Polling interval in milliseconds */ + //99 + 0x07, /* Endpoint descriptor length = 7 */ + 0x05, /* Endpoint descriptor type */ + MSC_EPOUT_ADDR, /* Endpoint address (OUT, address 1) */ + 0x02, /* Bulk endpoint type */ + LOBYTE(MSC_MAX_FS_PACKET), + HIBYTE(MSC_MAX_FS_PACKET), + 0x00 /* Polling interval in milliseconds */ + //106 +}; +__ALIGN_BEGIN static uint8_t USBD_CMPSIT_DeviceQualifierDesc[USB_LEN_DEV_QUALIFIER_DESC] __ALIGN_END = +{ + USB_LEN_DEV_QUALIFIER_DESC, + USB_DESC_TYPE_DEVICE_QUALIFIER, + 0x00, + 0x02, + 0x00, + 0x00, + 0x00, + 0x40, + 0x01, + 0x00, +}; + +static uint8_t *USBD_CMPSIT_GetFSCfgDesc(uint16_t *length); +static uint8_t *USBD_CMPSIT_GetHSCfgDesc(uint16_t *length); +static uint8_t *USBD_CMPSIT_GetOtherSpeedCfgDesc(uint16_t *length); +uint8_t *USBD_CMPSIT_GetDeviceQualifierDescriptor(uint16_t *length); + + + +USBD_ClassTypeDef USBD_CMPSIT= +{ + NULL, + NULL, + NULL, + NULL, /* EP0_TxSent */ + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + USBD_CMPSIT_GetHSCfgDesc, + USBD_CMPSIT_GetFSCfgDesc, + USBD_CMPSIT_GetOtherSpeedCfgDesc, + USBD_CMPSIT_GetDeviceQualifierDescriptor +}; + +#ifdef USE_USBD_COMPOSITE +void USBD_CMPSIT_AddClass(USBD_HandleTypeDef *pdev, USBD_ClassTypeDef *pclass, USBD_CompositeClassTypeDef classtype, uint8_t *EpAddr) +{ + //printf("classId=%d : %d\r\n",pdev->classId,classtype); + switch(classtype) + { + case CLASS_TYPE_CDC:{ + pdev->tclasslist[pdev->classId].ClassType = CLASS_TYPE_CDC; + + pdev->tclasslist[pdev->classId].Active = 1U; + pdev->tclasslist[pdev->classId].NumEps = 3; + + pdev->tclasslist[pdev->classId].Eps[0].add = CDC_CMD_EP; + pdev->tclasslist[pdev->classId].Eps[0].type = USBD_EP_TYPE_INTR; + pdev->tclasslist[pdev->classId].Eps[0].size = CDC_CMD_PACKET_SIZE; + pdev->tclasslist[pdev->classId].Eps[0].is_used = 1U; + + pdev->tclasslist[pdev->classId].Eps[1].add = CDC_OUT_EP; + pdev->tclasslist[pdev->classId].Eps[1].type = USBD_EP_TYPE_BULK; + pdev->tclasslist[pdev->classId].Eps[1].size = CDC_DATA_FS_MAX_PACKET_SIZE; + pdev->tclasslist[pdev->classId].Eps[1].is_used = 1U; + + pdev->tclasslist[pdev->classId].Eps[2].add = CDC_IN_EP; + pdev->tclasslist[pdev->classId].Eps[2].type = USBD_EP_TYPE_BULK; + pdev->tclasslist[pdev->classId].Eps[2].size = CDC_DATA_FS_MAX_PACKET_SIZE; + pdev->tclasslist[pdev->classId].Eps[2].is_used = 1U; + + pdev->tclasslist[pdev->classId].NumIf = 2; + pdev->tclasslist[pdev->classId].Ifs[0] = 0; + pdev->tclasslist[pdev->classId].Ifs[1] = 1; + + }break; + + case CLASS_TYPE_MSC:{ + pdev->tclasslist[pdev->classId].ClassType = CLASS_TYPE_MSC; + + pdev->tclasslist[pdev->classId].Active = 1U; + pdev->tclasslist[pdev->classId].NumEps = 2; + + pdev->tclasslist[pdev->classId].Eps[0].add = MSC_EPIN_ADDR; + pdev->tclasslist[pdev->classId].Eps[0].type = USBD_EP_TYPE_BULK; + pdev->tclasslist[pdev->classId].Eps[0].size = MSC_MAX_FS_PACKET; + pdev->tclasslist[pdev->classId].Eps[0].is_used = 1U; + + pdev->tclasslist[pdev->classId].Eps[1].add = MSC_EPOUT_ADDR; + pdev->tclasslist[pdev->classId].Eps[1].type = USBD_EP_TYPE_BULK; + pdev->tclasslist[pdev->classId].Eps[1].size = MSC_MAX_FS_PACKET; + pdev->tclasslist[pdev->classId].Eps[1].is_used = 1U; + + + pdev->tclasslist[pdev->classId].NumIf = 1; + pdev->tclasslist[pdev->classId].Ifs[0] = 2; + + }break; + default:break; + } + pdev->tclasslist[pdev->classId].CurrPcktSze = 0U; + +} + +#endif + +uint8_t * USBD_UsrStrDescriptor(struct _USBD_HandleTypeDef *pdev, uint8_t index, uint16_t *length) +{ + *length = 0; + //printf("index=%d\r\n",index); + /* if (USBD_IDX_MICROSOFT_DESC_STR == index) { + *length = sizeof (USBD_MS_OS_StringDescriptor); + return USBD_MS_OS_StringDescriptor; + } else if (USBD_IDX_ODRIVE_INTF_STR == index) { + USBD_GetString((uint8_t *)USBD_PRODUCT_XSTR(NATIVE_STRING), USBD_StrDesc, length); + return USBD_StrDesc; + } */ + if (USBD_IDX_CDC_INTF_STR == index) { + USBD_GetString((uint8_t *)USBD_CDC_INTERFACE_STRING_FS, USBD_CMPSIT_StrDesc, length); + return USBD_CMPSIT_StrDesc; + } + else if (USBD_IDX_MSC_INTF_STR == index) { + USBD_GetString((uint8_t *)USBD_MSC_INTERFACE_STRING_FS, USBD_CMPSIT_StrDesc, length); + return USBD_CMPSIT_StrDesc; + } + return NULL; +} + +static uint8_t *USBD_CMPSIT_GetFSCfgDesc(uint16_t *length) +{ + + *length = (uint16_t)sizeof(USBD_CMPSIT_CfgDesc); + return USBD_CMPSIT_CfgDesc; +} +static uint8_t *USBD_CMPSIT_GetHSCfgDesc(uint16_t *length) +{ +} +static uint8_t *USBD_CMPSIT_GetOtherSpeedCfgDesc(uint16_t *length) +{ + *length = (uint16_t)sizeof(USBD_CMPSIT_CfgDesc); + return USBD_CMPSIT_CfgDesc; +} +uint8_t *USBD_CMPSIT_GetDeviceQualifierDescriptor(uint16_t *length) +{ + *length = (uint16_t)sizeof(USBD_CMPSIT_DeviceQualifierDesc); + return USBD_CMPSIT_DeviceQualifierDesc; +} + +``` \ No newline at end of file