From 8bab7b664c9627dfbaa32b3bf64893d7487f1cd0 Mon Sep 17 00:00:00 2001 From: Yihui Xiong Date: Wed, 19 Aug 2020 20:18:17 +0800 Subject: [PATCH 1/4] support to get HID OUT report --- shared-bindings/usb_hid/Device.c | 20 ++++++++++++++++++++ shared-module/usb_hid/Device.c | 17 ++++++++++------- shared-module/usb_hid/Device.h | 2 ++ tools/gen_usb_descriptor.py | 16 +++++++++++++--- tools/hid_report_descriptors.py | 18 +++++++++--------- 5 files changed, 54 insertions(+), 19 deletions(-) diff --git a/shared-bindings/usb_hid/Device.c b/shared-bindings/usb_hid/Device.c index 83c0df4ae4..2fbc5fe51b 100644 --- a/shared-bindings/usb_hid/Device.c +++ b/shared-bindings/usb_hid/Device.c @@ -58,6 +58,25 @@ STATIC mp_obj_t usb_hid_device_send_report(mp_obj_t self_in, mp_obj_t buffer) { } MP_DEFINE_CONST_FUN_OBJ_2(usb_hid_device_send_report_obj, usb_hid_device_send_report); +//|report: bytes +//| """The HID OUT report as a `bytes`. (read-only)""" +//| +STATIC mp_obj_t usb_hid_device_obj_get_report(mp_obj_t self_in) { + usb_hid_device_obj_t *self = MP_OBJ_TO_PTR(self_in); + if (self->out_report_buffer == 0) { + return mp_const_none; + } + return mp_obj_new_bytes(self->out_report_buffer, self->out_report_length); +} +MP_DEFINE_CONST_FUN_OBJ_1(usb_hid_device_get_report_obj, usb_hid_device_obj_get_report); + +const mp_obj_property_t usb_hid_device_report_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&usb_hid_device_get_report_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + //| usage_page: int //| """The usage page of the device as an `int`. Can be thought of a category. (read-only)""" //| @@ -96,6 +115,7 @@ const mp_obj_property_t usb_hid_device_usage_obj = { STATIC const mp_rom_map_elem_t usb_hid_device_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_send_report), MP_ROM_PTR(&usb_hid_device_send_report_obj) }, + { MP_ROM_QSTR(MP_QSTR_report), MP_ROM_PTR(&usb_hid_device_report_obj) }, { MP_ROM_QSTR(MP_QSTR_usage_page), MP_ROM_PTR(&usb_hid_device_usage_page_obj)}, { MP_ROM_QSTR(MP_QSTR_usage), MP_ROM_PTR(&usb_hid_device_usage_obj)}, }; diff --git a/shared-module/usb_hid/Device.c b/shared-module/usb_hid/Device.c index 8e9df6f040..943c9bfed7 100644 --- a/shared-module/usb_hid/Device.c +++ b/shared-module/usb_hid/Device.c @@ -84,14 +84,17 @@ uint16_t tud_hid_get_report_cb(uint8_t report_id, hid_report_type_t report_type, // Callbacks invoked when receive Set_Report request through control endpoint void tud_hid_set_report_cb(uint8_t report_id, hid_report_type_t report_type, uint8_t const* buffer, uint16_t bufsize) { + if (report_type == HID_REPORT_TYPE_INVALID) { + report_id = buffer[0]; + buffer++; + bufsize--; + } else if (report_type != HID_REPORT_TYPE_OUTPUT) { + return; + } + usb_hid_device_obj_t* hid_device = get_hid_device(report_id); - if ( report_type == HID_REPORT_TYPE_OUTPUT ) { - // Check if it is Keyboard device - if (hid_device->usage_page == HID_USAGE_PAGE_DESKTOP && - hid_device->usage == HID_USAGE_DESKTOP_KEYBOARD) { - // This is LED indicator (CapsLock, NumLock) - // TODO Light up some LED here - } + if (hid_device && hid_device->out_report_length >= bufsize) { + memcpy(hid_device->out_report_buffer, buffer, bufsize); } } diff --git a/shared-module/usb_hid/Device.h b/shared-module/usb_hid/Device.h index 10f2ee897d..93c3518b43 100644 --- a/shared-module/usb_hid/Device.h +++ b/shared-module/usb_hid/Device.h @@ -43,6 +43,8 @@ typedef struct { uint8_t report_length; uint8_t usage_page; uint8_t usage; + uint8_t* out_report_buffer; + uint8_t out_report_length; } usb_hid_device_obj_t; diff --git a/tools/gen_usb_descriptor.py b/tools/gen_usb_descriptor.py index fb91fd3345..4ad6cfb565 100644 --- a/tools/gen_usb_descriptor.py +++ b/tools/gen_usb_descriptor.py @@ -535,7 +535,7 @@ c_file.write(""" }; """) -c_file.write("\n"); +c_file.write("\n") hid_descriptor_length = len(bytes(combined_hid_report_descriptor)) @@ -593,12 +593,18 @@ for name in args.hid_devices: static uint8_t {name}_report_buffer[{report_length}]; """.format(name=name.lower(), report_length=hid_report_descriptors.HID_DEVICE_DATA[name].report_length)) + if hid_report_descriptors.HID_DEVICE_DATA[name].out_report_length > 0: + c_file.write("""\ +static uint8_t {name}_out_report_buffer[{report_length}]; +""".format(name=name.lower(), report_length=hid_report_descriptors.HID_DEVICE_DATA[name].out_report_length)) + # Write out table of device objects. c_file.write(""" usb_hid_device_obj_t usb_hid_devices[] = { -"""); +""") for name in args.hid_devices: device_data = hid_report_descriptors.HID_DEVICE_DATA[name] + out_report_buffer = '{}_out_report_buffer'.format(name.lower()) if device_data.out_report_length > 0 else 'NULL' c_file.write("""\ {{ .base = {{ .type = &usb_hid_device_type }}, @@ -607,11 +613,15 @@ for name in args.hid_devices: .report_length = {report_length}, .usage_page = {usage_page:#04x}, .usage = {usage:#04x}, + .out_report_buffer = {out_report_buffer}, + .out_report_length = {out_report_length}, }}, """.format(name=name.lower(), report_id=report_ids[name], report_length=device_data.report_length, usage_page=device_data.usage_page, - usage=device_data.usage)) + usage=device_data.usage, + out_report_buffer=out_report_buffer, + out_report_length=device_data.out_report_length)) c_file.write("""\ }; """) diff --git a/tools/hid_report_descriptors.py b/tools/hid_report_descriptors.py index e13e0dbdd1..aaa5b18b1f 100644 --- a/tools/hid_report_descriptors.py +++ b/tools/hid_report_descriptors.py @@ -18,16 +18,16 @@ from adafruit_usb_descriptor import hid # Information about each kind of device # report_length does not include report ID in first byte, if present when sent. -DeviceData = namedtuple('DeviceData', ('report_length', 'usage_page', 'usage')) +DeviceData = namedtuple('DeviceData', ('report_length', 'out_report_length', 'usage_page', 'usage')) HID_DEVICE_DATA = { - "KEYBOARD" : DeviceData(report_length=8, usage_page=0x01, usage=0x06), # Generic Desktop, Keyboard - "MOUSE" : DeviceData(report_length=4, usage_page=0x01, usage=0x02), # Generic Desktop, Mouse - "CONSUMER" : DeviceData(report_length=2, usage_page=0x0C, usage=0x01), # Consumer, Consumer Control - "SYS_CONTROL" : DeviceData(report_length=1, usage_page=0x01, usage=0x80), # Generic Desktop, Sys Control - "GAMEPAD" : DeviceData(report_length=6, usage_page=0x01, usage=0x05), # Generic Desktop, Game Pad - "DIGITIZER" : DeviceData(report_length=5, usage_page=0x0D, usage=0x02), # Digitizers, Pen - "XAC_COMPATIBLE_GAMEPAD" : DeviceData(report_length=3, usage_page=0x01, usage=0x05), # Generic Desktop, Game Pad - "RAW" : DeviceData(report_length=64, usage_page=0xFFAF, usage=0xAF), # Vendor 0xFFAF "Adafruit", 0xAF + "KEYBOARD" : DeviceData(report_length=8, out_report_length=1, usage_page=0x01, usage=0x06), # Generic Desktop, Keyboard + "MOUSE" : DeviceData(report_length=4, out_report_length=0, usage_page=0x01, usage=0x02), # Generic Desktop, Mouse + "CONSUMER" : DeviceData(report_length=2, out_report_length=0, usage_page=0x0C, usage=0x01), # Consumer, Consumer Control + "SYS_CONTROL" : DeviceData(report_length=1, out_report_length=0, usage_page=0x01, usage=0x80), # Generic Desktop, Sys Control + "GAMEPAD" : DeviceData(report_length=6, out_report_length=0, usage_page=0x01, usage=0x05), # Generic Desktop, Game Pad + "DIGITIZER" : DeviceData(report_length=5, out_report_length=0, usage_page=0x0D, usage=0x02), # Digitizers, Pen + "XAC_COMPATIBLE_GAMEPAD" : DeviceData(report_length=3, out_report_length=0, usage_page=0x01, usage=0x05), # Generic Desktop, Game Pad + "RAW" : DeviceData(report_length=64, out_report_length=0, usage_page=0xFFAF, usage=0xAF), # Vendor 0xFFAF "Adafruit", 0xAF } def keyboard_hid_descriptor(report_id): From 9aca580195b8381d0db6663dd0dbe22f465ce170 Mon Sep 17 00:00:00 2001 From: Yihui Xiong Date: Wed, 19 Aug 2020 21:33:51 +0800 Subject: [PATCH 2/4] fix --- shared-bindings/usb_hid/Device.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shared-bindings/usb_hid/Device.c b/shared-bindings/usb_hid/Device.c index 2fbc5fe51b..a6c268c74d 100644 --- a/shared-bindings/usb_hid/Device.c +++ b/shared-bindings/usb_hid/Device.c @@ -58,7 +58,7 @@ STATIC mp_obj_t usb_hid_device_send_report(mp_obj_t self_in, mp_obj_t buffer) { } MP_DEFINE_CONST_FUN_OBJ_2(usb_hid_device_send_report_obj, usb_hid_device_send_report); -//|report: bytes +//| report: bytes //| """The HID OUT report as a `bytes`. (read-only)""" //| STATIC mp_obj_t usb_hid_device_obj_get_report(mp_obj_t self_in) { From 40f3cd3615ca7be009ba2deb37209fa4d3993bf9 Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Thu, 10 Sep 2020 13:26:51 -0400 Subject: [PATCH 3/4] Change `.report` to `.last_received_report` --- shared-bindings/usb_hid/Device.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/shared-bindings/usb_hid/Device.c b/shared-bindings/usb_hid/Device.c index a6c268c74d..8f28bc422d 100644 --- a/shared-bindings/usb_hid/Device.c +++ b/shared-bindings/usb_hid/Device.c @@ -58,21 +58,21 @@ STATIC mp_obj_t usb_hid_device_send_report(mp_obj_t self_in, mp_obj_t buffer) { } MP_DEFINE_CONST_FUN_OBJ_2(usb_hid_device_send_report_obj, usb_hid_device_send_report); -//| report: bytes -//| """The HID OUT report as a `bytes`. (read-only)""" +//| last_received_report: bytes +//| """The HID OUT report as a `bytes`. (read-only). `None` if nothing received.""" //| -STATIC mp_obj_t usb_hid_device_obj_get_report(mp_obj_t self_in) { +STATIC mp_obj_t usb_hid_device_obj_get_last_received_report(mp_obj_t self_in) { usb_hid_device_obj_t *self = MP_OBJ_TO_PTR(self_in); if (self->out_report_buffer == 0) { return mp_const_none; } return mp_obj_new_bytes(self->out_report_buffer, self->out_report_length); } -MP_DEFINE_CONST_FUN_OBJ_1(usb_hid_device_get_report_obj, usb_hid_device_obj_get_report); +MP_DEFINE_CONST_FUN_OBJ_1(usb_hid_device_get_last_received_report_obj, usb_hid_device_obj_get_last_received_report); -const mp_obj_property_t usb_hid_device_report_obj = { +const mp_obj_property_t usb_hid_device_last_received_report_obj = { .base.type = &mp_type_property, - .proxy = {(mp_obj_t)&usb_hid_device_get_report_obj, + .proxy = {(mp_obj_t)&usb_hid_device_get_last_received_report_obj, (mp_obj_t)&mp_const_none_obj, (mp_obj_t)&mp_const_none_obj}, }; @@ -114,10 +114,10 @@ const mp_obj_property_t usb_hid_device_usage_obj = { }; STATIC const mp_rom_map_elem_t usb_hid_device_locals_dict_table[] = { - { MP_ROM_QSTR(MP_QSTR_send_report), MP_ROM_PTR(&usb_hid_device_send_report_obj) }, - { MP_ROM_QSTR(MP_QSTR_report), MP_ROM_PTR(&usb_hid_device_report_obj) }, - { MP_ROM_QSTR(MP_QSTR_usage_page), MP_ROM_PTR(&usb_hid_device_usage_page_obj)}, - { MP_ROM_QSTR(MP_QSTR_usage), MP_ROM_PTR(&usb_hid_device_usage_obj)}, + { MP_ROM_QSTR(MP_QSTR_send_report), MP_ROM_PTR(&usb_hid_device_send_report_obj) }, + { MP_ROM_QSTR(MP_QSTR_last_received_report), MP_ROM_PTR(&usb_hid_device_report_obj) }, + { MP_ROM_QSTR(MP_QSTR_usage_page), MP_ROM_PTR(&usb_hid_device_usage_page_obj)}, + { MP_ROM_QSTR(MP_QSTR_usage), MP_ROM_PTR(&usb_hid_device_usage_obj)}, }; STATIC MP_DEFINE_CONST_DICT(usb_hid_device_locals_dict, usb_hid_device_locals_dict_table); From f0bb9635bf311013e7b1ff69d1a0542575cf9d0a Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Thu, 10 Sep 2020 14:21:36 -0400 Subject: [PATCH 4/4] MIssed one change for .last_received_report --- shared-bindings/usb_hid/Device.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shared-bindings/usb_hid/Device.c b/shared-bindings/usb_hid/Device.c index 8f28bc422d..c7c05a9749 100644 --- a/shared-bindings/usb_hid/Device.c +++ b/shared-bindings/usb_hid/Device.c @@ -115,7 +115,7 @@ const mp_obj_property_t usb_hid_device_usage_obj = { STATIC const mp_rom_map_elem_t usb_hid_device_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_send_report), MP_ROM_PTR(&usb_hid_device_send_report_obj) }, - { MP_ROM_QSTR(MP_QSTR_last_received_report), MP_ROM_PTR(&usb_hid_device_report_obj) }, + { MP_ROM_QSTR(MP_QSTR_last_received_report), MP_ROM_PTR(&usb_hid_device_last_received_report_obj) }, { MP_ROM_QSTR(MP_QSTR_usage_page), MP_ROM_PTR(&usb_hid_device_usage_page_obj)}, { MP_ROM_QSTR(MP_QSTR_usage), MP_ROM_PTR(&usb_hid_device_usage_obj)}, };