From e83bdcdfdc521fef2dd182a5f83cd1c1be673865 Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 12 May 2021 15:29:17 +0700 Subject: [PATCH] reworking hid host --- examples/host/cdc_msc_hid/src/main.c | 2 +- examples/host/cdc_msc_hid/src/tusb_config.h | 4 + src/class/hid/hid_host.c | 159 +++++++++++--------- src/class/hid/hid_host.h | 14 +- src/host/usbh.c | 1 + 5 files changed, 108 insertions(+), 72 deletions(-) diff --git a/examples/host/cdc_msc_hid/src/main.c b/examples/host/cdc_msc_hid/src/main.c index 652a372e9..b3fd1f2af 100644 --- a/examples/host/cdc_msc_hid/src/main.c +++ b/examples/host/cdc_msc_hid/src/main.c @@ -154,7 +154,7 @@ static inline void process_kbd_report(hid_keyboard_report_t const *p_new_report) prev_report = *p_new_report; } -void tuh_hid_keyboard_mounted_cb(uint8_t dev_addr) +void tuh_hid_mounted_cb(uint8_t dev_addr) { // application set-up printf("A Keyboard device (address %d) is mounted\r\n", dev_addr); diff --git a/examples/host/cdc_msc_hid/src/tusb_config.h b/examples/host/cdc_msc_hid/src/tusb_config.h index fabc7765c..82155f1ca 100644 --- a/examples/host/cdc_msc_hid/src/tusb_config.h +++ b/examples/host/cdc_msc_hid/src/tusb_config.h @@ -73,9 +73,13 @@ #define CFG_TUH_HUB 1 #define CFG_TUH_CDC 1 + +#define CFG_TUH_HID 2 + #define CFG_TUH_HID_KEYBOARD 1 #define CFG_TUH_HID_MOUSE 1 #define CFG_TUSB_HOST_HID_GENERIC 0 // (not yet supported) + #define CFG_TUH_MSC 1 #define CFG_TUH_VENDOR 0 diff --git a/src/class/hid/hid_host.c b/src/class/hid/hid_host.c index aa6188a24..dae20b305 100644 --- a/src/class/hid/hid_host.c +++ b/src/class/hid/hid_host.c @@ -44,11 +44,14 @@ "XAC_COMPATIBLE_GAMEPAD" : in_len=3 , out_len=0, usage_page=0x01, usage=0x05 # Generic Desktop, Game Pad "RAW" : in_len=64, out_len=0, usage_page=0xFFAF, usage=0xAF # Vendor 0xFFAF "Adafruit", 0xAF */ -typedef struct { +typedef struct +{ uint8_t itf_num; uint8_t ep_in; uint8_t ep_out; + uint16_t report_desc_len; + bool valid; uint16_t report_size; // TODO remove later @@ -61,16 +64,38 @@ typedef struct { uint8_t out_len; // length of OUT report uint8_t usage_page; uint8_t usage; - }reports[CFG_TUH_HID_MAX_REPORT]; + }reports[CFG_TUH_HID_REPORT_MAX]; // Parsed Report ID for convenient API - uint8_t report_id_keyboard; - uint8_t reprot_id_mouse; - uint8_t report_id_gamepad; - uint8_t report_id_consumer; - uint8_t report_id_vendor; + uint8_t rid_keyboard; + uint8_t rid_mouse; + uint8_t rid_gamepad; + uint8_t rid_consumer; }hidh_interface_t; +typedef struct +{ + uint8_t inst_count; + hidh_interface_t instance[CFG_TUH_HID]; +} hidh_device_t; + +static hidh_device_t _hidh_dev[CFG_TUSB_HOST_DEVICE_MAX-1]; + +#if 0 +CFG_TUSB_MEM_SECTION uint8_t report_descriptor[256]; +#endif + +TU_ATTR_ALWAYS_INLINE static inline hidh_device_t* get_dev(uint8_t dev_addr) +{ + return &_hidh_dev[dev_addr-1]; +} + +TU_ATTR_ALWAYS_INLINE static inline hidh_interface_t* get_instance(uint8_t dev_addr, uint8_t inst) +{ + return &_hidh_dev[dev_addr-1].instance[inst]; +} + + //--------------------------------------------------------------------+ // HID Interface common functions //--------------------------------------------------------------------+ @@ -108,27 +133,32 @@ tusb_error_t hidh_interface_get_report(uint8_t dev_addr, void * report, hidh_int //--------------------------------------------------------------------+ // KEYBOARD //--------------------------------------------------------------------+ -#if CFG_TUH_HID_KEYBOARD -static hidh_interface_t keyboardh_data[CFG_TUSB_HOST_DEVICE_MAX]; // does not have addr0, index = dev_address-1 - -//------------- KEYBOARD PUBLIC API (parameter validation required) -------------// -bool tuh_hid_keyboard_mounted(uint8_t dev_addr) +bool tuh_hid_keyboard_mounted(uint8_t dev_addr) { - return tuh_device_is_configured(dev_addr) && (keyboardh_data[dev_addr-1].ep_in != 0); + uint8_t itf = 0; + hidh_interface_t* hid_itf = get_instance(dev_addr, itf); + + // TODO check rid_keyboard + return tuh_device_is_configured(dev_addr) && (hid_itf->ep_in != 0); } -tusb_error_t tuh_hid_keyboard_get_report(uint8_t dev_addr, void* p_report) +tusb_error_t tuh_hid_keyboard_get_report(uint8_t dev_addr, void* buffer) { - return hidh_interface_get_report(dev_addr, p_report, &keyboardh_data[dev_addr-1]); + uint8_t itf = 0; + hidh_interface_t* hid_itf = get_instance(dev_addr, itf); + + return hidh_interface_get_report(dev_addr, buffer, hid_itf); } bool tuh_hid_keyboard_is_busy(uint8_t dev_addr) { - return tuh_hid_keyboard_mounted(dev_addr) && hcd_edpt_busy(dev_addr, keyboardh_data[dev_addr-1].ep_in); + uint8_t itf = 0; + hidh_interface_t* hid_itf = get_instance(dev_addr, itf); + + return tuh_hid_keyboard_mounted(dev_addr) && hcd_edpt_busy(dev_addr, hid_itf->ep_in); } -#endif //--------------------------------------------------------------------+ // MOUSE @@ -158,36 +188,20 @@ tusb_error_t tuh_hid_mouse_get_report(uint8_t dev_addr, void * report) //--------------------------------------------------------------------+ // GENERIC //--------------------------------------------------------------------+ -#if CFG_TUSB_HOST_HID_GENERIC -//STATIC_ struct { -// hidh_interface_info_t -//} generic_data[CFG_TUSB_HOST_DEVICE_MAX]; - -#endif //--------------------------------------------------------------------+ // CLASS-USBH API (don't require to verify parameters) //--------------------------------------------------------------------+ void hidh_init(void) { -#if CFG_TUH_HID_KEYBOARD - tu_memclr(&keyboardh_data, sizeof(hidh_interface_t)*CFG_TUSB_HOST_DEVICE_MAX); -#endif + tu_memclr(_hidh_dev, sizeof(_hidh_dev)); #if CFG_TUH_HID_MOUSE tu_memclr(&mouseh_data, sizeof(hidh_interface_t)*CFG_TUSB_HOST_DEVICE_MAX); #endif - -#if CFG_TUSB_HOST_HID_GENERIC - hidh_generic_init(); -#endif } -#if 0 -CFG_TUSB_MEM_SECTION uint8_t report_descriptor[256]; -#endif - bool hidh_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *desc_itf, uint16_t *p_length) { TU_VERIFY(TUSB_CLASS_HID == desc_itf->bInterfaceClass); @@ -199,6 +213,18 @@ bool hidh_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *de tusb_hid_descriptor_hid_t const *desc_hid = (tusb_hid_descriptor_hid_t const *) p_desc; TU_ASSERT(HID_DESC_TYPE_HID == desc_hid->bDescriptorType); + // not enough interface, try to increase CFG_TUH_HID + // TODO multiple devices + hidh_device_t* hid_dev = get_dev(dev_addr); + TU_ASSERT(hid_dev->inst_count < CFG_TUH_HID); + + hidh_interface_t* hid_itf = get_instance(dev_addr, hid_dev->inst_count); + hid_dev->inst_count++; + + hid_itf->itf_num = desc_itf->bInterfaceNumber; + hid_itf->boot_mode = false; // default is report mode + hid_itf->report_desc_len = tu_unaligned_read16(&desc_hid->wReportLength); + //------------- Endpoint Descriptor -------------// p_desc = tu_desc_next(p_desc); tusb_desc_endpoint_t const * desc_ep = (tusb_desc_endpoint_t const *) p_desc; @@ -206,11 +232,20 @@ bool hidh_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *de if ( HID_SUBCLASS_BOOT == desc_itf->bInterfaceSubClass ) { + hid_itf->boot_protocol = desc_itf->bInterfaceProtocol; + #if CFG_TUH_HID_KEYBOARD if ( HID_PROTOCOL_KEYBOARD == desc_itf->bInterfaceProtocol) { - TU_ASSERT( hidh_interface_open(rhport, dev_addr, desc_itf->bInterfaceNumber, desc_ep, &keyboardh_data[dev_addr-1]) ); - TU_LOG2_HEX(keyboardh_data[dev_addr-1].ep_in); + TU_ASSERT( hidh_interface_open(rhport, dev_addr, desc_itf->bInterfaceNumber, desc_ep, hid_itf) ); + TU_LOG2_HEX(hid_itf->ep_in); + + hid_itf->report_count = 1; + + hid_itf->reports[0].usage_page = HID_USAGE_PAGE_DESKTOP; + hid_itf->reports[0].usage = HID_USAGE_DESKTOP_KEYBOARD; + hid_itf->reports[0].in_len = 8; + hid_itf->reports[0].out_len = 1; } else #endif @@ -226,13 +261,9 @@ bool hidh_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *de // Not supported protocol return false; } - }else - { - // Not supported subclass - return false; } - *p_length = sizeof(tusb_desc_interface_t) + sizeof(tusb_hid_descriptor_hid_t) + sizeof(tusb_desc_endpoint_t); + *p_length = sizeof(tusb_desc_interface_t) + sizeof(tusb_hid_descriptor_hid_t) + desc_itf->bNumEndpoints*sizeof(tusb_desc_endpoint_t); return true; } @@ -276,12 +307,13 @@ bool hidh_set_config(uint8_t dev_addr, uint8_t itf_num) usbh_driver_set_config_complete(dev_addr, itf_num); -#if CFG_TUH_HID_KEYBOARD - if (( keyboardh_data[dev_addr-1].itf_num == itf_num) && keyboardh_data[dev_addr-1].valid) - { - tuh_hid_keyboard_mounted_cb(dev_addr); +// uint8_t itf = 0; +// hidh_interface_t* hid_itf = &_hidh_itf[itf]; + + + if (itf_num == 0 ) { + if (tuh_hid_mounted_cb) tuh_hid_mounted_cb(dev_addr); } -#endif #if CFG_TUH_HID_MOUSE if (( mouseh_data[dev_addr-1].ep_in == itf_num ) && mouseh_data[dev_addr-1].valid) @@ -297,12 +329,15 @@ bool hidh_xfer_cb(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t event, uint32 { (void) xferred_bytes; // TODO may need to use this para later +// uint8_t itf = 0; +// hidh_interface_t* hid_itf = &_hidh_itf[itf]; + #if CFG_TUH_HID_KEYBOARD - if ( ep_addr == keyboardh_data[dev_addr-1].ep_in ) - { - tuh_hid_keyboard_isr(dev_addr, event); - return true; - } +// if ( ep_addr == keyboardh_data[dev_addr-1].ep_in ) +// { +// tuh_hid_keyboard_isr(dev_addr, event); +// return true; +// } #endif #if CFG_TUH_HID_MOUSE @@ -311,10 +346,6 @@ bool hidh_xfer_cb(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t event, uint32 tuh_hid_mouse_isr(dev_addr, event); return true; } -#endif - -#if CFG_TUSB_HOST_HID_GENERIC - #endif return true; @@ -322,13 +353,11 @@ bool hidh_xfer_cb(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t event, uint32 void hidh_close(uint8_t dev_addr) { -#if CFG_TUH_HID_KEYBOARD - if ( keyboardh_data[dev_addr-1].ep_in != 0 ) - { - hidh_interface_close(&keyboardh_data[dev_addr-1]); - tuh_hid_keyboard_unmounted_cb(dev_addr); - } -#endif + uint8_t itf = 0; + hidh_interface_t* hid_itf = get_instance(dev_addr, itf); + + if (tuh_hid_unmounted_cb) tuh_hid_unmounted_cb(dev_addr); + hidh_interface_close(hid_itf); #if CFG_TUH_HID_MOUSE if( mouseh_data[dev_addr-1].ep_in != 0 ) @@ -337,12 +366,6 @@ void hidh_close(uint8_t dev_addr) tuh_hid_mouse_unmounted_cb( dev_addr ); } #endif - -#if CFG_TUSB_HOST_HID_GENERIC - hidh_generic_close(dev_addr); -#endif } - - #endif diff --git a/src/class/hid/hid_host.h b/src/class/hid/hid_host.h index f777fe45d..10ecc457f 100644 --- a/src/class/hid/hid_host.h +++ b/src/class/hid/hid_host.h @@ -42,8 +42,8 @@ // Class Driver Configuration //--------------------------------------------------------------------+ -#ifndef CFG_TUH_HID_MAX_REPORT -#define CFG_TUH_HID_MAX_REPORT 8 +#ifndef CFG_TUH_HID_REPORT_MAX +#define CFG_TUH_HID_REPORT_MAX 4 #endif //--------------------------------------------------------------------+ @@ -56,6 +56,12 @@ // Application API (Single Instance) //--------------------------------------------------------------------+ +// tuh_hid_instance_count() +//bool tuh_hid_get_report(uint8_t dev_addr, uint8_t report_id, void * p_report, uint8_t len); + +TU_ATTR_WEAK void tuh_hid_mounted_cb(uint8_t dev_addr); +TU_ATTR_WEAK void tuh_hid_unmounted_cb(uint8_t dev_addr); + //--------------------------------------------------------------------+ // KEYBOARD Application API //--------------------------------------------------------------------+ @@ -66,7 +72,9 @@ * The interface API includes status checking function, data transferring function and callback functions * @{ */ -extern uint8_t const hid_keycode_to_ascii_tbl[2][128]; // TODO used weak attr if build failed without KEYBOARD enabled +// TODO used weak attr if build failed without KEYBOARD enabled +// TODO remove +extern uint8_t const hid_keycode_to_ascii_tbl[2][128]; /** \brief Check if device supports Keyboard interface or not * \param[in] dev_addr device address diff --git a/src/host/usbh.c b/src/host/usbh.c index 88e5c02a7..f7cad4640 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -915,6 +915,7 @@ static bool enum_set_config_complete(uint8_t dev_addr, tusb_control_request_t co // Start the Set Configuration process for interfaces (itf = 0xff) // Since driver can perform control transfer within its set_config, this is done asynchronously. // The process continue with next interface when class driver complete its sequence with usbh_driver_set_config_complete() + // TODO use separated API instead of usig 0xff usbh_driver_set_config_complete(dev_addr, 0xff); return true;