From 3ef6e33533c533ef52336fae66e784b7d85e612f Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 15 Apr 2020 00:59:56 +0700 Subject: [PATCH] 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)