wip: starting to try to compile
This commit is contained in:
parent
9d1fcc3b14
commit
c26e49c2e6
@ -62,33 +62,4 @@ The tinyusb examples already include a "WebUSB serial" example.
|
||||
Basically, this feature was ported into CircuitPython by pulling code snippets out of the
|
||||
tinyusb example, and putting them where they best belonged in the CircuitPython codebase.
|
||||
|
||||
There was one complication:
|
||||
|
||||
tinyusb uses C preprocessor macros to define things like USB descriptors.
|
||||
|
||||
CircuitPython uses a Python program (tools/gen_usb_descriptor.py) to create USB descriptors (etc.)
|
||||
using "helper objects" from another repo (adafruit_usb_descriptor). This means some of the example
|
||||
code had to be adapted to the new programing model, and gen_usb_descriptor gained new command-line
|
||||
options to control the generated code.
|
||||
|
||||
The generated files go into the "build" directory, look for autogen_usb_descriptor.c and
|
||||
genhdr/autogen_usb_descriptor.h.
|
||||
|
||||
|
||||
Also worth pointing out - the re-use of the CDC connect/disconnect mechanism is not actually part
|
||||
of the WebUSB standard, it's more of "common idiom". We make use of it here because we need to know
|
||||
when we should be paying attention to the WebUSB serial interface, and when we should ignore it..
|
||||
|
||||
## Possible future work areas
|
||||
|
||||
The current code uses the existing Python infrastructure to create the Interface descriptor, but
|
||||
simply outputs the code snippets from the original tinyusb demo code to create the WEBUSB_URL,
|
||||
BOS, and MS_OS_20 descriptors. I suppose additional work could be done to add these to the
|
||||
adafruit_usb_descriptor project, and then gen_usb_descriptor.py could be modified to make use
|
||||
of them.
|
||||
|
||||
Program gen_usb_descriptor.py creates objects for most interface types, regardless of whether or
|
||||
not they are actually enabled. This increases the size of a generated string table. I made the
|
||||
new vendor-interface-related code not do this (because some of the ARM platforms would no longer
|
||||
build), but I did not go back and do this for the other interface types (CDC, MIDI, HID, etc.)
|
||||
Some FLASH savings are probably possible if this is done.
|
||||
### TODO: This needs to be reworked for dynamic USB descriptors.
|
||||
|
8
main.c
8
main.c
@ -518,7 +518,6 @@ STATIC void __attribute__ ((noinline)) run_boot_py(safe_mode_t safe_mode) {
|
||||
}
|
||||
#endif
|
||||
|
||||
// TODO(tannewt): Allocate temporary space to hold custom usb descriptors.
|
||||
filesystem_flush();
|
||||
supervisor_allocation* heap = allocate_remaining_memory();
|
||||
start_mp(heap);
|
||||
@ -535,6 +534,12 @@ STATIC void __attribute__ ((noinline)) run_boot_py(safe_mode_t safe_mode) {
|
||||
boot_output_file = NULL;
|
||||
#endif
|
||||
|
||||
#if CIRCUITPY_USB
|
||||
// Remember USB settings done during boot.py.
|
||||
// Call this before the boot.py heap is destroyed.
|
||||
usb_post_boot_py();
|
||||
#endif
|
||||
|
||||
cleanup_after_vm(heap);
|
||||
}
|
||||
}
|
||||
@ -588,6 +593,7 @@ int __attribute__((used)) main(void) {
|
||||
// Port-independent devices, like CIRCUITPY_BLEIO_HCI.
|
||||
reset_devices();
|
||||
reset_board();
|
||||
reset_usb();
|
||||
|
||||
// This is first time we are running CircuitPython after a reset or power-up.
|
||||
supervisor_set_run_reason(RUN_REASON_STARTUP);
|
||||
|
@ -2,60 +2,29 @@
|
||||
#ifndef HPL_USB_CONFIG_H
|
||||
#define HPL_USB_CONFIG_H
|
||||
|
||||
// CIRCUITPY:
|
||||
// CIRCUITPY: Since we have dynamic USB descriptors, we may end up using all endpoints.
|
||||
// So provide cache space for all of them.
|
||||
|
||||
// Use 64-byte USB buffers for endpoint directions that are in use. They're set to 0 below otherwise.
|
||||
|
||||
#include "genhdr/autogen_usb_descriptor.h"
|
||||
|
||||
#if defined(USB_ENDPOINT_1_OUT_USED) && USB_ENDPOINT_1_OUT_USED
|
||||
#define CONF_USB_EP1_CACHE 64
|
||||
#endif
|
||||
#if defined(USB_ENDPOINT_1_IN_USED) && USB_ENDPOINT_1_IN_USED
|
||||
#define CONF_USB_EP1_I_CACHE 64
|
||||
#endif
|
||||
|
||||
#if defined(USB_ENDPOINT_2_OUT_USED) && USB_ENDPOINT_2_OUT_USED
|
||||
#define CONF_USB_EP2_CACHE 64
|
||||
#endif
|
||||
#if defined(USB_ENDPOINT_2_IN_USED) && USB_ENDPOINT_2_IN_USED
|
||||
#define CONF_USB_EP2_I_CACHE 64
|
||||
#endif
|
||||
|
||||
#if defined(USB_ENDPOINT_3_OUT_USED) && USB_ENDPOINT_3_OUT_USED
|
||||
#define CONF_USB_EP3_CACHE 64
|
||||
#endif
|
||||
#if defined(USB_ENDPOINT_3_IN_USED) && USB_ENDPOINT_3_IN_USED
|
||||
#define CONF_USB_EP3_I_CACHE 64
|
||||
#endif
|
||||
|
||||
#if defined(USB_ENDPOINT_4_OUT_USED) && USB_ENDPOINT_4_OUT_USED
|
||||
#define CONF_USB_EP4_CACHE 64
|
||||
#endif
|
||||
#if defined(USB_ENDPOINT_4_IN_USED) && USB_ENDPOINT_4_IN_USED
|
||||
#define CONF_USB_EP4_I_CACHE 64
|
||||
#endif
|
||||
|
||||
#if defined(USB_ENDPOINT_5_OUT_USED) && USB_ENDPOINT_5_OUT_USED
|
||||
#define CONF_USB_EP5_CACHE 64
|
||||
#endif
|
||||
#if defined(USB_ENDPOINT_5_IN_USED) && USB_ENDPOINT_5_IN_USED
|
||||
#define CONF_USB_EP5_I_CACHE 64
|
||||
#endif
|
||||
|
||||
#if defined(USB_ENDPOINT_6_OUT_USED) && USB_ENDPOINT_6_OUT_USED
|
||||
#define CONF_USB_EP6_CACHE 64
|
||||
#endif
|
||||
#if defined(USB_ENDPOINT_6_IN_USED) && USB_ENDPOINT_6_IN_USED
|
||||
#define CONF_USB_EP6_I_CACHE 64
|
||||
#endif
|
||||
|
||||
#if defined(USB_ENDPOINT_7_OUT_USED) && USB_ENDPOINT_7_OUT_USED
|
||||
#define CONF_USB_EP7_CACHE 64
|
||||
#endif
|
||||
#if defined(USB_ENDPOINT_7_IN_USED) && USB_ENDPOINT_7_IN_USED
|
||||
#define CONF_USB_EP7_I_CACHE 64
|
||||
#endif
|
||||
|
||||
|
||||
// <<< Use Configuration Wizard in Context Menu >>>
|
||||
|
@ -2,60 +2,29 @@
|
||||
#ifndef HPL_USB_CONFIG_H
|
||||
#define HPL_USB_CONFIG_H
|
||||
|
||||
// CIRCUITPY:
|
||||
// CIRCUITPY: Since we have dynamic USB descriptors, we may end up using all endpoints.
|
||||
// So provide cache space for all of them.
|
||||
|
||||
// Use 64-byte USB buffers for endpoint directions that are in use. They're set to 0 below otherwise.
|
||||
|
||||
#include "genhdr/autogen_usb_descriptor.h"
|
||||
|
||||
#if defined(USB_ENDPOINT_1_OUT_USED) && USB_ENDPOINT_1_OUT_USED
|
||||
#define CONF_USB_EP1_CACHE 64
|
||||
#endif
|
||||
#if defined(USB_ENDPOINT_1_IN_USED) && USB_ENDPOINT_1_IN_USED
|
||||
#define CONF_USB_EP1_I_CACHE 64
|
||||
#endif
|
||||
|
||||
#if defined(USB_ENDPOINT_2_OUT_USED) && USB_ENDPOINT_2_OUT_USED
|
||||
#define CONF_USB_EP2_CACHE 64
|
||||
#endif
|
||||
#if defined(USB_ENDPOINT_2_IN_USED) && USB_ENDPOINT_2_IN_USED
|
||||
#define CONF_USB_EP2_I_CACHE 64
|
||||
#endif
|
||||
|
||||
#if defined(USB_ENDPOINT_3_OUT_USED) && USB_ENDPOINT_3_OUT_USED
|
||||
#define CONF_USB_EP3_CACHE 64
|
||||
#endif
|
||||
#if defined(USB_ENDPOINT_3_IN_USED) && USB_ENDPOINT_3_IN_USED
|
||||
#define CONF_USB_EP3_I_CACHE 64
|
||||
#endif
|
||||
|
||||
#if defined(USB_ENDPOINT_4_OUT_USED) && USB_ENDPOINT_4_OUT_USED
|
||||
#define CONF_USB_EP4_CACHE 64
|
||||
#endif
|
||||
#if defined(USB_ENDPOINT_4_IN_USED) && USB_ENDPOINT_4_IN_USED
|
||||
#define CONF_USB_EP4_I_CACHE 64
|
||||
#endif
|
||||
|
||||
#if defined(USB_ENDPOINT_5_OUT_USED) && USB_ENDPOINT_5_OUT_USED
|
||||
#define CONF_USB_EP5_CACHE 64
|
||||
#endif
|
||||
#if defined(USB_ENDPOINT_5_IN_USED) && USB_ENDPOINT_5_IN_USED
|
||||
#define CONF_USB_EP5_I_CACHE 64
|
||||
#endif
|
||||
|
||||
#if defined(USB_ENDPOINT_6_OUT_USED) && USB_ENDPOINT_6_OUT_USED
|
||||
#define CONF_USB_EP6_CACHE 64
|
||||
#endif
|
||||
#if defined(USB_ENDPOINT_6_IN_USED) && USB_ENDPOINT_6_IN_USED
|
||||
#define CONF_USB_EP6_I_CACHE 64
|
||||
#endif
|
||||
|
||||
#if defined(USB_ENDPOINT_7_OUT_USED) && USB_ENDPOINT_7_OUT_USED
|
||||
#define CONF_USB_EP7_CACHE 64
|
||||
#endif
|
||||
#if defined(USB_ENDPOINT_7_IN_USED) && USB_ENDPOINT_7_IN_USED
|
||||
#define CONF_USB_EP7_I_CACHE 64
|
||||
#endif
|
||||
|
||||
|
||||
// <<< Use Configuration Wizard in Context Menu >>>
|
||||
|
@ -2,60 +2,29 @@
|
||||
#ifndef HPL_USB_CONFIG_H
|
||||
#define HPL_USB_CONFIG_H
|
||||
|
||||
// CIRCUITPY:
|
||||
// CIRCUITPY: Since we have dynamic USB descriptors, we may end up using all endpoints.
|
||||
// So provide cache space for all of them.
|
||||
|
||||
// Use 64-byte USB buffers for endpoint directions that are in use. They're set to 0 below otherwise.
|
||||
|
||||
#include "genhdr/autogen_usb_descriptor.h"
|
||||
|
||||
#if defined(USB_ENDPOINT_1_OUT_USED) && USB_ENDPOINT_1_OUT_USED
|
||||
#define CONF_USB_EP1_CACHE 64
|
||||
#endif
|
||||
#if defined(USB_ENDPOINT_1_IN_USED) && USB_ENDPOINT_1_IN_USED
|
||||
#define CONF_USB_EP1_I_CACHE 64
|
||||
#endif
|
||||
|
||||
#if defined(USB_ENDPOINT_2_OUT_USED) && USB_ENDPOINT_2_OUT_USED
|
||||
#define CONF_USB_EP2_CACHE 64
|
||||
#endif
|
||||
#if defined(USB_ENDPOINT_2_IN_USED) && USB_ENDPOINT_2_IN_USED
|
||||
#define CONF_USB_EP2_I_CACHE 64
|
||||
#endif
|
||||
|
||||
#if defined(USB_ENDPOINT_3_OUT_USED) && USB_ENDPOINT_3_OUT_USED
|
||||
#define CONF_USB_EP3_CACHE 64
|
||||
#endif
|
||||
#if defined(USB_ENDPOINT_3_IN_USED) && USB_ENDPOINT_3_IN_USED
|
||||
#define CONF_USB_EP3_I_CACHE 64
|
||||
#endif
|
||||
|
||||
#if defined(USB_ENDPOINT_4_OUT_USED) && USB_ENDPOINT_4_OUT_USED
|
||||
#define CONF_USB_EP4_CACHE 64
|
||||
#endif
|
||||
#if defined(USB_ENDPOINT_4_IN_USED) && USB_ENDPOINT_4_IN_USED
|
||||
#define CONF_USB_EP4_I_CACHE 64
|
||||
#endif
|
||||
|
||||
#if defined(USB_ENDPOINT_5_OUT_USED) && USB_ENDPOINT_5_OUT_USED
|
||||
#define CONF_USB_EP5_CACHE 64
|
||||
#endif
|
||||
#if defined(USB_ENDPOINT_5_IN_USED) && USB_ENDPOINT_5_IN_USED
|
||||
#define CONF_USB_EP5_I_CACHE 64
|
||||
#endif
|
||||
|
||||
#if defined(USB_ENDPOINT_6_OUT_USED) && USB_ENDPOINT_6_OUT_USED
|
||||
#define CONF_USB_EP6_CACHE 64
|
||||
#endif
|
||||
#if defined(USB_ENDPOINT_6_IN_USED) && USB_ENDPOINT_6_IN_USED
|
||||
#define CONF_USB_EP6_I_CACHE 64
|
||||
#endif
|
||||
|
||||
#if defined(USB_ENDPOINT_7_OUT_USED) && USB_ENDPOINT_7_OUT_USED
|
||||
#define CONF_USB_EP7_CACHE 64
|
||||
#endif
|
||||
#if defined(USB_ENDPOINT_7_IN_USED) && USB_ENDPOINT_7_IN_USED
|
||||
#define CONF_USB_EP7_I_CACHE 64
|
||||
#endif
|
||||
|
||||
|
||||
// <<< Use Configuration Wizard in Context Menu >>>
|
||||
|
@ -2,60 +2,29 @@
|
||||
#ifndef HPL_USB_CONFIG_H
|
||||
#define HPL_USB_CONFIG_H
|
||||
|
||||
// CIRCUITPY:
|
||||
// CIRCUITPY: Since we have dynamic USB descriptors, we may end up using all endpoints.
|
||||
// So provide cache space for all of them.
|
||||
|
||||
// Use 64-byte USB buffers for endpoint directions that are in use. They're set to 0 below otherwise.
|
||||
|
||||
#include "genhdr/autogen_usb_descriptor.h"
|
||||
|
||||
#if defined(USB_ENDPOINT_1_OUT_USED) && USB_ENDPOINT_1_OUT_USED
|
||||
#define CONF_USB_EP1_CACHE 64
|
||||
#endif
|
||||
#if defined(USB_ENDPOINT_1_IN_USED) && USB_ENDPOINT_1_IN_USED
|
||||
#define CONF_USB_EP1_I_CACHE 64
|
||||
#endif
|
||||
|
||||
#if defined(USB_ENDPOINT_2_OUT_USED) && USB_ENDPOINT_2_OUT_USED
|
||||
#define CONF_USB_EP2_CACHE 64
|
||||
#endif
|
||||
#if defined(USB_ENDPOINT_2_IN_USED) && USB_ENDPOINT_2_IN_USED
|
||||
#define CONF_USB_EP2_I_CACHE 64
|
||||
#endif
|
||||
|
||||
#if defined(USB_ENDPOINT_3_OUT_USED) && USB_ENDPOINT_3_OUT_USED
|
||||
#define CONF_USB_EP3_CACHE 64
|
||||
#endif
|
||||
#if defined(USB_ENDPOINT_3_IN_USED) && USB_ENDPOINT_3_IN_USED
|
||||
#define CONF_USB_EP3_I_CACHE 64
|
||||
#endif
|
||||
|
||||
#if defined(USB_ENDPOINT_4_OUT_USED) && USB_ENDPOINT_4_OUT_USED
|
||||
#define CONF_USB_EP4_CACHE 64
|
||||
#endif
|
||||
#if defined(USB_ENDPOINT_4_IN_USED) && USB_ENDPOINT_4_IN_USED
|
||||
#define CONF_USB_EP4_I_CACHE 64
|
||||
#endif
|
||||
|
||||
#if defined(USB_ENDPOINT_5_OUT_USED) && USB_ENDPOINT_5_OUT_USED
|
||||
#define CONF_USB_EP5_CACHE 64
|
||||
#endif
|
||||
#if defined(USB_ENDPOINT_5_IN_USED) && USB_ENDPOINT_5_IN_USED
|
||||
#define CONF_USB_EP5_I_CACHE 64
|
||||
#endif
|
||||
|
||||
#if defined(USB_ENDPOINT_6_OUT_USED) && USB_ENDPOINT_6_OUT_USED
|
||||
#define CONF_USB_EP6_CACHE 64
|
||||
#endif
|
||||
#if defined(USB_ENDPOINT_6_IN_USED) && USB_ENDPOINT_6_IN_USED
|
||||
#define CONF_USB_EP6_I_CACHE 64
|
||||
#endif
|
||||
|
||||
#if defined(USB_ENDPOINT_7_OUT_USED) && USB_ENDPOINT_7_OUT_USED
|
||||
#define CONF_USB_EP7_CACHE 64
|
||||
#endif
|
||||
#if defined(USB_ENDPOINT_7_IN_USED) && USB_ENDPOINT_7_IN_USED
|
||||
#define CONF_USB_EP7_I_CACHE 64
|
||||
#endif
|
||||
|
||||
|
||||
// <<< Use Configuration Wizard in Context Menu >>>
|
||||
|
@ -308,6 +308,9 @@ CFLAGS += -DCIRCUITPY_STRUCT=$(CIRCUITPY_STRUCT)
|
||||
CIRCUITPY_SUPERVISOR ?= 1
|
||||
CFLAGS += -DCIRCUITPY_SUPERVISOR=$(CIRCUITPY_SUPERVISOR)
|
||||
|
||||
CIRCUITPY_SYNTHIO ?= $(CIRCUITPY_AUDIOCORE)
|
||||
CFLAGS += -DCIRCUITPY_SYNTHIO=$(CIRCUITPY_SYNTHIO)
|
||||
|
||||
CIRCUITPY_TERMINALIO ?= $(CIRCUITPY_DISPLAYIO)
|
||||
CFLAGS += -DCIRCUITPY_TERMINALIO=$(CIRCUITPY_TERMINALIO)
|
||||
|
||||
@ -325,39 +328,34 @@ CFLAGS += -DCIRCUITPY_TOUCHIO=$(CIRCUITPY_TOUCHIO)
|
||||
CIRCUITPY_UHEAP ?= 0
|
||||
CFLAGS += -DCIRCUITPY_UHEAP=$(CIRCUITPY_UHEAP)
|
||||
|
||||
# Secondary CDC is usually available if there are at least 8 endpoints.
|
||||
CIRCUITPY_USB_CDC ?= $(shell expr $(USB_NUM_EP) '>=' 8)
|
||||
CIRCUITPY_USB ?= 1
|
||||
CFLAGS += -DCIRCUITPY_USB=$(CIRCUITPY_USB)
|
||||
|
||||
# If you need to count endpoints, do:
|
||||
# $(shell expr $(USB_NUM_EP) '>=' 8)
|
||||
|
||||
CIRCUITPY_USB_CDC ?= 1
|
||||
CFLAGS += -DCIRCUITPY_USB_CDC=$(CIRCUITPY_USB_CDC)
|
||||
CIRCUITPY_USB_CDC_REPL_ENABLED ?= 1
|
||||
CFLAGS += -DCIRCUITPY_USB_CDC_DATA_ENABLED_DEFAULT=$(CIRCUITPY_USB_CDC_DATA_ENABLED_DEFAULT)
|
||||
CIRCUITPY_USB_CDC_DATA_ENABLED ?= 0
|
||||
CFLAGS += -DCIRCUITPY_USB_CDC_DATA_ENABLED_DEFAULT=$(CIRCUITPY_USB_CDC_DATA_ENABLED_DEFAULT)
|
||||
|
||||
CIRCUITPY_USB_HID ?= 1
|
||||
CFLAGS += -DCIRCUITPY_USB_HID=$(CIRCUITPY_USB_HID)
|
||||
CIRCUITPY_USB_HID_ENABLED_DEFAULT = $(CIRCUITPY_USB_HID)
|
||||
CFLAGS += -DCIRCUITPY_USB_HID_ENABLED_DEFAULT=$(CIRCUITPY_USB_HID_ENABLED_DEFAULT)
|
||||
|
||||
CIRCUITPY_USB_HID_CONSUMER ?= 1
|
||||
CFLAGS += -DCIRCUITPY_USB_HID_CONSUMER=$(CIRCUITPY_USB_HID_CONSUMER)
|
||||
|
||||
CIRCUITPY_USB_HID_DIGITIZER ?= 0
|
||||
CFLAGS += -DCIRCUITPY_USB_HID_DIGITIZER=$(CIRCUITPY_USB_HID_DIGITIZER)
|
||||
|
||||
CIRCUITPY_USB_HID_GAMEPAD ?= 1
|
||||
CFLAGS += -DCIRCUITPY_USB_HID_GAMEPAD=$(CIRCUITPY_USB_HID_GAMEPAD)
|
||||
|
||||
CIRCUITPY_USB_HID_KEYBOARD ?= 1
|
||||
CFLAGS += -DCIRCUITPY_USB_HID_KEYBOARD=$(CIRCUITPY_USB_HID_KEYBOARD)
|
||||
|
||||
CIRCUITPY_USB_HID_MOUSE ?= 1
|
||||
CFLAGS += -DCIRCUITPY_USB_HID_MOUSE=$(CIRCUITPY_USB_HID_MOUSE)
|
||||
|
||||
CIRCUITPY_USB_HID_SYS_CONTROL ?= 0
|
||||
CFLAGS += -DCIRCUITPY_USB_HID_SYS_CONTROL=$(CIRCUITPY_USB_HID_SYS_CONTROL)
|
||||
|
||||
CIRCUITPY_USB_HID_XAC_COMPATIBLE_GAMEPAD ?= 0
|
||||
CFLAGS += -DCIRCUITPY_USB_HID_XAC_COMPATIBLE_GAMEPAD=$(CIRCUITPY_USB_HID_XAC_COMPATIBLE_GAMEPAD)
|
||||
|
||||
CIRCUITPY_USB_MIDI ?= 1
|
||||
# MIDI is usually available if there are at least 8 endpoints.
|
||||
CIRCUITPY_USB_MIDI ?= $(shell expr $(USB_NUM_EP) '>=' 8)
|
||||
CFLAGS += -DCIRCUITPY_USB_MIDI=$(CIRCUITPY_USB_MIDI)
|
||||
CIRCUITPY_USB_MIDI_ENABLED_DEFAULT = $(CIRCUITPY_USB_MIDI)
|
||||
CFLAGS += -DCIRCUITPY_USB_MIDI_ENABLED_DEFAULT=$(CIRCUITPY_USB_MIDI_ENABLED_DEFAULT)
|
||||
|
||||
CIRCUITPY_USB_MSC ?= 1
|
||||
CFLAGS += -DCIRCUITPY_USB_MSC=$(CIRCUITPY_USB_MSC)
|
||||
CIRCUITPY_USB_MSC_ENABLED_DEFAULT = $(CIRCUITPY_USB_MSC)
|
||||
CFLAGS += -DCIRCUITPY_USB_MSC_ENABLED_DEFAULT=$(CIRCUITPY_USB_MSC_ENABLED_DEFAULT)
|
||||
|
||||
# Defaulting this to OFF initially because it has only been tested on a
|
||||
# limited number of platforms, and the other platforms do not have this
|
||||
|
@ -53,23 +53,19 @@
|
||||
STATIC mp_obj_t usb_hid_configure_usb(mp_obj_t devices) {
|
||||
|
||||
mp_obj_iter_buf_t iter_buf;
|
||||
mp_obj_t iterable = mp_getiter(devices, &iter_buf);
|
||||
mp_obj_t device;
|
||||
while ((device = mp_iternext(iterable)) != MP_OBJ_STOP_ITERATION) {
|
||||
|
||||
const mp_int_t len = mp_obj_get_int(mp_obj_len(devices_seq));
|
||||
for (size_t i = 0; i < len; i++) {
|
||||
mp_obj_t item = mp_obj_subscr(devices_seq, mp_obj_new_small_int(i), MP_OBJ_SENTINEL);
|
||||
if (!MP_OBJ_IS_TYPE(item, &usb_hid_device_type)) {
|
||||
mp_raise_ValueError_varg(translate("non-Device in %q", MP_QSTR_devices));
|
||||
}
|
||||
}
|
||||
|
||||
switch (common_hal_usb_hid_configure_usb(descriptors)) {
|
||||
case USB_CONFIG_TOO_LATE:
|
||||
if (!common_hal_usb_hid_configure_usb(descriptors)) {
|
||||
mp_raise_RuntimeError(translate("Cannot change USB devices now"));
|
||||
break;
|
||||
case USB_CONFIG_NON_DEVICE:
|
||||
mp_raise_ValueError_varg(translate("non-Device in %q", MP_QSTR_devices));
|
||||
break;
|
||||
default:
|
||||
}
|
||||
|
||||
return mp_const_none;
|
||||
}
|
||||
MP_DEFINE_CONST_FUN_OBJ_1(usb_hid_configure_usb_obj, usb_hid_configure_usb);
|
||||
|
@ -32,10 +32,7 @@
|
||||
|
||||
extern mp_obj_tuple_t common_hal_usb_hid_devices;
|
||||
|
||||
typedef enum {
|
||||
USB_CONFIG_OK = 0,
|
||||
USB_CONFIG_TOO_LATE = 1,
|
||||
USB_CONFIG_NON_DEVICE = 2,
|
||||
} usb_hid_configure_status;
|
||||
void common_hal_usb_hid_configure_usb_defaults(void);
|
||||
usb_hid_configure_status common_hal_usb_hid_configure_usb(mp_obj_t devices_seq);
|
||||
|
||||
usb_hid_configure_status common_hal_usb_hid_configure_usb(mp_obj_t devices_seqf // SHARED_BINDINGS_USB_HID_H
|
||||
#endif // SHARED_BINDINGS_USB_HID_H
|
||||
|
@ -24,7 +24,6 @@
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "genhdr/autogen_usb_descriptor.h"
|
||||
#include "py/gc.h"
|
||||
#include "py/obj.h"
|
||||
#include "py/mphal.h"
|
||||
|
@ -51,6 +51,9 @@ static const uint8_t usb_hid_descriptor_template[] = {
|
||||
0x08, // 21 bInterval 8 (unit depends on device speed)
|
||||
};
|
||||
|
||||
// Sequence of devices to configure.
|
||||
static mp_obj_t hid_devices_seq;
|
||||
|
||||
// Is the HID device enabled?
|
||||
bool usb_hid_enabled;
|
||||
supervisor_allocation *hid_report_descriptor_allocation;
|
||||
@ -78,23 +81,35 @@ size_t usb_hid_add_descriptor(uint8_t *descriptor_buf, uint8_t *current_interfac
|
||||
return sizeof(usb_hid_descriptor_template);
|
||||
}
|
||||
|
||||
usb_hid_configure_status common_hal_usb_hid_configure_usb(mp_obj_t devices_seq) {
|
||||
static mp_obj_t default_hid_devices[] = {
|
||||
MP_OBJ_FROM_PTR(usb_hid_device_keyboard_obj),
|
||||
MP_OBJ_FROM_PTR(usb_hid_device_mouse_obj),
|
||||
};
|
||||
|
||||
// Set the default list of devices that will be included. Called before boot.py runs, in the boot.py VM.
|
||||
void common_hal_usb_hid_configure_usb_defaults(void) {
|
||||
common_hal_usb_hid_configure_usb(mp_obj_new_tuple(sizeof(default_hid_devices), default_hid_devices));
|
||||
}
|
||||
|
||||
bool common_hal_usb_hid_configure_usb(mp_obj_t devices_seq) {
|
||||
// We can't change the devices once we're connected.
|
||||
if (tud_connected()) {
|
||||
return USB_CONFIG_TOO_LATE;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Assume no devices to start.
|
||||
usb_hid_enabled = false;
|
||||
if (devices_seq == mp_const_none) {
|
||||
return USB_CONFIG_OK;
|
||||
// Remember the devices for use in usb_hid_post_boot_py.
|
||||
hid_devices_seq = devices_seq;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Build the combined HID report descriptor and save the chosen devices.
|
||||
// Both are saved in supervisor allocations.
|
||||
void usb_hid_post_boot_py(void) {
|
||||
size_t total_report_descriptors_length = 0;
|
||||
|
||||
// Build a combined report descriptor
|
||||
|
||||
mp_int_t len = mp_obj_get_int(mp_obj_len(devices_seq));
|
||||
mp_int_t len = mp_obj_get_int(mp_obj_len(hid_devices_seq));
|
||||
|
||||
// First get the total size.
|
||||
for (size_t i = 0; i < len; i++) {
|
||||
@ -128,7 +143,7 @@ usb_hid_configure_status common_hal_usb_hid_configure_usb(mp_obj_t devices_seq)
|
||||
uint8_t *descriptor_start = (uint8_t *) hid_report_descriptor_allocation->ptr;
|
||||
|
||||
for (size_t i = 0; i < len; i++) {
|
||||
usb_hid_device_obj_t *device = MP_OBJ_TO_PTR(devices_seq, mp_obj_new_small_int(i), MP_OBJ_SENTINEL);
|
||||
usb_hid_device_obj_t *device = MP_OBJ_TO_PTR(hid_devices_seq, mp_obj_new_small_int(i), MP_OBJ_SENTINEL);
|
||||
|
||||
// Copy the report descriptor for this device.
|
||||
if (len == 1) {
|
||||
@ -150,6 +165,8 @@ usb_hid_configure_status common_hal_usb_hid_configure_usb(mp_obj_t devices_seq)
|
||||
hid_devices[i].descriptor_obj = mp_const_none;
|
||||
}
|
||||
|
||||
// No longer keeping the Python object of devices to configure.
|
||||
hid_devices_seq = MP_OBJ_NULL;
|
||||
}
|
||||
|
||||
void usb_hid_gc_collect(void) {
|
||||
@ -158,7 +175,8 @@ void usb_hid_gc_collect(void) {
|
||||
free_memory(hid_report_descriptor_allocation);
|
||||
free_memory(usb_hid_devices_allocation);
|
||||
} else {
|
||||
gc_collect_ptr(hid_devices_seq);
|
||||
gc_collect_ptr(hid_report_descriptor_allocation->ptr);
|
||||
gc_collect_ptr(usb_hid_devices_allocation);
|
||||
gc_collect_ptr(usb_hid_devices_allocation_ptr);
|
||||
}
|
||||
}
|
||||
|
@ -26,7 +26,6 @@
|
||||
|
||||
#include "shared-bindings/usb_midi/__init__.h"
|
||||
|
||||
#include "genhdr/autogen_usb_descriptor.h"
|
||||
#include "py/obj.h"
|
||||
#include "py/mphal.h"
|
||||
#include "py/runtime.h"
|
||||
|
@ -38,8 +38,6 @@
|
||||
#ifndef _TUSB_CONFIG_H_
|
||||
#define _TUSB_CONFIG_H_
|
||||
|
||||
#include "genhdr/autogen_usb_descriptor.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
@ -41,7 +41,6 @@
|
||||
#include "tusb.h"
|
||||
|
||||
#if CIRCUITPY_USB_VENDOR
|
||||
#include "genhdr/autogen_usb_descriptor.h"
|
||||
|
||||
// The WebUSB support being conditionally added to this file is based on the
|
||||
// tinyusb demo examples/device/webusb_serial.
|
||||
@ -55,15 +54,17 @@ bool usb_enabled(void) {
|
||||
return tusb_inited();
|
||||
}
|
||||
|
||||
// Initialization done only once, before boot.py is run.
|
||||
void reset_usb(void) {
|
||||
reset_usb_desc();
|
||||
}
|
||||
|
||||
|
||||
MP_WEAK void post_usb_init(void) {
|
||||
}
|
||||
|
||||
void usb_init(void) {
|
||||
usb_build_device_descriptor();
|
||||
usb_build_configuration_descriptor();
|
||||
usb_build_hid_descriptor();
|
||||
usb_build_string_descriptors();
|
||||
|
||||
usb_desc_init();
|
||||
|
||||
init_usb_hardware();
|
||||
|
||||
@ -82,6 +83,13 @@ void usb_init(void) {
|
||||
#endif
|
||||
}
|
||||
|
||||
// Remember USB settings done during boot.py.
|
||||
// The boot.py heap is still valid at this point.
|
||||
void usb_post_boot_py(void) {
|
||||
usb_desc_post_boot_py();
|
||||
}
|
||||
|
||||
|
||||
void usb_disconnect(void) {
|
||||
tud_disconnect();
|
||||
}
|
||||
|
@ -44,10 +44,8 @@
|
||||
|
||||
#include "shared-module/usb_hid/Device.h"
|
||||
|
||||
#include "genhdr/autogen_usb_descriptor.h"
|
||||
|
||||
supervisor_allocation *device_descriptor_allocation;
|
||||
supervisor_allocation *config_descriptor_allocation;
|
||||
uint8_t *device_descriptor;
|
||||
uint8_t *config_descriptor;
|
||||
|
||||
// Table for collecting interface strings (interface names) as descriptor is built.
|
||||
#define MAX_INTERFACE_STRINGS 16
|
||||
@ -99,31 +97,31 @@ static const uint8_t configuration_descriptor_template[] = {
|
||||
0x32, // 8 bMaxPower 100mA
|
||||
};
|
||||
|
||||
void usb_desc_init(void) {
|
||||
uint8_t raw_id[COMMON_HAL_MCU_PROCESSOR_UID_LENGTH];
|
||||
common_hal_mcu_processor_get_uid(raw_id);
|
||||
// Initialization done before boot.py is run.
|
||||
// Turn on or off various USB devices. On devices with limited endpoints,
|
||||
// some may be off by default.
|
||||
void reset_usb_desc(void) {
|
||||
// Set defaults for enabling/disabling of various USB devices.
|
||||
#if CIRCUITPY_USB_CDC
|
||||
common_hal_usb_cdc_configure_usb(
|
||||
(bool) CIRCUITPY_USB_CDC_REPL_ENABLED_DEFAULT,
|
||||
(bool) CIRCUITPY_USB_CDC_DATA_ENABLED_DEFAULT);
|
||||
#endif
|
||||
|
||||
for (int i = 0; i < COMMON_HAL_MCU_PROCESSOR_UID_LENGTH; i++) {
|
||||
for (int j = 0; j < 2; j++) {
|
||||
uint8_t nibble = (raw_id[i] >> (j * 4)) & 0xf;
|
||||
serial_number_hex_string[i * 2 + (1 - j)] = nibble_to_hex_upper[nibble];
|
||||
}
|
||||
#if CIRCUITPY_USB_MSC
|
||||
common_hal_storage_configure_usb((bool) CIRCUITPY_USB_MSC_ENABLED_DEFAULT);
|
||||
#endif
|
||||
|
||||
#if CIRCUITPY_USB_MIDI
|
||||
common_hal_usb_midi_configure_usb((bool) CIRCUITPY_USB_MIDI_ENABLED_DEFAULT);
|
||||
#endif
|
||||
|
||||
#if CIRCUITPY_USB_HID
|
||||
common_hal_usb_hid_configure_usb_default();
|
||||
#endif
|
||||
}
|
||||
|
||||
// Null-terminate the string.
|
||||
serial_number_hex_string[sizeof(serial_number_hex_string)] = '\0';
|
||||
|
||||
// Memory is cleared to zero when allocated; we depend on that.
|
||||
collected_interface_strings = m_malloc(MAX_INTERFACE_STRINGS + 1, false);
|
||||
current_interface_string = 1;
|
||||
}
|
||||
|
||||
|
||||
void usb_build_device_descriptor(uint16_t vid, uint16_t pid, uint8_t *current_interface_string) {
|
||||
device_descriptor_allocation =
|
||||
allocate_memory(sizeof(device_descriptor_template), false /*highaddress*/, true /*movable*/);
|
||||
uint8_t *device_descriptor = (uint8_t *) device_descriptor_allocation->ptr;
|
||||
|
||||
static void usb_build_device_descriptor(uint16_t vid, uint16_t pid, uint8_t *current_interface_string) {
|
||||
memcpy(device_descriptor, device_descriptor_template, sizeof(device_descriptor_template));
|
||||
|
||||
device_descriptor[DEVICE_VID_LO_INDEX] = vid & 0xFF;
|
||||
@ -144,7 +142,7 @@ void usb_build_device_descriptor(uint16_t vid, uint16_t pid, uint8_t *current_in
|
||||
(*current_interface_string)++;
|
||||
}
|
||||
|
||||
void usb_build_configuration_descriptor(uint16_t total_length, uint8_t num_interfaces) {
|
||||
static void usb_build_configuration_descriptor(uint16_t total_length, uint8_t num_interfaces) {
|
||||
size_t total_descriptor_length = sizeof(configuration_descriptor_template);
|
||||
|
||||
// CDC should be first, for compatibility with Adafruit Windows 7 drivers.
|
||||
@ -178,11 +176,6 @@ void usb_build_configuration_descriptor(uint16_t total_length, uint8_t num_inter
|
||||
#endif
|
||||
|
||||
// Now we now how big the configuration descriptor will be.
|
||||
|
||||
configuration_descriptor_allocation =
|
||||
allocate_memory(sizeof(configuration_descriptor_template), false /*highaddress*/, true /*movable*/);
|
||||
uint8_t *configuration_descriptor = (uint8_t *) device_descriptor_allocation->ptr;
|
||||
|
||||
// Copy the top-level template, and fix up its length.
|
||||
memcpy(config_descriptor, configuration_descriptor_template, sizeof(configuration_descriptor_template));
|
||||
configuration_descriptor[CONFIG_TOTAL_LENGTH_LO_INDEX] = total_descriptor_length & 0xFF;
|
||||
@ -241,7 +234,7 @@ void usb_build_configuration_descriptor(uint16_t total_length, uint8_t num_inter
|
||||
|
||||
}
|
||||
|
||||
void usb_add_interface_string(uint8_t interface_string_index, const char[] str) {
|
||||
static void usb_add_interface_string(uint8_t interface_string_index, const char[] str) {
|
||||
if (interface_string_index > MAX_INTERFACE_STRINGS) {
|
||||
mp_raise_SystemError("Too many USB interface names");
|
||||
}
|
||||
@ -259,15 +252,45 @@ void usb_add_interface_string(uint8_t interface_string_index, const char[] str)
|
||||
}
|
||||
|
||||
|
||||
// Remember USB information that must persist from the boot.py VM to the next VM.
|
||||
// Some of this is already remembered in globals, for example, usb_midi_enabled and similar bools.
|
||||
void usb_desc_post_boot_py(void) {
|
||||
usb_hid_post_boot_py();
|
||||
}
|
||||
|
||||
// Called in a the new VM created after boot.py is run. The USB devices to be used are now chosen.
|
||||
static void usb_desc_init(void) {
|
||||
uint8_t raw_id[COMMON_HAL_MCU_PROCESSOR_UID_LENGTH];
|
||||
common_hal_mcu_processor_get_uid(raw_id);
|
||||
|
||||
for (int i = 0; i < COMMON_HAL_MCU_PROCESSOR_UID_LENGTH; i++) {
|
||||
for (int j = 0; j < 2; j++) {
|
||||
uint8_t nibble = (raw_id[i] >> (j * 4)) & 0xf;
|
||||
serial_number_hex_string[i * 2 + (1 - j)] = nibble_to_hex_upper[nibble];
|
||||
}
|
||||
}
|
||||
|
||||
// Null-terminate the string.
|
||||
serial_number_hex_string[sizeof(serial_number_hex_string)] = '\0';
|
||||
|
||||
// Memory is cleared to zero when allocated; we depend on that.
|
||||
collected_interface_strings = m_malloc(MAX_INTERFACE_STRINGS + 1, false);
|
||||
current_interface_string = 1;
|
||||
|
||||
usb_build_device_descriptor();
|
||||
usb_build_configuration_descriptor();
|
||||
usb_build_hid_descriptor();
|
||||
usb_build_string_descriptors();
|
||||
}
|
||||
|
||||
void usb_desc_gc_collect(void) {
|
||||
// Once tud_mounted() is true, we're done with the constructed descriptors.
|
||||
if (tud_mounted()) {
|
||||
// GC will pick up the inaccessible blocks.
|
||||
free_memory(device_descriptor_allocation);
|
||||
free_memory(configuration_descriptor_allocation);
|
||||
gc_free(device_descriptor_allocation);
|
||||
gc_free(configuration_descriptor);
|
||||
} else {
|
||||
gc_collect_ptr(device_descriptor_allocation->ptr);
|
||||
gc_collect_ptr(configuration_descriptor_allocation->ptr);
|
||||
gc_collect_ptr(device_descriptor);
|
||||
gc_collect_ptr(configuration_descriptor);
|
||||
}
|
||||
}
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user