summaryrefslogtreecommitdiff
path: root/shared-module/usb_hid
diff options
context:
space:
mode:
authorScott Shawcroft <scott@tannewt.org>2018-10-19 18:46:22 -0700
committerScott Shawcroft <scott@tannewt.org>2018-11-08 17:25:30 -0800
commit9d91111b1b6a1eee77a88b13faf695ee0c5caea3 (patch)
tree97b1bf6ae67f8c91f7a32a0246e2f8ebd9a749c7 /shared-module/usb_hid
parentd08747d374057b24803b429bbf6474a2e4dcea5c (diff)
Move atmel-samd to tinyusb and support nRF flash.
This started while adding USB MIDI support (and descriptor support is in this change.) When seeing that I'd have to implement the MIDI class logic twice, once for atmel-samd and once for nrf, I decided to refactor the USB stack so its shared across ports. This has led to a number of changes that remove items from the ports folder and move them into supervisor. Furthermore, we had external SPI flash support for nrf pending so I factored out the connection between the usb stack and the flash API as well. This PR also includes the QSPI support for nRF.
Diffstat (limited to 'shared-module/usb_hid')
-rw-r--r--shared-module/usb_hid/Device.c88
-rw-r--r--shared-module/usb_hid/Device.h55
-rw-r--r--shared-module/usb_hid/__init__.c154
3 files changed, 297 insertions, 0 deletions
diff --git a/shared-module/usb_hid/Device.c b/shared-module/usb_hid/Device.c
new file mode 100644
index 000000000..820e14ad0
--- /dev/null
+++ b/shared-module/usb_hid/Device.c
@@ -0,0 +1,88 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2018 hathach 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.
+ */
+
+#include <string.h>
+#include "tick.h"
+#include "py/runtime.h"
+#include "shared-bindings/usb_hid/Device.h"
+#include "shared-module/usb_hid/Device.h"
+#include "supervisor/shared/translate.h"
+#include "tusb.h"
+
+uint8_t common_hal_usb_hid_device_get_usage_page(usb_hid_device_obj_t *self) {
+ return self->usage_page;
+}
+
+uint8_t common_hal_usb_hid_device_get_usage(usb_hid_device_obj_t *self) {
+ return self->usage;
+}
+
+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) {
+ mp_raise_ValueError_varg(translate("Buffer incorrect size. Should be %d bytes."), self->report_length);
+ }
+
+ // Wait until interface is ready, timeout = 2 seconds
+ uint64_t end_ticks = ticks_ms + 2000;
+ while ( (ticks_ms < end_ticks) && !tud_hid_generic_ready() ) { }
+
+ if ( !tud_hid_generic_ready() ) {
+ mp_raise_msg(&mp_type_OSError, translate("USB Busy"));
+ }
+
+ memcpy(self->report_buffer, report, len);
+
+ if ( !tud_hid_generic_report(self->report_id, self->report_buffer, len) ) {
+ mp_raise_msg(&mp_type_OSError, translate("USB Error"));
+ }
+}
+
+// Callbacks invoked when receive Get_Report request through control endpoint
+uint16_t tud_hid_generic_get_report_cb(uint8_t report_id, hid_report_type_t report_type, uint8_t* buffer, uint16_t reqlen) {
+ // only support Input Report
+ if ( report_type != HID_REPORT_TYPE_INPUT ) return 0;
+
+ // index is ID-1
+ uint8_t idx = ( report_id ? (report_id-1) : 0 );
+
+ // fill buffer with current report
+ memcpy(buffer, usb_hid_devices[idx].report_buffer, reqlen);
+ return reqlen;
+}
+
+// Callbacks invoked when receive Set_Report request through control endpoint
+void tud_hid_generic_set_report_cb(uint8_t report_id, hid_report_type_t report_type, uint8_t const* buffer, uint16_t bufsize) {
+ // index is ID-1
+ uint8_t idx = ( report_id ? (report_id-1) : 0 );
+
+ if ( report_type == HID_REPORT_TYPE_OUTPUT ) {
+ // Check if it is Keyboard device
+ if ( (usb_hid_devices[idx].usage_page == HID_USAGE_PAGE_DESKTOP) && (usb_hid_devices[idx].usage == HID_USAGE_DESKTOP_KEYBOARD) ) {
+ // This is LED indicator (CapsLock, NumLock)
+ // TODO Light up some LED here
+ }
+ }
+}
diff --git a/shared-module/usb_hid/Device.h b/shared-module/usb_hid/Device.h
new file mode 100644
index 000000000..10f2ee897
--- /dev/null
+++ b/shared-module/usb_hid/Device.h
@@ -0,0 +1,55 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2018 hathach 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 SHARED_MODULE_USB_HID_DEVICE_H
+#define SHARED_MODULE_USB_HID_DEVICE_H
+
+#include <stdint.h>
+#include <stdbool.h>
+
+#include "py/obj.h"
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+typedef struct {
+ mp_obj_base_t base;
+ uint8_t* report_buffer;
+ uint8_t report_id;
+ uint8_t report_length;
+ uint8_t usage_page;
+ uint8_t usage;
+} usb_hid_device_obj_t;
+
+
+extern usb_hid_device_obj_t usb_hid_devices[];
+
+#ifdef __cplusplus
+ }
+#endif
+
+#endif /* SHARED_MODULE_USB_HID_DEVICE_H */
diff --git a/shared-module/usb_hid/__init__.c b/shared-module/usb_hid/__init__.c
new file mode 100644
index 000000000..c0f9c897c
--- /dev/null
+++ b/shared-module/usb_hid/__init__.c
@@ -0,0 +1,154 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2018 hathach 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.
+ */
+
+#include "py/obj.h"
+#include "py/mphal.h"
+#include "py/runtime.h"
+
+#include "genhdr/autogen_usb_descriptor.h"
+#include "shared-module/usb_hid/Device.h"
+#include "shared-bindings/usb_hid/Device.h"
+#include "tusb.h"
+
+#ifdef USB_HID_REPORT_ID_KEYBOARD
+static uint8_t keyboard_report_buffer[USB_HID_REPORT_LENGTH_KEYBOARD];
+#endif
+
+#ifdef USB_HID_REPORT_ID_MOUSE
+static uint8_t mouse_report_buffer[USB_HID_REPORT_LENGTH_MOUSE];
+#endif
+
+#ifdef USB_HID_REPORT_ID_CONSUMER
+static uint8_t consumer_report_buffer[USB_HID_REPORT_LENGTH_CONSUMER];
+#endif
+
+#ifdef USB_HID_REPORT_ID_SYS_CONTROL
+static uint8_t sys_control_report_buffer[USB_HID_REPORT_LENGTH_SYS_CONTROL];
+#endif
+
+#ifdef USB_HID_REPORT_ID_GAMEPAD
+static uint8_t gamepad_report_buffer[USB_HID_REPORT_LENGTH_GAMEPAD];
+#endif
+
+#ifdef USB_HID_REPORT_ID_DIGITIZER
+static uint8_t digitizer_report_buffer[USB_HID_REPORT_LENGTH_DIGITIZER];
+#endif
+
+usb_hid_device_obj_t usb_hid_devices[] = {
+#if USB_HID_REPORT_ID_KEYBOARD
+ {
+ .base = { .type = &usb_hid_device_type } ,
+ .report_buffer = keyboard_report_buffer ,
+ .report_id = USB_HID_REPORT_ID_KEYBOARD ,
+ .report_length = USB_HID_REPORT_LENGTH_KEYBOARD ,
+ .usage_page = HID_USAGE_PAGE_DESKTOP ,
+ .usage = HID_USAGE_DESKTOP_KEYBOARD ,
+ },
+#endif
+
+#if USB_HID_REPORT_ID_MOUSE
+ {
+ .base = { .type = &usb_hid_device_type } ,
+ .report_buffer = mouse_report_buffer ,
+ .report_id = USB_HID_REPORT_ID_MOUSE ,
+ .report_length = USB_HID_REPORT_LENGTH_MOUSE ,
+ .usage_page = HID_USAGE_PAGE_DESKTOP ,
+ .usage = HID_USAGE_DESKTOP_MOUSE ,
+ },
+#endif
+
+#if USB_HID_REPORT_ID_CONSUMER
+ {
+ .base = { .type = &usb_hid_device_type } ,
+ .report_buffer = consumer_report_buffer ,
+ .report_id = USB_HID_REPORT_ID_CONSUMER ,
+ .report_length = USB_HID_REPORT_LENGTH_CONSUMER ,
+ .usage_page = HID_USAGE_PAGE_CONSUMER ,
+ .usage = HID_USAGE_CONSUMER_CONTROL ,
+ },
+#endif
+
+#if USB_HID_REPORT_ID_SYS_CONTROL
+ {
+ .base = { .type = &usb_hid_device_type } ,
+ .report_buffer = sys_control_report_buffer ,
+ .report_id = USB_HID_REPORT_ID_SYS_CONTROL ,
+ .report_length = USB_HID_REPORT_LENGTH_SYS_CONTROL ,
+ .usage_page = HID_USAGE_PAGE_DESKTOP ,
+ .usage = HID_USAGE_DESKTOP_SYSTEM_CONTROL ,
+ },
+#endif
+
+#if USB_HID_REPORT_ID_GAMEPAD
+ {
+ .base = { .type = &usb_hid_device_type } ,
+ .report_buffer = gamepad_report_buffer ,
+ .report_id = USB_HID_REPORT_ID_GAMEPAD ,
+ .report_length = USB_HID_REPORT_LENGTH_GAMEPAD ,
+ .usage_page = HID_USAGE_PAGE_DESKTOP ,
+ .usage = HID_USAGE_DESKTOP_GAMEPAD ,
+ },
+#endif
+
+#if USB_HID_REPORT_ID_DIGITIZER
+ {
+ .base = { .type = &usb_hid_device_type } ,
+ .report_buffer = digitizer_report_buffer ,
+ .report_id = USB_HID_REPORT_ID_DIGITIZER ,
+ .report_length = USB_HID_REPORT_LENGTH_DIGITIZER ,
+ .usage_page = 0x0D ,
+ .usage = 0x02 ,
+ },
+#endif
+};
+
+
+mp_obj_tuple_t common_hal_usb_hid_devices = {
+ .base = {
+ .type = &mp_type_tuple,
+ },
+ .len = USB_HID_NUM_DEVICES,
+ .items = {
+#if USB_HID_NUM_DEVICES >= 1
+ (mp_obj_t) &usb_hid_devices[0],
+#endif
+#if USB_HID_NUM_DEVICES >= 2
+ (mp_obj_t) &usb_hid_devices[1],
+#endif
+#if USB_HID_NUM_DEVICES >= 3
+ (mp_obj_t) &usb_hid_devices[2],
+#endif
+#if USB_HID_NUM_DEVICES >= 4
+ (mp_obj_t) &usb_hid_devices[3],
+#endif
+#if USB_HID_NUM_DEVICES >= 5
+ (mp_obj_t) &usb_hid_devices[4],
+#endif
+#if USB_HID_NUM_DEVICES >= 6
+ (mp_obj_t) &usb_hid_devices[5],
+#endif
+ }
+};