wip: compiles

This commit is contained in:
Dan Halbert 2021-04-27 14:37:36 -04:00
parent 7a40b4daec
commit f98a54628b
23 changed files with 374 additions and 254 deletions

View File

@ -91,10 +91,6 @@ msgstr ""
msgid "%q must be 1-255"
msgstr ""
#: shared-bindings/usb_hid/Device.c
msgid "%q must be > 1-255"
msgstr ""
#: shared-bindings/memorymonitor/AllocationAlarm.c
msgid "%q must be >= 0"
msgstr ""
@ -111,10 +107,6 @@ msgstr ""
msgid "%q must be None or 1-255"
msgstr ""
#: shared-bindings/usb_hid/Device.c
msgid "%q must be None or > 1-255"
msgstr ""
#: shared-module/vectorio/Polygon.c
msgid "%q must be a tuple of length 2"
msgstr ""
@ -1643,6 +1635,10 @@ msgstr ""
msgid "Not connected"
msgstr ""
#: supervisor/shared/usb/usb_desc.c
msgid "Not enough USB endpoints"
msgstr ""
#: shared-bindings/audiobusio/I2SOut.c shared-bindings/audioio/AudioOut.c
#: shared-bindings/audiopwmio/PWMAudioOut.c
msgid "Not playing"
@ -2149,6 +2145,10 @@ msgstr ""
msgid "To exit, please reset the board without "
msgstr ""
#: supervisor/shared/usb/usb_desc.c
msgid "Too many USB interface names"
msgstr ""
#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c
#: ports/raspberrypi/common-hal/audiobusio/I2SOut.c
msgid "Too many channels in sample."

8
main.c
View File

@ -103,6 +103,10 @@
#include "shared-module/usb_cdc/__init__.h"
#endif
#if CIRCUITPY_USB_HID
#include "shared-module/usb_hid/__init__.h"
#endif
#if CIRCUITPY_USB_MIDI
#include "shared-module/usb_midi/__init__.h"
#endif
@ -189,6 +193,10 @@ STATIC void start_mp(supervisor_allocation* heap) {
usb_cdc_init();
#endif
#if CIRCUITPY_USB_HID
usb_hid_init();
#endif
#if CIRCUITPY_USB_MIDI
usb_midi_init();
#endif

View File

@ -36,6 +36,13 @@
#define MICROPY_BYTES_PER_GC_BLOCK (32)
// CXD56 architecture uses fixed endpoint numbers
#define USB_CDC_EP_NUM_NOTIFICATION (3)
#define USB_CDC_EP_NUM_DATA_OUT (2)
#define USB_CDC_EP_NUM_DATA_IN (2)
#define USB_MSC_EP_NUM_OUT (5)
#define USB_MSC_EP_NUM_IN (4)
#define MICROPY_PORT_ROOT_POINTERS \
CIRCUITPY_COMMON_ROOT_POINTERS \

View File

@ -1,10 +1,4 @@
USB_HIGHSPEED = 1
USB_RENUMBER_ENDPOINTS = 0
USB_CDC_EP_NUM_NOTIFICATION = 3
USB_CDC_EP_NUM_DATA_OUT = 2
USB_CDC_EP_NUM_DATA_IN = 1
USB_MSC_EP_NUM_OUT = 5
USB_MSC_EP_NUM_IN = 4
# Number of USB endpoint pairs.
USB_NUM_EP = 6

View File

@ -992,4 +992,57 @@ void supervisor_run_background_tasks_if_tick(void);
#define CIRCUITPY_VERBOSE_BLE 0
// USB settings
// If the port requires certain USB endpoint numbers, define these in mpconfigport.h.
#ifndef USB_CDC_EP_NUM_NOTIFICATION
#define USB_CDC_EP_NUM_NOTIFICATION (0)
#endif
#ifndef USB_CDC_EP_NUM_DATA_OUT
#define USB_CDC_EP_NUM_DATA_OUT (0)
#endif
#ifndef USB_CDC_EP_NUM_DATA_IN
#define USB_CDC_EP_NUM_DATA_IN (0)
#endif
#ifndef USB_CDC2_EP_NUM_NOTIFICATION
#define USB_CDC2_EP_NUM_NOTIFICATION (0)
#endif
#ifndef USB_CDC2_EP_NUM_DATA_OUT
#define USB_CDC2_EP_NUM_DATA_OUT (0)
#endif
#ifndef USB_CDC2_EP_NUM_DATA_IN
#define USB_CDC2_EP_NUM_DATA_IN (0)
#endif
#ifndef USB_MSC_EP_NUM_OUT
#define USB_MSC_EP_NUM_OUT (0)
#endif
#ifndef USB_MSC_EP_NUM_IN
#define USB_MSC_EP_NUM_IN (0)
#endif
#ifndef USB_HID_EP_NUM_OUT
#define USB_HID_EP_NUM_OUT (0)
#endif
#ifndef USB_HID_EP_NUM_IN
#define USB_HID_EP_NUM_IN (0)
#endif
#ifndef USB_MIDI_EP_NUM_OUT
#define USB_MIDI_EP_NUM_OUT (0)
#endif
#ifndef USB_MIDI_EP_NUM_IN
#define USB_MIDI_EP_NUM_IN (0)
#endif
#endif // __INCLUDED_MPCONFIG_CIRCUITPY_H

View File

@ -271,6 +271,9 @@ CFLAGS += -DCIRCUITPY_RGBMATRIX=$(CIRCUITPY_RGBMATRIX)
CIRCUITPY_ROTARYIO ?= 1
CFLAGS += -DCIRCUITPY_ROTARYIO=$(CIRCUITPY_ROTARYIO)
CIRCUITPY_ROTARYIO_SOFTENCODER ?= 0
CFLAGS += -DCIRCUITPY_ROTARYIO_SOFTENCODER=$(CIRCUITPY_ROTARYIO_SOFTENCODER)
CIRCUITPY_RTC ?= 1
CFLAGS += -DCIRCUITPY_RTC=$(CIRCUITPY_RTC)
@ -366,6 +369,7 @@ CFLAGS += -DCIRCUITPY_USB_VENDOR=$(CIRCUITPY_USB_VENDOR)
ifndef USB_NUM_EP
$(error "USB_NUM_EP (number of USB endpoint pairs)must be defined")
endif
CFLAGS += -DUSB_NUM_EP=$(USB_NUM_EP)
# For debugging.
CIRCUITPY_USTACK ?= 0

View File

@ -30,6 +30,8 @@
#include <stdint.h>
#include <stdbool.h>
#include "shared-module/storage/__init__.h"
void common_hal_storage_mount(mp_obj_t vfs_obj, const char *path, bool readonly);
void common_hal_storage_umount_path(const char *path);
void common_hal_storage_umount_object(mp_obj_t vfs_obj);

View File

@ -44,7 +44,7 @@
//| """Create a description of a USB HID device. To create an actual device,
//| pass a `Device` to `usb_hid.configure_usb()`.
//|
//| :param ReadableBuffer descriptor: The USB HID Report descriptor bytes. The descriptor is not
//| :param ReadableBuffer report_descriptor: The USB HID Report descriptor bytes. The descriptor is not
//| not verified for correctness; it is up to you to make sure it is not malformed.
//| :param int usage_page: The Usage Page value from the descriptor. Must match what is in the descriptor.
//| :param int usage: The Usage value from the descriptor. Must match what is in the descriptor.
@ -60,9 +60,9 @@
STATIC mp_obj_t usb_hid_device_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
usb_hid_device_obj_t *self = m_new_obj(usb_hid_device_obj_t);
self->base.type = &usb_hid_device_type;
enum { ARG_descriptor, ARG_usage, ARG_usage_page, ARG_in_report_length, ARG_out_report_length, ARG_report_id_index };
enum { ARG_report_descriptor, ARG_usage, ARG_usage_page, ARG_in_report_length, ARG_out_report_length, ARG_report_id_index };
static const mp_arg_t allowed_args[] = {
{ MP_QSTR_descriptor, MP_ARG_KW_ONLY | MP_ARG_REQUIRED | MP_ARG_OBJ },
{ MP_QSTR_report_descriptor, MP_ARG_KW_ONLY | MP_ARG_REQUIRED | MP_ARG_OBJ },
{ MP_QSTR_usage_page, MP_ARG_KW_ONLY | MP_ARG_REQUIRED | MP_ARG_INT },
{ MP_QSTR_usage, MP_ARG_KW_ONLY | MP_ARG_REQUIRED | MP_ARG_INT },
{ MP_QSTR_in_report_length, MP_ARG_KW_ONLY | MP_ARG_REQUIRED | MP_ARG_INT } ,
@ -74,7 +74,7 @@ STATIC mp_obj_t usb_hid_device_make_new(const mp_obj_type_t *type, size_t n_args
mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
mp_buffer_info_t bufinfo;
mp_get_buffer_raise(args[ARG_descriptor].u_obj, &bufinfo, MP_BUFFER_READ);
mp_get_buffer_raise(args[ARG_report_descriptor].u_obj, &bufinfo, MP_BUFFER_READ);
mp_obj_t descriptor = mp_obj_new_bytearray(bufinfo.len, bufinfo.buf);
const mp_int_t usage_page_arg = args[ARG_usage_page].u_int;

View File

@ -67,17 +67,25 @@ STATIC mp_obj_t usb_hid_configure_usb(mp_obj_t devices) {
}
MP_DEFINE_CONST_FUN_OBJ_1(usb_hid_configure_usb_obj, usb_hid_configure_usb);
STATIC const mp_rom_map_elem_t usb_hid_module_globals_table[] = {
// usb_hid.devices is set once the usb devices are determined, after boot.py runs.
STATIC mp_map_elem_t usb_hid_module_globals_table[] = {
{ MP_ROM_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_usb_hid) },
{ MP_ROM_QSTR(MP_QSTR_configure_usb), MP_OBJ_FROM_PTR(&usb_hid_configure_usb_obj) },
{ MP_ROM_QSTR(MP_QSTR_devices), MP_ROM_PTR(&common_hal_usb_hid_devices) },
{ MP_ROM_QSTR(MP_QSTR_Device), MP_ROM_PTR(&usb_hid_device_type) },
{ MP_ROM_QSTR(MP_QSTR_devices), mp_const_none },
{ MP_ROM_QSTR(MP_QSTR_Device), MP_OBJ_FROM_PTR(&usb_hid_device_type) },
};
STATIC MP_DEFINE_CONST_DICT(usb_hid_module_globals, usb_hid_module_globals_table);
STATIC MP_DEFINE_MUTABLE_DICT(usb_hid_module_globals, usb_hid_module_globals_table);
const mp_obj_module_t usb_hid_module = {
.base = { &mp_type_module },
.globals = (mp_obj_dict_t *)&usb_hid_module_globals,
};
void usb_hid_set_devices(mp_obj_t devices) {
mp_map_elem_t *elem =
mp_map_lookup(&usb_hid_module_globals.map, MP_ROM_QSTR(MP_QSTR_devices), MP_MAP_LOOKUP);
if (elem) {
elem->value = devices;
}
}

View File

@ -29,9 +29,12 @@
#include "py/obj.h"
#include "py/objtuple.h"
#include "shared-module/usb_hid/__init__.h"
extern mp_obj_tuple_t common_hal_usb_hid_devices;
void usb_hid_set_devices(mp_obj_t devices);
void common_hal_usb_hid_configure_usb_defaults(void);
bool common_hal_usb_hid_configure_usb(mp_obj_t devices_seq);

View File

@ -28,6 +28,7 @@
#define MICROPY_INCLUDED_SHARED_BINDINGS_USB_MIDI___INIT___H
#include "py/obj.h"
#include "shared-module/usb_midi/__init__.h"
extern mp_obj_dict_t usb_midi_module_globals;

View File

@ -41,7 +41,7 @@
#include "supervisor/usb.h"
#include "tusb.h"
static const uint8_t storage_usb_msc_descriptor_template[] = {
static const uint8_t usb_msc_descriptor_template[] = {
// MSC Interface Descriptor
0x09, // 0 bLength
0x04, // 1 bDescriptorType (Interface)
@ -75,28 +75,32 @@ static const uint8_t storage_usb_msc_descriptor_template[] = {
};
// Is the MSC device enabled?
bool storage_usb_enabled;
bool storage_usb_is_enabled;
size_t storage_usb_descriptor_length(void) {
return sizeof(usb_msc_descriptor);
bool storage_usb_enabled(void) {
return storage_usb_is_enabled;
}
static const char[] storage_interface_name = MP_STRINGIFY(USB_INTERFACE_NAME) " Mass Storage";
size_t storage_usb_descriptor_length(void) {
return sizeof(usb_msc_descriptor_template);
}
static const char storage_interface_name[] = USB_INTERFACE_NAME " Mass Storage";
size_t storage_usb_add_descriptor(uint8_t *descriptor_buf, uint8_t *current_interface, uint8_t *current_endpoint, uint8_t* current_interface_string) {
memcpy(descriptor_buf, storage_usb_msc_descriptor_template, sizeof(storage_usb_msc_descriptor_template));
memcpy(descriptor_buf, usb_msc_descriptor_template, sizeof(usb_msc_descriptor_template));
descriptor_buf[MSC_INTERFACE_INDEX] = *current_interface;
(*current_interface)++;
descriptor_buf[MSC_IN_ENDPOINT_INDEX] = USB_MSC_EP_NUM_IN ? USB_MSC_EP_NUM_IN : *current_endpoint;
descriptor_buf[MSC_OUT_ENDPOINT_INDEX] = 0x80 | (USB_MSC_EP_NUM_OUT ? USB_MSC_EP_NUM_OUT : *current_endpoint);
(*current_endpoint)++:
(*current_endpoint)++;
usb_add_interface_string(*current_interface_string,);
usb_add_interface_string(*current_interface_string, storage_interface_name);
descriptor_buf[MSC_INTERFACE_STRING_INDEX] = *current_interface_string;
(*current_interface_string)++;
return sizeof(storage_usb_msc_descriptor_template);
return sizeof(usb_msc_descriptor_template);
}
@ -118,7 +122,7 @@ STATIC mp_obj_t mp_vfs_proxy_call(mp_vfs_mount_t *vfs, qstr meth_name, size_t n_
}
void storage_init(void) {
storage_usb_enabled = true;
storage_usb_is_enabled = true;
}
void common_hal_storage_mount(mp_obj_t vfs_obj, const char *mount_path, bool readonly) {
@ -238,6 +242,6 @@ bool common_hal_storage_configure_usb(bool enabled) {
if (tud_connected()) {
return false;
}
storage_usb_enabled = enabled;
storage_usb_is_enabled = enabled;
return true;
}

View File

@ -27,7 +27,7 @@
#ifndef SHARED_MODULE_STORAGE___INIT___H
#define SHARED_MODULE_STORAGE___INIT___H
extern bool storage_usb_enabled;
bool storage_usb_enabled(void);
void storage_init(void);
size_t storage_usb_descriptor_length(void);

View File

@ -37,9 +37,6 @@
#error CFG_TUD_CDC must be exactly 2
#endif
bool usb_cdc_repl_enabled;
bool usb_cdc_data_enabled;
static const uint8_t usb_cdc_descriptor_template[] = {
// CDC IAD Descriptor
0x08, // 0 bLength
@ -135,10 +132,10 @@ static const uint8_t usb_cdc_descriptor_template[] = {
0x00, // 65 bInterval 0 (unit depends on device speed)
};
static const char[] repl_cdc_comm_interface_name = MP_STRINGIFY(USB_INTERFACE_NAME) " CDC control";
static const char[] data_cdc_comm_interface_name = MP_STRINGIFY(USB_INTERFACE_NAME) " CDC2 control";
static const char[] repl_cdc_data_interface_name = MP_STRINGIFY(USB_INTERFACE_NAME) " CDC data";
static const char[] data_cdc_data_interface_name = MP_STRINGIFY(USB_INTERFACE_NAME) " CDC2 data";
static const char[] repl_cdc_comm_interface_name = USB_INTERFACE_NAME " CDC control";
static const char[] data_cdc_comm_interface_name = USB_INTERFACE_NAME " CDC2 control";
static const char[] repl_cdc_data_interface_name = USB_INTERFACE_NAME " CDC data";
static const char[] data_cdc_data_interface_name = USB_INTERFACE_NAME " CDC2 data";
static usb_cdc_serial_obj_t usb_cdc_repl_obj = {
.base.type = &usb_cdc_serial_type,
@ -154,6 +151,17 @@ static usb_cdc_serial_obj_t usb_cdc_data_obj = {
.idx = 1,
};
static bool usb_cdc_repl_is_enabled;
static bool usb_cdc_data_is_enabled;
bool usb_cdc_repl_enabled(void) {
return usb_cdc_repl_is_enabled;
}
bool usb_cdc_data_enabled(void) {
return usb_cdc_data_enabled;
}
size_t usb_cdc_descriptor_length(void) {
return sizeof(usb_cdc_descriptor_template);
}
@ -200,8 +208,8 @@ size_t usb_cdc_add_descriptor(uint8_t *descriptor_buf, uint8_t *current_interfac
}
void usb_cdc_init(void) {
usb_cdc_repl_enabled = true;
usb_cdc_data_enabled = false;
usb_cdc_repl_is_enabled = true;
usb_cdc_data_is_enabled = false;
}
bool common_hal_usb_cdc_configure_usb(bool repl_enabled, bool data_enabled) {

View File

@ -29,8 +29,8 @@
#include "py/objtuple.h"
extern bool usb_cdc_repl_enabled;
extern bool usb_cdc_data_enabled;
bool usb_cdc_repl_enabled(void);
bool usb_cdc_data_enabled(void);
void usb_cdc_init(void);
size_t usb_cdc_descriptor_length(void);

View File

@ -28,12 +28,13 @@
#include "py/runtime.h"
#include "shared-bindings/usb_hid/Device.h"
#include "shared-module/usb_hid/__init__.h"
#include "shared-module/usb_hid/Device.h"
#include "supervisor/shared/translate.h"
#include "supervisor/shared/tick.h"
#include "tusb.h"
static const uint8_t keyboard_descriptor[] = {
static const uint8_t keyboard_report_descriptor[] = {
0x05, 0x01, // 0,1 Usage Page (Generic Desktop Ctrls)
0x09, 0x06, // 2,3 Usage (Keyboard)
0xA1, 0x01, // 4,5 Collection (Application)
@ -69,9 +70,9 @@ static const uint8_t keyboard_descriptor[] = {
};
const usb_hid_device_obj_t usb_hid_device_keyboard_obj = {
.descriptor = keyboard_descriptor,
.descriptor_length = sizeof(keyboard_descriptor),
.usage_page = 0x01
.report_descriptor = keyboard_report_descriptor,
.report_descriptor_length = sizeof(keyboard_report_descriptor),
.usage_page = 0x01,
.usage = 0x06,
.in_report_length = 8,
.out_report_length = 1,
@ -79,7 +80,7 @@ const usb_hid_device_obj_t usb_hid_device_keyboard_obj = {
};
static const uint8_t mouse_descriptor[] = {
static const uint8_t mouse_report_descriptor[] = {
0x05, 0x01, // 0,1 Usage Page (Generic Desktop Ctrls)
0x09, 0x02, // 2,3 Usage (Mouse)
0xA1, 0x01, // 4,5 Collection (Application)
@ -117,17 +118,16 @@ static const uint8_t mouse_descriptor[] = {
};
const usb_hid_device_obj_t usb_hid_device_mouse_obj = {
.descriptor = mouse_descriptor,
.descriptor_length = sizeof(mouse_descriptor),
.usage_page = 0x01
.report_descriptor = mouse_report_descriptor,
.report_descriptor_length = sizeof(mouse_report_descriptor),
.usage_page = 0x01,
.usage = 0x02,
.in_report_length = 4,
.out_report_length = 0,
.descriptor = {
.report_id_index = MOUSE_REPORT_ID_INDEX,
};
static const uint8_t consumer_control_descriptor[] = {
static const uint8_t consumer_control_report_descriptor[] = {
0x05, 0x0C, // 0,1 Usage Page (Consumer)
0x09, 0x01, // 2,3 Usage (Consumer Control)
0xA1, 0x01, // 4,5 Collection (Application)
@ -144,9 +144,9 @@ static const uint8_t consumer_control_descriptor[] = {
};
const usb_hid_device_obj_t usb_hid_device_consumer_control_obj = {
.descriptor = consumer_control_descriptor,
.descriptor_length = sizeof(consumer_control_descriptor),
.usage_page = 0x0C
.report_descriptor = consumer_control_report_descriptor,
.report_descriptor_length = sizeof(consumer_control_report_descriptor),
.usage_page = 0x0C,
.usage = 0x01,
.in_report_length = 2,
.out_report_length = 0,
@ -154,14 +154,14 @@ const usb_hid_device_obj_t usb_hid_device_consumer_control_obj = {
};
void common_hal_usb_hid_device_construct(usb_hid_device_obj_t *self, mp_obj_t descriptor, uint8_t usage_page, uint8_t usage, uint8_t in_report_length, uint8_t out_report_length, uint8_t report_id_index) {
void common_hal_usb_hid_device_construct(usb_hid_device_obj_t *self, mp_obj_t report_descriptor, uint8_t usage_page, uint8_t usage, uint8_t in_report_length, uint8_t out_report_length, uint8_t report_id_index) {
// report buffer pointers are NULL at start, and are created on demand.
self->descriptor_obj = descriptor;
self->report_descriptor_obj = report_descriptor;
mp_buffer_info_t bufinfo;
mp_get_buffer_raise(descriptor, &bufinfo, MP_BUFFER_READ);
self->descriptor = bufinfo.buf;
self->descriptor_length = bufinfo.len;
mp_get_buffer_raise(report_descriptor, &bufinfo, MP_BUFFER_READ);
self->report_descriptor = bufinfo.buf;
self->report_descriptor_length = bufinfo.len;
self->usage_page = usage_page;
self->usage = usage;
@ -195,20 +195,11 @@ void common_hal_usb_hid_device_send_report(usb_hid_device_obj_t *self, uint8_t *
memcpy(self->in_report_buffer, report, len);
if (!tud_hid_report(self->in_report_id, self->in_report_buffer, len)) {
if (!tud_hid_report(self->report_id, self->in_report_buffer, len)) {
mp_raise_msg(&mp_type_OSError, translate("USB Error"));
}
}
static usb_hid_device_obj_t *get_hid_device(uint8_t report_id) {
for (uint8_t i = 0; i < USB_HID_NUM_DEVICES; i++) {
if (usb_hid_devices[i].report_id == report_id) {
return &usb_hid_devices[i];
}
}
return NULL;
}
// Callbacks invoked when receive Get_Report request through control endpoint
uint16_t tud_hid_get_report_cb(uint8_t itf, uint8_t report_id, hid_report_type_t report_type, uint8_t *buffer, uint16_t reqlen) {
(void)itf;
@ -218,7 +209,7 @@ uint16_t tud_hid_get_report_cb(uint8_t itf, uint8_t report_id, hid_report_type_t
}
// fill buffer with current report
memcpy(buffer, get_hid_device(report_id)->in_report_buffer, reqlen);
memcpy(buffer, usb_hid_get_device_with_report_id(report_id)->in_report_buffer, reqlen);
return reqlen;
}
@ -233,7 +224,7 @@ void tud_hid_set_report_cb(uint8_t itf, uint8_t report_id, hid_report_type_t rep
return;
}
usb_hid_device_obj_t *hid_device = get_hid_device(report_id);
usb_hid_device_obj_t *hid_device = usb_hid_get_device_with_report_id(report_id);
if (hid_device && hid_device->out_report_length >= bufsize) {
memcpy(hid_device->out_report_buffer, buffer, bufsize);

View File

@ -35,13 +35,13 @@
typedef struct {
mp_obj_base_t base;
// If not MP_OBJ_NULL, points to Python array object whose contents are the descriptor.
mp_obj_t descriptor_obj;
mp_obj_t report_descriptor_obj;
// If not NULL, points to raw bytes that are the descriptor.
uint8_t *descriptor;
const uint8_t *report_descriptor;
uint8_t *in_report_buffer;
uint8_t *out_report_buffer;
uint16_t report_id_index;
uint16_t descriptor_length;
uint16_t report_descriptor_length;
uint8_t usage_page;
uint8_t usage;
uint8_t report_id;
@ -49,8 +49,8 @@ typedef struct {
uint8_t out_report_length;
} usb_hid_device_obj_t;
extern usb_hid_device_obj_t usb_hid_device_keyboard_obj;
extern usb_hid_device_obj_t usb_hid_device_mouse_obj;
extern usb_hid_device_obj_t usb_hid_device_consumer_control_obj;
extern const usb_hid_device_obj_t usb_hid_device_keyboard_obj;
extern const usb_hid_device_obj_t usb_hid_device_mouse_obj;
extern const usb_hid_device_obj_t usb_hid_device_consumer_control_obj;
#endif /* SHARED_MODULE_USB_HID_DEVICE_H */

View File

@ -26,70 +26,106 @@
#include <string.h>
#include "shared-module/usb_hid/__init__.h"
#include "tusb.h"
#include "py/gc.h"
#include "shared-bindings/usb_hid/__init__.h"
#include "shared-module/usb_hid/Device.h"
#include "supervisor/memory.h"
#include "supervisor/usb.h"
static const uint8_t usb_hid_descriptor_template[] = {
0x09, // 0 bLength
0x21, // 1 bDescriptorType (HID)
0x11, 0x01, // 2 bcdHID 1.11
0x00, // 3 bCountryCode
0x01, // 4 bNumDescriptors
0x22, // 5 bDescriptorType[0] (HID)
0xFF, 0xFF, // 6,7 wDescriptorLength[0] [SET AT RUNTIME: lo, hi]
#define HID_DESCRIPTOR_LENGTH_INDEX (6)
0x04, // 1 bDescriptorType (Interface)
0xFF, // 2 bInterfaceNumber 3
#define HID_DESCRIPTOR_INTERFACE_INDEX (2)
0x00, // 3 bAlternateSetting
0x02, // 4 bNumEndpoints 2
0x03, // 5 bInterfaceClass: HID
0x00, // 6 bInterfaceSubClass: NOBOOT
0x00, // 7 bInterfaceProtocol: NONE
0xFF, // 8 iInterface (String Index) [SET AT RUNTIME]
#define HID_DESCRIPTOR_INTERFACE_STRING_INDEX (8)
0x07, // 8 bLength
0x05, // 9 bDescriptorType (Endpoint)
0xFF, // 10 bEndpointAddress (IN/D2H) [SET AT RUNTIME: 0x80 | endpoint]
#define HID_IN_ENDPOINT_INDEX (10)
0x03, // 11 bmAttributes (Interrupt)
0x40, 0x00, // 12,13 wMaxPacketSize 64
0x08, // 14 bInterval 8 (unit depends on device speed)
0x09, // 9 bLength
0x21, // 10 bDescriptorType (HID)
0x11, 0x01, // 11,12 bcdHID 1.11
0x00, // 13 bCountryCode
0x01, // 14 bNumDescriptors
0x22, // 15 bDescriptorType[0] (HID)
0xFF, 0xFF, // 16,17 wDescriptorLength[0] [SET AT RUNTIME: lo, hi]
#define HID_DESCRIPTOR_LENGTH_INDEX (16)
0x07, // 15 bLength
0x05, // 16 bDescriptorType (Endpoint)
0xFF, // 17 bEndpointAddress (OUT/H2D) [SET AT RUNTIME]
#define HID_OUT_ENDPOINT_INDEX (17)
0x03, // 18 bmAttributes (Interrupt)
0x40, 0x00, // 19,20 wMaxPacketSize 64
0x08, // 21 bInterval 8 (unit depends on device speed)
0x07, // 18 bLength
0x05, // 19 bDescriptorType (Endpoint)
0xFF, // 20 bEndpointAddress (IN/D2H) [SET AT RUNTIME: 0x80 | endpoint]
#define HID_IN_ENDPOINT_INDEX (20)
0x03, // 21 bmAttributes (Interrupt)
0x40, 0x00, // 22,23 wMaxPacketSize 64
0x08, // 24 bInterval 8 (unit depends on device speed)
0x07, // 25 bLength
0x05, // 26 bDescriptorType (Endpoint)
0xFF, // 27 bEndpointAddress (OUT/H2D) [SET AT RUNTIME]
#define HID_OUT_ENDPOINT_INDEX (26)
0x03, // 28 bmAttributes (Interrupt)
0x40, 0x00, // 29,30 wMaxPacketSize 64
0x08, // 31 bInterval 8 (unit depends on device speed)
};
// Sequence of devices to configure.
// Sequence of devices to configure. Passed to usb_hid.configure_usb().
// Not used after boot.py finishes and VM restarts.
static mp_obj_t hid_devices_seq;
// Is the HID device enabled?
bool usb_hid_enabled;
supervisor_allocation *hid_report_descriptor_allocation;
supervisor_allocation *hid_devices_allocation;
static bool usb_hid_is_enabled;
static supervisor_allocation *hid_report_descriptor_allocation;
static size_t total_hid_report_descriptor_length;
static supervisor_allocation *hid_devices_allocation;
static mp_int_t hid_devices_num;
// This is the interface descriptor, not the report descriptor.
size_t usb_hid_descriptor_length(void) {
return sizeof(usb_hid_descriptor_template);
}
static const char usb_hid_interface_name[] = MP_STRINGIFY(USB_INTERFACE_NAME) " HID";
// Total length of the report descriptor, with all configured devices.
size_t usb_hid_report_descriptor_length(void) {
return total_hid_report_descriptor_length;
}
bool usb_hid_enabled(void) {
return usb_hid_is_enabled;
}
static const char usb_hid_interface_name[] = USB_INTERFACE_NAME " HID";
// This is the interface descriptor, not the report descriptor.
size_t usb_hid_add_descriptor(uint8_t *descriptor_buf, uint8_t *current_interface, uint8_t *current_endpoint, uint8_t* current_interface_string, uint16_t report_descriptor_length) {
memcpy(descriptor_buf, usb_hid_descriptor_template, sizeof(usb_hid_descriptor_template));
descriptor_buf[HID_DESCRIPTOR_INTERFACE_INDEX] = *current_interface;
(*current_interface)++;
usb_add_interface_string(*current_interface, usb_hid_interface_name);
descriptor_buf[HID_DESCRIPTOR_INTERFACE_STRING_INDEX] = *current_interface_string;
(*current_interface_string)++;
descriptor_buf[HID_DESCRIPTOR_LENGTH_INDEX] = report_descriptor_length & 0xFF;
descriptor_buf[HID_DESCRIPTOR_LENGTH_INDEX + 1] = (report_descriptor_length >> 8);
descriptor_buf[HID_IN_ENDPOINT_INDEX] = USB_HID_EP_NUM_IN ? USB_HID_EP_NUM_IN : *current_endpoint;
descriptor_buf[HID_OUT_ENDPOINT_INDEX] = 0x80 | (USB_HID_EP_NUM_OUT ? USB_HID_EP_NUM_OUT : *current_endpoint);
(*current_endpoint)++:
(*current_endpoint)++;
return sizeof(usb_hid_descriptor_template);
}
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),
MP_OBJ_FROM_PTR(usb_hid_device_consumer_control_obj),
MP_OBJ_FROM_PTR(&usb_hid_device_keyboard_obj),
MP_OBJ_FROM_PTR(&usb_hid_device_mouse_obj),
MP_OBJ_FROM_PTR(&usb_hid_device_consumer_control_obj),
};
// Set the default list of devices that will be included. Called before boot.py runs, in the boot.py VM.
@ -97,78 +133,79 @@ 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) {
bool common_hal_usb_hid_configure_usb(mp_obj_t devices) {
// We can't change the devices once we're connected.
if (tud_connected()) {
return false;
}
// Remember the devices for use in usb_hid_post_boot_py.
hid_devices_seq = devices_seq;
hid_devices_seq = devices;
return true;
}
void usb_hid_init(void) {
usb_hid_is_enabled = 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(hid_devices_seq));
hid_devices_num = mp_obj_get_int(mp_obj_len(hid_devices_seq));
// First get the total size.
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)) {
return USB_CONFIG_NON_DEVICE; for (size_t i = 0; i < len; i++) {
mp_obj_t item = (devices, mp_obj_new_small_int(i), MP_OBJ_SENTINEL);
if (!MP_OBJ_IS_TYPE(item, &usb_hid_device_type)) {
return USB_CONFIG_NON_DEVICE;
}
total_report_descriptors_length += device->report_descriptor_length;
total_hid_report_descriptor_length = 0;
for (mp_int_t i = 0; i < hid_devices_num; i++) {
// hid_devices_seq has already been validated to contain only usb_hid_device_obj_t objects.
usb_hid_device_obj_t *device =
MP_OBJ_TO_PTR(mp_obj_subscr(hid_devices_seq, MP_OBJ_NEW_SMALL_INT(i), MP_OBJ_SENTINEL));
total_hid_report_descriptor_length += device->report_descriptor_length;
}
}
total_report_descriptors_length += device->report_descriptor_length;
}
if (len == 1) {
// Don't need space for a report id if there's only one device.
total_report_descriptors_length -= 2;
// Don't need space for a report id if there's only one device.
if (hid_devices_num == 1) {
total_hid_report_descriptor_length -= 2;
}
// Allocate storage that persists across VMs to build the combined descriptor
// and to remember the device details.
hid_report_descriptor_allocation =
allocate_memory(total_report_descriptors_length, false /*highaddress*/, true /*movable*/);
allocate_memory(align32_size(total_hid_report_descriptor_length),
false /*highaddress*/, true /*movable*/);
hid_devices_allocation = allocate_memory(sizeof(usb_hid_device_obj_t) * len);
usb_hid_device_obj_t hid_devices[] = (usb_hid_device_obj_t[]) hid_devices_allocation->ptr;
hid_devices_allocation =
allocate_memory(align32_size(sizeof(usb_hid_device_obj_t) * hid_devices_num),
false /*highaddress*/, true /*movable*/);
usb_hid_device_obj_t *hid_devices = (usb_hid_device_obj_t *) hid_devices_allocation->ptr;
uint8_t *descriptor_start = (uint8_t *) hid_report_descriptor_allocation->ptr;
uint8_t *report_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(hid_devices_seq, mp_obj_new_small_int(i), MP_OBJ_SENTINEL);
for (mp_int_t i = 0; i < hid_devices_num; i++) {
usb_hid_device_obj_t *device =
MP_OBJ_TO_PTR(mp_obj_subscr(hid_devices_seq, MP_OBJ_NEW_SMALL_INT(i), MP_OBJ_SENTINEL));
// Copy the report descriptor for this device.
if (len == 1) {
if (hid_devices_num == 1) {
// Theres only one device, so it shouldn't have a report ID.
// Copy the descriptor, but splice out the report id indicator and value (2 bytes).
memcpy(descriptor_start, device->descriptor, device->report_id_index - 1);
descriptor_start += device->report_id_index - 1;
memcpy(descriptor_start, device->descriptor + device->report_id_index + 1,
memcpy(report_descriptor_start, device->report_descriptor, device->report_id_index - 1);
report_descriptor_start += device->report_id_index - 1;
memcpy(report_descriptor_start, device->report_descriptor + device->report_id_index + 1,
device->report_descriptor_length - device->report_id_index - 1);
} else {
// Copy the whole descriptor and fill in the report id.
memcpy(descriptor_start, device->descriptor, device->descriptor_len);
descriptor_start[device->report_id_index] = i + 1;
descriptor_start += device->descriptor_len;
memcpy(report_descriptor_start, device->report_descriptor, device->report_descriptor_length);
report_descriptor_start[device->report_id_index] = i + 1;
report_descriptor_start += device->report_descriptor_length;
}
// Copy the device data and discard any descriptor-bytes object pointer.
memcpy(&hid_devices[i], device, sizeof(usb_hid_device_obj_t));
hid_devices[i].descriptor_obj = mp_const_none;
hid_devices[i].report_descriptor_obj = mp_const_none;
}
// No longer keeping the Python object of devices to configure.
@ -176,13 +213,31 @@ void usb_hid_post_boot_py(void) {
}
void usb_hid_gc_collect(void) {
// Once tud_mounted() is true, we're done with the constructed descriptors.
if (tud_mounted()) {
// Once tud_mounted() is true, we're done with the constructed descriptors.
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_ptr);
}
gc_collect_ptr(hid_devices_seq);
gc_collect_ptr(hid_report_descriptor_allocation->ptr);
gc_collect_ptr(hid_devices_allocation->ptr);
}
#if CIRCUITPY_USB_HID
// Invoked when GET HID REPORT DESCRIPTOR is received.
// Application return pointer to descriptor
// Descriptor contents must exist long enough for transfer to complete
uint8_t const *tud_hid_descriptor_report_cb(uint8_t itf) {
return (uint8_t *) hid_report_descriptor_allocation->ptr;
}
#endif
usb_hid_device_obj_t *usb_hid_get_device_with_report_id(uint8_t report_id) {
for (uint8_t i = 0; i < hid_devices_num; i++) {
usb_hid_device_obj_t *hid_devices = (usb_hid_device_obj_t *) hid_devices_allocation->ptr;
if (hid_devices[i].report_id == report_id) {
return &hid_devices[i];
}
}
return NULL;
}

View File

@ -29,10 +29,19 @@
#include "shared-module/usb_hid/Device.h"
extern bool usb_hid_enabled;
extern usb_hid_device_obj_t usb_hid_devices[];
bool usb_hid_enabled(void);
void usb_hid_init(void);
void usb_hid_post_boot_py(void);
size_t usb_hid_add_descriptor(uint8_t *descriptor_buf, uint8_t *current_interface, uint8_t *current_endpoint, uint8_t* current_interface_string, uint16_t report_descriptor_length);
size_t usb_hid_descriptor_length(void);
size_t usb_hid_report_descriptor_length(void);
usb_hid_device_obj_t *usb_hid_get_device_with_report_id(uint8_t report_id);
void usb_hid_gc_collect(void);
#endif // SHARED_MODULE_USB_HID___INIT___H

View File

@ -33,6 +33,7 @@
#include "shared-bindings/usb_midi/PortIn.h"
#include "shared-bindings/usb_midi/PortOut.h"
#include "supervisor/memory.h"
#include "supervisor/usb.h"
#include "tusb.h"
supervisor_allocation *usb_midi_allocation;
@ -79,7 +80,7 @@ static const uint8_t usb_midi_descriptor_template[] = {
0x24, // 28 bDescriptorType: CLASS SPECIFIC INTERFACE
0x01, // 29 bDescriptorSubtype: MIDI STREAMING HEADER
0x00, 0x01, // 30,31 bsdMSC (MIDI STREAMING) version 1.0
0x25, 0x00 // 32,33 wLength
0x25, 0x00, // 32,33 wLength
// MIDI Embedded In Jack Descriptor
0x06, // 34 bLength
@ -155,17 +156,21 @@ static const uint8_t usb_midi_descriptor_template[] = {
};
// Is the USB MIDI device enabled?
bool usb_midi_enabled;
static bool usb_midi_is_enabled;
bool usb_midi_enabled(void) {
return usb_midi_is_enabled;
}
size_t usb_midi_descriptor_length(void) {
return sizeof(usb_midi_descriptor_template);
}
static const char[] midi_streaming_interface_name = MP_STRINGIFY(USB_INTERFACE_NAME) " MIDI";
static const char[] midi_audio_control_interface_name = MP_STRINGIFY(USB_INTERFACE_NAME) " Audio";
static const char[] midi_in_jack_name = MP_STRINGIFY(USB_INTERFACE_NAME) " usb_midi.ports[0]";
static const char[] midi_out_jack_name = MP_STRINGIFY(USB_INTERFACE_NAME) " usb_midi.ports[0]";
static const char midi_streaming_interface_name[] = USB_INTERFACE_NAME " MIDI";
static const char midi_audio_control_interface_name[] = USB_INTERFACE_NAME " Audio";
static const char midi_in_jack_name[] = USB_INTERFACE_NAME " usb_midi.ports[0]";
static const char midi_out_jack_name[] = USB_INTERFACE_NAME " usb_midi.ports[0]";
size_t usb_midi_add_descriptor(uint8_t *descriptor_buf, uint8_t *current_interface, uint8_t *current_endpoint, uint8_t* current_interface_string) {
memcpy(descriptor_buf, usb_midi_descriptor_template, sizeof(usb_midi_descriptor_template));
@ -173,8 +178,9 @@ size_t usb_midi_add_descriptor(uint8_t *descriptor_buf, uint8_t *current_interfa
descriptor_buf[MIDI_AUDIO_CONTROL_INTERFACE_NUMBER_INDEX] = *current_interface;
(*current_interface)++;
descriptor_buf[MSC_IN_ENDPOINT_INDEX] = USB_MIDI_EP_NUM_IN ? USB_MIDI_EP_NUM_IN : *current_endpoint;
descriptor_buf[MSC_OUT_ENDPOINT_INDEX] =
descriptor_buf[MIDI_STREAMING_IN_ENDPOINT_INDEX] =
USB_MIDI_EP_NUM_IN ? USB_MIDI_EP_NUM_IN : *current_endpoint;
descriptor_buf[MIDI_STREAMING_OUT_ENDPOINT_INDEX] =
0x80 | (USB_MIDI_EP_NUM_OUT ? USB_MIDI_EP_NUM_OUT : *current_endpoint);
(*current_endpoint)++;
@ -203,13 +209,13 @@ size_t usb_midi_add_descriptor(uint8_t *descriptor_buf, uint8_t *current_interfa
void usb_midi_init(void) {
usb_midi_enabled = true;
usb_midi_is_enabled = true;
}
void usb_midi_usb_init(void) {
mp_obj_tuple_t *ports;
if (usb_midi_enabled) {
if (usb_midi_is_enabled) {
// TODO(tannewt): Make this dynamic.
size_t tuple_size = align32_size(sizeof(mp_obj_tuple_t) + sizeof(mp_obj_t *) * 2);
size_t portin_size = align32_size(sizeof(usb_midi_portin_obj_t));
@ -241,6 +247,6 @@ bool common_hal_usb_midi_configure_usb(bool enabled) {
if (tud_connected()) {
return false;
}
usb_midi_enabled = enabled;
usb_midi_is_enabled = enabled;
return true;
}

View File

@ -27,11 +27,11 @@
#ifndef SHARED_MODULE_USB_MIDI___INIT___H
#define SHARED_MODULE_USB_MIDI___INIT___H
extern bool usb_midi_enabled;
void usb_midi_init(void);
void usb_midi_usb_init(void);
bool usb_midi_enabled(void);
size_t usb_midi_descriptor_length(void);
size_t usb_midi_add_descriptor(uint8_t *descriptor_buf, uint8_t *current_interface, uint8_t *current_endpoint, uint8_t* current_interface_string);

View File

@ -26,6 +26,9 @@
#include "lib/tinyusb/src/tusb.h"
#include "py/gc.h"
#include "py/objstr.h"
#include "py/runtime.h"
#include "supervisor/usb.h"
#if CIRCUITPY_USB_CDC
@ -44,20 +47,17 @@
#include "shared-bindings/storage/__init__.h"
#endif
// For COMMON_HAL_MCU_PROCESSOR_UID_LENGTH
#include "common-hal/microcontroller/Processor.h"
#include "shared-bindings/microcontroller/Processor.h"
uint8_t *device_descriptor;
uint8_t *config_descriptor;
// Table for collecting interface strings (interface names) as descriptor is built.
#define MAX_INTERFACE_STRINGS 16
// slot 0 is not used.
static char * collected_interface_strings[];
static uint16_t current_interface_string;
static uint16_t **collected_interface_strings;
static uint8_t current_interface_string;
static const char manufacturer_name[] = MP_STRINGIFY(USB_MANUFACTURER);
static const char product_name[] = MP_STRINGIFY(USB_PRODUCT);
static const char manufacturer_name[] = USB_MANUFACTURER;
static const char product_name[] = USB_PRODUCT;
// Serial number string is UID length * 2 (2 nibbles per byte) + 1 byte for null termination.
static char serial_number_hex_string[COMMON_HAL_MCU_PROCESSOR_UID_LENGTH * 2 + 1];
@ -86,6 +86,8 @@ static const uint8_t device_descriptor_template[] = {
0x01, // 17 bNumConfigurations 1
};
static uint8_t device_descriptor[sizeof(device_descriptor_template)];
static const uint8_t configuration_descriptor_template[] = {
0x09, // 0 bLength
0x02, // 1 bDescriptorType (Configuration)
@ -100,6 +102,8 @@ static const uint8_t configuration_descriptor_template[] = {
0x32, // 8 bMaxPower 100mA
};
static uint8_t configuration_descriptor[sizeof(configuration_descriptor_template)];
// 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.
@ -132,55 +136,53 @@ static void usb_build_device_descriptor(uint16_t vid, uint16_t pid) {
device_descriptor[DEVICE_PID_LO_INDEX] = pid & 0xFF;
device_descriptor[DEVICE_PID_HI_INDEX] = pid >> 8;
usb_add_interface_string(*current_interface_string, manufacturer_name);
device_descriptor[DEVICE_MANUFACTURER_STRING_INDEX] = *current_interface_string;
(*current_interface_string)++;
usb_add_interface_string(current_interface_string, manufacturer_name);
device_descriptor[DEVICE_MANUFACTURER_STRING_INDEX] = current_interface_string;
current_interface_string++;
usb_add_interface_string(*current_interface_string, product_name);
device_descriptor[DEVICE_PRODUCT_STRING_INDEX] = *current_interface_string;
(*current_interface_string)++;
usb_add_interface_string(current_interface_string, product_name);
device_descriptor[DEVICE_PRODUCT_STRING_INDEX] = current_interface_string;
current_interface_string++;
usb_add_interface_string(*current_interface_string, serial_number_hex_string);
device_descriptor[DEVICE_SERIAL_NUMBER_STRING_INDEX] = *current_interface_string;
(*current_interface_string)++;
usb_add_interface_string(current_interface_string, serial_number_hex_string);
device_descriptor[DEVICE_SERIAL_NUMBER_STRING_INDEX] = current_interface_string;
current_interface_string++;
}
static void usb_build_configuration_descriptor(uint16_t total_length, uint8_t num_interfaces) {
static void usb_build_configuration_descriptor(void) {
size_t total_descriptor_length = sizeof(configuration_descriptor_template);
// CDC should be first, for compatibility with Adafruit Windows 7 drivers.
// In the past, the order has been CDC, MSC, MIDI, HID, so preserve
// that order.
// In the past, the order has been CDC, MSC, MIDI, HID, so preserve that order.
#if CIRCUITPY_USB_CDC
if (usb_cdc_repl_enabled) {
if (usb_cdc_repl_enabled()) {
total_descriptor_length += usb_cdc_descriptor_length();
}
if (usb_cdc_data_enabled) {
if (usb_cdc_data_enabled()) {
total_descriptor_length += usb_cdc_descriptor_length();
}
#endif
#if CIRCUITPY_USB_MSC
if (storage_usb_enabled) {
if (storage_usb_enabled()) {
total_descriptor_length += storage_usb_descriptor_length();
}
#endif
#if CIRCUITPY_USB_MIDI
if (usb_midi_enabled) {
if (usb_midi_enabled()) {
total_descriptor_length += usb_midi_descriptor_length();
}
#endif
#if CIRCUITPY_USB_HID
if (usb_hid_enabled) {
if (usb_hid_enabled()) {
total_descriptor_length += usb_hid_descriptor_length();
}
#endif
// Now we now how big the configuration descriptor will be.
// 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;
configuration_descriptor[CONFIG_TOTAL_LENGTH_HI_INDEX] = (total_descriptor_length >> 8) & 0xFF;
@ -192,38 +194,39 @@ static void usb_build_configuration_descriptor(uint16_t total_length, uint8_t nu
uint8_t *descriptor_buf_remaining = configuration_descriptor + sizeof(configuration_descriptor_template);
#if CIRCUITPY_USB_CDC
if (usb_cdc_repl_enabled) {
if (usb_cdc_repl_enabled()) {
// Concatenate and fix up the CDC REPL descriptor.
descriptor_buf_remaining += usb_cdc_add_descriptor(
descriptor_buf_remaining, *current_interface, *current_endpoint, *current_interface_string, true);
descriptor_buf_remaining, &current_interface, &current_endpoint, &current_interface_string, true);
}
if (usb_cdc_data_enabled) {
if (usb_cdc_data_enabled()) {
// Concatenate and fix up the CDC data descriptor.
descriptor_buf_remaining += usb_cdc_add_descriptor(
descriptor_buf_remaining, *current_interface, *current_endpoint, *current_interface_string, false);
descriptor_buf_remaining, &current_interface, &current_endpoint, &current_interface_string, false);
}
#endif
#if CIRCUITPY_USB_MSC
if (storage_usb_enabled) {
if (storage_usb_enabled()) {
// Concatenate and fix up the MSC descriptor.
descriptor_buf_remaining += storage_usb_add_descriptor(
descriptor_buf_remaining, *current_interface, *current_endpoint, *current_interface_string);
descriptor_buf_remaining, &current_interface, &current_endpoint, &current_interface_string);
}
#endif
#if CIRCUITPY_USB_MIDI
if (usb_midi_enabled) {
if (usb_midi_enabled()) {
// Concatenate and fix up the MIDI descriptor.
descriptor_buf_remaining += usb_midi_add_descriptor(
descriptor_buf_remaining, *current_interface, *current_endpoint, *current_interface_string);
descriptor_buf_remaining, &current_interface, &current_endpoint, &current_interface_string);
}
#endif
#if CIRCUITPY_USB_HID
if (usb_hid_enabled) {
if (usb_hid_enabled()) {
descriptor_buf_remaining += usb_hid_add_descriptor(
descriptor_buf_remaining, *current_interface, *current_endpoint, *current_interface_string);
descriptor_buf_remaining, &current_interface, &current_endpoint, &current_interface_string,
usb_hid_report_descriptor_length());
}
#endif
@ -232,14 +235,14 @@ static void usb_build_configuration_descriptor(uint16_t total_length, uint8_t nu
// Did we run out of endpoints?
if (current_endpoint - 1 > USB_NUM_EP) {
mp_raise_SystemError("Not enough USB endpoints");
mp_raise_RuntimeError(translate("Not enough USB endpoints"));
}
}
void usb_add_interface_string(uint8_t interface_string_index, const char[] str) {
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");
mp_raise_RuntimeError(translate("Too many USB interface names"));
}
// 2 bytes for String Descriptor header, then 2 bytes for each character
const size_t str_len = strlen(str);
@ -247,7 +250,7 @@ void usb_add_interface_string(uint8_t interface_string_index, const char[] str)
uint16_t *string_descriptor = (uint16_t *) m_malloc(descriptor_size, false);
string_descriptor[0] = 0x0300 | descriptor_size;
// Convert to le16
for (i = 0; i <= str_len; i++) {
for (size_t i = 0; i <= str_len; i++) {
string_descriptor[i + 1] = str[i];
}
@ -261,8 +264,8 @@ 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) {
// Called in the new VM created after boot.py is run. The USB devices to be used are now chosen.
void usb_desc_init(void) {
uint8_t raw_id[COMMON_HAL_MCU_PROCESSOR_UID_LENGTH];
common_hal_mcu_processor_get_uid(raw_id);
@ -282,14 +285,12 @@ static void usb_desc_init(void) {
usb_build_device_descriptor(USB_VID, USB_PID);
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_free(device_descriptor_allocation);
gc_free(device_descriptor);
gc_free(configuration_descriptor);
} else {
gc_collect_ptr(device_descriptor);
@ -301,7 +302,7 @@ void usb_desc_gc_collect(void) {
// Invoked when GET DEVICE DESCRIPTOR is received.
// Application return pointer to descriptor
uint8_t const *tud_descriptor_device_cb(void) {
return usb_descriptor_dev;
return device_descriptor;
}
// Invoked when GET CONFIGURATION DESCRIPTOR is received.
@ -309,18 +310,9 @@ uint8_t const *tud_descriptor_device_cb(void) {
// Descriptor contents must exist long enough for transfer to complete
uint8_t const *tud_descriptor_configuration_cb(uint8_t index) {
(void)index; // for multiple configurations
return config_desc;
return configuration_descriptor;
}
#if CIRCUITPY_USB_HID
// Invoked when GET HID REPORT DESCRIPTOR is received.
// Application return pointer to descriptor
// Descriptor contents must exist long enough for transfer to complete
uint8_t const *tud_hid_descriptor_report_cb(uint8_t itf) {
return hid_report_descriptor;
}
#endif
// Invoked when GET STRING DESCRIPTOR request is received.
// Application return pointer to descriptor, whose contents must exist long enough for transfer to complete
uint16_t const *tud_descriptor_string_cb(uint8_t index, uint16_t langid) {

View File

@ -134,14 +134,16 @@ ifeq ($(CIRCUITPY_DISPLAYIO), 1)
endif
endif
# Preserve double quotes in these values by single-quoting them.
USB_INTERFACE_NAME ?= "CircuitPython"
CFLAGS += -DUSB_INTERFACE_NAME=$(USB_INTERFACE_NAME)
CFLAGS += -DUSB_INTERFACE_NAME='$(USB_INTERFACE_NAME)'
ifneq ($(USB_VID),)
CFLAGS += -DUSB_VID=$(USB_VID)
CFLAGS += -DSUB_PID=$(USB_PID)
CFLAGS += -DUSB_MANUFACTURER=$(USB_MANUFACTURER)
CFLAGS += -DUSB_PRODUCT=$(USB_PRODUCT)
CFLAGS += -DUSB_PID=$(USB_PID)
CFLAGS += -DUSB_MANUFACTURER='$(USB_MANUFACTURER)'
CFLAGS += -DUSB_PRODUCT='$(USB_PRODUCT)'
endif
# In the following URL, don't include the https:// prefix.
@ -149,39 +151,12 @@ endif
USB_WEBUSB_URL ?= "circuitpython.org"
ifeq ($(CIRCUITPY_USB_CDC),1)
# Inform TinyUSB there are two CDC devices.
# Inform TinyUSB there will be up to two CDC devices.
CFLAGS += -DCFG_TUD_CDC=2
endif
USB_HIGHSPEED ?= 0
************ move these from make variables to cpp only ???
USB_CDC_EP_NUM_NOTIFICATION ?= 0
CFLAGS += -DUSB_CDC_EP_NUM_NOTIFICATION=$(USB_CDC_EP_NUM_NOTIFICATION)
USB_CDC_EP_NUM_DATA_OUT ?= 0
CFLAGS += -DUSB_CDC_EP_NUM_DATA_OUT=$(USB_CDC_EP_NUM_DATA_OUT)
USB_CDC_EP_NUM_DATA_IN ?= 0
CFLAGS += -DUSB_CDC_EP_NUM_DATA_IN=$(USB_CDC_EP_NUM_DATA_IN)
USB_CDC2_EP_NUM_NOTIFICATION ?= 0
CFLAGS += -DUSB_CDC2_EP_NUM_NOTIFICATION=$(USB_CDC2_EP_NUM_NOTIFICATION)
USB_CDC2_EP_NUM_DATA_OUT ?= 0
CFLAGS += -DUSB_CDC2_EP_NUM_DATA_OUT=$(USB_CDC2_EP_NUM_DATA_OUT)
USB_CDC2_EP_NUM_DATA_IN ?= 0
CFLAGS += -DUSB_CDC2_EP_NUM_DATA_IN=$(USB_CDC2_EP_NUM_DATA_IN)
USB_MSC_EP_NUM_OUT ?= 0
CFLAGS += -DUSB
USB_MSC_EP_NUM_IN ?= 0
USB_HID_EP_NUM_OUT ?= 0
USB_HID_EP_NUM_IN ?= 0
USB_MIDI_EP_NUM_OUT ?= 0
USB_MIDI_EP_NUM_IN ?= 0
USB_NUM_EP ?= 0
$(BUILD)/supervisor/shared/translate.o: $(HEADER_BUILD)/qstrdefs.generated.h
CIRCUITPY_DISPLAY_FONT ?= "../../tools/fonts/ter-u12n.bdf"