WIP: simple working HID
This commit is contained in:
parent
9d928b5726
commit
31f5b6a238
4
main.c
4
main.c
@ -286,12 +286,12 @@ int __attribute__((used)) main(void) {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Reset to remove any state that boot.py setup. It should only be used to
|
// 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_port();
|
||||||
reset_mp();
|
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();
|
serial_init();
|
||||||
|
|
||||||
// Boot script is finished, so now go into REPL/main mode.
|
// Boot script is finished, so now go into REPL/main mode.
|
||||||
|
@ -97,7 +97,7 @@ ifeq ($(DEBUG), 1)
|
|||||||
# Turn on Python modules useful for debugging (e.g. uheap, ustack).
|
# Turn on Python modules useful for debugging (e.g. uheap, ustack).
|
||||||
CFLAGS += -ggdb
|
CFLAGS += -ggdb
|
||||||
CFLAGS += -flto
|
CFLAGS += -flto
|
||||||
## CFLAGS += -fno-inline
|
CFLAGS += -fno-inline
|
||||||
ifeq ($(CHIP_FAMILY), samd21)
|
ifeq ($(CHIP_FAMILY), samd21)
|
||||||
CFLAGS += -DENABLE_MICRO_TRACE_BUFFER
|
CFLAGS += -DENABLE_MICRO_TRACE_BUFFER
|
||||||
endif
|
endif
|
||||||
@ -193,6 +193,8 @@ SRC_ASF := \
|
|||||||
hpl/systick/hpl_systick.c \
|
hpl/systick/hpl_systick.c \
|
||||||
hpl/usb/hpl_usb.c \
|
hpl/usb/hpl_usb.c \
|
||||||
usb/class/cdc/device/cdcdf_acm.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/class/msc/device/mscdf.c \
|
||||||
usb/device/usbdc.c \
|
usb/device/usbdc.c \
|
||||||
usb/usb_protocol.c \
|
usb/usb_protocol.c \
|
||||||
@ -282,6 +284,8 @@ SRC_COMMON_HAL = \
|
|||||||
pulseio/PulseIn.c \
|
pulseio/PulseIn.c \
|
||||||
pulseio/PulseOut.c \
|
pulseio/PulseOut.c \
|
||||||
pulseio/PWMOut.c \
|
pulseio/PWMOut.c \
|
||||||
|
usb_hid/__init__.c \
|
||||||
|
usb_hid/Device.c
|
||||||
# audiobusio/__init__.c \
|
# audiobusio/__init__.c \
|
||||||
audiobusio/PDMIn.c \
|
audiobusio/PDMIn.c \
|
||||||
audioio/__init__.c \
|
audioio/__init__.c \
|
||||||
@ -290,8 +294,6 @@ SRC_COMMON_HAL = \
|
|||||||
nvm/ByteArray.c \
|
nvm/ByteArray.c \
|
||||||
touchio/__init__.c \
|
touchio/__init__.c \
|
||||||
touchio/TouchIn.c \
|
touchio/TouchIn.c \
|
||||||
usb_hid/__init__.c \
|
|
||||||
usb_hid/Device.c
|
|
||||||
|
|
||||||
ifeq ($(INTERNAL_LIBM),1)
|
ifeq ($(INTERNAL_LIBM),1)
|
||||||
SRC_LIBM = $(addprefix lib/,\
|
SRC_LIBM = $(addprefix lib/,\
|
||||||
|
@ -1 +1 @@
|
|||||||
Subproject commit aaa0f428111fbea7d56ab548053b11c9f12068f1
|
Subproject commit 1e2165aa981f3eef39db8c27c05836aa94788e3d
|
@ -26,60 +26,65 @@
|
|||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "py/nlr.h"
|
#include "common-hal/usb_hid/Device.h"
|
||||||
#include "common-hal/usb_hid/__init__.h"
|
|
||||||
|
#include "py/runtime.h"
|
||||||
#include "shared-bindings/microcontroller/__init__.h"
|
#include "shared-bindings/microcontroller/__init__.h"
|
||||||
#include "shared-bindings/usb_hid/Device.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,
|
#include "tick.h"
|
||||||
udd_ep_id_t ep) {
|
|
||||||
UNUSED(status);
|
#include "usb/class/hid/device/hiddf_mouse.h"
|
||||||
UNUSED(nb_sent);
|
#include "usb/class/hid/device/hiddf_keyboard.h"
|
||||||
for (uint8_t i = 0; i < 2; i++) {
|
|
||||||
if (ep == usb_hid_devices[i].endpoint) {
|
static uint32_t usb_hid_send_report(usb_hid_device_obj_t *self, uint8_t* report, uint8_t len) {
|
||||||
usb_hid_devices[i].transaction_ongoing = false;
|
|
||||||
return;
|
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;
|
||||||
|
}
|
||||||
bool usb_hid_send_report(usb_hid_device_obj_t *self, uint8_t* report, uint8_t len) {
|
// Some error. Give up.
|
||||||
if (!self->enabled) {
|
return status;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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);
|
memcpy(self->report_buffer, report, len);
|
||||||
|
|
||||||
// Disable interrupts to make sure we save the ongoing state before the
|
switch (self->kind) {
|
||||||
// report_sent interrupt.
|
case USB_HID_MOUSE:
|
||||||
common_hal_mcu_disable_interrupts();
|
status = hiddf_mouse_write(self->report_buffer, self->report_length);
|
||||||
bool ok = udd_ep_run(self->endpoint, false,
|
break;
|
||||||
self->report_buffer, self->report_length, report_sent);
|
|
||||||
self->transaction_ongoing = ok;
|
case USB_HID_KEYBOARD:
|
||||||
common_hal_mcu_enable_interrupts();
|
status = hiddf_keyboard_write(self->report_buffer, self->report_length);
|
||||||
return ok;
|
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) {
|
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) {
|
if (len != self->report_length) {
|
||||||
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError,
|
mp_raise_ValueError_varg("Buffer incorrect size. Should be %d bytes.", self->report_length);
|
||||||
"Buffer incorrect size. Should be %d bytes.", self->report_length));
|
|
||||||
}
|
}
|
||||||
if (!self->enabled) {
|
int32_t status = usb_hid_send_report(self, report, len);
|
||||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, "USB Inactive"));
|
if (status != ERR_NONE) {
|
||||||
}
|
mp_raise_msg(&mp_type_OSError, status == USB_BUSY ? "USB Busy" : "USB Error");
|
||||||
if (!usb_hid_send_report(self, report, len)) {
|
|
||||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, "USB Busy"));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -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) {
|
uint8_t common_hal_usb_hid_device_get_usage(usb_hid_device_obj_t *self) {
|
||||||
return self->usage;
|
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);
|
||||||
|
}
|
||||||
|
@ -30,8 +30,34 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdbool.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
|
#endif // COMMON_HAL_USB_HID_DEVICE_H
|
||||||
|
@ -28,37 +28,29 @@
|
|||||||
#include "py/mphal.h"
|
#include "py/mphal.h"
|
||||||
#include "py/runtime.h"
|
#include "py/runtime.h"
|
||||||
|
|
||||||
#include "common-hal/usb_hid/__init__.h"
|
|
||||||
#include "common-hal/usb_hid/Device.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"
|
#include "shared-bindings/usb_hid/Device.h"
|
||||||
|
|
||||||
#define UDI_HID_MOUSE_REPORT_SIZE 4
|
#include "tools/autogen_usb_descriptor.h"
|
||||||
#define UDI_HID_KBD_REPORT_SIZE 8
|
|
||||||
|
|
||||||
uint8_t mouse_report_buffer[UDI_HID_MOUSE_REPORT_SIZE];
|
static uint8_t mouse_report_buffer[UDI_HID_MOUSE_REPORT_SIZE];
|
||||||
uint8_t kbd_report_buffer[UDI_HID_KBD_REPORT_SIZE];
|
static uint8_t kbd_report_buffer[UDI_HID_KBD_REPORT_SIZE];
|
||||||
|
|
||||||
usb_hid_device_obj_t usb_hid_devices[2] = {
|
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_length = UDI_HID_MOUSE_REPORT_SIZE,
|
||||||
.report_buffer = mouse_report_buffer,
|
.report_buffer = mouse_report_buffer,
|
||||||
.usage_page = 0x01,
|
.usage_page = 0x01,
|
||||||
.usage = 0x02,
|
.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_length = UDI_HID_KBD_REPORT_SIZE,
|
||||||
.report_buffer = kbd_report_buffer,
|
.report_buffer = kbd_report_buffer,
|
||||||
.usage_page = 0x01,
|
.usage_page = 0x01,
|
||||||
.usage = 0x06,
|
.usage = 0x06,
|
||||||
.enabled = false,
|
|
||||||
.transaction_ongoing = false
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -70,48 +62,7 @@ mp_obj_tuple2_t common_hal_usb_hid_devices = {
|
|||||||
},
|
},
|
||||||
.len = 2,
|
.len = 2,
|
||||||
.items = {
|
.items = {
|
||||||
(mp_obj_t) &usb_hid_devices[0],
|
(mp_obj_t) &usb_hid_devices[USB_HID_DEVICE_MOUSE],
|
||||||
(mp_obj_t) &usb_hid_devices[1]
|
(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);
|
|
||||||
}
|
|
||||||
|
@ -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
|
|
@ -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
|
|
@ -213,7 +213,6 @@ extern const struct _mp_obj_module_t usb_hid_module;
|
|||||||
// Disabled for now.
|
// Disabled for now.
|
||||||
// { MP_OBJ_NEW_QSTR(MP_QSTR_touchio), (mp_obj_t)&touchio_module },
|
// { 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__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 \
|
#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_supervisor), (mp_obj_t)&supervisor_module }, \
|
||||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_math), (mp_obj_t)&math_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_time), (mp_obj_t)&time_module }, \
|
||||||
|
{ MP_OBJ_NEW_QSTR(MP_QSTR_usb_hid),(mp_obj_t)&usb_hid_module }, \
|
||||||
EXTRA_BUILTIN_MODULES
|
EXTRA_BUILTIN_MODULES
|
||||||
|
|
||||||
#define MICROPY_PORT_BUILTIN_DEBUG_MODULES \
|
#define MICROPY_PORT_BUILTIN_DEBUG_MODULES \
|
||||||
|
@ -49,6 +49,7 @@
|
|||||||
#include "common-hal/pulseio/PulseIn.h"
|
#include "common-hal/pulseio/PulseIn.h"
|
||||||
#include "common-hal/pulseio/PulseOut.h"
|
#include "common-hal/pulseio/PulseOut.h"
|
||||||
#include "common-hal/pulseio/PWMOut.h"
|
#include "common-hal/pulseio/PWMOut.h"
|
||||||
|
#include "common-hal/usb_hid/Device.h"
|
||||||
#include "shared_dma.h"
|
#include "shared_dma.h"
|
||||||
#include "tick.h"
|
#include "tick.h"
|
||||||
|
|
||||||
@ -229,9 +230,8 @@ void reset_port(void) {
|
|||||||
// gpio_set_pin_function(PIN_PB15, GPIO_PIN_FUNCTION_M); // GCLK1, D6
|
// gpio_set_pin_function(PIN_PB15, GPIO_PIN_FUNCTION_M); // GCLK1, D6
|
||||||
// #endif
|
// #endif
|
||||||
|
|
||||||
//
|
usb_hid_reset();
|
||||||
// usb_hid_reset();
|
|
||||||
//
|
|
||||||
// #ifdef CALIBRATE_CRYSTALLESS
|
// #ifdef CALIBRATE_CRYSTALLESS
|
||||||
// // If we are on USB lets double check our fine calibration for the clock and
|
// // If we are on USB lets double check our fine calibration for the clock and
|
||||||
// // save the new value if its different enough.
|
// // save the new value if its different enough.
|
||||||
|
@ -28,6 +28,8 @@
|
|||||||
|
|
||||||
#include "supervisor/serial.h"
|
#include "supervisor/serial.h"
|
||||||
|
|
||||||
|
#include "common-hal/usb_hid/Device.h"
|
||||||
|
|
||||||
#include "usb.h"
|
#include "usb.h"
|
||||||
#include "tools/autogen_usb_descriptor.h"
|
#include "tools/autogen_usb_descriptor.h"
|
||||||
|
|
||||||
@ -57,6 +59,7 @@ void load_serial_number(void) {
|
|||||||
void serial_init(void) {
|
void serial_init(void) {
|
||||||
load_serial_number();
|
load_serial_number();
|
||||||
init_usb();
|
init_usb();
|
||||||
|
usb_hid_init();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool serial_connected(void) {
|
bool serial_connected(void) {
|
||||||
|
@ -32,5 +32,7 @@
|
|||||||
struct usbd_descriptors descriptor_bounds;
|
struct usbd_descriptors descriptor_bounds;
|
||||||
uint8_t* serial_number;
|
uint8_t* serial_number;
|
||||||
uint8_t serial_number_length;
|
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
|
#endif // MICROPY_INCLUDED_ATMEL_SAMD_TOOLS_AUTOGEN_USB_DESCRIPTOR_H
|
||||||
|
@ -6,7 +6,7 @@ import sys
|
|||||||
# path hacking
|
# path hacking
|
||||||
sys.path.append("../../tools/usb_descriptor")
|
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 = argparse.ArgumentParser(description='Generate USB descriptors.')
|
||||||
parser.add_argument('--manufacturer', type=str,
|
parser.add_argument('--manufacturer', type=str,
|
||||||
@ -43,9 +43,9 @@ device = standard.DeviceDescriptor(
|
|||||||
# until core.join_interfaces renumbers them.
|
# until core.join_interfaces renumbers them.
|
||||||
cdc_interfaces = [
|
cdc_interfaces = [
|
||||||
standard.InterfaceDescriptor(
|
standard.InterfaceDescriptor(
|
||||||
bInterfaceClass=0x2, # Communications Device Class
|
bInterfaceClass=cdc.CDC_CLASS_COMM, # Communications Device Class
|
||||||
bInterfaceSubClass=0x02, # Abstract control model
|
bInterfaceSubClass=cdc.CDC_SUBCLASS_ACM, # Abstract control model
|
||||||
bInterfaceProtocol=0x01, # Common AT Commands
|
bInterfaceProtocol=cdc.CDC_PROTOCOL_V25TER, # Common AT Commands
|
||||||
subdescriptors=[
|
subdescriptors=[
|
||||||
# Working 2.x
|
# Working 2.x
|
||||||
# radix: hexadecimal
|
# radix: hexadecimal
|
||||||
@ -57,16 +57,16 @@ cdc_interfaces = [
|
|||||||
cdc.CallManagement(bmCapabilities=0x03, bDataInterface=0x01),
|
cdc.CallManagement(bmCapabilities=0x03, bDataInterface=0x01),
|
||||||
cdc.AbstractControlManagement(bmCapabilities=0x02),
|
cdc.AbstractControlManagement(bmCapabilities=0x02),
|
||||||
cdc.Union(bMasterInterface=0x00,
|
cdc.Union(bMasterInterface=0x00,
|
||||||
bSlaveInterface=[0x01]),
|
bSlaveInterface_list=[0x01]),
|
||||||
standard.EndpointDescriptor(
|
standard.EndpointDescriptor(
|
||||||
bEndpointAddress=0x0 | standard.EndpointDescriptor.DIRECTION_IN,
|
bEndpointAddress=0x0 | standard.EndpointDescriptor.DIRECTION_IN,
|
||||||
bmAttributes=standard.EndpointDescriptor.TYPE_INTERRUPT,
|
bmAttributes=standard.EndpointDescriptor.TYPE_INTERRUPT,
|
||||||
wMaxPacketSize=0x8,
|
wMaxPacketSize=0x0040,
|
||||||
bInterval=10)
|
bInterval=0x10)
|
||||||
]
|
]
|
||||||
),
|
),
|
||||||
standard.InterfaceDescriptor(
|
standard.InterfaceDescriptor(
|
||||||
bInterfaceClass=0x0a,
|
bInterfaceClass=cdc.CDC_CLASS_DATA,
|
||||||
subdescriptors=[
|
subdescriptors=[
|
||||||
standard.EndpointDescriptor(
|
standard.EndpointDescriptor(
|
||||||
bEndpointAddress=0x0 | standard.EndpointDescriptor.DIRECTION_IN,
|
bEndpointAddress=0x0 | standard.EndpointDescriptor.DIRECTION_IN,
|
||||||
@ -80,9 +80,9 @@ cdc_interfaces = [
|
|||||||
|
|
||||||
msc_interfaces = [
|
msc_interfaces = [
|
||||||
standard.InterfaceDescriptor(
|
standard.InterfaceDescriptor(
|
||||||
bInterfaceClass=0x08,
|
bInterfaceClass=msc.MSC_CLASS,
|
||||||
bInterfaceSubClass=0x06,
|
bInterfaceSubClass=msc.MSC_SUBCLASS_TRANSPARENT,
|
||||||
bInterfaceProtocol=0x50,
|
bInterfaceProtocol=msc.MSC_PROTOCOL_BULK,
|
||||||
subdescriptors=[
|
subdescriptors=[
|
||||||
standard.EndpointDescriptor(
|
standard.EndpointDescriptor(
|
||||||
bEndpointAddress=0x0 | standard.EndpointDescriptor.DIRECTION_IN,
|
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(
|
cdc_function = standard.InterfaceAssociationDescriptor(
|
||||||
bFirstInterface=interfaces.index(cdc_interfaces[0]),
|
bFirstInterface=interfaces.index(cdc_interfaces[0]),
|
||||||
@ -111,16 +154,24 @@ configuration = standard.ConfigurationDescriptor(
|
|||||||
|
|
||||||
descriptor_list = [device, configuration, cdc_function]
|
descriptor_list = [device, configuration, cdc_function]
|
||||||
descriptor_list.extend(interfaces)
|
descriptor_list.extend(interfaces)
|
||||||
|
##descriptor_list.extend(hid_report_descriptors)
|
||||||
descriptor_list.extend(strings)
|
descriptor_list.extend(strings)
|
||||||
|
|
||||||
output_file = args.output_file
|
output_file = args.output_file
|
||||||
|
|
||||||
output_file.write("#include <stdint.h>\n\n")
|
output_file.write("""
|
||||||
output_file.write("#include \"tools/autogen_usb_descriptor.h\"\n\n")
|
#include <stdint.h>
|
||||||
output_file.write("uint8_t usb_descriptors[] = {\n")
|
|
||||||
|
#include "tools/autogen_usb_descriptor.h"
|
||||||
|
|
||||||
|
uint8_t usb_descriptors[] = {
|
||||||
|
""")
|
||||||
|
|
||||||
descriptor_length = 0
|
descriptor_length = 0
|
||||||
serial_number_offset = None
|
serial_number_offset = None
|
||||||
for descriptor in descriptor_list:
|
for descriptor in descriptor_list:
|
||||||
|
print(str(descriptor))
|
||||||
|
print([hex(x) for x in bytes(descriptor)])
|
||||||
output_file.write("// " + str(descriptor) + "\n")
|
output_file.write("// " + str(descriptor) + "\n")
|
||||||
b = bytes(descriptor)
|
b = bytes(descriptor)
|
||||||
i = 0
|
i = 0
|
||||||
@ -136,14 +187,23 @@ for descriptor in descriptor_list:
|
|||||||
i += length
|
i += length
|
||||||
descriptor_length += 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
|
||||||
|
)
|
||||||
|
)
|
||||||
|
@ -34,9 +34,8 @@
|
|||||||
|
|
||||||
#include "hal/include/hal_gpio.h"
|
#include "hal/include/hal_gpio.h"
|
||||||
#include "usb/class/cdc/device/cdcdf_acm.h"
|
#include "usb/class/cdc/device/cdcdf_acm.h"
|
||||||
// #include "hiddf_mouse.h"
|
#include "usb/class/hid/device/hiddf_mouse.h"
|
||||||
// #include "hiddf_keyboard.h"
|
#include "usb/class/hid/device/hiddf_keyboard.h"
|
||||||
#include "usb/class/hid/device/hiddf_generic.h"
|
|
||||||
#include "usb/class/composite/device/composite_desc.h"
|
#include "usb/class/composite/device/composite_desc.h"
|
||||||
#include "usb/class/msc/device/mscdf.h"
|
#include "usb/class/msc/device/mscdf.h"
|
||||||
#include "peripheral_clk_config.h"
|
#include "peripheral_clk_config.h"
|
||||||
@ -209,9 +208,6 @@ void init_usb(void) {
|
|||||||
pending_read = false;
|
pending_read = false;
|
||||||
|
|
||||||
mscdf_init(1);
|
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_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_GET_DISK_CAPACITY, (FUNC_PTR)usb_msc_get_capacity);
|
||||||
mscdf_register_callback(MSCDF_CB_START_READ_DISK, (FUNC_PTR)usb_msc_new_read);
|
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_XFER_BLOCKS_DONE, (FUNC_PTR)usb_msc_xfer_done);
|
||||||
mscdf_register_callback(MSCDF_CB_IS_WRITABLE, (FUNC_PTR)usb_msc_disk_is_writable);
|
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_start(&descriptor_bounds);
|
||||||
|
|
||||||
usbdc_attach();
|
usbdc_attach();
|
||||||
|
@ -27,7 +27,7 @@
|
|||||||
#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_USB_HID_DEVICE_H
|
#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_USB_HID_DEVICE_H
|
||||||
#define 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;
|
const mp_obj_type_t usb_hid_device_type;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user