From 99add05aa78a0fd5d462ab822d0c4656c41c59d7 Mon Sep 17 00:00:00 2001 From: hathach Date: Sat, 22 May 2021 16:27:28 +0700 Subject: [PATCH] simplify hid api add hid set_protocol() and set_protocol_complete_cb() --- examples/host/cdc_msc_hid/src/hid_app.c | 2 +- src/class/hid/hid_host.c | 113 +++++++++++------------- src/class/hid/hid_host.h | 13 +-- 3 files changed, 61 insertions(+), 67 deletions(-) diff --git a/examples/host/cdc_msc_hid/src/hid_app.c b/examples/host/cdc_msc_hid/src/hid_app.c index de92ab84..72e7c30d 100644 --- a/examples/host/cdc_msc_hid/src/hid_app.c +++ b/examples/host/cdc_msc_hid/src/hid_app.c @@ -64,7 +64,7 @@ void tuh_hid_mounted_cb(uint8_t dev_addr, uint8_t instance, uint8_t const* desc_ // Interface protocol const char* protocol_str[] = { "None", "Keyboard", "Mouse" }; // hid_protocol_type_t - uint8_t const interface_protocol = tuh_n_hid_n_interface_protocol(dev_addr, instance); + uint8_t const interface_protocol = tuh_n_hid_interface_protocol(dev_addr, instance); printf(", Interface protocol = %s, ", protocol_str[interface_protocol]); } diff --git a/src/class/hid/hid_host.c b/src/class/hid/hid_host.c index 62e6c4b7..e35e4e4d 100644 --- a/src/class/hid/hid_host.c +++ b/src/class/hid/hid_host.c @@ -51,15 +51,15 @@ typedef struct uint8_t ep_in; uint8_t ep_out; + uint8_t itf_protocol; // None, Keyboard, Mouse + uint8_t protocol_mode; // Boot (0) or Report protocol (1) + uint8_t report_desc_type; uint16_t report_desc_len; uint16_t epin_size; uint16_t epout_size; - uint8_t itf_protocol; // None, Keyboard, Mouse - bool boot_mode; // Boot or Report protocol - uint8_t epin_buf[CFG_TUH_HID_EP_BUFSIZE]; uint8_t epout_buf[CFG_TUH_HID_EP_BUFSIZE]; } hidh_interface_t; @@ -76,7 +76,6 @@ static hidh_device_t _hidh_dev[CFG_TUSB_HOST_DEVICE_MAX-1]; TU_ATTR_ALWAYS_INLINE static inline hidh_device_t* get_dev(uint8_t dev_addr); TU_ATTR_ALWAYS_INLINE static inline hidh_interface_t* get_instance(uint8_t dev_addr, uint8_t instance); static uint8_t get_instance_id_by_itfnum(uint8_t dev_addr, uint8_t itf); -static hidh_interface_t* get_instance_by_itfnum(uint8_t dev_addr, uint8_t itf); static uint8_t get_instance_id_by_epaddr(uint8_t dev_addr, uint8_t ep_addr); TU_ATTR_ALWAYS_INLINE static inline bool hidh_get_report(uint8_t dev_addr, hidh_interface_t* hid_itf) @@ -93,28 +92,64 @@ uint8_t tuh_n_hid_instance_count(uint8_t dev_addr) return get_dev(dev_addr)->inst_count; } -bool tuh_n_hid_n_mounted(uint8_t dev_addr, uint8_t instance) +bool tuh_n_hid_mounted(uint8_t dev_addr, uint8_t instance) { hidh_interface_t* hid_itf = get_instance(dev_addr, instance); return (hid_itf->ep_in != 0) || (hid_itf->ep_out != 0); } -uint8_t tuh_n_hid_n_interface_protocol(uint8_t dev_addr, uint8_t instance) +uint8_t tuh_n_hid_interface_protocol(uint8_t dev_addr, uint8_t instance) { hidh_interface_t* hid_itf = get_instance(dev_addr, instance); return hid_itf->itf_protocol; } -bool tuh_n_hid_n_get_protocol(uint8_t dev_addr, uint8_t instance) +bool tuh_n_hid_get_protocol(uint8_t dev_addr, uint8_t instance) { hidh_interface_t* hid_itf = get_instance(dev_addr, instance); - return hid_itf->boot_mode ? HID_PROTOCOL_BOOT : HID_PROTOCOL_REPORT; + return hid_itf->protocol_mode; } -// bool tuh_n_hid_n_set_protocol(uint8_t dev_addr, uint8_t instance, uint8_t protocol) -//{ -// -//} +static bool set_protocol_complete(uint8_t dev_addr, tusb_control_request_t const * request, xfer_result_t result) +{ + uint8_t const itf_num = (uint8_t) request->wIndex; + uint8_t const instance = get_instance_id_by_itfnum(dev_addr, itf_num); + hidh_interface_t* hid_itf = get_instance(dev_addr, instance); + + if (XFER_RESULT_SUCCESS == result) hid_itf->protocol_mode = (uint8_t) request->wValue; + + if (tuh_hid_set_protocol_complete_cb) + { + tuh_hid_set_protocol_complete_cb(dev_addr, instance, hid_itf->protocol_mode); + } + + return true; +} + +bool tuh_n_hid_set_protocol(uint8_t dev_addr, uint8_t instance, uint8_t protocol) +{ + hidh_interface_t* hid_itf = get_instance(dev_addr, instance); + TU_VERIFY(hid_itf->itf_protocol != HID_ITF_PROTOCOL_NONE); + + TU_LOG2("Set Protocol = %d\r\n", protocol); + + tusb_control_request_t const request = + { + .bmRequestType_bit = + { + .recipient = TUSB_REQ_RCPT_INTERFACE, + .type = TUSB_REQ_TYPE_CLASS, + .direction = TUSB_DIR_OUT + }, + .bRequest = HID_REQ_CONTROL_SET_PROTOCOL, + .wValue = protocol, + .wIndex = hid_itf->itf_num, + .wLength = 0 + }; + + TU_ASSERT( tuh_control_xfer(dev_addr, &request, NULL, set_protocol_complete) ); + return true; +} //bool tuh_n_hid_n_ready(uint8_t dev_addr, uint8_t instance) //{ @@ -209,39 +244,8 @@ bool hidh_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *de hid_itf->report_desc_type = desc_hid->bReportType; hid_itf->report_desc_len = tu_unaligned_read16(&desc_hid->wReportLength); - hid_itf->boot_mode = false; // default is report mode - if ( HID_SUBCLASS_BOOT == desc_itf->bInterfaceSubClass ) - { - hid_itf->itf_protocol = desc_itf->bInterfaceProtocol; - - if ( HID_ITF_PROTOCOL_KEYBOARD == desc_itf->bInterfaceProtocol) - { - TU_LOG2(" Boot Keyboard\r\n"); - // TODO boot protocol may still have more report in report mode -// hid_itf->report_info.count = 1; - -// hid_itf->report_info.info[0].usage_page = HID_USAGE_PAGE_DESKTOP; -// hid_itf->report_info.info[0].usage = HID_USAGE_DESKTOP_KEYBOARD; -// hid_itf->report_info.info[0].in_len = 8; -// hid_itf->report_info.info[0].out_len = 1; - } - else if ( HID_ITF_PROTOCOL_MOUSE == desc_itf->bInterfaceProtocol) - { - TU_LOG2(" Boot Mouse\r\n"); - // TODO boot protocol may still have more report in report mode -// hid_itf->report_info.count = 1; - -// hid_itf->report_info.info[0].usage_page = HID_USAGE_PAGE_DESKTOP; -// hid_itf->report_info.info[0].usage = HID_USAGE_DESKTOP_MOUSE; -// hid_itf->report_info.info[0].in_len = 5; -// hid_itf->report_info.info[0].out_len = 0; - } - else - { - // Unknown protocol - TU_ASSERT(false); - } - } + hid_itf->protocol_mode = HID_PROTOCOL_REPORT; // Per Specs: default is report mode + if ( HID_SUBCLASS_BOOT == desc_itf->bInterfaceSubClass ) hid_itf->itf_protocol = desc_itf->bInterfaceProtocol; *p_length = sizeof(tusb_desc_interface_t) + sizeof(tusb_hid_descriptor_hid_t) + desc_itf->bNumEndpoints*sizeof(tusb_desc_endpoint_t); @@ -279,9 +283,9 @@ bool config_set_idle_complete(uint8_t dev_addr, tusb_control_request_t const * r // Stall is a valid response for SET_IDLE, therefore we could ignore its result (void) result; - uint8_t const itf_num = (uint8_t) request->wIndex; - - hidh_interface_t* hid_itf = get_instance_by_itfnum(dev_addr, itf_num); + uint8_t const itf_num = (uint8_t) request->wIndex; + uint8_t const instance = get_instance_id_by_itfnum(dev_addr, itf_num); + hidh_interface_t* hid_itf = get_instance(dev_addr, instance); // Get Report Descriptor // using usbh enumeration buffer since report descriptor can be very long @@ -509,19 +513,6 @@ TU_ATTR_ALWAYS_INLINE static inline hidh_interface_t* get_instance(uint8_t dev_a return &_hidh_dev[dev_addr-1].instances[instance]; } -// Get instance by interface number -static hidh_interface_t* get_instance_by_itfnum(uint8_t dev_addr, uint8_t itf) -{ - for ( uint8_t inst = 0; inst < CFG_TUH_HID; inst++ ) - { - hidh_interface_t *hid = get_instance(dev_addr, inst); - - if ( (hid->itf_num == itf) && (hid->ep_in || hid->ep_out) ) return hid; - } - - return NULL; -} - // Get instance ID by interface number static uint8_t get_instance_id_by_itfnum(uint8_t dev_addr, uint8_t itf) { diff --git a/src/class/hid/hid_host.h b/src/class/hid/hid_host.h index 677c8c9d..dc0d8c93 100644 --- a/src/class/hid/hid_host.h +++ b/src/class/hid/hid_host.h @@ -72,18 +72,18 @@ typedef struct uint8_t tuh_n_hid_instance_count(uint8_t dev_addr); // Check if HID instance is mounted -bool tuh_n_hid_n_mounted(uint8_t dev_addr, uint8_t instance); +bool tuh_n_hid_mounted(uint8_t dev_addr, uint8_t instance); // Get interface supported protocol (bInterfaceProtocol) check out hid_interface_protocol_enum_t for possible values -uint8_t tuh_n_hid_n_interface_protocol(uint8_t dev_addr, uint8_t instance); +uint8_t tuh_n_hid_interface_protocol(uint8_t dev_addr, uint8_t instance); // Get current active protocol: HID_PROTOCOL_BOOT (0) or HID_PROTOCOL_REPORT (1) // Note: as HID spec, device will be initialized in Report mode -bool tuh_n_hid_n_get_protocol(uint8_t dev_addr, uint8_t instance); +bool tuh_n_hid_get_protocol(uint8_t dev_addr, uint8_t instance); // Set protocol to HID_PROTOCOL_BOOT (0) or HID_PROTOCOL_REPORT (1) -// This function is only supported by Boot interface tuh_n_hid_n_boot_interface() -bool tuh_n_hid_n_set_protocol(uint8_t dev_addr, uint8_t instance, uint8_t protocol); +// This function is only supported by Boot interface (tuh_n_hid_interface_protocol() != NONE) +bool tuh_n_hid_set_protocol(uint8_t dev_addr, uint8_t instance, uint8_t protocol); // Parse report descriptor into array of report_info struct and return number of reports. // If return 0, this is a ingle report, otherwise it is composite report with 1st byte as ID. @@ -116,6 +116,9 @@ void tuh_hid_get_report_cb(uint8_t dev_addr, uint8_t instance, uint8_t const* re // Invoked when Sent Report to device via either regular or control endpoint TU_ATTR_WEAK void tuh_hid_set_report_complete_cb(uint8_t dev_addr, uint8_t instance, uint8_t xferred_bytes); +// Invoked when Set Protocol request is complete +TU_ATTR_WEAK void tuh_hid_set_protocol_complete_cb(uint8_t dev_addr, uint8_t instance, uint8_t protocol); + //--------------------------------------------------------------------+ // Application API (Single device) //--------------------------------------------------------------------+