very much WIP

This commit is contained in:
Dan Halbert 2021-04-26 23:54:01 -04:00
parent c26e49c2e6
commit 7a40b4daec
17 changed files with 108 additions and 68 deletions

View File

@ -331,7 +331,7 @@ CFLAGS += -DCIRCUITPY_UHEAP=$(CIRCUITPY_UHEAP)
CIRCUITPY_USB ?= 1
CFLAGS += -DCIRCUITPY_USB=$(CIRCUITPY_USB)
# If you need to count endpoints, do:
# If you need to count endpoints, use:
# $(shell expr $(USB_NUM_EP) '>=' 8)
CIRCUITPY_USB_CDC ?= 1

View File

@ -26,6 +26,7 @@
#include "py/objproperty.h"
#include "shared-bindings/usb_hid/Device.h"
#include "py/runtime.h"
//| class Device:
//| """HID Device
@ -73,12 +74,11 @@ 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(descriptor, &bufinfo, MP_BUFFER_READ);
bytearray_obj_t descriptor = mp_obj_array_t new_bytearray(bufinfo.len, bufinfo.buf);
mp_get_buffer_raise(args[ARG_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;
if (usage_page_arg <= 0 || usage_arg > 255) {
if (usage_page_arg <= 0 || usage_page_arg > 255) {
mp_raise_ValueError_varg(translate("%q must be 1-255"), MP_QSTR_usage_page);
}
const uint8_t usage_page = usage_page_arg;
@ -91,7 +91,7 @@ STATIC mp_obj_t usb_hid_device_make_new(const mp_obj_type_t *type, size_t n_args
const mp_int_t in_report_length_arg = args[ARG_in_report_length].u_int;
if (in_report_length_arg <= 0 || in_report_length_arg > 255) {
mp_raise_ValueError_varg(translate("%q must be > 1-255"), MP_QSTR_in_report_length);
mp_raise_ValueError_varg(translate("%q must be 1-255"), MP_QSTR_in_report_length);
}
const uint8_t in_report_length = in_report_length_arg;
@ -102,7 +102,7 @@ STATIC mp_obj_t usb_hid_device_make_new(const mp_obj_type_t *type, size_t n_args
else if (!MP_OBJ_IS_SMALL_INT(out_report_length_arg) ||
MP_OBJ_SMALL_INT_VALUE(out_report_length_arg) <= 0 ||
MP_OBJ_SMALL_INT_VALUE(out_report_length_arg) > 255) {
mp_raise_ValueError_varg(translate("%q must be None or > 1-255"), MP_QSTR_out_report_length);
mp_raise_ValueError_varg(translate("%q must be None or 1-255"), MP_QSTR_out_report_length);
}
uint8_t out_report_length = MP_OBJ_SMALL_INT_VALUE(out_report_length_arg);
@ -118,6 +118,7 @@ STATIC mp_obj_t usb_hid_device_make_new(const mp_obj_type_t *type, size_t n_args
uint8_t report_id_index = MP_OBJ_SMALL_INT_VALUE(report_id_index_arg);
common_hal_usb_hid_device_construct(self, descriptor, usage_page, usage, in_report_length, out_report_length, report_id_index);
return (mp_obj_t)self;
}

View File

@ -27,11 +27,13 @@
#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_USB_HID_DEVICE_H
#define MICROPY_INCLUDED_SHARED_BINDINGS_USB_HID_DEVICE_H
#include "py/objarray.h"
#include "shared-module/usb_hid/Device.h"
extern const mp_obj_type_t usb_hid_device_type;
void common_hal_usb_hid_device_construct(usb_hid_device_obj_t *self, ***);
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_send_report(usb_hid_device_obj_t *self, uint8_t *report, uint8_t len);
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);

View File

@ -51,18 +51,15 @@
//| ...
//|
STATIC mp_obj_t usb_hid_configure_usb(mp_obj_t devices) {
mp_obj_iter_buf_t iter_buf;
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);
const mp_int_t len = mp_obj_get_int(mp_obj_len(devices));
for (mp_int_t i = 0; i < len; i++) {
mp_obj_t item = mp_obj_subscr(devices, 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));
mp_raise_ValueError_varg(translate("non-Device in %q"), MP_QSTR_devices);
}
}
if (!common_hal_usb_hid_configure_usb(descriptors)) {
if (!common_hal_usb_hid_configure_usb(devices)) {
mp_raise_RuntimeError(translate("Cannot change USB devices now"));
}
@ -73,7 +70,7 @@ 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[] = {
{ 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_midi_configure_usb_obj) },
{ 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) },
};

View File

@ -27,12 +27,12 @@
#ifndef SHARED_BINDINGS_USB_HID_H
#define SHARED_BINDINGS_USB_HID_H
#include <stdint.h>
#include <stdbool.h>
#include "py/obj.h"
#include "py/objtuple.h"
extern mp_obj_tuple_t common_hal_usb_hid_devices;
void common_hal_usb_hid_configure_usb_defaults(void);
usb_hid_configure_status common_hal_usb_hid_configure_usb(mp_obj_t devices_seq);
bool common_hal_usb_hid_configure_usb(mp_obj_t devices_seq);
#endif // SHARED_BINDINGS_USB_HID_H

View File

@ -81,7 +81,7 @@ size_t storage_usb_descriptor_length(void) {
return sizeof(usb_msc_descriptor);
}
static const char[] storage_interface_name = USB_INTERFACE_NAME " Mass Storage";
static const char[] storage_interface_name = MP_STRINGIFY(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));

View File

@ -135,15 +135,29 @@ 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 usb_cdc_serial_obj_t usb_cdc_repl_obj = {
.base.type = &usb_cdc_serial_type,
.timeout = -1.0f,
.write_timeout = -1.0f,
.idx = 0,
};
static usb_cdc_serial_obj_t usb_cdc_data_obj = {
.base.type = &usb_cdc_serial_type,
.timeout = -1.0f,
.write_timeout = -1.0f,
.idx = 1,
};
size_t usb_cdc_descriptor_length(void) {
return sizeof(usb_cdc_descriptor_template);
}
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";
size_t usb_cdc_add_descriptor(uint8_t *descriptor_buf, uint8_t *current_interface, uint8_t *current_endpoint, uint8_t* current_interface_string, bool repl) {
memcpy(descriptor_buf, usb_midi_descriptor_template, sizeof(usb_midi_descriptor_template));
@ -185,20 +199,6 @@ size_t usb_cdc_add_descriptor(uint8_t *descriptor_buf, uint8_t *current_interfac
return sizeof(usb_midi_descriptor_template);
}
static usb_cdc_serial_obj_t usb_cdc_repl_obj = {
.base.type = &usb_cdc_serial_type,
.timeout = -1.0f,
.write_timeout = -1.0f,
.idx = 0,
};
static usb_cdc_serial_obj_t usb_cdc_data_obj = {
.base.type = &usb_cdc_serial_type,
.timeout = -1.0f,
.write_timeout = -1.0f,
.idx = 1,
};
void usb_cdc_init(void) {
usb_cdc_repl_enabled = true;
usb_cdc_data_enabled = false;

View File

@ -66,7 +66,7 @@ static const uint8_t keyboard_descriptor[] = {
0x95, 0x03, // Report Count (3)
0x91, 0x01, // Output (Const,Array,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0xC0, // End Collection
},
};
const usb_hid_device_obj_t usb_hid_device_keyboard_obj = {
.descriptor = keyboard_descriptor,
@ -154,7 +154,7 @@ const usb_hid_device_obj_t usb_hid_device_consumer_control_obj = {
};
void common_hal_usb_hid_device_construct(usb_hid_dev_obj_t *self, mp_obj_array_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 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;

View File

@ -40,6 +40,7 @@ typedef struct {
uint8_t *descriptor;
uint8_t *in_report_buffer;
uint8_t *out_report_buffer;
uint16_t report_id_index;
uint16_t descriptor_length;
uint8_t usage_page;
uint8_t usage;
@ -50,6 +51,6 @@ typedef struct {
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_mouse_obj usb_hid_device_consumer_control_obj;
extern usb_hid_device_obj_t usb_hid_device_consumer_control_obj;
#endif /* SHARED_MODULE_USB_HID_DEVICE_H */

View File

@ -24,6 +24,11 @@
* THE SOFTWARE.
*/
#include <string.h>
#include "shared-module/usb_hid/__init__.h"
#include "supervisor/memory.h"
static const uint8_t usb_hid_descriptor_template[] = {
0x09, // 0 bLength
0x21, // 1 bDescriptorType (HID)
@ -62,10 +67,10 @@ supervisor_allocation *hid_devices_allocation;
// This is the interface descriptor, not the report descriptor.
size_t usb_hid_descriptor_length(void) {
return sizeof(usb_hid_descriptor);
return sizeof(usb_hid_descriptor_template);
}
static const char[] usb_hid_interface_name = USB_INTERFACE_NAME " HID";
static const char usb_hid_interface_name[] = MP_STRINGIFY(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) {
@ -84,6 +89,7 @@ size_t usb_hid_add_descriptor(uint8_t *descriptor_buf, uint8_t *current_interfac
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),
};
// Set the default list of devices that will be included. Called before boot.py runs, in the boot.py VM.

View File

@ -27,6 +27,8 @@
#ifndef SHARED_MODULE_USB_HID___INIT___H
#define SHARED_MODULE_USB_HID___INIT___H
#include "shared-module/usb_hid/Device.h"
extern bool usb_hid_enabled;
extern usb_hid_device_obj_t usb_hid_devices[];

View File

@ -162,10 +162,10 @@ size_t usb_midi_descriptor_length(void) {
return sizeof(usb_midi_descriptor_template);
}
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]";
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]";
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));

View File

@ -59,6 +59,14 @@ extern "C" {
// DEVICE CONFIGURATION
// --------------------------------------------------------------------+
#define CFG_TUSB_RHPORT0_MODE (OPT_MODE_DEVICE | OPT_MODE_HIGH_SPEED)
// Vendor name included in Inquiry response, max 8 bytes
#define CFG_TUD_MSC_VENDOR USB_MANUFACTURER
// Product name included in Inquiry response, max 16 bytes
#define CFG_TUD_MSC_PRODUCT USB_PRODUCT
#define CFG_TUD_ENDPOINT0_SIZE 64
// ------------- CLASS -------------//

View File

@ -34,6 +34,10 @@
#include "lib/utils/interrupt_char.h"
#include "lib/mp-readline/readline.h"
#if CIRCUITPY_USB_HID
#include "shared-module/usb_hid/__init__.h"
#endif
#if CIRCUITPY_USB_MIDI
#include "shared-module/usb_midi/__init__.h"
#endif
@ -78,6 +82,10 @@ void usb_init(void) {
tud_cdc_set_wanted_char(CHAR_CTRL_C);
#endif
#if CIRCUITPY_USB_CDC
usb_cdcx_usb_init();
#endif
#if CIRCUITPY_USB_MIDI
usb_midi_usb_init();
#endif

View File

@ -26,23 +26,26 @@
#include "lib/tinyusb/src/tusb.h"
#include "supervisor/usb.h"
#if CIRCUITPY_USB_CDC
#include "shared-module/storage/__init__.h"
#include "shared-bindings/usb_cdc/__init__.h"
#endif
#if CIRCUITPY_USB_HID
#include "shared-module/usb_hid/__init__.h"
#include "shared-bindings/usb_hid/__init__.h"
#endif
#if CIRCUITPY_USB_MIDI
#include "shared-module/usb_midi/__init__.h"
#include "shared-bindings/usb_midi/__init__.h"
#endif
#if CIRCUITPY_USB_MSC
#include "shared-module/storage/__init__.h"
#if CIRCUITPY_USB_MSC && CIRCUITPY_STORAGE
#include "shared-bindings/storage/__init__.h"
#endif
#include "shared-module/usb_hid/Device.h"
// For COMMON_HAL_MCU_PROCESSOR_UID_LENGTH
#include "common-hal/microcontroller/Processor.h"
uint8_t *device_descriptor;
uint8_t *config_descriptor;
@ -53,8 +56,8 @@ uint8_t *config_descriptor;
static char * collected_interface_strings[];
static uint16_t current_interface_string;
static const char[] manufacturer_name = USB_MANUFACTURER;
static const char[] product_name = USB_PRODUCT;
static const char manufacturer_name[] = MP_STRINGIFY(USB_MANUFACTURER);
static const char product_name[] = MP_STRINGIFY(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];
@ -67,12 +70,12 @@ static const uint8_t device_descriptor_template[] = {
0x00, // 5 bDeviceSubClass
0x00, // 6 bDeviceProtocol
0x40, // 7 bMaxPacketSize0 64
0x9A, 0x23, // 8,9 idVendor [SET AT RUNTIME: lo,hi]
0xFF, 0xFF, // 8,9 idVendor [SET AT RUNTIME: lo,hi]
#define DEVICE_VID_LO_INDEX (8)
#define DEVICE_VID_HI_INDEX (9)
0x, 0xFF, // 10,11 idProduct [SET AT RUNTIME: lo,hi]
#define DEVICE PID_LO_INDEX (10)
#define DEVICE PID_HI_INDEX (11)
0xFF, 0xFF, // 10,11 idProduct [SET AT RUNTIME: lo,hi]
#define DEVICE_PID_LO_INDEX (10)
#define DEVICE_PID_HI_INDEX (11)
0x00, 0x01, // 12,13 bcdDevice 2.00
0x02, // 14 iManufacturer (String Index) [SET AT RUNTIME]
#define DEVICE_MANUFACTURER_STRING_INDEX (14)
@ -117,11 +120,11 @@ void reset_usb_desc(void) {
#endif
#if CIRCUITPY_USB_HID
common_hal_usb_hid_configure_usb_default();
common_hal_usb_hid_configure_usb_defaults();
#endif
}
static void usb_build_device_descriptor(uint16_t vid, uint16_t pid, uint8_t *current_interface_string) {
static void usb_build_device_descriptor(uint16_t vid, uint16_t pid) {
memcpy(device_descriptor, device_descriptor_template, sizeof(device_descriptor_template));
device_descriptor[DEVICE_VID_LO_INDEX] = vid & 0xFF;
@ -234,7 +237,7 @@ static void usb_build_configuration_descriptor(uint16_t total_length, uint8_t nu
}
static 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");
}
@ -277,7 +280,7 @@ static void usb_desc_init(void) {
collected_interface_strings = m_malloc(MAX_INTERFACE_STRINGS + 1, false);
current_interface_string = 1;
usb_build_device_descriptor();
usb_build_device_descriptor(USB_VID, USB_PID);
usb_build_configuration_descriptor();
usb_build_hid_descriptor();
usb_build_string_descriptors();

View File

@ -135,6 +135,7 @@ ifeq ($(CIRCUITPY_DISPLAYIO), 1)
endif
USB_INTERFACE_NAME ?= "CircuitPython"
CFLAGS += -DUSB_INTERFACE_NAME=$(USB_INTERFACE_NAME)
ifneq ($(USB_VID),)
CFLAGS += -DUSB_VID=$(USB_VID)
@ -154,15 +155,23 @@ 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

View File

@ -49,16 +49,19 @@ void init_usb_hardware(void);
void post_usb_init(void);
// Shared implementation.
void reset_usb(void);
bool usb_enabled(void);
void usb_init(void);
void usb_disconnect(void);
void usb_gc_collect(void);
void usb_post_boot_py(void);
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[]);
void reset_usb_desc(void);
void usb_desc_gc_collect(void);
void usb_desc_init(void);
void usb_build_device_descriptor(uint16_t vid, uint16_t pid, uint8_t *current_interface_string);
void usb_build_configuration_descriptor(uint16_t total_length, uint8_t num_interfaces);
void usb_desc_post_boot_py(void);
// Propagate plug/unplug events to the MSC logic.
#if CIRCUITPY_USB_MSC