From 593fe154eca8e70b02beb0e5a2872e690ae74296 Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 14 Apr 2020 18:00:59 +0700 Subject: [PATCH 01/14] adding subclass & protocol to class driver structure --- src/common/tusb_types.h | 7 ++++++ src/device/usbd.c | 56 +++++++++++++++++++++++++++++++---------- src/device/usbd.h | 14 +++++------ 3 files changed, 57 insertions(+), 20 deletions(-) diff --git a/src/common/tusb_types.h b/src/common/tusb_types.h index c37c19bad..70d0db942 100644 --- a/src/common/tusb_types.h +++ b/src/common/tusb_types.h @@ -139,6 +139,7 @@ typedef enum TUSB_REQ_RCPT_OTHER } tusb_request_recipient_t; +// https://www.usb.org/defined-class-codes typedef enum { TUSB_CLASS_UNSPECIFIED = 0 , @@ -176,6 +177,12 @@ typedef enum MISC_PROTOCOL_IAD = 1 }misc_protocol_type_t; +typedef enum +{ + APP_SUBCLASS_USBTMC = 0x03, + APP_SUBCLASS_DFU_RUNTIME = 0x01 +} app_subclass_type_t; + typedef enum { DEVICE_CAPABILITY_WIRELESS_USB = 0x01, diff --git a/src/device/usbd.c b/src/device/usbd.c index 9d15ea4a4..06fe1f23c 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -73,8 +73,11 @@ enum { DRVID_INVALID = 0xFFu }; //--------------------------------------------------------------------+ // Class Driver //--------------------------------------------------------------------+ -typedef struct { +typedef struct +{ uint8_t class_code; + uint8_t subclass; // 0xFF support all values of subclass + uint8_t protocol; // 0xFF support all values of protocol void (* init ) (void); void (* reset ) (uint8_t rhport); @@ -90,6 +93,9 @@ static usbd_class_driver_t const _usbd_driver[] = #if CFG_TUD_CDC { .class_code = TUSB_CLASS_CDC, + .subclass = CDC_COMM_SUBCLASS_ABSTRACT_CONTROL_MODEL, + .protocol = 0xFF, // all protocols + .init = cdcd_init, .reset = cdcd_reset, .open = cdcd_open, @@ -103,6 +109,9 @@ static usbd_class_driver_t const _usbd_driver[] = #if CFG_TUD_MSC { .class_code = TUSB_CLASS_MSC, + .subclass = MSC_SUBCLASS_SCSI, + .protocol = MSC_PROTOCOL_BOT, + .init = mscd_init, .reset = mscd_reset, .open = mscd_open, @@ -116,6 +125,9 @@ static usbd_class_driver_t const _usbd_driver[] = #if CFG_TUD_HID { .class_code = TUSB_CLASS_HID, + .subclass = 0xFF, // all subclass + .protocol = 0xFF, // all protocol + .init = hidd_init, .reset = hidd_reset, .open = hidd_open, @@ -129,6 +141,9 @@ static usbd_class_driver_t const _usbd_driver[] = #if CFG_TUD_MIDI { .class_code = TUSB_CLASS_AUDIO, + .subclass = AUDIO_SUBCLASS_CONTROL, + .protocol = AUDIO_PROTOCOL_V1, + .init = midid_init, .open = midid_open, .reset = midid_reset, @@ -142,6 +157,9 @@ static usbd_class_driver_t const _usbd_driver[] = #if CFG_TUD_VENDOR { .class_code = TUSB_CLASS_VENDOR_SPECIFIC, + .subclass = 0xFF, // all subclass + .protocol = 0xFF, // all protocol + .init = vendord_init, .reset = vendord_reset, .open = vendord_open, @@ -153,12 +171,11 @@ static usbd_class_driver_t const _usbd_driver[] = #endif #if CFG_TUD_USBTMC - // Presently USBTMC is the only defined class with the APP_SPECIFIC class code. - // We maybe need to add subclass codes here, or a callback to ask if a driver can - // handle a particular interface. { - .class_code = TUD_USBTMC_APP_CLASS, - //.subclass_code = TUD_USBTMC_APP_SUBCLASS + .class_code = TUSB_CLASS_APPLICATION_SPECIFIC, + .subclass = APP_SUBCLASS_USBTMC, + .protocol = 0xFF, // all protocol + .init = usbtmcd_init_cb, .reset = usbtmcd_reset_cb, .open = usbtmcd_open_cb, @@ -171,8 +188,10 @@ static usbd_class_driver_t const _usbd_driver[] = #if CFG_TUD_DFU_RT { - .class_code = TUD_DFU_APP_CLASS, - //.subclass_code = TUD_DFU_APP_SUBCLASS + .class_code = TUSB_CLASS_APPLICATION_SPECIFIC, + .subclass = APP_SUBCLASS_DFU_RUNTIME, + .protocol = DFU_PROTOCOL_RT, + .init = dfu_rtd_init, .reset = dfu_rtd_reset, .open = dfu_rtd_open, @@ -183,11 +202,14 @@ static usbd_class_driver_t const _usbd_driver[] = }, #endif - #if CFG_TUD_NET -#if CFG_TUD_NET != OPT_NET_EEM +#if CFG_TUD_NET + #if CFG_TUD_NET != OPT_NET_EEM /* RNDIS management interface */ { .class_code = TUD_RNDIS_ITF_CLASS, + .subclass = TUD_RNDIS_ITF_SUBCLASS, + .protocol = TUD_RNDIS_ITF_PROTOCOL, + .init = netd_init, .reset = netd_reset, .open = netd_open, @@ -196,10 +218,14 @@ static usbd_class_driver_t const _usbd_driver[] = .xfer_cb = netd_xfer_cb, .sof = NULL, }, -#endif + #endif + /* CDC-ECM management interface; CDC-EEM data interface */ { .class_code = TUSB_CLASS_CDC, + .subclass = CDC_COMM_SUBCLASS_ETHERNET_NETWORKING_CONTROL_MODEL, + .protocol = 0x00, + .init = netd_init, .reset = netd_reset, #if CFG_TUD_NET == OPT_NET_EEM @@ -212,10 +238,14 @@ static usbd_class_driver_t const _usbd_driver[] = .xfer_cb = netd_xfer_cb, .sof = NULL, }, + /* RNDIS/CDC-ECM data interface */ -#if CFG_TUD_NET != OPT_NET_EEM + #if CFG_TUD_NET != OPT_NET_EEM { .class_code = TUSB_CLASS_CDC_DATA, + .subclass = 0x00, + .protocol = 0x00, + .init = netd_init_data, .reset = NULL, .open = netd_open_data, @@ -224,8 +254,8 @@ static usbd_class_driver_t const _usbd_driver[] = .xfer_cb = netd_xfer_cb, .sof = NULL, }, -#endif #endif +#endif }; enum { USBD_CLASS_DRIVER_COUNT = TU_ARRAY_SIZE(_usbd_driver) }; diff --git a/src/device/usbd.h b/src/device/usbd.h index dbc94bc35..7b04ef9a7 100644 --- a/src/device/usbd.h +++ b/src/device/usbd.h @@ -291,23 +291,23 @@ TU_ATTR_WEAK bool tud_vendor_control_complete_cb(uint8_t rhport, tusb_control_re // Interface number, number of endpoints, EP string index, USB_TMC_PROTOCOL*, bulk-out endpoint ID, // bulk-in endpoint ID #define TUD_USBTMC_IF_DESCRIPTOR(_itfnum, _bNumEndpoints, _stridx, _itfProtocol) \ -/* Interface */ \ + /* Interface */ \ 0x09, TUSB_DESC_INTERFACE, _itfnum, 0x00, _bNumEndpoints, TUD_USBTMC_APP_CLASS, TUD_USBTMC_APP_SUBCLASS, _itfProtocol, _stridx #define TUD_USBTMC_IF_DESCRIPTOR_LEN 9u #define TUD_USBTMC_BULK_DESCRIPTORS(_epout, _epin, _bulk_epsize) \ -/* Endpoint Out */ \ -7, TUSB_DESC_ENDPOINT, _epout, TUSB_XFER_BULK, U16_TO_U8S_LE(_bulk_epsize), 0u, \ -/* Endpoint In */ \ -7, TUSB_DESC_ENDPOINT, _epin, TUSB_XFER_BULK, U16_TO_U8S_LE(_bulk_epsize), 0u + /* Endpoint Out */ \ + 7, TUSB_DESC_ENDPOINT, _epout, TUSB_XFER_BULK, U16_TO_U8S_LE(_bulk_epsize), 0u, \ + /* Endpoint In */ \ + 7, TUSB_DESC_ENDPOINT, _epin, TUSB_XFER_BULK, U16_TO_U8S_LE(_bulk_epsize), 0u #define TUD_USBTMC_BULK_DESCRIPTORS_LEN (7u+7u) /* optional interrupt endpoint */ \ // _int_pollingInterval : for LS/FS, expressed in frames (1ms each). 16 may be a good number? #define TUD_USBTMC_INT_DESCRIPTOR(_ep_interrupt, _ep_interrupt_size, _int_pollingInterval ) \ -7, TUSB_DESC_ENDPOINT, _ep_interrupt, TUSB_XFER_INTERRUPT, U16_TO_U8S_LE(_ep_interrupt_size), 0x16 + 7, TUSB_DESC_ENDPOINT, _ep_interrupt, TUSB_XFER_INTERRUPT, U16_TO_U8S_LE(_ep_interrupt_size), 0x16 #define TUD_USBTMC_INT_DESCRIPTOR_LEN (7u) @@ -377,7 +377,7 @@ TU_ATTR_WEAK bool tud_vendor_control_complete_cb(uint8_t rhport, tusb_control_re #define TUD_RNDIS_ITF_PROTOCOL 0xFF /* CDC_COMM_PROTOCOL_MICROSOFT_RNDIS */ #else /* Windows 7+ */ - #define TUD_RNDIS_ITF_CLASS 0xE0 + #define TUD_RNDIS_ITF_CLASS TUSB_CLASS_WIRELESS_CONTROLLER #define TUD_RNDIS_ITF_SUBCLASS 0x01 #define TUD_RNDIS_ITF_PROTOCOL 0x03 #endif From b90b00d43b18e1bed81c81e87ec148479ab1e696 Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 14 Apr 2020 18:35:50 +0700 Subject: [PATCH 02/14] complete adding subclass and protocol to driver id --- src/device/usbd.c | 30 +++++++++++++++++++++++------- 1 file changed, 23 insertions(+), 7 deletions(-) diff --git a/src/device/usbd.c b/src/device/usbd.c index 06fe1f23c..c0e17c058 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -273,6 +273,8 @@ static osal_queue_t _usbd_q; // Prototypes //--------------------------------------------------------------------+ static void mark_interface_endpoint(uint8_t ep2drv[8][2], uint8_t const* p_desc, uint16_t desc_len, uint8_t driver_id); +static uint8_t find_driver_id(tusb_desc_interface_t const * desc_itf); + static bool process_control_request(uint8_t rhport, tusb_control_request_t const * p_request); static bool process_set_config(uint8_t rhport, uint8_t cfg_num); static bool process_get_descriptor(uint8_t rhport, tusb_control_request_t const * p_request); @@ -793,14 +795,10 @@ static bool process_set_config(uint8_t rhport, uint8_t cfg_num) { TU_ASSERT( TUSB_DESC_INTERFACE == tu_desc_type(p_desc) ); - tusb_desc_interface_t* desc_itf = (tusb_desc_interface_t*) p_desc; + tusb_desc_interface_t const * desc_itf = (tusb_desc_interface_t const*) p_desc; - // Check if class is supported - uint8_t drv_id; - for (drv_id = 0; drv_id < USBD_CLASS_DRIVER_COUNT; drv_id++) - { - if ( _usbd_driver[drv_id].class_code == desc_itf->bInterfaceClass ) break; - } + // Find driver id for the interface + uint8_t drv_id = find_driver_id(desc_itf); TU_ASSERT( drv_id < USBD_CLASS_DRIVER_COUNT ); // Interface number must not be used already TODO alternate interface @@ -824,6 +822,24 @@ static bool process_set_config(uint8_t rhport, uint8_t cfg_num) return true; } +// Helper to find class driver id for an interface +// return 0xFF if not found +static uint8_t find_driver_id(tusb_desc_interface_t const * desc_itf) +{ + for (uint8_t drv_id = 0; drv_id < USBD_CLASS_DRIVER_COUNT; drv_id++) + { + usbd_class_driver_t const *driver = &_usbd_driver[drv_id]; + if ( (driver->class_code == desc_itf->bInterfaceClass) && // match class code + (driver->subclass == desc_itf->bInterfaceSubClass || driver->subclass == 0xFF) && // match subclass or 0xFF from driver + (driver->protocol == desc_itf->bInterfaceProtocol || driver->protocol == 0xFF)) // match protocol or 0xFF from driver + { + return drv_id; + } + } + + return DRVID_INVALID; +} + // Helper marking endpoint of interface belongs to class driver static void mark_interface_endpoint(uint8_t ep2drv[8][2], uint8_t const* p_desc, uint16_t desc_len, uint8_t driver_id) { From ae6014627408ec938d94a7d2796abd54dfff6b1f Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 14 Apr 2020 22:35:34 +0700 Subject: [PATCH 03/14] use explicit all_subclass and all_protocol since 0xFF is stil valid --- src/device/usbd.c | 44 +++++++++++++++++++++++++++++++++++--------- 1 file changed, 35 insertions(+), 9 deletions(-) diff --git a/src/device/usbd.c b/src/device/usbd.c index c0e17c058..c1ef482e2 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -79,6 +79,12 @@ typedef struct uint8_t subclass; // 0xFF support all values of subclass uint8_t protocol; // 0xFF support all values of protocol + struct TU_ATTR_PACKED + { + uint8_t all_subclass : 1; + uint8_t all_protocol : 1; + }; + void (* init ) (void); void (* reset ) (uint8_t rhport); bool (* open ) (uint8_t rhport, tusb_desc_interface_t const * desc_intf, uint16_t* p_length); @@ -94,7 +100,9 @@ static usbd_class_driver_t const _usbd_driver[] = { .class_code = TUSB_CLASS_CDC, .subclass = CDC_COMM_SUBCLASS_ABSTRACT_CONTROL_MODEL, - .protocol = 0xFF, // all protocols + .protocol = 0x00, + .all_subclass = 0, + .all_protocol = 1, .init = cdcd_init, .reset = cdcd_reset, @@ -111,6 +119,8 @@ static usbd_class_driver_t const _usbd_driver[] = .class_code = TUSB_CLASS_MSC, .subclass = MSC_SUBCLASS_SCSI, .protocol = MSC_PROTOCOL_BOT, + .all_subclass = 0, + .all_protocol = 0, .init = mscd_init, .reset = mscd_reset, @@ -125,8 +135,10 @@ static usbd_class_driver_t const _usbd_driver[] = #if CFG_TUD_HID { .class_code = TUSB_CLASS_HID, - .subclass = 0xFF, // all subclass - .protocol = 0xFF, // all protocol + .subclass = 0x00, + .protocol = 0x00, + .all_subclass = 1, + .all_protocol = 1, .init = hidd_init, .reset = hidd_reset, @@ -143,6 +155,8 @@ static usbd_class_driver_t const _usbd_driver[] = .class_code = TUSB_CLASS_AUDIO, .subclass = AUDIO_SUBCLASS_CONTROL, .protocol = AUDIO_PROTOCOL_V1, + .all_subclass = 0, + .all_protocol = 0, .init = midid_init, .open = midid_open, @@ -157,8 +171,10 @@ static usbd_class_driver_t const _usbd_driver[] = #if CFG_TUD_VENDOR { .class_code = TUSB_CLASS_VENDOR_SPECIFIC, - .subclass = 0xFF, // all subclass - .protocol = 0xFF, // all protocol + .subclass = 0x00, + .protocol = 0x00, + .all_subclass = 1, + .all_protocol = 1, .init = vendord_init, .reset = vendord_reset, @@ -174,7 +190,9 @@ static usbd_class_driver_t const _usbd_driver[] = { .class_code = TUSB_CLASS_APPLICATION_SPECIFIC, .subclass = APP_SUBCLASS_USBTMC, - .protocol = 0xFF, // all protocol + .protocol = 0x00, + .all_subclass = 0, + .all_protocol = 1, .init = usbtmcd_init_cb, .reset = usbtmcd_reset_cb, @@ -191,6 +209,8 @@ static usbd_class_driver_t const _usbd_driver[] = .class_code = TUSB_CLASS_APPLICATION_SPECIFIC, .subclass = APP_SUBCLASS_DFU_RUNTIME, .protocol = DFU_PROTOCOL_RT, + .all_subclass = 0, + .all_protocol = 0, .init = dfu_rtd_init, .reset = dfu_rtd_reset, @@ -209,6 +229,8 @@ static usbd_class_driver_t const _usbd_driver[] = .class_code = TUD_RNDIS_ITF_CLASS, .subclass = TUD_RNDIS_ITF_SUBCLASS, .protocol = TUD_RNDIS_ITF_PROTOCOL, + .all_subclass = 0, + .all_protocol = 0, .init = netd_init, .reset = netd_reset, @@ -225,6 +247,8 @@ static usbd_class_driver_t const _usbd_driver[] = .class_code = TUSB_CLASS_CDC, .subclass = CDC_COMM_SUBCLASS_ETHERNET_NETWORKING_CONTROL_MODEL, .protocol = 0x00, + .all_subclass = 0, + .all_protocol = 0, .init = netd_init, .reset = netd_reset, @@ -245,6 +269,8 @@ static usbd_class_driver_t const _usbd_driver[] = .class_code = TUSB_CLASS_CDC_DATA, .subclass = 0x00, .protocol = 0x00, + .all_subclass = 0, + .all_protocol = 0, .init = netd_init_data, .reset = NULL, @@ -829,9 +855,9 @@ static uint8_t find_driver_id(tusb_desc_interface_t const * desc_itf) for (uint8_t drv_id = 0; drv_id < USBD_CLASS_DRIVER_COUNT; drv_id++) { usbd_class_driver_t const *driver = &_usbd_driver[drv_id]; - if ( (driver->class_code == desc_itf->bInterfaceClass) && // match class code - (driver->subclass == desc_itf->bInterfaceSubClass || driver->subclass == 0xFF) && // match subclass or 0xFF from driver - (driver->protocol == desc_itf->bInterfaceProtocol || driver->protocol == 0xFF)) // match protocol or 0xFF from driver + if ( (driver->class_code == desc_itf->bInterfaceClass) && // match class code + (driver->subclass == desc_itf->bInterfaceSubClass || driver->all_subclass ) && // match subclass or driver support all + (driver->protocol == desc_itf->bInterfaceProtocol || driver->all_protocol)) // match protocol or driver support all { return drv_id; } From 3ef6e33533c533ef52336fae66e784b7d85e612f Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 15 Apr 2020 00:59:56 +0700 Subject: [PATCH 04/14] use class driver open() for interface support detection tested with dfu_runtime --- examples/device/dfu_rt/src/main.h | 5 -- examples/device/dfu_rt/src/usb_descriptors.c | 71 +------------------- src/class/dfu/dfu_rt_device.c | 4 +- src/class/dfu/dfu_rt_device.h | 2 +- src/device/usbd.c | 37 ++++++++-- 5 files changed, 38 insertions(+), 81 deletions(-) delete mode 100644 examples/device/dfu_rt/src/main.h diff --git a/examples/device/dfu_rt/src/main.h b/examples/device/dfu_rt/src/main.h deleted file mode 100644 index 673247ec7..000000000 --- a/examples/device/dfu_rt/src/main.h +++ /dev/null @@ -1,5 +0,0 @@ -#ifndef MAIN_H -#define MAIN_H -void led_indicator_pulse(void); - -#endif diff --git a/examples/device/dfu_rt/src/usb_descriptors.c b/examples/device/dfu_rt/src/usb_descriptors.c index 5cd661b2b..3d900efd9 100644 --- a/examples/device/dfu_rt/src/usb_descriptors.c +++ b/examples/device/dfu_rt/src/usb_descriptors.c @@ -77,92 +77,25 @@ uint8_t const * tud_descriptor_device_cb(void) return (uint8_t const *) &desc_device; } -//--------------------------------------------------------------------+ -// HID Report Descriptor -//--------------------------------------------------------------------+ -#if CFG_TUD_HID - -uint8_t const desc_hid_report[] = -{ - TUD_HID_REPORT_DESC_KEYBOARD( HID_REPORT_ID(REPORT_ID_KEYBOARD), ), - TUD_HID_REPORT_DESC_MOUSE ( HID_REPORT_ID(REPORT_ID_MOUSE), ) -}; - -// Invoked when received GET HID REPORT DESCRIPTOR -// Application return pointer to descriptor -// Descriptor contents must exist long enough for transfer to complete -uint8_t const * tud_hid_descriptor_report_cb(void) -{ - return desc_hid_report; -} - -#endif - //--------------------------------------------------------------------+ // Configuration Descriptor //--------------------------------------------------------------------+ enum { -#if CFG_TUD_CDC - ITF_NUM_CDC = 0, - ITF_NUM_CDC_DATA, -#endif - -#if CFG_TUD_MSC - ITF_NUM_MSC, -#endif - -#if CFG_TUD_HID - ITF_NUM_HID, -#endif - -#if CFG_TUD_DFU_RT ITF_NUM_DFU_RT, -#endif - ITF_NUM_TOTAL }; - -#define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + CFG_TUD_CDC*TUD_CDC_DESC_LEN + CFG_TUD_MSC*TUD_MSC_DESC_LEN + \ - CFG_TUD_HID*TUD_HID_DESC_LEN + (CFG_TUD_DFU_RT)*TUD_DFU_RT_DESC_LEN) - -#if CFG_TUSB_MCU == OPT_MCU_LPC175X_6X || CFG_TUSB_MCU == OPT_MCU_LPC177X_8X || CFG_TUSB_MCU == OPT_MCU_LPC40XX - // LPC 17xx and 40xx endpoint type (bulk/interrupt/iso) are fixed by its number - // 0 control, 1 In, 2 Bulk, 3 Iso, 4 In etc ... - // Note: since CDC EP ( 1 & 2), HID (4) are spot-on, thus we only need to force - // endpoint number for MSC to 5 - #define EPNUM_MSC 0x05 -#else - #define EPNUM_MSC 0x03 -#endif - +#define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_DFU_RT_DESC_LEN) uint8_t const desc_configuration[] = { // Config number, interface count, string index, total length, attribute, power in mA TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP, 100), -#if CFG_TUD_CDC - // Interface number, string index, EP notification address and size, EP data address (out, in) and size. - TUD_CDC_DESCRIPTOR(ITF_NUM_CDC, 1, 0x81, 8, 0x02, 0x82, 64), -#endif - -#if CFG_TUD_MSC - // Interface number, string index, EP Out & EP In address, EP size - TUD_MSC_DESCRIPTOR(ITF_NUM_MSC, 5, EPNUM_MSC, 0x80 | EPNUM_MSC, (CFG_TUSB_RHPORT0_MODE & OPT_MODE_HIGH_SPEED) ? 512 : 64), -#endif - -#if CFG_TUD_HID - // Interface number, string index, protocol, report descriptor len, EP In address, size & polling interval - TUD_HID_DESCRIPTOR(ITF_NUM_HID, 6, HID_PROTOCOL_NONE, sizeof(desc_hid_report), 0x84, 16, 10), -#endif - -#if CFG_TUD_DFU_RT // Interface number, string index, attributes, detach timeout, transfer size */ - TUD_DFU_RT_DESCRIPTOR(ITF_NUM_DFU_RT, 7, 0x0d, 1000, 4096), -#endif + TUD_DFU_RT_DESCRIPTOR(ITF_NUM_DFU_RT, 4, 0x0d, 1000, 4096), }; diff --git a/src/class/dfu/dfu_rt_device.c b/src/class/dfu/dfu_rt_device.c index ad1871dad..0ef5fe63f 100644 --- a/src/class/dfu/dfu_rt_device.c +++ b/src/class/dfu/dfu_rt_device.c @@ -61,8 +61,8 @@ bool dfu_rtd_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16 (void) rhport; // Ensure this is DFU Runtime - TU_ASSERT(itf_desc->bInterfaceSubClass == TUD_DFU_APP_SUBCLASS); - TU_ASSERT(itf_desc->bInterfaceProtocol == DFU_PROTOCOL_RT); + TU_VERIFY(itf_desc->bInterfaceSubClass == TUD_DFU_APP_SUBCLASS); + TU_VERIFY(itf_desc->bInterfaceProtocol == DFU_PROTOCOL_RT); uint8_t const * p_desc = tu_desc_next( itf_desc ); (*p_length) = sizeof(tusb_desc_interface_t); diff --git a/src/class/dfu/dfu_rt_device.h b/src/class/dfu/dfu_rt_device.h index 4348a0f3a..294d993e3 100644 --- a/src/class/dfu/dfu_rt_device.h +++ b/src/class/dfu/dfu_rt_device.h @@ -58,7 +58,7 @@ typedef enum //--------------------------------------------------------------------+ // Invoked when received new data -TU_ATTR_WEAK void tud_dfu_rt_reboot_to_dfu(void); +TU_ATTR_WEAK void tud_dfu_rt_reboot_to_dfu(void); // TODO rename to _cb convention //--------------------------------------------------------------------+ // Internal Class Driver API diff --git a/src/device/usbd.c b/src/device/usbd.c index c1ef482e2..eea344c3b 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -76,8 +76,8 @@ enum { DRVID_INVALID = 0xFFu }; typedef struct { uint8_t class_code; - uint8_t subclass; // 0xFF support all values of subclass - uint8_t protocol; // 0xFF support all values of protocol + uint8_t subclass; + uint8_t protocol; struct TU_ATTR_PACKED { @@ -299,7 +299,7 @@ static osal_queue_t _usbd_q; // Prototypes //--------------------------------------------------------------------+ static void mark_interface_endpoint(uint8_t ep2drv[8][2], uint8_t const* p_desc, uint16_t desc_len, uint8_t driver_id); -static uint8_t find_driver_id(tusb_desc_interface_t const * desc_itf); +//static uint8_t find_driver_id(tusb_desc_interface_t const * desc_itf); static bool process_control_request(uint8_t rhport, tusb_control_request_t const * p_request); static bool process_set_config(uint8_t rhport, uint8_t cfg_num); @@ -346,6 +346,9 @@ static char const* const _usbd_driver_str[USBD_CLASS_DRIVER_COUNT] = #if CFG_TUD_VENDOR "Vendor", #endif + #if CFG_TUD_DFU_RT + "DFU Runtime", + #endif #if CFG_TUD_USBTMC "USBTMC" #endif @@ -823,6 +826,7 @@ static bool process_set_config(uint8_t rhport, uint8_t cfg_num) tusb_desc_interface_t const * desc_itf = (tusb_desc_interface_t const*) p_desc; +#if 0 // Find driver id for the interface uint8_t drv_id = find_driver_id(desc_itf); TU_ASSERT( drv_id < USBD_CLASS_DRIVER_COUNT ); @@ -835,8 +839,31 @@ static bool process_set_config(uint8_t rhport, uint8_t cfg_num) TU_LOG2(" %s open\r\n", _usbd_driver_str[drv_id]); TU_ASSERT( _usbd_driver[drv_id].open(rhport, desc_itf, &itf_len) ); TU_ASSERT( itf_len >= sizeof(tusb_desc_interface_t) ); +#else + uint8_t drv_id; + uint16_t itf_len; - mark_interface_endpoint(_usbd_dev.ep2drv, p_desc, itf_len, drv_id); + for (drv_id = 0; drv_id < USBD_CLASS_DRIVER_COUNT; drv_id++) + { + usbd_class_driver_t const *driver = &_usbd_driver[drv_id]; + + itf_len = 0; + if ( driver->open(rhport, desc_itf, &itf_len) ) + { + // Interface number must not be used already TODO alternate interface + TU_ASSERT( DRVID_INVALID == _usbd_dev.itf2drv[desc_itf->bInterfaceNumber] ); + _usbd_dev.itf2drv[desc_itf->bInterfaceNumber] = drv_id; + + TU_LOG2(" itf_len = %d \r\n", itf_len); + break; + } + } + + // Assert if cannot find a driver + TU_ASSERT( drv_id < USBD_CLASS_DRIVER_COUNT && itf_len >= sizeof(tusb_desc_interface_t) ); +#endif + + mark_interface_endpoint(_usbd_dev.ep2drv, p_desc, itf_len, drv_id); // TODO refactor p_desc += itf_len; // next interface } @@ -848,6 +875,7 @@ static bool process_set_config(uint8_t rhport, uint8_t cfg_num) return true; } +#if 0 // Helper to find class driver id for an interface // return 0xFF if not found static uint8_t find_driver_id(tusb_desc_interface_t const * desc_itf) @@ -865,6 +893,7 @@ static uint8_t find_driver_id(tusb_desc_interface_t const * desc_itf) return DRVID_INVALID; } +#endif // Helper marking endpoint of interface belongs to class driver static void mark_interface_endpoint(uint8_t ep2drv[8][2], uint8_t const* p_desc, uint16_t desc_len, uint8_t driver_id) From 8614dcece7792aab34431156c499f778baafa7c3 Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 15 Apr 2020 01:01:07 +0700 Subject: [PATCH 05/14] tested with hid --- src/class/hid/hid_device.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/class/hid/hid_device.c b/src/class/hid/hid_device.c index 7cb35f1ce..ca00cb942 100644 --- a/src/class/hid/hid_device.c +++ b/src/class/hid/hid_device.c @@ -160,6 +160,8 @@ void hidd_reset(uint8_t rhport) bool hidd_open(uint8_t rhport, tusb_desc_interface_t const * desc_itf, uint16_t *p_len) { + TU_VERIFY(desc_itf->bInterfaceClass == TUSB_CLASS_HID); + uint8_t const *p_desc = (uint8_t const *) desc_itf; // Find available interface From bae570f7c7ab16fcd727dde7e41bd182ade18d71 Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 15 Apr 2020 01:01:31 +0700 Subject: [PATCH 06/14] tested with midi --- src/class/midi/midi_device.c | 46 +++++++++++++++++++++++------------- 1 file changed, 30 insertions(+), 16 deletions(-) diff --git a/src/class/midi/midi_device.c b/src/class/midi/midi_device.c index ae6e3afe1..6eb522380 100644 --- a/src/class/midi/midi_device.c +++ b/src/class/midi/midi_device.c @@ -253,21 +253,31 @@ void midid_reset(uint8_t rhport) } } -bool midid_open(uint8_t rhport, tusb_desc_interface_t const * p_interface_desc, uint16_t *p_length) +bool midid_open(uint8_t rhport, tusb_desc_interface_t const * desc_itf, uint16_t *p_length) { - // For now handle the audio control interface as well. - if ( AUDIO_SUBCLASS_CONTROL == p_interface_desc->bInterfaceSubClass) { - uint8_t const * p_desc = tu_desc_next ( (uint8_t const *) p_interface_desc ); - (*p_length) = sizeof(tusb_desc_interface_t); - // Skip over the class specific descriptor. - (*p_length) += tu_desc_len(p_desc); + // 1st Interface is Audio Control v1 + TU_VERIFY(TUSB_CLASS_AUDIO == desc_itf->bInterfaceClass && + AUDIO_SUBCLASS_CONTROL == desc_itf->bInterfaceSubClass && + AUDIO_PROTOCOL_V1 == desc_itf->bInterfaceProtocol); + + uint16_t drv_len = tu_desc_len(desc_itf); + uint8_t const * p_desc = tu_desc_next(desc_itf); + + // Skip Class Specific descriptors + while ( TUSB_DESC_CS_INTERFACE == tu_desc_type(p_desc) ) + { + drv_len += tu_desc_len(p_desc); p_desc = tu_desc_next(p_desc); - return true; } - TU_VERIFY(AUDIO_SUBCLASS_MIDI_STREAMING == p_interface_desc->bInterfaceSubClass && - AUDIO_PROTOCOL_V1 == p_interface_desc->bInterfaceProtocol ); + // 2nd Interface is MIDI Streaming + TU_VERIFY(TUSB_DESC_INTERFACE == tu_desc_type(p_desc)); + tusb_desc_interface_t const * desc_midi = (tusb_desc_interface_t const *) p_desc; + + TU_VERIFY(TUSB_CLASS_AUDIO == desc_midi->bInterfaceClass && + AUDIO_SUBCLASS_MIDI_STREAMING == desc_midi->bInterfaceSubClass && + AUDIO_PROTOCOL_V1 == desc_midi->bInterfaceProtocol ); // Find available interface midid_interface_t * p_midi = NULL; @@ -280,13 +290,15 @@ bool midid_open(uint8_t rhport, tusb_desc_interface_t const * p_interface_desc, } } - p_midi->itf_num = p_interface_desc->bInterfaceNumber; + p_midi->itf_num = desc_midi->bInterfaceNumber; - uint8_t const * p_desc = tu_desc_next( (uint8_t const *) p_interface_desc ); - (*p_length) = sizeof(tusb_desc_interface_t); + // next descriptor + drv_len += tu_desc_len(p_desc); + p_desc = tu_desc_next(p_desc); + // Find and open endpoint descriptors uint8_t found_endpoints = 0; - while (found_endpoints < p_interface_desc->bNumEndpoints) + while (found_endpoints < desc_midi->bNumEndpoints) { if ( TUSB_DESC_ENDPOINT == p_desc[DESC_OFFSET_TYPE]) { @@ -298,14 +310,16 @@ bool midid_open(uint8_t rhport, tusb_desc_interface_t const * p_interface_desc, p_midi->ep_out = ep_addr; } - (*p_length) += p_desc[DESC_OFFSET_LEN]; + drv_len += p_desc[DESC_OFFSET_LEN]; p_desc = tu_desc_next(p_desc); found_endpoints += 1; } - (*p_length) += p_desc[DESC_OFFSET_LEN]; + drv_len += p_desc[DESC_OFFSET_LEN]; p_desc = tu_desc_next(p_desc); } + *p_length = drv_len; + // Prepare for incoming data TU_ASSERT( usbd_edpt_xfer(rhport, p_midi->ep_out, p_midi->epout_buf, CFG_TUD_MIDI_EPSIZE), false); From e713b534fa563509cad81807fbe11937dfcca8fb Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 15 Apr 2020 10:30:34 +0700 Subject: [PATCH 07/14] test ok with cdc and msc --- src/class/cdc/cdc_device.c | 8 ++++---- src/class/hid/hid_device.c | 2 +- src/class/msc/msc_device.c | 3 ++- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/class/cdc/cdc_device.c b/src/class/cdc/cdc_device.c index 14b9a3153..04c73da78 100644 --- a/src/class/cdc/cdc_device.c +++ b/src/class/cdc/cdc_device.c @@ -223,11 +223,11 @@ void cdcd_reset(uint8_t rhport) bool cdcd_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t *p_length) { // Only support ACM subclass - TU_ASSERT ( CDC_COMM_SUBCLASS_ABSTRACT_CONTROL_MODEL == itf_desc->bInterfaceSubClass); + TU_VERIFY ( TUSB_CLASS_CDC == itf_desc->bInterfaceClass && + CDC_COMM_SUBCLASS_ABSTRACT_CONTROL_MODEL == itf_desc->bInterfaceSubClass); - // Only support AT commands, no protocol and vendor specific commands. - TU_ASSERT(tu_within(CDC_COMM_PROTOCOL_NONE, itf_desc->bInterfaceProtocol, CDC_COMM_PROTOCOL_ATCOMMAND_CDMA) || - itf_desc->bInterfaceProtocol == 0xff); + // Note: 0xFF can be used with RNDIS + TU_VERIFY(tu_within(CDC_COMM_PROTOCOL_NONE, itf_desc->bInterfaceProtocol, CDC_COMM_PROTOCOL_ATCOMMAND_CDMA)); // Find available interface cdcd_interface_t * p_cdc = NULL; diff --git a/src/class/hid/hid_device.c b/src/class/hid/hid_device.c index ca00cb942..cbdc5bece 100644 --- a/src/class/hid/hid_device.c +++ b/src/class/hid/hid_device.c @@ -160,7 +160,7 @@ void hidd_reset(uint8_t rhport) bool hidd_open(uint8_t rhport, tusb_desc_interface_t const * desc_itf, uint16_t *p_len) { - TU_VERIFY(desc_itf->bInterfaceClass == TUSB_CLASS_HID); + TU_VERIFY(TUSB_CLASS_HID == desc_itf->bInterfaceClass); uint8_t const *p_desc = (uint8_t const *) desc_itf; diff --git a/src/class/msc/msc_device.c b/src/class/msc/msc_device.c index 06cc9dbb6..68f5587fd 100644 --- a/src/class/msc/msc_device.c +++ b/src/class/msc/msc_device.c @@ -157,7 +157,8 @@ void mscd_reset(uint8_t rhport) bool mscd_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t *p_len) { // only support SCSI's BOT protocol - TU_ASSERT(MSC_SUBCLASS_SCSI == itf_desc->bInterfaceSubClass && + TU_VERIFY(TUSB_CLASS_MSC == itf_desc->bInterfaceClass && + MSC_SUBCLASS_SCSI == itf_desc->bInterfaceSubClass && MSC_PROTOCOL_BOT == itf_desc->bInterfaceProtocol); mscd_interface_t * p_msc = &_mscd_itf; From c1c9ca5629270e545c54d5e2983b77a5c3821a4e Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 15 Apr 2020 10:37:31 +0700 Subject: [PATCH 08/14] test with tmc --- src/class/usbtmc/usbtmc_device.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/class/usbtmc/usbtmc_device.c b/src/class/usbtmc/usbtmc_device.c index 92d8d34ef..abe26ced3 100644 --- a/src/class/usbtmc/usbtmc_device.c +++ b/src/class/usbtmc/usbtmc_device.c @@ -263,17 +263,19 @@ void usbtmcd_init_cb(void) bool usbtmcd_open_cb(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t *p_length) { (void)rhport; - TU_ASSERT(usbtmc_state.state == STATE_CLOSED); uint8_t const * p_desc; uint8_t found_endpoints = 0; + TU_VERIFY(itf_desc->bInterfaceClass == TUD_USBTMC_APP_CLASS); + TU_VERIFY(itf_desc->bInterfaceSubClass == TUD_USBTMC_APP_SUBCLASS); + #ifndef NDEBUG - TU_ASSERT(itf_desc->bInterfaceClass == TUD_USBTMC_APP_CLASS); - TU_ASSERT(itf_desc->bInterfaceSubClass == TUD_USBTMC_APP_SUBCLASS); // Only 2 or 3 endpoints are allowed for USBTMC. TU_ASSERT((itf_desc->bNumEndpoints == 2) || (itf_desc->bNumEndpoints ==3)); #endif + TU_ASSERT(usbtmc_state.state == STATE_CLOSED); + // Interface (*p_length) = 0u; p_desc = (uint8_t const *) itf_desc; From 490771a094baaa9ead60c7ea2e7c4a594d322825 Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 15 Apr 2020 10:39:01 +0700 Subject: [PATCH 09/14] test vendor --- src/class/vendor/vendor_device.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/class/vendor/vendor_device.c b/src/class/vendor/vendor_device.c index 8db5005f4..7f2fe9793 100644 --- a/src/class/vendor/vendor_device.c +++ b/src/class/vendor/vendor_device.c @@ -168,6 +168,8 @@ void vendord_reset(uint8_t rhport) bool vendord_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t *p_len) { + TU_VERIFY(TUSB_CLASS_VENDOR_SPECIFIC == itf_desc->bInterfaceClass); + // Find available interface vendord_interface_t* p_vendor = NULL; for(uint8_t i=0; i Date: Wed, 15 Apr 2020 11:06:35 +0700 Subject: [PATCH 10/14] remove class_code/subclass/protocol from driver structure, add name for logging --- src/device/usbd.c | 129 ++++++++++++++-------------------------------- 1 file changed, 40 insertions(+), 89 deletions(-) diff --git a/src/device/usbd.c b/src/device/usbd.c index f9c52d841..4db6cd671 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -73,17 +73,17 @@ enum { DRVID_INVALID = 0xFFu }; //--------------------------------------------------------------------+ // Class Driver //--------------------------------------------------------------------+ +#if CFG_TUSB_DEBUG >= 2 + #define DRIVER_NAME(_name) .name = _name, +#else + #define DRIVER_NAME(_name) +#endif + typedef struct { - uint8_t class_code; - uint8_t subclass; - uint8_t protocol; - - struct TU_ATTR_PACKED - { - uint8_t all_subclass : 1; - uint8_t all_protocol : 1; - }; + #if CFG_TUSB_DEBUG >= 2 + char const* name; + #endif void (* init ) (void); void (* reset ) (uint8_t rhport); @@ -98,12 +98,7 @@ static usbd_class_driver_t const _usbd_driver[] = { #if CFG_TUD_CDC { - .class_code = TUSB_CLASS_CDC, - .subclass = CDC_COMM_SUBCLASS_ABSTRACT_CONTROL_MODEL, - .protocol = 0x00, - .all_subclass = 0, - .all_protocol = 1, - + DRIVER_NAME("CDC") .init = cdcd_init, .reset = cdcd_reset, .open = cdcd_open, @@ -116,12 +111,7 @@ static usbd_class_driver_t const _usbd_driver[] = #if CFG_TUD_MSC { - .class_code = TUSB_CLASS_MSC, - .subclass = MSC_SUBCLASS_SCSI, - .protocol = MSC_PROTOCOL_BOT, - .all_subclass = 0, - .all_protocol = 0, - + DRIVER_NAME("MSC") .init = mscd_init, .reset = mscd_reset, .open = mscd_open, @@ -134,12 +124,7 @@ static usbd_class_driver_t const _usbd_driver[] = #if CFG_TUD_HID { - .class_code = TUSB_CLASS_HID, - .subclass = 0x00, - .protocol = 0x00, - .all_subclass = 1, - .all_protocol = 1, - + DRIVER_NAME("HID") .init = hidd_init, .reset = hidd_reset, .open = hidd_open, @@ -152,12 +137,7 @@ static usbd_class_driver_t const _usbd_driver[] = #if CFG_TUD_MIDI { - .class_code = TUSB_CLASS_AUDIO, - .subclass = AUDIO_SUBCLASS_CONTROL, - .protocol = AUDIO_PROTOCOL_V1, - .all_subclass = 0, - .all_protocol = 0, - + DRIVER_NAME("MIDI") .init = midid_init, .open = midid_open, .reset = midid_reset, @@ -170,12 +150,7 @@ static usbd_class_driver_t const _usbd_driver[] = #if CFG_TUD_VENDOR { - .class_code = TUSB_CLASS_VENDOR_SPECIFIC, - .subclass = 0x00, - .protocol = 0x00, - .all_subclass = 1, - .all_protocol = 1, - + DRIVER_NAME("VENDOR") .init = vendord_init, .reset = vendord_reset, .open = vendord_open, @@ -188,12 +163,7 @@ static usbd_class_driver_t const _usbd_driver[] = #if CFG_TUD_USBTMC { - .class_code = TUSB_CLASS_APPLICATION_SPECIFIC, - .subclass = APP_SUBCLASS_USBTMC, - .protocol = 0x00, - .all_subclass = 0, - .all_protocol = 1, - + DRIVER_NAME("TMC") .init = usbtmcd_init_cb, .reset = usbtmcd_reset_cb, .open = usbtmcd_open_cb, @@ -206,12 +176,7 @@ static usbd_class_driver_t const _usbd_driver[] = #if CFG_TUD_DFU_RT { - .class_code = TUSB_CLASS_APPLICATION_SPECIFIC, - .subclass = APP_SUBCLASS_DFU_RUNTIME, - .protocol = DFU_PROTOCOL_RT, - .all_subclass = 0, - .all_protocol = 0, - + DRIVER_NAME("DFU-RT") .init = dfu_rtd_init, .reset = dfu_rtd_reset, .open = dfu_rtd_open, @@ -225,7 +190,12 @@ static usbd_class_driver_t const _usbd_driver[] = #if CFG_TUD_NET /* RNDIS management interface */ { - .class_code = TUD_RNDIS_ITF_CLASS, +// .class_code = TUD_RNDIS_ITF_CLASS, +// .subclass = TUD_RNDIS_ITF_SUBCLASS, +// .protocol = TUD_RNDIS_ITF_PROTOCOL, +// .all_subclass = 0, +// .all_protocol = 0, + DRIVER_NAME("RNDIS") .init = netd_init, .reset = netd_reset, .open = netd_open, @@ -236,7 +206,13 @@ static usbd_class_driver_t const _usbd_driver[] = }, /* CDC-ECM management interface */ { - .class_code = TUSB_CLASS_CDC, +// .class_code = TUSB_CLASS_CDC, +// .subclass = CDC_COMM_SUBCLASS_ETHERNET_NETWORKING_CONTROL_MODEL, +// .protocol = 0x00, +// .all_subclass = 0, +// .all_protocol = 0, + + DRIVER_NAME("CDC-ECM") .init = netd_init, .reset = netd_reset, .open = netd_open, @@ -247,7 +223,12 @@ static usbd_class_driver_t const _usbd_driver[] = }, /* RNDIS/CDC-ECM data interface */ { - .class_code = TUSB_CLASS_CDC_DATA, +// .class_code = TUSB_CLASS_CDC_DATA, +// .subclass = 0x00, +// .protocol = 0x00, +// .all_subclass = 0, +// .all_protocol = 0, + DRIVER_NAME("CDC-DATA") .init = netd_init_data, .reset = NULL, .open = netd_open_data, @@ -303,35 +284,6 @@ static char const* const _usbd_event_str[DCD_EVENT_COUNT] = "FUNC_CALL" }; -// must be same driver order as usbd_class_drivers[] -static char const* const _usbd_driver_str[USBD_CLASS_DRIVER_COUNT] = -{ - #if CFG_TUD_CDC - "CDC", - #endif - #if CFG_TUD_MSC - "MSC", - #endif - #if CFG_TUD_HID - "HID", - #endif - #if CFG_TUD_MIDI - "MIDI", - #endif - #if CFG_TUD_VENDOR - "Vendor", - #endif - #if CFG_TUD_DFU_RT - "DFU Runtime", - #endif - #if CFG_TUD_USBTMC - "USBTMC" - #endif - #if CFG_TUD_NET - "NET" - #endif -}; - static char const* const _tusb_std_request_str[] = { "Get Status" , @@ -388,7 +340,7 @@ bool tud_init (void) // Init class drivers for (uint8_t i = 0; i < USBD_CLASS_DRIVER_COUNT; i++) { - TU_LOG2("%s init\r\n", _usbd_driver_str[i]); + TU_LOG2("%s init\r\n", _usbd_driver[i].name); _usbd_driver[i].init(); } @@ -497,7 +449,7 @@ void tud_task (void) uint8_t const drv_id = _usbd_dev.ep2drv[epnum][ep_dir]; TU_ASSERT(drv_id < USBD_CLASS_DRIVER_COUNT,); - TU_LOG2(" %s xfer callback\r\n", _usbd_driver_str[drv_id]); + TU_LOG2(" %s xfer callback\r\n", _usbd_driver[drv_id].name); _usbd_driver[drv_id].xfer_cb(event.rhport, ep_addr, event.xfer_complete.result, event.xfer_complete.len); } } @@ -542,7 +494,7 @@ static bool invoke_class_control(uint8_t rhport, uint8_t drvid, tusb_control_req TU_ASSERT(_usbd_driver[drvid].control_request); usbd_control_set_complete_callback(_usbd_driver[drvid].control_complete); - TU_LOG2(" %s control request\r\n", _usbd_driver_str[drvid]); + TU_LOG2(" %s control request\r\n", _usbd_driver[drvid].name); return _usbd_driver[drvid].control_request(rhport, request); } @@ -811,7 +763,7 @@ static bool process_set_config(uint8_t rhport, uint8_t cfg_num) _usbd_dev.itf2drv[desc_itf->bInterfaceNumber] = drv_id; uint16_t itf_len=0; - TU_LOG2(" %s open\r\n", _usbd_driver_str[drv_id]); + TU_LOG2(" %s open\r\n", _usbd_driver[drv_id].name); TU_ASSERT( _usbd_driver[drv_id].open(rhport, desc_itf, &itf_len) ); TU_ASSERT( itf_len >= sizeof(tusb_desc_interface_t) ); #else @@ -827,9 +779,8 @@ static bool process_set_config(uint8_t rhport, uint8_t cfg_num) { // Interface number must not be used already TODO alternate interface TU_ASSERT( DRVID_INVALID == _usbd_dev.itf2drv[desc_itf->bInterfaceNumber] ); + TU_LOG2(" %s open\r\n", _usbd_driver[drv_id].name); _usbd_dev.itf2drv[desc_itf->bInterfaceNumber] = drv_id; - - TU_LOG2(" itf_len = %d \r\n", itf_len); break; } } From 1faa3b2768f625ffcc06429b7266c88e11605bfc Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 15 Apr 2020 11:41:26 +0700 Subject: [PATCH 11/14] tested usbnet, completely remove class code --- src/class/net/net_device.c | 17 ++++++++++++++--- src/device/usbd.c | 18 ++---------------- 2 files changed, 16 insertions(+), 19 deletions(-) diff --git a/src/class/net/net_device.c b/src/class/net/net_device.c index 777d0da98..8d0cb5d37 100644 --- a/src/class/net/net_device.c +++ b/src/class/net/net_device.c @@ -130,13 +130,22 @@ void netd_reset(uint8_t rhport) bool netd_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t *p_length) { - // sanity check the descriptor - _netd_itf.ecm_mode = (CDC_COMM_SUBCLASS_ETHERNET_NETWORKING_CONTROL_MODEL == itf_desc->bInterfaceSubClass); - TU_VERIFY ( (TUD_RNDIS_ITF_SUBCLASS == itf_desc->bInterfaceSubClass) || _netd_itf.ecm_mode ); + bool const is_rndis = (TUD_RNDIS_ITF_CLASS == itf_desc->bInterfaceClass && + TUD_RNDIS_ITF_SUBCLASS == itf_desc->bInterfaceSubClass && + TUD_RNDIS_ITF_PROTOCOL == itf_desc->bInterfaceProtocol); + + bool const is_ecm = (TUSB_CLASS_CDC == itf_desc->bInterfaceClass && + CDC_COMM_SUBCLASS_ETHERNET_NETWORKING_CONTROL_MODEL == itf_desc->bInterfaceSubClass && + 0x00 == itf_desc->bInterfaceProtocol); + + TU_VERIFY ( is_rndis || is_ecm ); // confirm interface hasn't already been allocated TU_ASSERT(0 == _netd_itf.ep_notif); + // sanity check the descriptor + _netd_itf.ecm_mode = is_ecm; + //------------- Management Interface -------------// _netd_itf.itf_num = itf_desc->bInterfaceNumber; @@ -165,6 +174,8 @@ bool netd_open(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t bool netd_open_data(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t *p_length) { + TU_VERIFY(TUSB_CLASS_CDC_DATA == itf_desc->bInterfaceClass); + // confirm interface hasn't already been allocated TU_ASSERT(0 == _netd_itf.ep_in); diff --git a/src/device/usbd.c b/src/device/usbd.c index 4db6cd671..0f60117ee 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -190,11 +190,6 @@ static usbd_class_driver_t const _usbd_driver[] = #if CFG_TUD_NET /* RNDIS management interface */ { -// .class_code = TUD_RNDIS_ITF_CLASS, -// .subclass = TUD_RNDIS_ITF_SUBCLASS, -// .protocol = TUD_RNDIS_ITF_PROTOCOL, -// .all_subclass = 0, -// .all_protocol = 0, DRIVER_NAME("RNDIS") .init = netd_init, .reset = netd_reset, @@ -204,14 +199,9 @@ static usbd_class_driver_t const _usbd_driver[] = .xfer_cb = netd_xfer_cb, .sof = NULL, }, + /* CDC-ECM management interface */ { -// .class_code = TUSB_CLASS_CDC, -// .subclass = CDC_COMM_SUBCLASS_ETHERNET_NETWORKING_CONTROL_MODEL, -// .protocol = 0x00, -// .all_subclass = 0, -// .all_protocol = 0, - DRIVER_NAME("CDC-ECM") .init = netd_init, .reset = netd_reset, @@ -221,13 +211,9 @@ static usbd_class_driver_t const _usbd_driver[] = .xfer_cb = netd_xfer_cb, .sof = NULL, }, + /* RNDIS/CDC-ECM data interface */ { -// .class_code = TUSB_CLASS_CDC_DATA, -// .subclass = 0x00, -// .protocol = 0x00, -// .all_subclass = 0, -// .all_protocol = 0, DRIVER_NAME("CDC-DATA") .init = netd_init_data, .reset = NULL, From 3bfb402d8ce0fda082f77d4e552537a51f93375c Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 15 Apr 2020 11:44:12 +0700 Subject: [PATCH 12/14] clean up --- src/device/usbd.c | 29 +++++++---------------------- 1 file changed, 7 insertions(+), 22 deletions(-) diff --git a/src/device/usbd.c b/src/device/usbd.c index 0f60117ee..eabe24be0 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -739,29 +739,15 @@ static bool process_set_config(uint8_t rhport, uint8_t cfg_num) tusb_desc_interface_t const * desc_itf = (tusb_desc_interface_t const*) p_desc; -#if 0 - // Find driver id for the interface - uint8_t drv_id = find_driver_id(desc_itf); - TU_ASSERT( drv_id < USBD_CLASS_DRIVER_COUNT ); - - // Interface number must not be used already TODO alternate interface - TU_ASSERT( DRVID_INVALID == _usbd_dev.itf2drv[desc_itf->bInterfaceNumber] ); - _usbd_dev.itf2drv[desc_itf->bInterfaceNumber] = drv_id; - - uint16_t itf_len=0; - TU_LOG2(" %s open\r\n", _usbd_driver[drv_id].name); - TU_ASSERT( _usbd_driver[drv_id].open(rhport, desc_itf, &itf_len) ); - TU_ASSERT( itf_len >= sizeof(tusb_desc_interface_t) ); -#else uint8_t drv_id; - uint16_t itf_len; + uint16_t drv_len; for (drv_id = 0; drv_id < USBD_CLASS_DRIVER_COUNT; drv_id++) { usbd_class_driver_t const *driver = &_usbd_driver[drv_id]; - itf_len = 0; - if ( driver->open(rhport, desc_itf, &itf_len) ) + drv_len = 0; + if ( driver->open(rhport, desc_itf, &drv_len) ) { // Interface number must not be used already TODO alternate interface TU_ASSERT( DRVID_INVALID == _usbd_dev.itf2drv[desc_itf->bInterfaceNumber] ); @@ -771,13 +757,12 @@ static bool process_set_config(uint8_t rhport, uint8_t cfg_num) } } - // Assert if cannot find a driver - TU_ASSERT( drv_id < USBD_CLASS_DRIVER_COUNT && itf_len >= sizeof(tusb_desc_interface_t) ); -#endif + // Assert if cannot find supported driver + TU_ASSERT( drv_id < USBD_CLASS_DRIVER_COUNT && drv_len >= sizeof(tusb_desc_interface_t) ); - mark_interface_endpoint(_usbd_dev.ep2drv, p_desc, itf_len, drv_id); // TODO refactor + mark_interface_endpoint(_usbd_dev.ep2drv, p_desc, drv_len, drv_id); // TODO refactor - p_desc += itf_len; // next interface + p_desc += drv_len; // next interface } } From 93ffe317b262df34afe74e216017411ac70324b5 Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 15 Apr 2020 13:53:50 +0700 Subject: [PATCH 13/14] clean up --- src/device/usbd.c | 22 ---------------------- 1 file changed, 22 deletions(-) diff --git a/src/device/usbd.c b/src/device/usbd.c index eabe24be0..4587a2cc7 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -241,8 +241,6 @@ static osal_queue_t _usbd_q; // Prototypes //--------------------------------------------------------------------+ static void mark_interface_endpoint(uint8_t ep2drv[8][2], uint8_t const* p_desc, uint16_t desc_len, uint8_t driver_id); -//static uint8_t find_driver_id(tusb_desc_interface_t const * desc_itf); - static bool process_control_request(uint8_t rhport, tusb_control_request_t const * p_request); static bool process_set_config(uint8_t rhport, uint8_t cfg_num); static bool process_get_descriptor(uint8_t rhport, tusb_control_request_t const * p_request); @@ -772,26 +770,6 @@ static bool process_set_config(uint8_t rhport, uint8_t cfg_num) return true; } -#if 0 -// Helper to find class driver id for an interface -// return 0xFF if not found -static uint8_t find_driver_id(tusb_desc_interface_t const * desc_itf) -{ - for (uint8_t drv_id = 0; drv_id < USBD_CLASS_DRIVER_COUNT; drv_id++) - { - usbd_class_driver_t const *driver = &_usbd_driver[drv_id]; - if ( (driver->class_code == desc_itf->bInterfaceClass) && // match class code - (driver->subclass == desc_itf->bInterfaceSubClass || driver->all_subclass ) && // match subclass or driver support all - (driver->protocol == desc_itf->bInterfaceProtocol || driver->all_protocol)) // match protocol or driver support all - { - return drv_id; - } - } - - return DRVID_INVALID; -} -#endif - // Helper marking endpoint of interface belongs to class driver static void mark_interface_endpoint(uint8_t ep2drv[8][2], uint8_t const* p_desc, uint16_t desc_len, uint8_t driver_id) { From b03b9eb93991c561610a01c379154e7db55e9f4b Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 15 Apr 2020 15:14:26 +0700 Subject: [PATCH 14/14] change cdc template protocol to None --- src/class/cdc/cdc_host.c | 2 +- src/device/usbd.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/class/cdc/cdc_host.c b/src/class/cdc/cdc_host.c index 595e7fd62..5e45e8f6b 100644 --- a/src/class/cdc/cdc_host.c +++ b/src/class/cdc/cdc_host.c @@ -86,7 +86,7 @@ bool tuh_cdc_serial_is_mounted(uint8_t dev_addr) { // TODO consider all AT Command as serial candidate return tuh_cdc_mounted(dev_addr) && - (CDC_COMM_PROTOCOL_ATCOMMAND <= cdch_data[dev_addr-1].itf_protocol) && + (CDC_COMM_PROTOCOL_NONE <= cdch_data[dev_addr-1].itf_protocol) && (cdch_data[dev_addr-1].itf_protocol <= CDC_COMM_PROTOCOL_ATCOMMAND_CDMA); } diff --git a/src/device/usbd.h b/src/device/usbd.h index 7b04ef9a7..acefb6943 100644 --- a/src/device/usbd.h +++ b/src/device/usbd.h @@ -183,9 +183,9 @@ TU_ATTR_WEAK bool tud_vendor_control_complete_cb(uint8_t rhport, tusb_control_re // Interface number, string index, EP notification address and size, EP data address (out, in) and size. #define TUD_CDC_DESCRIPTOR(_itfnum, _stridx, _ep_notif, _ep_notif_size, _epout, _epin, _epsize) \ /* Interface Associate */\ - 8, TUSB_DESC_INTERFACE_ASSOCIATION, _itfnum, 2, TUSB_CLASS_CDC, CDC_COMM_SUBCLASS_ABSTRACT_CONTROL_MODEL, CDC_COMM_PROTOCOL_ATCOMMAND, 0,\ + 8, TUSB_DESC_INTERFACE_ASSOCIATION, _itfnum, 2, TUSB_CLASS_CDC, CDC_COMM_SUBCLASS_ABSTRACT_CONTROL_MODEL, CDC_COMM_PROTOCOL_NONE, 0,\ /* CDC Control Interface */\ - 9, TUSB_DESC_INTERFACE, _itfnum, 0, 1, TUSB_CLASS_CDC, CDC_COMM_SUBCLASS_ABSTRACT_CONTROL_MODEL, CDC_COMM_PROTOCOL_ATCOMMAND, _stridx,\ + 9, TUSB_DESC_INTERFACE, _itfnum, 0, 1, TUSB_CLASS_CDC, CDC_COMM_SUBCLASS_ABSTRACT_CONTROL_MODEL, CDC_COMM_PROTOCOL_NONE, _stridx,\ /* CDC Header */\ 5, TUSB_DESC_CS_INTERFACE, CDC_FUNC_DESC_HEADER, U16_TO_U8S_LE(0x0120),\ /* CDC Call */\