From df65c35b31581881b2bf49d9e16608d46f98fe4b Mon Sep 17 00:00:00 2001 From: hathach Date: Sat, 22 May 2021 21:48:42 +0700 Subject: [PATCH] implement hid host set report with control transfer rename mount, umount callback --- examples/host/cdc_msc_hid/src/hid_app.c | 4 +- examples/host/cdc_msc_hid/src/msc_app.c | 2 +- src/class/hid/hid_host.c | 54 ++++++++++++++++++++++--- src/class/hid/hid_host.h | 16 ++++---- src/class/msc/msc_host.c | 2 +- src/class/msc/msc_host.h | 2 +- 6 files changed, 63 insertions(+), 17 deletions(-) diff --git a/examples/host/cdc_msc_hid/src/hid_app.c b/examples/host/cdc_msc_hid/src/hid_app.c index 71904245a..79f10251f 100644 --- a/examples/host/cdc_msc_hid/src/hid_app.c +++ b/examples/host/cdc_msc_hid/src/hid_app.c @@ -53,7 +53,7 @@ void hid_app_task(void) // TinyUSB Callbacks //--------------------------------------------------------------------+ -void tuh_hid_mounted_cb(uint8_t dev_addr, uint8_t instance, uint8_t const* desc_report, uint16_t desc_len) +void tuh_hid_mount_cb(uint8_t dev_addr, uint8_t instance, uint8_t const* desc_report, uint16_t desc_len) { printf("HID device address = %d, instance = %d is mounted\r\n", dev_addr, instance); @@ -66,7 +66,7 @@ void tuh_hid_mounted_cb(uint8_t dev_addr, uint8_t instance, uint8_t const* desc_ printf("HID has %u reports and interface protocol = %s\r\n", _report_count[instance], protocol_str[interface_protocol]); } -void tuh_hid_unmounted_cb(uint8_t dev_addr, uint8_t instance) +void tuh_hid_umount_cb(uint8_t dev_addr, uint8_t instance) { printf("HID device address = %d, instance = %d is unmounted\r\n", dev_addr, instance); } diff --git a/examples/host/cdc_msc_hid/src/msc_app.c b/examples/host/cdc_msc_hid/src/msc_app.c index 3a8ef3a07..3657a3d35 100644 --- a/examples/host/cdc_msc_hid/src/msc_app.c +++ b/examples/host/cdc_msc_hid/src/msc_app.c @@ -80,7 +80,7 @@ void tuh_msc_mount_cb(uint8_t dev_addr) // } } -void tuh_msc_unmount_cb(uint8_t dev_addr) +void tuh_msc_umount_cb(uint8_t dev_addr) { (void) dev_addr; printf("A MassStorage device is unmounted\r\n"); diff --git a/src/class/hid/hid_host.c b/src/class/hid/hid_host.c index 15533cf3a..f15f0b72a 100644 --- a/src/class/hid/hid_host.c +++ b/src/class/hid/hid_host.c @@ -73,6 +73,8 @@ typedef struct static hidh_device_t _hidh_dev[CFG_TUSB_HOST_DEVICE_MAX-1]; //------------- Internal prototypes -------------// + +// Get HID device & interface 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); @@ -131,7 +133,7 @@ bool tuh_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); + TU_LOG2("HID Set Protocol = %d\r\n", protocol); tusb_control_request_t const request = { @@ -151,6 +153,48 @@ bool tuh_hid_set_protocol(uint8_t dev_addr, uint8_t instance, uint8_t protocol) return true; } +static bool set_report_complete(uint8_t dev_addr, tusb_control_request_t const * request, xfer_result_t result) +{ + TU_LOG2("HID Set Report complete\r\n"); + + if (tuh_hid_set_report_complete_cb) + { + uint8_t const itf_num = (uint8_t) request->wIndex; + uint8_t const instance = get_instance_id_by_itfnum(dev_addr, itf_num); + + uint8_t const report_type = tu_u16_high(request->wValue); + uint8_t const report_id = tu_u16_low(request->wValue); + + tuh_hid_set_report_complete_cb(dev_addr, instance, report_id, report_type, (result == XFER_RESULT_SUCCESS) ? request->wLength : 0); + } + + return true; +} + + +bool tuh_hid_set_report(uint8_t dev_addr, uint8_t instance, uint8_t report_id, uint8_t report_type, void* report, uint16_t len) +{ + hidh_interface_t* hid_itf = get_instance(dev_addr, instance); + TU_LOG2("HID Set Report: id = %u, type = %u, len = %u\r\n", report_id, report_type, len); + + 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_REPORT, + .wValue = tu_u16(report_type, report_id), + .wIndex = hid_itf->itf_num, + .wLength = len + }; + + TU_ASSERT( tuh_control_xfer(dev_addr, &request, NULL, set_report_complete) ); + return true; +} + //bool tuh_n_hid_n_ready(uint8_t dev_addr, uint8_t instance) //{ // TU_VERIFY(tuh_n_hid_n_mounted(dev_addr, instance)); @@ -185,7 +229,7 @@ bool hidh_xfer_cb(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t result, uint3 hidh_get_report(dev_addr, hid_itf); }else { - if (tuh_hid_set_report_complete_cb) tuh_hid_set_report_complete_cb(dev_addr, instance, xferred_bytes); +// if (tuh_hid_set_report_complete_cb) tuh_hid_set_report_complete_cb(dev_addr, instance, xferred_bytes); } return true; @@ -194,9 +238,9 @@ bool hidh_xfer_cb(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t result, uint3 void hidh_close(uint8_t dev_addr) { hidh_device_t* hid_dev = get_dev(dev_addr); - if (tuh_hid_unmounted_cb) + if (tuh_hid_umount_cb) { - for ( uint8_t inst = 0; inst < hid_dev->inst_count; inst++) tuh_hid_unmounted_cb(dev_addr, inst); + for ( uint8_t inst = 0; inst < hid_dev->inst_count; inst++) tuh_hid_umount_cb(dev_addr, inst); } tu_memclr(hid_dev, sizeof(hidh_device_t)); @@ -322,7 +366,7 @@ bool config_get_report_desc_complete(uint8_t dev_addr, tusb_control_request_t co uint16_t const desc_len = request->wLength; // enumeration is complete - tuh_hid_mounted_cb(dev_addr, instance, desc_report, desc_len); + tuh_hid_mount_cb(dev_addr, instance, desc_report, desc_len); // queue transfer for IN endpoint hidh_get_report(dev_addr, hid_itf); diff --git a/src/class/hid/hid_host.h b/src/class/hid/hid_host.h index 3ac1f7c69..f962f5b0a 100644 --- a/src/class/hid/hid_host.h +++ b/src/class/hid/hid_host.h @@ -79,6 +79,10 @@ bool tuh_hid_get_protocol(uint8_t dev_addr, uint8_t instance); // This function is only supported by Boot interface (tuh_n_hid_interface_protocol() != NONE) bool tuh_hid_set_protocol(uint8_t dev_addr, uint8_t instance, uint8_t protocol); +// Set Report using control endpoint +// report_type is either Intput, Output or Feature, (value from hid_report_type_t) +bool tuh_hid_set_report(uint8_t dev_addr, uint8_t instance, uint8_t report_id, uint8_t report_type, void* report, uint16_t len); + // Parse report descriptor into array of report_info struct and return number of reports. // For complicated report, application should write its own parser. uint8_t tuh_hid_parse_report_descriptor(tuh_hid_report_info_t* reports_info_arr, uint8_t arr_count, uint8_t const* desc_report, uint16_t desc_len) TU_ATTR_UNUSED; @@ -86,9 +90,6 @@ uint8_t tuh_hid_parse_report_descriptor(tuh_hid_report_info_t* reports_info_arr, // Check if the interface is ready to use //bool tuh_n_hid_n_ready(uint8_t dev_addr, uint8_t instance); -// Set Report using control endpoint -//bool tuh_n_hid_n_set_report_control(uint8_t dev_addr, uint8_t instance, void* report, uint16_t len); - //--------------------------------------------------------------------+ // Callbacks (Weak is optional) //--------------------------------------------------------------------+ @@ -96,16 +97,17 @@ uint8_t tuh_hid_parse_report_descriptor(tuh_hid_report_info_t* reports_info_arr, // Invoked when device with hid interface is mounted // Report descriptor is also available for use. tuh_hid_parse_report_descriptor() // can be used to parse common/simple enough descriptor. -void tuh_hid_mounted_cb(uint8_t dev_addr, uint8_t instance, uint8_t const* report_desc, uint16_t desc_len); +void tuh_hid_mount_cb(uint8_t dev_addr, uint8_t instance, uint8_t const* report_desc, uint16_t desc_len); // Invoked when device with hid interface is un-mounted -TU_ATTR_WEAK void tuh_hid_unmounted_cb(uint8_t dev_addr, uint8_t instance); +TU_ATTR_WEAK void tuh_hid_umount_cb(uint8_t dev_addr, uint8_t instance); // Invoked when received Report from device via either regular or control endpoint void tuh_hid_get_report_cb(uint8_t dev_addr, uint8_t instance, uint8_t const* report, uint16_t len); -// 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 Sent Report to device via either control endpoint +// len = 0 indicate there is error in the transfer e.g stalled response +TU_ATTR_WEAK void tuh_hid_set_report_complete_cb(uint8_t dev_addr, uint8_t instance, uint8_t report_id, uint8_t report_type, uint16_t len); // 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); diff --git a/src/class/msc/msc_host.c b/src/class/msc/msc_host.c index 4869c8c03..08b4db9e1 100644 --- a/src/class/msc/msc_host.c +++ b/src/class/msc/msc_host.c @@ -300,7 +300,7 @@ void msch_close(uint8_t dev_addr) tu_memclr(p_msc, sizeof(msch_interface_t)); // invoke Application Callback - if (tuh_msc_unmount_cb) tuh_msc_unmount_cb(dev_addr); + if (tuh_msc_umount_cb) tuh_msc_umount_cb(dev_addr); } bool msch_xfer_cb(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t event, uint32_t xferred_bytes) diff --git a/src/class/msc/msc_host.h b/src/class/msc/msc_host.h index 7ebc9b5a8..b5ffcd401 100644 --- a/src/class/msc/msc_host.h +++ b/src/class/msc/msc_host.h @@ -109,7 +109,7 @@ bool tuh_msc_read_capacity(uint8_t dev_addr, uint8_t lun, scsi_read_capacity10_r TU_ATTR_WEAK void tuh_msc_mount_cb(uint8_t dev_addr); // Invoked when a device with MassStorage interface is unmounted -TU_ATTR_WEAK void tuh_msc_unmount_cb(uint8_t dev_addr); +TU_ATTR_WEAK void tuh_msc_umount_cb(uint8_t dev_addr); //--------------------------------------------------------------------+ // Internal Class Driver API