summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Halbert <halbert@halwitz.org>2018-03-24 18:29:12 -0400
committerDan Halbert <halbert@halwitz.org>2018-03-24 18:29:12 -0400
commit31f5b6a2389c7485fe044cf6e37259f6254c76e9 (patch)
treedb07d016d6eb7c79a8d95c835fcfd047be41255f
parent9d928b5726ee314fb625a79086675d548be12eef (diff)
WIP: simple working HID
-rw-r--r--main.c4
-rw-r--r--ports/atmel-samd/Makefile8
m---------ports/atmel-samd/asf40
-rw-r--r--ports/atmel-samd/common-hal/usb_hid/Device.c101
-rw-r--r--ports/atmel-samd/common-hal/usb_hid/Device.h30
-rw-r--r--ports/atmel-samd/common-hal/usb_hid/__init__.c63
-rw-r--r--ports/atmel-samd/common-hal/usb_hid/__init__.h40
-rw-r--r--ports/atmel-samd/common-hal/usb_hid/types.h43
-rw-r--r--ports/atmel-samd/mpconfigport.h2
-rw-r--r--ports/atmel-samd/supervisor/port.c6
-rw-r--r--ports/atmel-samd/supervisor/serial.c3
-rw-r--r--ports/atmel-samd/tools/autogen_usb_descriptor.h2
-rw-r--r--ports/atmel-samd/tools/gen_usb_descriptor.py112
-rw-r--r--ports/atmel-samd/usb.c11
-rw-r--r--shared-bindings/usb_hid/Device.h2
15 files changed, 205 insertions, 222 deletions
diff --git a/main.c b/main.c
index 8c981aee1..0ad050608 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 73799e5f2..71acca18e 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
-Subproject aaa0f428111fbea7d56ab548053b11c9f12068f
+Subproject 1e2165aa981f3eef39db8c27c05836aa94788e3
diff --git a/ports/atmel-samd/common-hal/usb_hid/Device.c b/ports/atmel-samd/common-hal/usb_hid/Device.c
index 443a67f8e..9568a27ef 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 <string.h>
-#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"
-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;
+#include "usb/class/hid/device/hiddf_mouse.h"
+#include "usb/class/hid/device/hiddf_keyboard.h"
- while (self->transaction_ongoing && timeout > 0) {
- timeout--;
- }
+static uint32_t usb_hid_send_report(usb_hid_device_obj_t *self, uint8_t* report, uint8_t len) {
- if (self->transaction_ongoing) {
- return false;
+ 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;
+ }
+ 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 1b313f9ce..d4d016009 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 <stdint.h>
#include <stdbool.h>
-#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 5fa704cf8..3b49d3576 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 21f629f13..000000000
--- 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 <stdint.h>
-#include <stdbool.h>
-
-#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 c276ebd0d..000000000
--- 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 1ce44ac8a..032bd164f 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 cb8ffac47..23d9bc909 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 0410c7417..9461381b3 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 d9260681c..a1f4f9ba0 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 545600523..fb8bf2bbe 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 <stdint.h>\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 <stdint.h>
+
+#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 740486aa1..bc7313fdc 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 33b9f1c99..2bc553c4a 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;