Skip to content

Commit b6ebf3d

Browse files
authored
Merge pull request adafruit#11282 from mikeysklar/fix-1136-boot-hid
usb_hid: honor a boot protocol request that arrives after startup
2 parents 10d9122 + 3b30ce4 commit b6ebf3d

3 files changed

Lines changed: 21 additions & 0 deletions

File tree

‎shared-bindings/usb_hid/Device.c‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,10 @@ static mp_obj_t usb_hid_device_make_new(const mp_obj_type_t *type, size_t n_args
156156
//| The ``report`` itself will be discarded, to prevent unwanted extraneous characters,
157157
//| mouse clicks, etc.
158158
//|
159+
//| If the host has put the interface in boot protocol, the boot device sends its report
160+
//| without a report ID, and `send_report()` on any other device discards the report,
161+
//| because the host reads only the boot device.
162+
//|
159163
//| Note: Host operating systems allow enabling and disabling specific devices
160164
//| and kinds of devices to do wakeup.
161165
//| The defaults are different for different operating systems.

‎shared-bindings/usb_hid/__init__.c‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,10 @@
2525
//| the `devices` tuple is **replaced** when ``code.py`` starts with a single-element tuple
2626
//| containing a `Device` that describes the boot device chosen (keyboard or mouse).
2727
//| The request for a boot device overrides any other HID devices.
28+
//|
29+
//| If the host requests a boot device after ``code.py`` has started, `devices` is not replaced.
30+
//| The boot device then sends reports in the boot format, with no report ID, and
31+
//| `Device.send_report()` on any other device does nothing, because the host ignores it.
2832
//| """
2933
//|
3034
//|

‎shared-module/usb_hid/Device.c‎

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,19 @@ void common_hal_usb_hid_device_send_report(usb_hid_device_obj_t *self, uint8_t *
130130
mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("USB busy"));
131131
}
132132

133+
const uint8_t boot_device = usb_hid_boot_device();
134+
if (boot_device != 0 && tud_hid_get_protocol() == HID_PROTOCOL_BOOT) {
135+
// In boot protocol the host reads the fixed boot report, which carries no report ID,
136+
// and ignores every device other than the boot device.
137+
if (self->usage_page == HID_USAGE_PAGE_DESKTOP &&
138+
((boot_device == 1 && self->usage == HID_USAGE_DESKTOP_KEYBOARD) ||
139+
(boot_device == 2 && self->usage == HID_USAGE_DESKTOP_MOUSE))) {
140+
report_id = 0;
141+
} else {
142+
return;
143+
}
144+
}
145+
133146
if (!tud_hid_report(report_id, report, len)) {
134147
mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("USB error"));
135148
}

0 commit comments

Comments
 (0)