This commit is contained in:
Dan Halbert 2021-04-25 10:23:59 -04:00
parent 556a126917
commit aea3c4d3ab
4 changed files with 42 additions and 35 deletions

View File

@ -38,6 +38,4 @@ typedef enum {
USB_CONFIG_NON_DEVICE = 2,
} usb_hid_configure_status;
usb_hid_configure_status common_hal_usb_hid_configure_usb(mp_obj_t devices);
#endif // SHARED_BINDINGS_USB_HID_H
usb_hid_configure_status common_hal_usb_hid_configure_usb(mp_obj_t devices_seqf // SHARED_BINDINGS_USB_HID_H

View File

@ -53,8 +53,8 @@ static const uint8_t usb_hid_descriptor_template[] = {
// Is the HID device enabled?
bool usb_hid_enabled;
supervisor_allocation *combined_hid_report_descriptor_allocation;
supervisor_allocation *devices_allocation;
supervisor_allocation *hid_report_descriptor_allocation;
supervisor_allocation *hid_devices_allocation;
// This is the interface descriptor, not the report descriptor.
@ -64,7 +64,7 @@ size_t usb_hid_descriptor_length(void) {
static const char[] usb_hid_interface_name = USB_INTERFACE_NAME " HID";
// This is the interface descriptor, nto the report descriptor.
// 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));
@ -78,7 +78,7 @@ 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) {
usb_hid_configure_status 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;
@ -86,7 +86,7 @@ usb_hid_configure_status common_hal_usb_hid_configure_usb(mp_obj_t devices) {
// Assume no devices to start.
usb_hid_enabled = false;
if (devices == mp_const_none) {
if (devices_seq == mp_const_none) {
return USB_CONFIG_OK;
}
@ -94,11 +94,11 @@ usb_hid_configure_status common_hal_usb_hid_configure_usb(mp_obj_t devices) {
// Build a combined report descriptor
mp_int_t len = mp_obj_get_int(mp_obj_len(devices));
mp_int_t len = mp_obj_get_int(mp_obj_len(devices_seq));
// First get the total size.
for (size_t i = 0; i < len; i++) {
mp_obj_t item = mp_obj_subscr(devices, mp_obj_new_small_int(i), MP_OBJ_SENTINEL);
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);
@ -119,16 +119,16 @@ usb_hid_configure_status common_hal_usb_hid_configure_usb(mp_obj_t devices) {
// Allocate storage that persists across VMs to build the combined descriptor
// and to remember the device details.
// allocate_memory(length, highaddress=false, movable=true)
combined_hid_report_descriptor_allocation = allocate_memory(total_report_descriptors_length, false, true);
hid_report_descriptor_allocation =
allocate_memory(total_report_descriptors_length, false /*highaddress*/, true /*movable*/);
devices_allocation = allocate_memory(sizeof(usb_hid_device_obj_t) * len);
usb_hid_device_obj_t devices[] = (devices[]) device_details_allocation->ptr;
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;
uint8_t *descriptor_start = combined_hid_report_descriptor_allocation->ptr;
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, mp_obj_new_small_int(i), MP_OBJ_SENTINEL);
usb_hid_device_obj_t *device = MP_OBJ_TO_PTR(devices_seq, mp_obj_new_small_int(i), MP_OBJ_SENTINEL);
// Copy the report descriptor for this device.
if (len == 1) {
@ -146,8 +146,8 @@ usb_hid_configure_status common_hal_usb_hid_configure_usb(mp_obj_t devices) {
}
// Copy the device data and discard any descriptor-bytes object pointer.
memcpy(&devices[i], device, sizeof(usb_hid_device_obj_t));
devices[i].descriptor_obj = mp_const_none;
memcpy(&hid_devices[i], device, sizeof(usb_hid_device_obj_t));
hid_devices[i].descriptor_obj = mp_const_none;
}
}
@ -155,9 +155,10 @@ usb_hid_configure_status common_hal_usb_hid_configure_usb(mp_obj_t devices) {
void usb_hid_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.
usb_hid_devices_to_configure = NULL;
free_memory(hid_report_descriptor_allocation);
free_memory(usb_hid_devices_allocation);
} else {
gc_collect_ptr(usb_hid_devices);
gc_collect_ptr(hid_report_descriptor_allocation->ptr);
gc_collect_ptr(usb_hid_devices_allocation);
}
}

View File

@ -34,7 +34,7 @@
enum {
CIRCUITPY_SUPERVISOR_IMMOVABLE_ALLOC_COUNT =
// stack + heap
// stack + heap
2
#if INTERNAL_FLASH_FILESYSTEM == 0
+ 1
@ -45,8 +45,13 @@ enum {
,
CIRCUITPY_SUPERVISOR_MOVABLE_ALLOC_COUNT =
0
#if CIRCUITPY_USB
+ 1 // device_descriptor_allocation
+ 1 // config_descriptor_allocation
#endif
#if CIRCUITPY_USB_HID
+ 2
+ 1 // hid_report_descriptor_allocation
+ 1 // hid_devices_allocation
#endif
#if CIRCUITPY_DISPLAYIO
#if CIRCUITPY_TERMINALIO

View File

@ -46,9 +46,8 @@
#include "genhdr/autogen_usb_descriptor.h"
static uint8_t *device_descriptor;
static uint8_t *config_descriptor;
static uint8_t *hid_report_descriptor;
supervisor_allocation *device_descriptor_allocation;
supervisor_allocation *config_descriptor_allocation;
// Table for collecting interface strings (interface names) as descriptor is built.
#define MAX_INTERFACE_STRINGS 16
@ -114,14 +113,17 @@ void usb_desc_init(void) {
// Null-terminate the string.
serial_number_hex_string[sizeof(serial_number_hex_string)] = '\0';
// Set to zero when allocated; we depend on that.
// 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 = m_malloc(sizeof(device_descriptor_template), false);
device_descriptor_allocation =
allocate_memory(sizeof(device_descriptor_template), false /*highaddress*/, true /*movable*/);
uint8_t *device_descriptor = (uint8_t *) device_descriptor_allocation->ptr;
memcpy(device_descriptor, device_descriptor_template, sizeof(device_descriptor_template));
device_descriptor[DEVICE_VID_LO_INDEX] = vid & 0xFF;
@ -176,7 +178,10 @@ 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 = m_malloc(total_descriptor_length, false);
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));
@ -258,13 +263,11 @@ 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.
device_descriptor = NULL;
configuration_descriptor = NULL;
hid_report_descriptors = NULL;
free_memory(device_descriptor_allocation);
free_memory(configuration_descriptor_allocation);
} else {
gc_collect_ptr(device_descriptor);
gc_collect_ptr(configuration_descriptor);
gc_collect_ptr(hid_report_descriptors); // Collects children too.
gc_collect_ptr(device_descriptor_allocation->ptr);
gc_collect_ptr(configuration_descriptor_allocation->ptr);
}
}