partially working
This commit is contained in:
parent
f98a54628b
commit
8500e846c6
232
main.c
232
main.c
@ -182,24 +182,6 @@ STATIC void start_mp(supervisor_allocation* heap) {
|
||||
#if CIRCUITPY_NETWORK
|
||||
network_module_init();
|
||||
#endif
|
||||
|
||||
// Do before boot.py.
|
||||
|
||||
#if CIRCUITPY_STORAGE
|
||||
storage_init();
|
||||
#endif
|
||||
|
||||
#if CIRCUITPY_USB_CDC
|
||||
usb_cdc_init();
|
||||
#endif
|
||||
|
||||
#if CIRCUITPY_USB_HID
|
||||
usb_hid_init();
|
||||
#endif
|
||||
|
||||
#if CIRCUITPY_USB_MIDI
|
||||
usb_midi_init();
|
||||
#endif
|
||||
}
|
||||
|
||||
STATIC void stop_mp(void) {
|
||||
@ -284,6 +266,97 @@ STATIC void cleanup_after_vm(supervisor_allocation* heap) {
|
||||
reset_status_led();
|
||||
}
|
||||
|
||||
FIL* boot_output_file;
|
||||
|
||||
STATIC void __attribute__ ((noinline)) run_boot_py(safe_mode_t safe_mode) {
|
||||
// If not in safe mode, run boot before initing USB and capture output in a
|
||||
// file.
|
||||
if (filesystem_present() && safe_mode == NO_SAFE_MODE && MP_STATE_VM(vfs_mount_table) != NULL) {
|
||||
static const char * const boot_py_filenames[] = STRING_LIST("settings.txt", "settings.py", "boot.py", "boot.txt");
|
||||
|
||||
new_status_color(BOOT_RUNNING);
|
||||
|
||||
#ifdef CIRCUITPY_BOOT_OUTPUT_FILE
|
||||
FIL file_pointer;
|
||||
boot_output_file = &file_pointer;
|
||||
|
||||
// Get the base filesystem.
|
||||
FATFS *fs = &((fs_user_mount_t *) MP_STATE_VM(vfs_mount_table)->obj)->fatfs;
|
||||
|
||||
bool have_boot_py = first_existing_file_in_list(boot_py_filenames) != NULL;
|
||||
|
||||
bool skip_boot_output = false;
|
||||
|
||||
// If there's no boot.py file that might write some changing output,
|
||||
// read the existing copy of CIRCUITPY_BOOT_OUTPUT_FILE and see if its contents
|
||||
// match the version info we would print anyway. If so, skip writing CIRCUITPY_BOOT_OUTPUT_FILE.
|
||||
// This saves wear and tear on the flash and also prevents filesystem damage if power is lost
|
||||
// during the write, which may happen due to bobbling the power connector or weak power.
|
||||
|
||||
static const size_t NUM_CHARS_TO_COMPARE = 160;
|
||||
if (!have_boot_py && f_open(fs, boot_output_file, CIRCUITPY_BOOT_OUTPUT_FILE, FA_READ) == FR_OK) {
|
||||
|
||||
char file_contents[NUM_CHARS_TO_COMPARE];
|
||||
UINT chars_read = 0;
|
||||
f_read(boot_output_file, file_contents, NUM_CHARS_TO_COMPARE, &chars_read);
|
||||
f_close(boot_output_file);
|
||||
skip_boot_output =
|
||||
// + 2 accounts for \r\n.
|
||||
chars_read == strlen(MICROPY_FULL_VERSION_INFO) + 2 &&
|
||||
strncmp(file_contents, MICROPY_FULL_VERSION_INFO, strlen(MICROPY_FULL_VERSION_INFO)) == 0;
|
||||
}
|
||||
|
||||
if (!skip_boot_output) {
|
||||
// Wait 1.5 seconds before opening CIRCUITPY_BOOT_OUTPUT_FILE for write,
|
||||
// in case power is momentary or will fail shortly due to, say a low, battery.
|
||||
if (common_hal_mcu_processor_get_reset_reason() == RESET_REASON_POWER_ON) {
|
||||
mp_hal_delay_ms(1500);
|
||||
}
|
||||
// USB isn't up, so we can write the file.
|
||||
filesystem_set_internal_writable_by_usb(false);
|
||||
f_open(fs, boot_output_file, CIRCUITPY_BOOT_OUTPUT_FILE, FA_WRITE | FA_CREATE_ALWAYS);
|
||||
|
||||
// Switch the filesystem back to non-writable by Python now instead of later,
|
||||
// since boot.py might change it back to writable.
|
||||
filesystem_set_internal_writable_by_usb(true);
|
||||
|
||||
// Write version info to boot_out.txt.
|
||||
mp_hal_stdout_tx_str(MICROPY_FULL_VERSION_INFO);
|
||||
mp_hal_stdout_tx_str("\r\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
filesystem_flush();
|
||||
supervisor_allocation* heap = allocate_remaining_memory();
|
||||
start_mp(heap);
|
||||
|
||||
#if CIRCUITPY_USB
|
||||
// Set up default USB values after boot.py VM starts but before running boot.py.
|
||||
usb_pre_boot_py();
|
||||
#endif
|
||||
|
||||
// TODO(tannewt): Re-add support for flashing boot error output.
|
||||
bool found_boot = maybe_run_list(boot_py_filenames, NULL);
|
||||
(void) found_boot;
|
||||
|
||||
#ifdef CIRCUITPY_BOOT_OUTPUT_FILE
|
||||
if (!skip_boot_output) {
|
||||
f_close(boot_output_file);
|
||||
filesystem_flush();
|
||||
}
|
||||
boot_output_file = NULL;
|
||||
#endif
|
||||
|
||||
#if CIRCUITPY_USB
|
||||
// Remember USB settings, which may have changed during boot.py.
|
||||
// Call this before the boot.py heap is destroyed.
|
||||
usb_post_boot_py();
|
||||
#endif
|
||||
|
||||
cleanup_after_vm(heap);
|
||||
}
|
||||
}
|
||||
|
||||
STATIC void print_code_py_status_message(safe_mode_t safe_mode) {
|
||||
if (autoreload_is_enabled()) {
|
||||
serial_write_compressed(translate("Auto-reload is on. Simply save files over USB to run them or enter REPL to disable.\n"));
|
||||
@ -296,7 +369,7 @@ STATIC void print_code_py_status_message(safe_mode_t safe_mode) {
|
||||
}
|
||||
}
|
||||
|
||||
STATIC bool run_code_py(safe_mode_t safe_mode) {
|
||||
STATIC bool run_code_py(safe_mode_t safe_mode, supervisor_allocation *heap) {
|
||||
bool serial_connected_at_start = serial_connected();
|
||||
#if CIRCUITPY_AUTORELOAD_DELAY_MS > 0
|
||||
serial_write("\n");
|
||||
@ -324,11 +397,6 @@ STATIC bool run_code_py(safe_mode_t safe_mode) {
|
||||
"main.txt.py", "main.py.txt", "main.txt.txt","main.py.py");
|
||||
#endif
|
||||
|
||||
stack_resize();
|
||||
filesystem_flush();
|
||||
supervisor_allocation* heap = allocate_remaining_memory();
|
||||
start_mp(heap);
|
||||
|
||||
found_main = maybe_run_list(supported_filenames, &result);
|
||||
#if CIRCUITPY_FULL_BUILD
|
||||
if (!found_main){
|
||||
@ -466,98 +534,9 @@ STATIC bool run_code_py(safe_mode_t safe_mode) {
|
||||
}
|
||||
}
|
||||
|
||||
FIL* boot_output_file;
|
||||
|
||||
STATIC void __attribute__ ((noinline)) run_boot_py(safe_mode_t safe_mode) {
|
||||
// If not in safe mode, run boot before initing USB and capture output in a
|
||||
// file.
|
||||
if (filesystem_present() && safe_mode == NO_SAFE_MODE && MP_STATE_VM(vfs_mount_table) != NULL) {
|
||||
static const char * const boot_py_filenames[] = STRING_LIST("settings.txt", "settings.py", "boot.py", "boot.txt");
|
||||
|
||||
new_status_color(BOOT_RUNNING);
|
||||
|
||||
#ifdef CIRCUITPY_BOOT_OUTPUT_FILE
|
||||
FIL file_pointer;
|
||||
boot_output_file = &file_pointer;
|
||||
|
||||
// Get the base filesystem.
|
||||
FATFS *fs = &((fs_user_mount_t *) MP_STATE_VM(vfs_mount_table)->obj)->fatfs;
|
||||
|
||||
bool have_boot_py = first_existing_file_in_list(boot_py_filenames) != NULL;
|
||||
|
||||
bool skip_boot_output = false;
|
||||
|
||||
// If there's no boot.py file that might write some changing output,
|
||||
// read the existing copy of CIRCUITPY_BOOT_OUTPUT_FILE and see if its contents
|
||||
// match the version info we would print anyway. If so, skip writing CIRCUITPY_BOOT_OUTPUT_FILE.
|
||||
// This saves wear and tear on the flash and also prevents filesystem damage if power is lost
|
||||
// during the write, which may happen due to bobbling the power connector or weak power.
|
||||
|
||||
static const size_t NUM_CHARS_TO_COMPARE = 160;
|
||||
if (!have_boot_py && f_open(fs, boot_output_file, CIRCUITPY_BOOT_OUTPUT_FILE, FA_READ) == FR_OK) {
|
||||
|
||||
char file_contents[NUM_CHARS_TO_COMPARE];
|
||||
UINT chars_read = 0;
|
||||
f_read(boot_output_file, file_contents, NUM_CHARS_TO_COMPARE, &chars_read);
|
||||
f_close(boot_output_file);
|
||||
skip_boot_output =
|
||||
// + 2 accounts for \r\n.
|
||||
chars_read == strlen(MICROPY_FULL_VERSION_INFO) + 2 &&
|
||||
strncmp(file_contents, MICROPY_FULL_VERSION_INFO, strlen(MICROPY_FULL_VERSION_INFO)) == 0;
|
||||
}
|
||||
|
||||
if (!skip_boot_output) {
|
||||
// Wait 1.5 seconds before opening CIRCUITPY_BOOT_OUTPUT_FILE for write,
|
||||
// in case power is momentary or will fail shortly due to, say a low, battery.
|
||||
if (common_hal_mcu_processor_get_reset_reason() == RESET_REASON_POWER_ON) {
|
||||
mp_hal_delay_ms(1500);
|
||||
}
|
||||
// USB isn't up, so we can write the file.
|
||||
filesystem_set_internal_writable_by_usb(false);
|
||||
f_open(fs, boot_output_file, CIRCUITPY_BOOT_OUTPUT_FILE, FA_WRITE | FA_CREATE_ALWAYS);
|
||||
|
||||
// Switch the filesystem back to non-writable by Python now instead of later,
|
||||
// since boot.py might change it back to writable.
|
||||
filesystem_set_internal_writable_by_usb(true);
|
||||
|
||||
// Write version info to boot_out.txt.
|
||||
mp_hal_stdout_tx_str(MICROPY_FULL_VERSION_INFO);
|
||||
mp_hal_stdout_tx_str("\r\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
filesystem_flush();
|
||||
supervisor_allocation* heap = allocate_remaining_memory();
|
||||
start_mp(heap);
|
||||
|
||||
// TODO(tannewt): Re-add support for flashing boot error output.
|
||||
bool found_boot = maybe_run_list(boot_py_filenames, NULL);
|
||||
(void) found_boot;
|
||||
|
||||
#ifdef CIRCUITPY_BOOT_OUTPUT_FILE
|
||||
if (!skip_boot_output) {
|
||||
f_close(boot_output_file);
|
||||
filesystem_flush();
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
STATIC int run_repl(void) {
|
||||
STATIC int run_repl(supervisor_allocation *heap) {
|
||||
int exit_code = PYEXEC_FORCED_EXIT;
|
||||
stack_resize();
|
||||
filesystem_flush();
|
||||
supervisor_allocation* heap = allocate_remaining_memory();
|
||||
start_mp(heap);
|
||||
|
||||
autoreload_suspend();
|
||||
new_status_color(REPL_RUNNING);
|
||||
if (pyexec_mode_kind == PYEXEC_MODE_RAW_REPL) {
|
||||
@ -618,27 +597,40 @@ int __attribute__((used)) main(void) {
|
||||
|
||||
run_boot_py(safe_mode);
|
||||
|
||||
// Start serial and HID after giving boot.py a chance to tweak behavior.
|
||||
serial_init();
|
||||
|
||||
#if CIRCUITPY_BLEIO
|
||||
supervisor_start_bluetooth();
|
||||
#endif
|
||||
|
||||
// Boot script is finished, so now go into REPL/main mode.
|
||||
|
||||
// Set up heap for REPL or code.py
|
||||
stack_resize();
|
||||
filesystem_flush();
|
||||
supervisor_allocation* heap = allocate_remaining_memory();
|
||||
start_mp(heap);
|
||||
|
||||
#if CIRCUITPY_USB
|
||||
// Setup USB connection after heap is available.
|
||||
// It needs the heap to build descriptors.
|
||||
usb_init();
|
||||
#endif
|
||||
|
||||
// Set up any other serial connection.
|
||||
serial_init();
|
||||
|
||||
int exit_code = PYEXEC_FORCED_EXIT;
|
||||
bool skip_repl = true;
|
||||
bool first_run = true;
|
||||
for (;;) {
|
||||
if (!skip_repl) {
|
||||
exit_code = run_repl();
|
||||
exit_code = run_repl(heap);
|
||||
}
|
||||
if (exit_code == PYEXEC_FORCED_EXIT) {
|
||||
if (!first_run) {
|
||||
serial_write_compressed(translate("soft reboot\n"));
|
||||
}
|
||||
first_run = false;
|
||||
skip_repl = run_code_py(safe_mode);
|
||||
skip_repl = run_code_py(safe_mode, heap);
|
||||
} else if (exit_code != 0) {
|
||||
break;
|
||||
}
|
||||
|
@ -51,7 +51,7 @@ CIRCUITPY_SDCARDIO ?= 0
|
||||
CIRCUITPY_FRAMEBUFFERIO ?= 0
|
||||
|
||||
# Not enough room in 192kB or 256kB builds for secondary CDC.
|
||||
CIRCUITPY_USB_CDC ?= 0
|
||||
CIRCUITPY_USB_CDC ?= 1
|
||||
|
||||
CIRCUITPY_ULAB = 0
|
||||
|
||||
|
@ -339,9 +339,9 @@ CFLAGS += -DCIRCUITPY_USB=$(CIRCUITPY_USB)
|
||||
|
||||
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
|
||||
CIRCUITPY_USB_CDC_REPL_ENABLED_DEFAULT ?= 1
|
||||
CFLAGS += -DCIRCUITPY_USB_CDC_REPL_ENABLED_DEFAULT=$(CIRCUITPY_USB_CDC_REPL_ENABLED_DEFAULT)
|
||||
CIRCUITPY_USB_CDC_DATA_ENABLED_DEFAULT ?= 0
|
||||
CFLAGS += -DCIRCUITPY_USB_CDC_DATA_ENABLED_DEFAULT=$(CIRCUITPY_USB_CDC_DATA_ENABLED_DEFAULT)
|
||||
|
||||
CIRCUITPY_USB_HID ?= 1
|
||||
|
@ -39,6 +39,8 @@
|
||||
#include "supervisor/filesystem.h"
|
||||
#include "supervisor/flash.h"
|
||||
#include "supervisor/usb.h"
|
||||
|
||||
#if CIRCUITPY_USB_MSC
|
||||
#include "tusb.h"
|
||||
|
||||
static const uint8_t usb_msc_descriptor_template[] = {
|
||||
@ -77,6 +79,10 @@ static const uint8_t usb_msc_descriptor_template[] = {
|
||||
// Is the MSC device enabled?
|
||||
bool storage_usb_is_enabled;
|
||||
|
||||
void storage_init_usb(void) {
|
||||
storage_usb_is_enabled = true;
|
||||
}
|
||||
|
||||
bool storage_usb_enabled(void) {
|
||||
return storage_usb_is_enabled;
|
||||
}
|
||||
@ -92,8 +98,8 @@ size_t storage_usb_add_descriptor(uint8_t *descriptor_buf, uint8_t *current_inte
|
||||
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);
|
||||
descriptor_buf[MSC_IN_ENDPOINT_INDEX] = 0x80 | (USB_MSC_EP_NUM_IN ? USB_MSC_EP_NUM_IN : *current_endpoint);
|
||||
descriptor_buf[MSC_OUT_ENDPOINT_INDEX] = USB_MSC_EP_NUM_OUT ? USB_MSC_EP_NUM_OUT : *current_endpoint;
|
||||
(*current_endpoint)++;
|
||||
|
||||
usb_add_interface_string(*current_interface_string, storage_interface_name);
|
||||
@ -103,6 +109,15 @@ size_t storage_usb_add_descriptor(uint8_t *descriptor_buf, uint8_t *current_inte
|
||||
return sizeof(usb_msc_descriptor_template);
|
||||
}
|
||||
|
||||
bool common_hal_storage_configure_usb(bool enabled) {
|
||||
// We can't change the descriptors once we're connected.
|
||||
if (tud_connected()) {
|
||||
return false;
|
||||
}
|
||||
storage_usb_is_enabled = enabled;
|
||||
return true;
|
||||
}
|
||||
#endif // CIRCUITPY_USB_MSC
|
||||
|
||||
STATIC mp_obj_t mp_vfs_proxy_call(mp_vfs_mount_t *vfs, qstr meth_name, size_t n_args, const mp_obj_t *args) {
|
||||
if (vfs == MP_VFS_NONE) {
|
||||
@ -121,10 +136,6 @@ STATIC mp_obj_t mp_vfs_proxy_call(mp_vfs_mount_t *vfs, qstr meth_name, size_t n_
|
||||
return mp_call_method_n_kw(n_args, 0, meth);
|
||||
}
|
||||
|
||||
void storage_init(void) {
|
||||
storage_usb_is_enabled = true;
|
||||
}
|
||||
|
||||
void common_hal_storage_mount(mp_obj_t vfs_obj, const char *mount_path, bool readonly) {
|
||||
// create new object
|
||||
mp_vfs_mount_t *vfs = m_new_obj(mp_vfs_mount_t);
|
||||
@ -236,12 +247,3 @@ void common_hal_storage_erase_filesystem(void) {
|
||||
common_hal_mcu_reset();
|
||||
// We won't actually get here, since we're resetting.
|
||||
}
|
||||
|
||||
bool common_hal_storage_configure_usb(bool enabled) {
|
||||
// We can't change the descriptors once we're connected.
|
||||
if (tud_connected()) {
|
||||
return false;
|
||||
}
|
||||
storage_usb_is_enabled = enabled;
|
||||
return true;
|
||||
}
|
||||
|
@ -27,10 +27,13 @@
|
||||
#ifndef SHARED_MODULE_STORAGE___INIT___H
|
||||
#define SHARED_MODULE_STORAGE___INIT___H
|
||||
|
||||
bool storage_usb_enabled(void);
|
||||
#include "py/mpconfig.h"
|
||||
|
||||
void storage_init(void);
|
||||
#if CIRCUITPY_USB
|
||||
bool storage_usb_enabled(void);
|
||||
void storage_init_usb(void);
|
||||
size_t storage_usb_descriptor_length(void);
|
||||
size_t storage_usb_add_descriptor(uint8_t *descriptor_buf, uint8_t *current_interface, uint8_t *current_endpoint, uint8_t* current_interface_string);
|
||||
#endif
|
||||
|
||||
#endif // SHARED_MODULE_STORAGE___INIT___H
|
||||
|
@ -31,6 +31,8 @@
|
||||
#include "py/objtuple.h"
|
||||
#include "shared-bindings/usb_cdc/__init__.h"
|
||||
#include "shared-bindings/usb_cdc/Serial.h"
|
||||
#include "supervisor/usb.h"
|
||||
|
||||
#include "tusb.h"
|
||||
|
||||
#if CFG_TUD_CDC != 2
|
||||
@ -94,7 +96,7 @@ static const uint8_t usb_cdc_descriptor_template[] = {
|
||||
// CDC Control IN Endpoint Descriptor
|
||||
0x07, // 36 bLength
|
||||
0x05, // 37 bDescriptorType (Endpoint)
|
||||
0xFF, // 38 bEndpointAddress (IN/D2H) [SET AT RUNTIME: 0x8 | number]
|
||||
0xFF, // 38 bEndpointAddress (IN/D2H) [SET AT RUNTIME: 0x80 | number]
|
||||
#define CDC_CONTROL_IN_ENDPOINT_INDEX 38
|
||||
0x03, // 39 bmAttributes (Interrupt)
|
||||
0x40, 0x00, // 40, 41 wMaxPacketSize 64
|
||||
@ -125,17 +127,17 @@ static const uint8_t usb_cdc_descriptor_template[] = {
|
||||
// CDC Data IN Endpoint Descriptor
|
||||
0x07, // 59 bLength
|
||||
0x05, // 60 bDescriptorType (Endpoint)
|
||||
0xFF, // 61 bEndpointAddress (IN/D2H) [SET AT RUNTIME: 0x8 | number]
|
||||
0xFF, // 61 bEndpointAddress (IN/D2H) [SET AT RUNTIME: 0x80 | number]
|
||||
#define CDC_DATA_IN_ENDPOINT_INDEX 61
|
||||
0x02, // 62 bmAttributes (Bulk)
|
||||
0x40, 0x00, // 63,64 wMaxPacketSize 64
|
||||
0x00, // 65 bInterval 0 (unit depends on device speed)
|
||||
};
|
||||
|
||||
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 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,
|
||||
@ -159,7 +161,7 @@ bool usb_cdc_repl_enabled(void) {
|
||||
}
|
||||
|
||||
bool usb_cdc_data_enabled(void) {
|
||||
return usb_cdc_data_enabled;
|
||||
return usb_cdc_data_is_enabled;
|
||||
}
|
||||
|
||||
size_t usb_cdc_descriptor_length(void) {
|
||||
@ -167,7 +169,7 @@ size_t usb_cdc_descriptor_length(void) {
|
||||
}
|
||||
|
||||
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));
|
||||
memcpy(descriptor_buf, usb_cdc_descriptor_template, sizeof(usb_cdc_descriptor_template));
|
||||
|
||||
// Store comm interface number.
|
||||
descriptor_buf[CDC_FIRST_INTERFACE_INDEX] = *current_interface;
|
||||
@ -179,19 +181,23 @@ size_t usb_cdc_add_descriptor(uint8_t *descriptor_buf, uint8_t *current_interfac
|
||||
descriptor_buf[CDC_CALL_MANAGEMENT_DATA_INTERFACE_INDEX] = *current_interface;
|
||||
descriptor_buf[CDC_UNION_SLAVE_INTERFACE_INDEX] = *current_interface;
|
||||
descriptor_buf[CDC_DATA_INTERFACE_INDEX] = *current_interface;
|
||||
(*current_interface)++;
|
||||
|
||||
descriptor_buf[CDC_CONTROL_IN_ENDPOINT_INDEX] = repl
|
||||
descriptor_buf[CDC_CONTROL_IN_ENDPOINT_INDEX] = 0x80 | (
|
||||
repl
|
||||
? (USB_CDC_EP_NUM_NOTIFICATION ? USB_CDC_EP_NUM_NOTIFICATION : *current_endpoint)
|
||||
: (USB_CDC2_EP_NUM_NOTIFICATION ? USB_CDC2_EP_NUM_NOTIFICATION : *current_endpoint);
|
||||
: (USB_CDC2_EP_NUM_NOTIFICATION ? USB_CDC2_EP_NUM_NOTIFICATION : *current_endpoint));
|
||||
(*current_endpoint)++;
|
||||
|
||||
descriptor_buf[CDC_DATA_OUT_ENDPOINT_INDEX] = repl
|
||||
descriptor_buf[CDC_DATA_OUT_ENDPOINT_INDEX] =
|
||||
repl
|
||||
? (USB_CDC_EP_NUM_DATA_OUT ? USB_CDC_EP_NUM_DATA_OUT : *current_endpoint)
|
||||
: (USB_CDC2_EP_NUM_DATA_OUT ? USB_CDC2_EP_NUM_DATA_OUT : *current_endpoint);
|
||||
|
||||
descriptor_buf[CDC_DATA_IN_ENDPOINT_INDEX] = repl
|
||||
descriptor_buf[CDC_DATA_IN_ENDPOINT_INDEX] = 0x80 | (
|
||||
repl
|
||||
? (USB_CDC_EP_NUM_DATA_IN ? USB_CDC_EP_NUM_DATA_IN : *current_endpoint)
|
||||
: (USB_CDC2_EP_NUM_DATA_IN ? USB_CDC2_EP_NUM_DATA_IN : *current_endpoint);
|
||||
: (USB_CDC2_EP_NUM_DATA_IN ? USB_CDC2_EP_NUM_DATA_IN : *current_endpoint));
|
||||
(*current_endpoint)++;
|
||||
|
||||
usb_add_interface_string(*current_interface_string,
|
||||
@ -204,10 +210,11 @@ size_t usb_cdc_add_descriptor(uint8_t *descriptor_buf, uint8_t *current_interfac
|
||||
descriptor_buf[CDC_DATA_INTERFACE_STRING_INDEX] = *current_interface_string;
|
||||
(*current_interface_string)++;
|
||||
|
||||
return sizeof(usb_midi_descriptor_template);
|
||||
return sizeof(usb_cdc_descriptor_template);
|
||||
}
|
||||
|
||||
void usb_cdc_init(void) {
|
||||
// Called only once, before boot.py
|
||||
void usb_cdc_init_usb(void) {
|
||||
usb_cdc_repl_is_enabled = true;
|
||||
usb_cdc_data_is_enabled = false;
|
||||
}
|
||||
@ -218,10 +225,10 @@ bool common_hal_usb_cdc_configure_usb(bool repl_enabled, bool data_enabled) {
|
||||
return false;
|
||||
}
|
||||
|
||||
usb_cdc_repl_enabled = repl_enabled;
|
||||
usb_cdc_repl_is_enabled = repl_enabled;
|
||||
usb_cdc_set_repl(repl_enabled ? MP_OBJ_FROM_PTR(&usb_cdc_repl_obj) : mp_const_none);
|
||||
|
||||
usb_cdc_data_enabled = data_enabled;
|
||||
usb_cdc_data_is_enabled = data_enabled;
|
||||
usb_cdc_set_data(data_enabled ? MP_OBJ_FROM_PTR(&usb_cdc_data_obj) : mp_const_none);
|
||||
|
||||
return true;
|
||||
|
@ -27,12 +27,13 @@
|
||||
#ifndef SHARED_MODULE_USB_CDC___INIT___H
|
||||
#define SHARED_MODULE_USB_CDC___INIT___H
|
||||
|
||||
#include "py/mpconfig.h"
|
||||
#include "py/objtuple.h"
|
||||
|
||||
bool usb_cdc_repl_enabled(void);
|
||||
bool usb_cdc_data_enabled(void);
|
||||
|
||||
void usb_cdc_init(void);
|
||||
void usb_cdc_init_usb(void);
|
||||
size_t usb_cdc_descriptor_length(void);
|
||||
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);
|
||||
|
||||
|
@ -67,7 +67,7 @@ static const uint8_t usb_hid_descriptor_template[] = {
|
||||
0x07, // 25 bLength
|
||||
0x05, // 26 bDescriptorType (Endpoint)
|
||||
0xFF, // 27 bEndpointAddress (OUT/H2D) [SET AT RUNTIME]
|
||||
#define HID_OUT_ENDPOINT_INDEX (26)
|
||||
#define HID_OUT_ENDPOINT_INDEX (27)
|
||||
0x03, // 28 bmAttributes (Interrupt)
|
||||
0x40, 0x00, // 29,30 wMaxPacketSize 64
|
||||
0x08, // 31 bInterval 8 (unit depends on device speed)
|
||||
@ -115,22 +115,28 @@ size_t usb_hid_add_descriptor(uint8_t *descriptor_buf, uint8_t *current_interfac
|
||||
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);
|
||||
descriptor_buf[HID_IN_ENDPOINT_INDEX] = 0x80 | (USB_HID_EP_NUM_IN ? USB_HID_EP_NUM_IN : *current_endpoint);
|
||||
descriptor_buf[HID_OUT_ENDPOINT_INDEX] = USB_HID_EP_NUM_OUT ? USB_HID_EP_NUM_OUT : *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),
|
||||
static mp_rom_obj_tuple_t default_hid_devices_tuple = {
|
||||
.base = {
|
||||
.type = &mp_type_tuple,
|
||||
},
|
||||
.len = 3,
|
||||
.items = {
|
||||
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.
|
||||
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));
|
||||
common_hal_usb_hid_configure_usb(&default_hid_devices_tuple);
|
||||
}
|
||||
|
||||
bool common_hal_usb_hid_configure_usb(mp_obj_t devices) {
|
||||
@ -144,7 +150,8 @@ bool common_hal_usb_hid_configure_usb(mp_obj_t devices) {
|
||||
return true;
|
||||
}
|
||||
|
||||
void usb_hid_init(void) {
|
||||
// Called only once, before boot.py
|
||||
void usb_hid_init_usb(void) {
|
||||
usb_hid_is_enabled = true;
|
||||
}
|
||||
|
||||
@ -170,7 +177,7 @@ void usb_hid_post_boot_py(void) {
|
||||
total_hid_report_descriptor_length -= 2;
|
||||
}
|
||||
|
||||
// Allocate storage that persists across VMs to build the combined descriptor
|
||||
// Allocate storage that persists across VMs to build the combined report descriptor
|
||||
// and to remember the device details.
|
||||
|
||||
hid_report_descriptor_allocation =
|
||||
|
@ -33,7 +33,7 @@ extern usb_hid_device_obj_t usb_hid_devices[];
|
||||
|
||||
bool usb_hid_enabled(void);
|
||||
|
||||
void usb_hid_init(void);
|
||||
void usb_hid_init_usb(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);
|
||||
|
@ -26,6 +26,7 @@
|
||||
|
||||
#include "shared-bindings/usb_midi/__init__.h"
|
||||
|
||||
#include "py/gc.h"
|
||||
#include "py/obj.h"
|
||||
#include "py/mphal.h"
|
||||
#include "py/runtime.h"
|
||||
@ -72,7 +73,7 @@ static const uint8_t usb_midi_descriptor_template[] = {
|
||||
0x01, // 23 bInterfaceClass (Audio)
|
||||
0x03, // 24 bInterfaceSubClass (MIDI Streaming)
|
||||
0x00, // 25 bInterfaceProtocol
|
||||
0xFF, // 26 iInterface (String Index) [SET AT RUNTIME]
|
||||
0xFF, // 26 iInterface (String Index) [SET AT RUNTIME]
|
||||
#define MIDI_STREAMING_INTERFACE_STRING_INDEX (26)
|
||||
|
||||
// MIDI Header Descriptor
|
||||
@ -141,7 +142,7 @@ static const uint8_t usb_midi_descriptor_template[] = {
|
||||
// MIDI IN Data Endpoint
|
||||
0x07, // 76 bLength
|
||||
0x05, // 77 bDescriptorType: Endpoint
|
||||
0xFF, // 78 bEndpointAddress (IN/D2H) [SET AT RUNTIME: 0x8 | number]
|
||||
0xFF, // 78 bEndpointAddress (IN/D2H) [SET AT RUNTIME: 0x80 | number]
|
||||
#define MIDI_STREAMING_IN_ENDPOINT_INDEX (78)
|
||||
0x02, // 79 bmAttributes (Bulk)
|
||||
0x40, 0x00, // 8081 wMaxPacketSize 64
|
||||
@ -179,9 +180,9 @@ size_t usb_midi_add_descriptor(uint8_t *descriptor_buf, uint8_t *current_interfa
|
||||
(*current_interface)++;
|
||||
|
||||
descriptor_buf[MIDI_STREAMING_IN_ENDPOINT_INDEX] =
|
||||
USB_MIDI_EP_NUM_IN ? USB_MIDI_EP_NUM_IN : *current_endpoint;
|
||||
0x80 | (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);
|
||||
USB_MIDI_EP_NUM_OUT ? USB_MIDI_EP_NUM_OUT : *current_endpoint;
|
||||
(*current_endpoint)++;
|
||||
|
||||
descriptor_buf[MIDI_STREAMING_INTERFACE_NUMBER_INDEX] = *current_interface;
|
||||
@ -208,38 +209,36 @@ size_t usb_midi_add_descriptor(uint8_t *descriptor_buf, uint8_t *current_interfa
|
||||
}
|
||||
|
||||
|
||||
void usb_midi_init(void) {
|
||||
// Called once, before
|
||||
void usb_midi_init_usb(void) {
|
||||
usb_midi_is_enabled = true;
|
||||
}
|
||||
|
||||
void usb_midi_usb_init(void) {
|
||||
// Called before REPL or code.py
|
||||
void usb_midi_setup(void) {
|
||||
mp_obj_tuple_t *ports;
|
||||
|
||||
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));
|
||||
size_t portout_size = align32_size(sizeof(usb_midi_portout_obj_t));
|
||||
// Make these objects long-lived, because they will not be going away.
|
||||
|
||||
// For each embedded MIDI Jack in the descriptor we create a Port
|
||||
usb_midi_allocation = allocate_memory(tuple_size + portin_size + portout_size, false, false);
|
||||
|
||||
ports = (mp_obj_tuple_t *)usb_midi_allocation->ptr;
|
||||
ports->base.type = &mp_type_tuple;
|
||||
ports->len = 2;
|
||||
|
||||
usb_midi_portin_obj_t *in = (usb_midi_portin_obj_t *)(usb_midi_allocation->ptr + tuple_size / 4);
|
||||
usb_midi_portin_obj_t *in = gc_alloc(sizeof(usb_midi_portin_obj_t), false, true);
|
||||
in->base.type = &usb_midi_portin_type;
|
||||
ports->items[0] = MP_OBJ_FROM_PTR(in);
|
||||
|
||||
usb_midi_portout_obj_t *out = (usb_midi_portout_obj_t *)(usb_midi_allocation->ptr + tuple_size / 4 + portin_size / 4);
|
||||
usb_midi_portout_obj_t *out = gc_alloc(sizeof(usb_midi_portout_obj_t), false, true);
|
||||
out->base.type = &usb_midi_portout_type;
|
||||
ports->items[1] = MP_OBJ_FROM_PTR(out);
|
||||
|
||||
mp_obj_t tuple_items[2] = {
|
||||
MP_OBJ_FROM_PTR(in),
|
||||
MP_OBJ_FROM_PTR(out),
|
||||
};
|
||||
|
||||
ports = mp_obj_new_tuple(2, tuple_items);
|
||||
} else {
|
||||
ports = mp_const_empty_tuple;
|
||||
}
|
||||
|
||||
mp_map_lookup(&usb_midi_module_globals.map, MP_ROM_QSTR(MP_QSTR_ports), MP_MAP_LOOKUP)->value = MP_OBJ_FROM_PTR(ports);
|
||||
mp_map_lookup(&usb_midi_module_globals.map, MP_ROM_QSTR(MP_QSTR_ports), MP_MAP_LOOKUP)->value =
|
||||
MP_OBJ_FROM_PTR(ports);
|
||||
}
|
||||
|
||||
bool common_hal_usb_midi_configure_usb(bool enabled) {
|
||||
|
@ -28,8 +28,8 @@
|
||||
#define SHARED_MODULE_USB_MIDI___INIT___H
|
||||
|
||||
|
||||
void usb_midi_init(void);
|
||||
void usb_midi_usb_init(void);
|
||||
void usb_midi_init_usb(void);
|
||||
void usb_midi_setup(void);
|
||||
|
||||
bool usb_midi_enabled(void);
|
||||
size_t usb_midi_descriptor_length(void);
|
||||
|
@ -39,16 +39,9 @@ enum {
|
||||
#if INTERNAL_FLASH_FILESYSTEM == 0
|
||||
+ 1
|
||||
#endif
|
||||
#if CIRCUITPY_USB_MIDI
|
||||
+ 1
|
||||
#endif
|
||||
,
|
||||
CIRCUITPY_SUPERVISOR_MOVABLE_ALLOC_COUNT =
|
||||
0
|
||||
#if CIRCUITPY_USB
|
||||
+ 1 // device_descriptor_allocation
|
||||
+ 1 // config_descriptor_allocation
|
||||
#endif
|
||||
#if CIRCUITPY_USB_HID
|
||||
+ 1 // hid_report_descriptor_allocation
|
||||
+ 1 // hid_devices_allocation
|
||||
|
@ -67,7 +67,7 @@ void serial_early_init(void) {
|
||||
}
|
||||
|
||||
void serial_init(void) {
|
||||
usb_init();
|
||||
// USB serial is set up separately.
|
||||
}
|
||||
|
||||
bool serial_connected(void) {
|
||||
|
@ -34,6 +34,14 @@
|
||||
#include "lib/utils/interrupt_char.h"
|
||||
#include "lib/mp-readline/readline.h"
|
||||
|
||||
#if CIRCUITPY_STORAGE
|
||||
#include "shared-module/storage/__init__.h"
|
||||
#endif
|
||||
|
||||
#if CIRCUITPY_USB_CDC
|
||||
#include "shared-module/usb_cdc/__init__.h"
|
||||
#endif
|
||||
|
||||
#if CIRCUITPY_USB_HID
|
||||
#include "shared-module/usb_hid/__init__.h"
|
||||
#endif
|
||||
@ -82,14 +90,28 @@ void usb_init(void) {
|
||||
tud_cdc_set_wanted_char(CHAR_CTRL_C);
|
||||
#endif
|
||||
|
||||
#if CIRCUITPY_USB_MIDI
|
||||
usb_midi_setup();
|
||||
#endif
|
||||
}
|
||||
|
||||
void usb_pre_boot_py(void) {
|
||||
#if CIRCUITPY_STORAGE
|
||||
storage_init_usb();
|
||||
#endif
|
||||
|
||||
#if CIRCUITPY_USB_CDC
|
||||
usb_cdcx_usb_init();
|
||||
usb_cdc_init_usb();
|
||||
#endif
|
||||
|
||||
#if CIRCUITPY_USB_HID
|
||||
usb_hid_init_usb();
|
||||
#endif
|
||||
|
||||
#if CIRCUITPY_USB_MIDI
|
||||
usb_midi_usb_init();
|
||||
usb_midi_init_usb();
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
// Remember USB settings done during boot.py.
|
||||
// The boot.py heap is still valid at this point.
|
||||
|
@ -52,8 +52,8 @@
|
||||
|
||||
// Table for collecting interface strings (interface names) as descriptor is built.
|
||||
#define MAX_INTERFACE_STRINGS 16
|
||||
// slot 0 is not used.
|
||||
static uint16_t **collected_interface_strings;
|
||||
// slot 0 is always the Language ID
|
||||
static uint16_t *collected_interface_strings[MAX_INTERFACE_STRINGS];
|
||||
static uint8_t current_interface_string;
|
||||
|
||||
static const char manufacturer_name[] = USB_MANUFACTURER;
|
||||
@ -77,11 +77,11 @@ static const uint8_t device_descriptor_template[] = {
|
||||
#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]
|
||||
0xFF, // 14 iManufacturer (String Index) [SET AT RUNTIME]
|
||||
#define DEVICE_MANUFACTURER_STRING_INDEX (14)
|
||||
0x03, // 15 iProduct (String Index) [SET AT RUNTIME]
|
||||
0xFF, // 15 iProduct (String Index) [SET AT RUNTIME]
|
||||
#define DEVICE_PRODUCT_STRING_INDEX (15)
|
||||
0x01, // 16 iSerialNumber (String Index) [SET AT RUNTIME]
|
||||
0xFF, // 16 iSerialNumber (String Index) [SET AT RUNTIME]
|
||||
#define DEVICE_SERIAL_NUMBER_STRING_INDEX (16)
|
||||
0x01, // 17 bNumConfigurations 1
|
||||
};
|
||||
@ -102,7 +102,7 @@ static const uint8_t configuration_descriptor_template[] = {
|
||||
0x32, // 8 bMaxPower 100mA
|
||||
};
|
||||
|
||||
static uint8_t configuration_descriptor[sizeof(configuration_descriptor_template)];
|
||||
static uint8_t *configuration_descriptor;
|
||||
|
||||
// Initialization done before boot.py is run.
|
||||
// Turn on or off various USB devices. On devices with limited endpoints,
|
||||
@ -169,20 +169,23 @@ static void usb_build_configuration_descriptor(void) {
|
||||
}
|
||||
#endif
|
||||
|
||||
#if CIRCUITPY_USB_MIDI
|
||||
if (usb_midi_enabled()) {
|
||||
total_descriptor_length += usb_midi_descriptor_length();
|
||||
}
|
||||
#endif
|
||||
|
||||
#if CIRCUITPY_USB_HID
|
||||
if (usb_hid_enabled()) {
|
||||
total_descriptor_length += usb_hid_descriptor_length();
|
||||
}
|
||||
#endif
|
||||
|
||||
#if CIRCUITPY_USB_MIDI
|
||||
if (usb_midi_enabled()) {
|
||||
total_descriptor_length += usb_midi_descriptor_length();
|
||||
}
|
||||
#endif
|
||||
|
||||
// Now we now how big the configuration descriptor will be.
|
||||
// Copy the top-level template, and fix up its length.
|
||||
// Copy the template, which is the first part of the descriptor, and fix up its length.
|
||||
configuration_descriptor = gc_alloc(total_descriptor_length, false, false);
|
||||
memcpy(configuration_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;
|
||||
|
||||
@ -214,14 +217,6 @@ static void usb_build_configuration_descriptor(void) {
|
||||
}
|
||||
#endif
|
||||
|
||||
#if CIRCUITPY_USB_MIDI
|
||||
if (usb_midi_enabled()) {
|
||||
// Concatenate and fix up the MIDI descriptor.
|
||||
descriptor_buf_remaining += usb_midi_add_descriptor(
|
||||
descriptor_buf_remaining, ¤t_interface, ¤t_endpoint, ¤t_interface_string);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if CIRCUITPY_USB_HID
|
||||
if (usb_hid_enabled()) {
|
||||
descriptor_buf_remaining += usb_hid_add_descriptor(
|
||||
@ -230,8 +225,19 @@ static void usb_build_configuration_descriptor(void) {
|
||||
}
|
||||
#endif
|
||||
|
||||
#if CIRCUITPY_USB_MIDI
|
||||
if (usb_midi_enabled()) {
|
||||
// Concatenate and fix up the MIDI descriptor.
|
||||
descriptor_buf_remaining += usb_midi_add_descriptor(
|
||||
descriptor_buf_remaining, ¤t_interface, ¤t_endpoint, ¤t_interface_string);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Now we know how many interfaces have been used.
|
||||
configuration_descriptor[CONFIG_NUM_INTERFACES_INDEX] = current_interface - 1;
|
||||
// current_interface is the next free interface, counting from 0,
|
||||
// so move back to the last interface number, and then get a count.
|
||||
// (E.g., interfaces 0-5 are used, so the number of interfaces is 6.)
|
||||
configuration_descriptor[CONFIG_NUM_INTERFACES_INDEX] = current_interface - 1 + 1;
|
||||
|
||||
// Did we run out of endpoints?
|
||||
if (current_endpoint - 1 > USB_NUM_EP) {
|
||||
@ -266,6 +272,14 @@ void usb_desc_post_boot_py(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) {
|
||||
memset(collected_interface_strings, 0, sizeof(collected_interface_strings));
|
||||
|
||||
// Language ID is always the 0th string descriptor.
|
||||
collected_interface_strings[0] = (uint16_t[]) {
|
||||
0x0304,
|
||||
0x0409,
|
||||
};
|
||||
|
||||
uint8_t raw_id[COMMON_HAL_MCU_PROCESSOR_UID_LENGTH];
|
||||
common_hal_mcu_processor_get_uid(raw_id);
|
||||
|
||||
@ -277,10 +291,8 @@ void usb_desc_init(void) {
|
||||
}
|
||||
|
||||
// Null-terminate the string.
|
||||
serial_number_hex_string[sizeof(serial_number_hex_string)] = '\0';
|
||||
serial_number_hex_string[sizeof(serial_number_hex_string) - 1] = '\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_VID, USB_PID);
|
||||
@ -292,9 +304,13 @@ void usb_desc_gc_collect(void) {
|
||||
if (tud_mounted()) {
|
||||
gc_free(device_descriptor);
|
||||
gc_free(configuration_descriptor);
|
||||
for (size_t i = 0; i < MAX_INTERFACE_STRINGS; i ++) {
|
||||
gc_free(collected_interface_strings[i]);
|
||||
}
|
||||
} else {
|
||||
gc_collect_ptr(device_descriptor);
|
||||
gc_collect_ptr(configuration_descriptor);
|
||||
gc_collect_root((void **) collected_interface_strings, MAX_INTERFACE_STRINGS);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -54,6 +54,7 @@ bool usb_enabled(void);
|
||||
void usb_init(void);
|
||||
void usb_disconnect(void);
|
||||
void usb_gc_collect(void);
|
||||
void usb_pre_boot_py(void);
|
||||
void usb_post_boot_py(void);
|
||||
|
||||
void usb_add_interface_string(uint8_t interface_string_index, const char str[]);
|
||||
|
Loading…
Reference in New Issue
Block a user