From 36aec9f20b177d4bc684a6076afc4fba7f8c6942 Mon Sep 17 00:00:00 2001 From: Conor Patrick Date: Mon, 12 Aug 2019 16:18:30 +0800 Subject: [PATCH] separate interface into two and add "IAD" descriptor --- targets/stm32l432/lib/usbd/usbd_composite.c | 87 +++++++++++++++------ 1 file changed, 64 insertions(+), 23 deletions(-) diff --git a/targets/stm32l432/lib/usbd/usbd_composite.c b/targets/stm32l432/lib/usbd/usbd_composite.c index a1a868c..182f3cc 100644 --- a/targets/stm32l432/lib/usbd/usbd_composite.c +++ b/targets/stm32l432/lib/usbd/usbd_composite.c @@ -26,16 +26,18 @@ static uint8_t *USBD_Composite_GetOtherSpeedCfgDesc (uint16_t *length); static uint8_t *USBD_Composite_GetDeviceQualifierDescriptor (uint16_t *length); -#define NUM_INTERFACES 2 +#define NUM_CLASSES 2 +#define NUM_INTERFACES 3 #if NUM_INTERFACES>1 -#define COMPOSITE_CDC_HID_DESCRIPTOR_SIZE (90) +#define COMPOSITE_CDC_HID_DESCRIPTOR_SIZE (90 + 8+9 + 4) #else #define COMPOSITE_CDC_HID_DESCRIPTOR_SIZE (41) #endif -#define HID_INTF_NUM 0 -#define CDC_INTF_NUM 1 +#define HID_INTF_NUM 0 +#define CDC_MASTER_INTF_NUM 1 +#define CDC_SLAVE_INTF_NUM 2 __ALIGN_BEGIN uint8_t COMPOSITE_CDC_HID_DESCRIPTOR[COMPOSITE_CDC_HID_DESCRIPTOR_SIZE] __ALIGN_END = { /*Configuration Descriptor*/ @@ -43,7 +45,7 @@ __ALIGN_BEGIN uint8_t COMPOSITE_CDC_HID_DESCRIPTOR[COMPOSITE_CDC_HID_DESCRIPTOR_ USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */ COMPOSITE_CDC_HID_DESCRIPTOR_SIZE, /* wTotalLength:no of returned bytes */ 0x00, - NUM_INTERFACES, /* bNumInterfaces: 1 interface */ + NUM_INTERFACES, /* bNumInterfaces */ 0x01, /* bConfigurationValue: Configuration value */ 0x00, /* iConfiguration: Index of string descriptor describing the configuration */ 0x80, /* bmAttributes: self powered */ @@ -99,15 +101,23 @@ __ALIGN_BEGIN uint8_t COMPOSITE_CDC_HID_DESCRIPTOR[COMPOSITE_CDC_HID_DESCRIPTOR_ /* */ /* CDC */ /* */ - + // This "IAD" is needed for Windows since it ignores the standard Union Functional Descriptor + 0x08, // bLength + 0x0B, // IAD type + CDC_MASTER_INTF_NUM, // First interface + CDC_SLAVE_INTF_NUM, // Next interface + 0x02, // bInterfaceClass of the first interface + 0x02, // bInterfaceSubClass of the first interface + 0x00, // bInterfaceProtocol of the first interface + 0x00, // Interface string index /*Interface Descriptor */ 0x09, /* bLength: Interface Descriptor size */ USB_DESC_TYPE_INTERFACE, /* bDescriptorType: Interface */ /* Interface descriptor type */ -/*!*/ CDC_INTF_NUM, /* bInterfaceNumber: Number of Interface */ +/*!*/ CDC_MASTER_INTF_NUM, /* bInterfaceNumber: Number of Interface */ 0x00, /* bAlternateSetting: Alternate setting */ - 0x03, /* bNumEndpoints: 3 endpoints used */ + 0x01, /* bNumEndpoints: 1 endpoint used */ 0x02, /* bInterfaceClass: Communication Interface Class */ 0x02, /* bInterfaceSubClass: Abstract Control Model */ 0x00, /* bInterfaceProtocol: Common AT commands */ @@ -125,7 +135,7 @@ __ALIGN_BEGIN uint8_t COMPOSITE_CDC_HID_DESCRIPTOR[COMPOSITE_CDC_HID_DESCRIPTOR_ 0x24, /* bDescriptorType: CS_INTERFACE */ 0x01, /* bDescriptorSubtype: Call Management Func Desc */ 0x00, /* bmCapabilities: D0+D1 */ -/*!*/ CDC_INTF_NUM, /* bDataInterface: 0 */ +/*!*/ CDC_SLAVE_INTF_NUM, /* bDataInterface: 0 */ /*ACM Functional Descriptor*/ 0x04, /* bFunctionLength */ @@ -137,10 +147,10 @@ __ALIGN_BEGIN uint8_t COMPOSITE_CDC_HID_DESCRIPTOR[COMPOSITE_CDC_HID_DESCRIPTOR_ 0x05, /* bFunctionLength */ 0x24, /* bDescriptorType: CS_INTERFACE */ 0x06, /* bDescriptorSubtype: Union func desc */ -/*!*/ CDC_INTF_NUM, /* bMasterInterface: Communication class interface */ -/*!*/ CDC_INTF_NUM, /* bSlaveInterface0: Data Class Interface */ +/*!*/ CDC_MASTER_INTF_NUM, /* bMasterInterface: Communication class interface */ +/*!*/ CDC_SLAVE_INTF_NUM, /* bSlaveInterface0: Data Class Interface */ - /*Endpoint 2 Descriptor*/ + /* Control Endpoint Descriptor*/ 0x07, /* bLength: Endpoint Descriptor size */ USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */ CDC_CMD_EP, /* bEndpointAddress */ @@ -149,6 +159,17 @@ __ALIGN_BEGIN uint8_t COMPOSITE_CDC_HID_DESCRIPTOR[COMPOSITE_CDC_HID_DESCRIPTOR_ HIBYTE(CDC_CMD_PACKET_SIZE), 0x10, /* bInterval: */ +/* Interface descriptor */ + 0x09, /* bLength */ + USB_DESC_TYPE_INTERFACE, /* bDescriptorType */ + CDC_SLAVE_INTF_NUM, /* bInterfaceNumber */ + 0x00, /* bAlternateSetting */ + 0x02, /* bNumEndpoints */ + 0x0A, /* bInterfaceClass: Communication class data */ + 0x00, /* bInterfaceSubClass */ + 0x00, /* bInterfaceProtocol */ + 0x00, + /*Endpoint OUT Descriptor*/ 0x07, /* bLength: Endpoint Descriptor size */ USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */ @@ -167,6 +188,10 @@ __ALIGN_BEGIN uint8_t COMPOSITE_CDC_HID_DESCRIPTOR[COMPOSITE_CDC_HID_DESCRIPTOR_ HIBYTE(CDC_DATA_FS_MAX_PACKET_SIZE), 0x00, /* bInterval: ignore for Bulk transfer */ + 4, /* Descriptor size */ + 3, /* Descriptor type */ + 0x09, + 0x04, #endif }; @@ -195,14 +220,27 @@ int in_endpoint_to_class[MAX_ENDPOINTS]; int out_endpoint_to_class[MAX_ENDPOINTS]; -void USBD_Composite_Set_Classes(USBD_ClassTypeDef *class0, USBD_ClassTypeDef *class1) { - USBD_Classes[0] = class0; - USBD_Classes[1] = class1; +void USBD_Composite_Set_Classes(USBD_ClassTypeDef *hid_class, USBD_ClassTypeDef *cdc_class) { + USBD_Classes[0] = hid_class; + USBD_Classes[1] = cdc_class; +} + +static USBD_ClassTypeDef * getClass(uint8_t index) +{ + switch(index) + { + case HID_INTF_NUM: + return USBD_Classes[0]; + case CDC_MASTER_INTF_NUM: + case CDC_SLAVE_INTF_NUM: + return USBD_Classes[1]; + } + return NULL; } static uint8_t USBD_Composite_Init (USBD_HandleTypeDef *pdev, uint8_t cfgidx) { int i; - for(i = 0; i < NUM_INTERFACES; i++) { + for(i = 0; i < NUM_CLASSES; i++) { if (USBD_Classes[i]->Init(pdev, cfgidx) != USBD_OK) { return USBD_FAIL; } @@ -213,7 +251,7 @@ static uint8_t USBD_Composite_Init (USBD_HandleTypeDef *pdev, uint8_t cfgidx) { static uint8_t USBD_Composite_DeInit (USBD_HandleTypeDef *pdev, uint8_t cfgidx) { int i; - for(i = 0; i < NUM_INTERFACES; i++) { + for(i = 0; i < NUM_CLASSES; i++) { if (USBD_Classes[i]->DeInit(pdev, cfgidx) != USBD_OK) { return USBD_FAIL; } @@ -224,10 +262,13 @@ static uint8_t USBD_Composite_DeInit (USBD_HandleTypeDef *pdev, uint8_t cfgidx) static uint8_t USBD_Composite_Setup (USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) { int i; + USBD_ClassTypeDef * device_class; + device_class = getClass(req->wIndex); + switch (req->bmRequest & USB_REQ_TYPE_MASK) { case USB_REQ_TYPE_CLASS : - if (req->wIndex < NUM_INTERFACES) - return USBD_Classes[req->wIndex]->Setup(pdev, req); + if (device_class != NULL) + return device_class->Setup(pdev, req); else return USBD_FAIL; @@ -236,7 +277,7 @@ static uint8_t USBD_Composite_Setup (USBD_HandleTypeDef *pdev, USBD_SetupReqType switch (req->bRequest) { case USB_REQ_GET_DESCRIPTOR : - for(i = 0; i < NUM_INTERFACES; i++) { + for(i = 0; i < NUM_CLASSES; i++) { if (USBD_Classes[i]->Setup(pdev, req) != USBD_OK) { return USBD_FAIL; } @@ -246,8 +287,8 @@ static uint8_t USBD_Composite_Setup (USBD_HandleTypeDef *pdev, USBD_SetupReqType case USB_REQ_GET_INTERFACE : case USB_REQ_SET_INTERFACE : - if (req->wIndex < NUM_INTERFACES) - return USBD_Classes[req->wIndex]->Setup(pdev, req); + if (device_class != NULL) + return device_class->Setup(pdev, req); else return USBD_FAIL; } @@ -274,7 +315,7 @@ static uint8_t USBD_Composite_DataOut (USBD_HandleTypeDef *pdev, uint8_t epnum) static uint8_t USBD_Composite_EP0_RxReady (USBD_HandleTypeDef *pdev) { int i; - for(i = 0; i < NUM_INTERFACES; i++) { + for(i = 0; i < NUM_CLASSES; i++) { if (USBD_Classes[i]->EP0_RxReady != NULL) { if (USBD_Classes[i]->EP0_RxReady(pdev) != USBD_OK) { return USBD_FAIL;