diff --git a/main.c b/main.c index 8c981aee18..0ad0506082 100644 --- a/main.c +++ b/main.c @@ -286,12 +286,12 @@ int __attribute__((used)) main(void) { #endif // Reset to remove any state that boot.py setup. It should only be used to - // change internal state thats not in the heap. + // change internal state that's not in the heap. reset_port(); reset_mp(); } - // Start serial after giving boot.py a chance to tweak behavior. + // Start serial and HID after giving boot.py a chance to tweak behavior. serial_init(); // Boot script is finished, so now go into REPL/main mode. diff --git a/ports/atmel-samd/Makefile b/ports/atmel-samd/Makefile index 73799e5f28..71acca18ed 100644 --- a/ports/atmel-samd/Makefile +++ b/ports/atmel-samd/Makefile @@ -97,7 +97,7 @@ ifeq ($(DEBUG), 1) # Turn on Python modules useful for debugging (e.g. uheap, ustack). CFLAGS += -ggdb CFLAGS += -flto - ## CFLAGS += -fno-inline + CFLAGS += -fno-inline ifeq ($(CHIP_FAMILY), samd21) CFLAGS += -DENABLE_MICRO_TRACE_BUFFER endif @@ -193,6 +193,8 @@ SRC_ASF := \ hpl/systick/hpl_systick.c \ hpl/usb/hpl_usb.c \ usb/class/cdc/device/cdcdf_acm.c \ + usb/class/hid/device/hiddf_keyboard.c \ + usb/class/hid/device/hiddf_mouse.c \ usb/class/msc/device/mscdf.c \ usb/device/usbdc.c \ usb/usb_protocol.c \ @@ -282,6 +284,8 @@ SRC_COMMON_HAL = \ pulseio/PulseIn.c \ pulseio/PulseOut.c \ pulseio/PWMOut.c \ + usb_hid/__init__.c \ + usb_hid/Device.c # audiobusio/__init__.c \ audiobusio/PDMIn.c \ audioio/__init__.c \ @@ -290,8 +294,6 @@ SRC_COMMON_HAL = \ nvm/ByteArray.c \ touchio/__init__.c \ touchio/TouchIn.c \ - usb_hid/__init__.c \ - usb_hid/Device.c ifeq ($(INTERNAL_LIBM),1) SRC_LIBM = $(addprefix lib/,\ diff --git a/ports/atmel-samd/asf4 b/ports/atmel-samd/asf4 index aaa0f42811..1e2165aa98 160000 --- a/ports/atmel-samd/asf4 +++ b/ports/atmel-samd/asf4 @@ -1 +1 @@ -Subproject commit aaa0f428111fbea7d56ab548053b11c9f12068f1 +Subproject commit 1e2165aa981f3eef39db8c27c05836aa94788e3d diff --git a/ports/atmel-samd/common-hal/usb_hid/Device.c b/ports/atmel-samd/common-hal/usb_hid/Device.c index 443a67f8ed..9568a27ef1 100644 --- a/ports/atmel-samd/common-hal/usb_hid/Device.c +++ b/ports/atmel-samd/common-hal/usb_hid/Device.c @@ -26,60 +26,65 @@ #include -#include "py/nlr.h" -#include "common-hal/usb_hid/__init__.h" +#include "common-hal/usb_hid/Device.h" + +#include "py/runtime.h" #include "shared-bindings/microcontroller/__init__.h" #include "shared-bindings/usb_hid/Device.h" +#include "tools/autogen_usb_descriptor.h" -static void report_sent(udd_ep_status_t status, iram_size_t nb_sent, - udd_ep_id_t ep) { - UNUSED(status); - UNUSED(nb_sent); - for (uint8_t i = 0; i < 2; i++) { - if (ep == usb_hid_devices[i].endpoint) { - usb_hid_devices[i].transaction_ongoing = false; - return; +#include "tick.h" + +#include "usb/class/hid/device/hiddf_mouse.h" +#include "usb/class/hid/device/hiddf_keyboard.h" + +static uint32_t usb_hid_send_report(usb_hid_device_obj_t *self, uint8_t* report, uint8_t len) { + + int32_t status; + + // Don't get stuck if USB fails in some way; timeout after a while. + uint64_t end_ticks = ticks_ms + 2000; + + while (ticks_ms < end_ticks) { + status = usb_d_ep_get_status(self->endpoint, NULL); + if (status == USB_BUSY) { + continue; } - } -} - -bool usb_hid_send_report(usb_hid_device_obj_t *self, uint8_t* report, uint8_t len) { - if (!self->enabled) { - return true; - } - // Wait for the previous transaction to finish. Shouldn't happen. - uint32_t timeout = 0xffff; - - while (self->transaction_ongoing && timeout > 0) { - timeout--; - } - - if (self->transaction_ongoing) { - return false; + if (status == USB_OK) { + break; + } + // Some error. Give up. + return status; } + // Copy the data only when endpoint is ready to send. The previous + // buffer load gets zero'd out when transaction completes, so if + // you copy before it's ready, only zeros will get sent. memcpy(self->report_buffer, report, len); - // Disable interrupts to make sure we save the ongoing state before the - // report_sent interrupt. - common_hal_mcu_disable_interrupts(); - bool ok = udd_ep_run(self->endpoint, false, - self->report_buffer, self->report_length, report_sent); - self->transaction_ongoing = ok; - common_hal_mcu_enable_interrupts(); - return ok; + switch (self->kind) { + case USB_HID_MOUSE: + status = hiddf_mouse_write(self->report_buffer, self->report_length); + break; + + case USB_HID_KEYBOARD: + status = hiddf_keyboard_write(self->report_buffer, self->report_length); + break; + + default: + mp_raise_ValueError("Unknown HID device"); + } + + return status; } void common_hal_usb_hid_device_send_report(usb_hid_device_obj_t *self, uint8_t* report, uint8_t len) { if (len != self->report_length) { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, - "Buffer incorrect size. Should be %d bytes.", self->report_length)); + mp_raise_ValueError_varg("Buffer incorrect size. Should be %d bytes.", self->report_length); } - if (!self->enabled) { - nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, "USB Inactive")); - } - if (!usb_hid_send_report(self, report, len)) { - nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, "USB Busy")); + int32_t status = usb_hid_send_report(self, report, len); + if (status != ERR_NONE) { + mp_raise_msg(&mp_type_OSError, status == USB_BUSY ? "USB Busy" : "USB Error"); } } @@ -90,3 +95,21 @@ uint8_t common_hal_usb_hid_device_get_usage_page(usb_hid_device_obj_t *self) { uint8_t common_hal_usb_hid_device_get_usage(usb_hid_device_obj_t *self) { return self->usage; } + + +void usb_hid_init() { + usb_hid_devices[USB_HID_DEVICE_MOUSE].base.type = &usb_hid_device_type; + usb_hid_devices[USB_HID_DEVICE_MOUSE].endpoint = hid_mouse_endpoint_in; + + usb_hid_devices[USB_HID_DEVICE_KEYBOARD].base.type = &usb_hid_device_type; + usb_hid_devices[USB_HID_DEVICE_KEYBOARD].endpoint = hid_keyboard_endpoint_in; +} + +void usb_hid_reset() { + // We don't actually reset. We just set a report that is empty to prevent + // long keypresses and such. + uint8_t report[8] = {0, 0, 0, 0, 0, 0, 0, 0}; + + usb_hid_send_report(&usb_hid_devices[USB_HID_DEVICE_MOUSE], report, UDI_HID_MOUSE_REPORT_SIZE); + usb_hid_send_report(&usb_hid_devices[USB_HID_DEVICE_KEYBOARD], report, UDI_HID_KBD_REPORT_SIZE); +} diff --git a/ports/atmel-samd/common-hal/usb_hid/Device.h b/ports/atmel-samd/common-hal/usb_hid/Device.h index 1b313f9ceb..d4d016009b 100644 --- a/ports/atmel-samd/common-hal/usb_hid/Device.h +++ b/ports/atmel-samd/common-hal/usb_hid/Device.h @@ -30,8 +30,34 @@ #include #include -#include "common-hal/usb_hid/types.h" +#include "py/obj.h" -bool usb_hid_send_report(usb_hid_device_obj_t *self, uint8_t* report, uint8_t len); +#define UDI_HID_MOUSE_REPORT_SIZE 4 +#define UDI_HID_KBD_REPORT_SIZE 8 + +enum usb_hid_device_kind { + USB_HID_UNKNOWN, + USB_HID_MOUSE, + USB_HID_KEYBOARD, +}; + +typedef struct { + mp_obj_base_t base; + enum usb_hid_device_kind kind; + uint8_t endpoint; + uint8_t report_length; + uint8_t* report_buffer; + uint8_t usage_page; + uint8_t usage; + +} usb_hid_device_obj_t; + +usb_hid_device_obj_t usb_hid_devices[2]; +// Indices into usb_hid_devices: +#define USB_HID_DEVICE_MOUSE 0 +#define USB_HID_DEVICE_KEYBOARD 1 + +void usb_hid_init(void); +void usb_hid_reset(void); #endif // COMMON_HAL_USB_HID_DEVICE_H diff --git a/ports/atmel-samd/common-hal/usb_hid/__init__.c b/ports/atmel-samd/common-hal/usb_hid/__init__.c index 5fa704cf83..3b49d35761 100644 --- a/ports/atmel-samd/common-hal/usb_hid/__init__.c +++ b/ports/atmel-samd/common-hal/usb_hid/__init__.c @@ -28,37 +28,29 @@ #include "py/mphal.h" #include "py/runtime.h" -#include "common-hal/usb_hid/__init__.h" #include "common-hal/usb_hid/Device.h" -#include "common-hal/usb_hid/types.h" -#include "shared-bindings/usb_hid/__init__.h" #include "shared-bindings/usb_hid/Device.h" -#define UDI_HID_MOUSE_REPORT_SIZE 4 -#define UDI_HID_KBD_REPORT_SIZE 8 +#include "tools/autogen_usb_descriptor.h" -uint8_t mouse_report_buffer[UDI_HID_MOUSE_REPORT_SIZE]; -uint8_t kbd_report_buffer[UDI_HID_KBD_REPORT_SIZE]; +static uint8_t mouse_report_buffer[UDI_HID_MOUSE_REPORT_SIZE]; +static uint8_t kbd_report_buffer[UDI_HID_KBD_REPORT_SIZE]; usb_hid_device_obj_t usb_hid_devices[2] = { { - .endpoint = UDI_HID_MOUSE_EP_IN, + .kind = USB_HID_MOUSE, .report_length = UDI_HID_MOUSE_REPORT_SIZE, .report_buffer = mouse_report_buffer, .usage_page = 0x01, .usage = 0x02, - .enabled = false, - .transaction_ongoing = false }, { - .endpoint = UDI_HID_KBD_EP_IN, + .kind = USB_HID_KEYBOARD, .report_length = UDI_HID_KBD_REPORT_SIZE, .report_buffer = kbd_report_buffer, .usage_page = 0x01, .usage = 0x06, - .enabled = false, - .transaction_ongoing = false } }; @@ -70,48 +62,7 @@ mp_obj_tuple2_t common_hal_usb_hid_devices = { }, .len = 2, .items = { - (mp_obj_t) &usb_hid_devices[0], - (mp_obj_t) &usb_hid_devices[1] + (mp_obj_t) &usb_hid_devices[USB_HID_DEVICE_MOUSE], + (mp_obj_t) &usb_hid_devices[USB_HID_DEVICE_KEYBOARD], } }; - -void usb_hid_init() { - usb_hid_devices[0].base.type = &usb_hid_device_type; - usb_hid_devices[1].base.type = &usb_hid_device_type; -} - -void usb_hid_reset() { - // We don't actually reset. We just set a report that is empty to prevent - // long keypresses and such. - uint8_t report[8] = {0, 0, 0, 0, 0, 0, 0, 0}; - - usb_hid_send_report(&usb_hid_devices[0], report, 4); - usb_hid_send_report(&usb_hid_devices[1], report, 8); -} - -bool mp_mouse_enable(void) -{ - usb_hid_devices[0].enabled = true; - return true; -} - -void mp_mouse_disable(void) -{ - usb_hid_devices[0].enabled = false; -} - -bool mp_keyboard_enable(void) -{ - usb_hid_devices[1].enabled = true; - return true; -} - -void mp_keyboard_disable(void) -{ - usb_hid_devices[1].enabled = false; -} - -void mp_keyboard_led(uint8_t leds) -{ - UNUSED(leds); -} diff --git a/ports/atmel-samd/common-hal/usb_hid/__init__.h b/ports/atmel-samd/common-hal/usb_hid/__init__.h deleted file mode 100644 index 21f629f137..0000000000 --- a/ports/atmel-samd/common-hal/usb_hid/__init__.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef COMMON_HAL_USB_HID_H -#define COMMON_HAL_USB_HID_H - -#include -#include - -#include "common-hal/usb_hid/types.h" - -usb_hid_device_obj_t usb_hid_devices[2]; - -void usb_hid_init(void); -void usb_hid_reset(void); - -#endif // COMMON_HAL_USB_HID_H diff --git a/ports/atmel-samd/common-hal/usb_hid/types.h b/ports/atmel-samd/common-hal/usb_hid/types.h deleted file mode 100644 index c276ebd0de..0000000000 --- a/ports/atmel-samd/common-hal/usb_hid/types.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef MICROPY_INCLUDED_COMMON_HAL_USB_HID_TYPES_H -#define MICROPY_INCLUDED_COMMON_HAL_USB_HID_TYPES_H - -#include "py/obj.h" - -typedef struct { - mp_obj_base_t base; - udd_ep_id_t endpoint; - volatile bool transaction_ongoing; - volatile bool enabled; - uint8_t report_length; - uint8_t* report_buffer; - uint8_t usage_page; - uint8_t usage; -} usb_hid_device_obj_t; - -#endif // MICROPY_INCLUDED_COMMON_HAL_USB_HID_TYPES_H diff --git a/ports/atmel-samd/mpconfigport.h b/ports/atmel-samd/mpconfigport.h index 1ce44ac8af..032bd164f4 100644 --- a/ports/atmel-samd/mpconfigport.h +++ b/ports/atmel-samd/mpconfigport.h @@ -213,7 +213,6 @@ extern const struct _mp_obj_module_t usb_hid_module; // Disabled for now. // { MP_OBJ_NEW_QSTR(MP_QSTR_touchio), (mp_obj_t)&touchio_module }, // { MP_OBJ_NEW_QSTR(MP_QSTR__stage), (mp_obj_t)&stage_module }, -// { MP_OBJ_NEW_QSTR(MP_QSTR_usb_hid),(mp_obj_t)&usb_hid_module }, #define MICROPY_PORT_BUILTIN_MODULES \ @@ -231,6 +230,7 @@ extern const struct _mp_obj_module_t usb_hid_module; { MP_OBJ_NEW_QSTR(MP_QSTR_supervisor), (mp_obj_t)&supervisor_module }, \ { MP_OBJ_NEW_QSTR(MP_QSTR_math), (mp_obj_t)&math_module }, \ { MP_OBJ_NEW_QSTR(MP_QSTR_time), (mp_obj_t)&time_module }, \ + { MP_OBJ_NEW_QSTR(MP_QSTR_usb_hid),(mp_obj_t)&usb_hid_module }, \ EXTRA_BUILTIN_MODULES #define MICROPY_PORT_BUILTIN_DEBUG_MODULES \ diff --git a/ports/atmel-samd/supervisor/port.c b/ports/atmel-samd/supervisor/port.c index cb8ffac47e..23d9bc9098 100644 --- a/ports/atmel-samd/supervisor/port.c +++ b/ports/atmel-samd/supervisor/port.c @@ -49,6 +49,7 @@ #include "common-hal/pulseio/PulseIn.h" #include "common-hal/pulseio/PulseOut.h" #include "common-hal/pulseio/PWMOut.h" +#include "common-hal/usb_hid/Device.h" #include "shared_dma.h" #include "tick.h" @@ -229,9 +230,8 @@ void reset_port(void) { // gpio_set_pin_function(PIN_PB15, GPIO_PIN_FUNCTION_M); // GCLK1, D6 // #endif -// -// usb_hid_reset(); -// + usb_hid_reset(); + // #ifdef CALIBRATE_CRYSTALLESS // // If we are on USB lets double check our fine calibration for the clock and // // save the new value if its different enough. diff --git a/ports/atmel-samd/supervisor/serial.c b/ports/atmel-samd/supervisor/serial.c index 0410c74176..9461381b30 100644 --- a/ports/atmel-samd/supervisor/serial.c +++ b/ports/atmel-samd/supervisor/serial.c @@ -28,6 +28,8 @@ #include "supervisor/serial.h" +#include "common-hal/usb_hid/Device.h" + #include "usb.h" #include "tools/autogen_usb_descriptor.h" @@ -57,6 +59,7 @@ void load_serial_number(void) { void serial_init(void) { load_serial_number(); init_usb(); + usb_hid_init(); } bool serial_connected(void) { diff --git a/ports/atmel-samd/tools/autogen_usb_descriptor.h b/ports/atmel-samd/tools/autogen_usb_descriptor.h index d9260681c3..a1f4f9ba0e 100644 --- a/ports/atmel-samd/tools/autogen_usb_descriptor.h +++ b/ports/atmel-samd/tools/autogen_usb_descriptor.h @@ -32,5 +32,7 @@ struct usbd_descriptors descriptor_bounds; uint8_t* serial_number; uint8_t serial_number_length; +uint8_t hid_mouse_endpoint_in; +uint8_t hid_keyboard_endpoint_in; #endif // MICROPY_INCLUDED_ATMEL_SAMD_TOOLS_AUTOGEN_USB_DESCRIPTOR_H diff --git a/ports/atmel-samd/tools/gen_usb_descriptor.py b/ports/atmel-samd/tools/gen_usb_descriptor.py index 5456005236..fb8bf2bbe5 100644 --- a/ports/atmel-samd/tools/gen_usb_descriptor.py +++ b/ports/atmel-samd/tools/gen_usb_descriptor.py @@ -6,7 +6,7 @@ import sys # path hacking sys.path.append("../../tools/usb_descriptor") -from adafruit_usb_descriptor import cdc, standard, util +from adafruit_usb_descriptor import cdc, hid, msc, standard, util parser = argparse.ArgumentParser(description='Generate USB descriptors.') parser.add_argument('--manufacturer', type=str, @@ -43,9 +43,9 @@ device = standard.DeviceDescriptor( # until core.join_interfaces renumbers them. cdc_interfaces = [ standard.InterfaceDescriptor( - bInterfaceClass=0x2, # Communications Device Class - bInterfaceSubClass=0x02, # Abstract control model - bInterfaceProtocol=0x01, # Common AT Commands + bInterfaceClass=cdc.CDC_CLASS_COMM, # Communications Device Class + bInterfaceSubClass=cdc.CDC_SUBCLASS_ACM, # Abstract control model + bInterfaceProtocol=cdc.CDC_PROTOCOL_V25TER, # Common AT Commands subdescriptors=[ # Working 2.x # radix: hexadecimal @@ -57,16 +57,16 @@ cdc_interfaces = [ cdc.CallManagement(bmCapabilities=0x03, bDataInterface=0x01), cdc.AbstractControlManagement(bmCapabilities=0x02), cdc.Union(bMasterInterface=0x00, - bSlaveInterface=[0x01]), + bSlaveInterface_list=[0x01]), standard.EndpointDescriptor( bEndpointAddress=0x0 | standard.EndpointDescriptor.DIRECTION_IN, bmAttributes=standard.EndpointDescriptor.TYPE_INTERRUPT, - wMaxPacketSize=0x8, - bInterval=10) + wMaxPacketSize=0x0040, + bInterval=0x10) ] ), standard.InterfaceDescriptor( - bInterfaceClass=0x0a, + bInterfaceClass=cdc.CDC_CLASS_DATA, subdescriptors=[ standard.EndpointDescriptor( bEndpointAddress=0x0 | standard.EndpointDescriptor.DIRECTION_IN, @@ -80,9 +80,9 @@ cdc_interfaces = [ msc_interfaces = [ standard.InterfaceDescriptor( - bInterfaceClass=0x08, - bInterfaceSubClass=0x06, - bInterfaceProtocol=0x50, + bInterfaceClass=msc.MSC_CLASS, + bInterfaceSubClass=msc.MSC_SUBCLASS_TRANSPARENT, + bInterfaceProtocol=msc.MSC_PROTOCOL_BULK, subdescriptors=[ standard.EndpointDescriptor( bEndpointAddress=0x0 | standard.EndpointDescriptor.DIRECTION_IN, @@ -94,7 +94,50 @@ msc_interfaces = [ ) ] -interfaces = util.join_interfaces(cdc_interfaces, msc_interfaces) +hid_report_descriptors = [ + hid.ReportDescriptor.GENERIC_MOUSE_REPORT, + hid.ReportDescriptor.GENERIC_KEYBOARD_REPORT, +] + +mouse_endpoint_descriptor = standard.EndpointDescriptor( + bEndpointAddress=0x0 | standard.EndpointDescriptor.DIRECTION_IN, + bmAttributes=standard.EndpointDescriptor.TYPE_INTERRUPT, + wMaxPacketSize=8, # mouse report is small + bInterval=0x0a) + +keyboard_endpoint_descriptor = standard.EndpointDescriptor( + bEndpointAddress=0x0 | standard.EndpointDescriptor.DIRECTION_IN, + bmAttributes=standard.EndpointDescriptor.TYPE_INTERRUPT, + wMaxPacketSize=8, # keyboard report is 8 bytes + bInterval=0x02) + +hid_interfaces = [ + standard.InterfaceDescriptor( + bInterfaceClass = hid.HID_CLASS, + bInterfaceSubClass = hid.HID_SUBCLASS_BOOT, + bInterfaceProtocol = hid.HID_PROTOCOL_MOUSE, + subdescriptors=[ + mouse_endpoint_descriptor, + hid.HIDDescriptor(wDescriptorLength=len(bytes(hid_report_descriptors[0]))), + ] + ), + standard.InterfaceDescriptor( + bInterfaceClass = hid.HID_CLASS, + bInterfaceSubClass = hid.HID_SUBCLASS_NOBOOT, + bInterfaceProtocol = hid.HID_PROTOCOL_KEYBOARD, + subdescriptors=[ + keyboard_endpoint_descriptor, + hid.HIDDescriptor(wDescriptorLength=len(bytes(hid_report_descriptors[1]))), + ] + ), + ] + +# This will renumber the endpoints to make them unique across descriptors. +print(mouse_endpoint_descriptor.bEndpointAddress, keyboard_endpoint_descriptor.bEndpointAddress) +###interfaces = util.join_interfaces(cdc_interfaces, msc_interfaces, hid_interfaces) +interfaces = util.join_interfaces(cdc_interfaces, hid_interfaces) +print(mouse_endpoint_descriptor.bEndpointAddress, keyboard_endpoint_descriptor.bEndpointAddress) + cdc_function = standard.InterfaceAssociationDescriptor( bFirstInterface=interfaces.index(cdc_interfaces[0]), @@ -111,16 +154,24 @@ configuration = standard.ConfigurationDescriptor( descriptor_list = [device, configuration, cdc_function] descriptor_list.extend(interfaces) +##descriptor_list.extend(hid_report_descriptors) descriptor_list.extend(strings) output_file = args.output_file -output_file.write("#include \n\n") -output_file.write("#include \"tools/autogen_usb_descriptor.h\"\n\n") -output_file.write("uint8_t usb_descriptors[] = {\n") +output_file.write(""" +#include + +#include "tools/autogen_usb_descriptor.h" + +uint8_t usb_descriptors[] = { +""") + descriptor_length = 0 serial_number_offset = None for descriptor in descriptor_list: + print(str(descriptor)) + print([hex(x) for x in bytes(descriptor)]) output_file.write("// " + str(descriptor) + "\n") b = bytes(descriptor) i = 0 @@ -136,14 +187,23 @@ for descriptor in descriptor_list: i += length descriptor_length += length - output_file.write("\n") -output_file.write("};\n\n") -output_file.write("struct usbd_descriptors descriptor_bounds = " + - "{usb_descriptors," + - " usb_descriptors + sizeof(usb_descriptors)};\n") -output_file.write("uint8_t* serial_number = usb_descriptors + " + - str(serial_number_offset) + ";\n") -output_file.write("uint8_t serial_number_length = " + - str(args.serial_number_length) + ";\n") -output_file.close() +output_file.write(""" +}; + +""") + +output_file.write(""" + +struct usbd_descriptors descriptor_bounds = {{usb_descriptors, usb_descriptors + sizeof(usb_descriptors)}}; +uint8_t* serial_number = usb_descriptors + {SERIAL_NUMBER_OFFSET}; +uint8_t serial_number_length = {SERIAL_NUMBER_LENGTH}; + +uint8_t hid_mouse_endpoint_in = {MOUSE_ENDPOINT_ADDRESS}; +uint8_t hid_keyboard_endpoint_in = {KEYBOARD_ENDPOINT_ADDRESS}; +""".format(SERIAL_NUMBER_OFFSET=serial_number_offset, + SERIAL_NUMBER_LENGTH=args.serial_number_length, + MOUSE_ENDPOINT_ADDRESS=mouse_endpoint_descriptor.bEndpointAddress, + KEYBOARD_ENDPOINT_ADDRESS=keyboard_endpoint_descriptor.bEndpointAddress + ) +) diff --git a/ports/atmel-samd/usb.c b/ports/atmel-samd/usb.c index 740486aa1e..bc7313fdcb 100644 --- a/ports/atmel-samd/usb.c +++ b/ports/atmel-samd/usb.c @@ -34,9 +34,8 @@ #include "hal/include/hal_gpio.h" #include "usb/class/cdc/device/cdcdf_acm.h" -// #include "hiddf_mouse.h" -// #include "hiddf_keyboard.h" -#include "usb/class/hid/device/hiddf_generic.h" +#include "usb/class/hid/device/hiddf_mouse.h" +#include "usb/class/hid/device/hiddf_keyboard.h" #include "usb/class/composite/device/composite_desc.h" #include "usb/class/msc/device/mscdf.h" #include "peripheral_clk_config.h" @@ -209,9 +208,6 @@ void init_usb(void) { pending_read = false; mscdf_init(1); - // hiddf_mouse_init(); - // hiddf_keyboard_init(); - mscdf_register_callback(MSCDF_CB_INQUIRY_DISK, (FUNC_PTR)usb_msc_inquiry_info); mscdf_register_callback(MSCDF_CB_GET_DISK_CAPACITY, (FUNC_PTR)usb_msc_get_capacity); mscdf_register_callback(MSCDF_CB_START_READ_DISK, (FUNC_PTR)usb_msc_new_read); @@ -221,6 +217,9 @@ void init_usb(void) { mscdf_register_callback(MSCDF_CB_XFER_BLOCKS_DONE, (FUNC_PTR)usb_msc_xfer_done); mscdf_register_callback(MSCDF_CB_IS_WRITABLE, (FUNC_PTR)usb_msc_disk_is_writable); + hiddf_mouse_init(); + hiddf_keyboard_init(); + usbdc_start(&descriptor_bounds); usbdc_attach(); diff --git a/shared-bindings/usb_hid/Device.h b/shared-bindings/usb_hid/Device.h index 33b9f1c994..2bc553c4a2 100644 --- a/shared-bindings/usb_hid/Device.h +++ b/shared-bindings/usb_hid/Device.h @@ -27,7 +27,7 @@ #ifndef MICROPY_INCLUDED_SHARED_BINDINGS_USB_HID_DEVICE_H #define MICROPY_INCLUDED_SHARED_BINDINGS_USB_HID_DEVICE_H -#include "common-hal/usb_hid/types.h" +#include "common-hal/usb_hid/Device.h" const mp_obj_type_t usb_hid_device_type;