diff --git a/shared-bindings/microcontroller/Processor.c b/shared-bindings/microcontroller/Processor.c index e1d569efca..c1bb626db8 100644 --- a/shared-bindings/microcontroller/Processor.c +++ b/shared-bindings/microcontroller/Processor.c @@ -97,8 +97,9 @@ const mp_obj_property_t mcu_processor_reset_reason_obj = { //| //| Is `None` if the temperature is not available.""" //| +extern volatile float indicator; STATIC mp_obj_t mcu_processor_get_temperature(mp_obj_t self) { - float temperature = common_hal_mcu_processor_get_temperature(); + float temperature = indicator; // common_hal_mcu_processor_get_temperature(); return isnan(temperature) ? mp_const_none : mp_obj_new_float(temperature); } diff --git a/shared-bindings/usb_hid/Device.c b/shared-bindings/usb_hid/Device.c index 44f3216b01..32305afd06 100644 --- a/shared-bindings/usb_hid/Device.c +++ b/shared-bindings/usb_hid/Device.c @@ -136,7 +136,7 @@ STATIC mp_obj_t usb_hid_device_make_new(const mp_obj_type_t *type, size_t n_args // It's not the actual argument that's out of range, but its elements. // But the error message is close enough. MP_OBJ_SMALL_INT_VALUE(mp_obj_subscr(report_ids, i_obj, MP_OBJ_SENTINEL)), - 1, 255, MP_QSTR_report_ids); + 0, 255, MP_QSTR_report_ids); in_report_lengths_array[i] = (uint8_t)mp_arg_validate_int_range( MP_OBJ_SMALL_INT_VALUE(mp_obj_subscr(in_report_lengths, i_obj, MP_OBJ_SENTINEL)), diff --git a/shared-bindings/usb_hid/__init__.c b/shared-bindings/usb_hid/__init__.c index 0c60015ee7..5c903dda5d 100644 --- a/shared-bindings/usb_hid/__init__.c +++ b/shared-bindings/usb_hid/__init__.c @@ -40,6 +40,11 @@ //| """Tuple of all active HID device interfaces. //| The default set of devices is ``Device.KEYBOARD, Device.MOUSE, Device.CONSUMER_CONTROL``, //| On boards where `usb_hid` is disabled by default, `devices` is an empty tuple. +//| +//| If a boot device is enabled by `usb_hid.enable)`, *and* the host has requested a boot device, +//| the `devices` tuple is *replaced* when ``code.py`` starts with a single-element tuple +//| containing a `Device` that describes the boot device chosen (keyboard or mouse). +//| The request for a boot device overrides any other HID devices. //| """ //| @@ -84,12 +89,12 @@ MP_DEFINE_CONST_FUN_OBJ_0(usb_hid_disable_obj, usb_hid_disable); //| Boot devices implement a fixed, predefined report descriptor, defined in //| https://www.usb.org/sites/default/files/hid1_12.pdf, Appendix B. A USB host //| can request to use the boot device if the USB device says it is available. -//| Usually only a BIOS or other kind of boot-time, limited-functionality +//| Usually only a BIOS or other kind of limited-functionality //| host needs boot keyboard support. //| //| For example, to make a boot keyboard available, you can use this code:: //| -//| usb_hid.enable((Device.KEYBOARD), boot_device=1) +//| usb_hid.enable((Device.KEYBOARD), boot_device=1) # 1 for a keyboard //| //| If the host requests the boot keyboard, the report descriptor provided by `Device.KEYBOARD` //| will be ignored, and the predefined report descriptor will be used. @@ -104,11 +109,11 @@ STATIC mp_obj_t usb_hid_enable(size_t n_args, const mp_obj_t *pos_args, mp_map_t enum { ARG_devices, ARG_boot_device }; static const mp_arg_t allowed_args[] = { { MP_QSTR_devices, MP_ARG_REQUIRED | MP_ARG_OBJ }, - { MP_QSTR_boot_device, MP_ARG_OBJ, {.u_int = 0} }, + { MP_QSTR_boot_device, MP_ARG_INT, {.u_int = 0} }, }; mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; - mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); mp_obj_t devices = args[ARG_devices].u_obj; const mp_int_t len = mp_obj_get_int(mp_obj_len(devices)); @@ -128,18 +133,16 @@ STATIC mp_obj_t usb_hid_enable(size_t n_args, const mp_obj_t *pos_args, mp_map_t return mp_const_none; } -MP_DEFINE_CONST_FUN_OBJ_KW(usb_hid_enable_obj, 2, usb_hid_enable); +MP_DEFINE_CONST_FUN_OBJ_KW(usb_hid_enable_obj, 1, usb_hid_enable); //| def get_boot_device() -> int: //| """ //| :return: the boot device requested by the host, if any. //| Returns 0 if the host did not request a boot device, or if `usb_hid.enable()` //| was called with `boot_device=0`, the default, which disables boot device support. -//| If the host did request aboot device, +//| If the host did request a boot device, //| returns the value of ``boot_device`` set in `usb_hid.enable()`: //| ``1`` for a boot keyboard, or ``2`` for boot mouse. -//| Your device driver should check and act on this value if the keyboard or mouse -//| device you specified provides reports that differ from the standard boot keyboard or mouse. //| However, the standard devices provided by CircuitPython, `Device.KEYBOARD` and `Device.MOUSE`, //| describe reports that match the boot device reports, so you don't need to check this //| if you are using those devices. diff --git a/shared-module/usb_hid/__init__.c b/shared-module/usb_hid/__init__.c index fb5c9dd107..21bf6e72a1 100644 --- a/shared-module/usb_hid/__init__.c +++ b/shared-module/usb_hid/__init__.c @@ -31,10 +31,12 @@ #include "py/gc.h" #include "py/runtime.h" #include "shared-bindings/usb_hid/__init__.h" -#include "shared-module/usb_hid/Device.h" +#include "shared-bindings/usb_hid/Device.h" #include "supervisor/memory.h" #include "supervisor/usb.h" +volatile float indicator = 0.1f; + static const uint8_t usb_hid_descriptor_template[] = { 0x09, // 0 bLength 0x04, // 1 bDescriptorType (Interface) @@ -86,6 +88,7 @@ static mp_int_t num_hid_devices; // Which boot device is available 0: no boot devices, 1: boot keyboard, 2: boot mouse. // This value is set by usb_hid.enable(), and used to build the HID interface descriptor. // The value is remembered here from boot.py to code.py. + static uint8_t hid_boot_device; // Whether a boot device was requested by a SET_PROTOCOL request from the host. @@ -106,6 +109,38 @@ static mp_obj_tuple_t default_hid_devices_tuple = { }, }; +// These describe the standard descriptors used for boot keyboard and mouse, which don't use report IDs. +// When the host requests a boot device, replace whatever HID devices were enabled with a tuple +// containing just one of these, since the host is uninterested in other devices. +// The driver code will then use the proper report length and send_report() will not send a report ID. +static const usb_hid_device_obj_t boot_keyboard_obj = { + .base = { + .type = &usb_hid_device_type, + }, + .report_descriptor = NULL, + .report_descriptor_length = 0, + .usage_page = 0x01, + .usage = 0x06, + .num_report_ids = 1, + .report_ids = { 0, }, + .in_report_lengths = { 8, }, + .out_report_lengths = { 1, }, +}; + +static const usb_hid_device_obj_t boot_mouse_obj = { + .base = { + .type = &usb_hid_device_type, + }, + .report_descriptor = NULL, + .report_descriptor_length = 0, + .usage_page = 0x01, + .usage = 0x02, + .num_report_ids = 1, + .report_ids = { 0, }, + .in_report_lengths = { 4, }, + .out_report_lengths = { 0, }, +}; + bool usb_hid_enabled(void) { return num_hid_devices > 0; } @@ -121,6 +156,7 @@ uint8_t common_hal_usb_hid_get_boot_device(void) { void usb_hid_set_defaults(void) { hid_boot_device = 0; + hid_boot_device_requested = false; common_hal_usb_hid_enable( CIRCUITPY_USB_HID_ENABLED_DEFAULT ? &default_hid_devices_tuple : mp_const_empty_tuple, 0); } @@ -209,7 +245,17 @@ bool common_hal_usb_hid_enable(const mp_obj_t devices, uint8_t boot_device) { // Called when HID devices are ready to be used, when code.py or the REPL starts running. void usb_hid_setup_devices(void) { - hid_boot_device_requested = false; + + // If the host requested a boot device, replace the current list of devices + // with a single-element tuple containing the proper boot device. + if (hid_boot_device_requested) { + memcpy(&hid_devices[0], + // Will be 1 (keyboard) or 2 (mouse). + hid_boot_device == 1 ? &boot_keyboard_obj : &boot_mouse_obj, + sizeof(usb_hid_device_obj_t)); + num_hid_devices = 1; + } + usb_hid_set_devices_from_hid_devices(); // Create report buffers on the heap.