diff options
Diffstat (limited to 'supervisor/shared')
| -rw-r--r-- | supervisor/shared/background_callback.c | 3 | ||||
| -rw-r--r-- | supervisor/shared/serial.c | 30 | ||||
| -rw-r--r-- | supervisor/shared/usb/tusb_config.h | 1 | ||||
| -rw-r--r-- | supervisor/shared/usb/usb.c | 76 |
4 files changed, 107 insertions, 3 deletions
diff --git a/supervisor/shared/background_callback.c b/supervisor/shared/background_callback.c index 288c9a4df..68a0a9667 100644 --- a/supervisor/shared/background_callback.c +++ b/supervisor/shared/background_callback.c @@ -33,7 +33,7 @@ #include "supervisor/shared/tick.h" #include "shared-bindings/microcontroller/__init__.h" -STATIC volatile background_callback_t *callback_head, *callback_tail; +STATIC volatile background_callback_t * volatile callback_head, * volatile callback_tail; #define CALLBACK_CRITICAL_BEGIN (common_hal_mcu_disable_interrupts()) #define CALLBACK_CRITICAL_END (common_hal_mcu_enable_interrupts()) @@ -50,7 +50,6 @@ void background_callback_add_core(background_callback_t *cb) { cb->prev = (background_callback_t*)callback_tail; if (callback_tail) { callback_tail->next = cb; - cb->prev = (background_callback_t*)callback_tail; } if (!callback_head) { callback_head = cb; diff --git a/supervisor/shared/serial.c b/supervisor/shared/serial.c index 303f89e75..b9feb04f2 100644 --- a/supervisor/shared/serial.c +++ b/supervisor/shared/serial.c @@ -47,6 +47,10 @@ busio_uart_obj_t debug_uart; byte buf_array[64]; #endif +#if CIRCUITPY_USB_VENDOR +bool tud_vendor_connected(void); +#endif + void serial_early_init(void) { #if defined(DEBUG_UART_TX) && defined(DEBUG_UART_RX) debug_uart.base.type = &busio_uart_type; @@ -66,6 +70,12 @@ void serial_init(void) { } bool serial_connected(void) { +#if CIRCUITPY_USB_VENDOR + if (tud_vendor_connected()) { + return true; + } +#endif + #if defined(DEBUG_UART_TX) && defined(DEBUG_UART_RX) return true; #else @@ -74,6 +84,14 @@ bool serial_connected(void) { } char serial_read(void) { +#if CIRCUITPY_USB_VENDOR + if (tud_vendor_connected() && tud_vendor_available() > 0) { + char tiny_buffer; + tud_vendor_read(&tiny_buffer, 1); + return tiny_buffer; + } +#endif + #if defined(DEBUG_UART_TX) && defined(DEBUG_UART_RX) if (tud_cdc_connected() && tud_cdc_available() > 0) { return (char) tud_cdc_read_char(); @@ -88,6 +106,12 @@ char serial_read(void) { } bool serial_bytes_available(void) { +#if CIRCUITPY_USB_VENDOR + if (tud_vendor_connected() && tud_vendor_available() > 0) { + return true; + } +#endif + #if defined(DEBUG_UART_TX) && defined(DEBUG_UART_RX) return common_hal_busio_uart_rx_characters_available(&debug_uart) || (tud_cdc_available() > 0); #else @@ -104,6 +128,12 @@ void serial_write_substring(const char* text, uint32_t length) { common_hal_terminalio_terminal_write(&supervisor_terminal, (const uint8_t*) text, length, &errcode); #endif +#if CIRCUITPY_USB_VENDOR + if (tud_vendor_connected()) { + tud_vendor_write(text, length); + } +#endif + uint32_t count = 0; while (count < length && tud_cdc_connected()) { count += tud_cdc_write(text + count, length - count); diff --git a/supervisor/shared/usb/tusb_config.h b/supervisor/shared/usb/tusb_config.h index 15d9fabaf..d3a35f537 100644 --- a/supervisor/shared/usb/tusb_config.h +++ b/supervisor/shared/usb/tusb_config.h @@ -68,6 +68,7 @@ #define CFG_TUD_MSC 1 #define CFG_TUD_HID CIRCUITPY_USB_HID #define CFG_TUD_MIDI CIRCUITPY_USB_MIDI +#define CFG_TUD_VENDOR CIRCUITPY_USB_VENDOR #define CFG_TUD_CUSTOM_CLASS 0 /*------------------------------------------------------------------*/ diff --git a/supervisor/shared/usb/usb.c b/supervisor/shared/usb/usb.c index 07c6aee6c..43564d5d5 100644 --- a/supervisor/shared/usb/usb.c +++ b/supervisor/shared/usb/usb.c @@ -37,6 +37,19 @@ #include "tusb.h" +#if CIRCUITPY_USB_VENDOR +#include "genhdr/autogen_usb_descriptor.h" + +// The WebUSB support being conditionally added to this file is based on the +// tinyusb demo examples/device/webusb_serial. + +extern const tusb_desc_webusb_url_t desc_webusb_url; + +static bool web_serial_connected = false; +#endif + + + // Serial number as hex characters. This writes directly to the USB // descriptor. extern uint16_t usb_serial_number[1 + COMMON_HAL_MCU_PROCESSOR_UID_LENGTH * 2]; @@ -98,9 +111,14 @@ static void usb_background_do(void* unused) { usb_background(); } +void usb_background_schedule(void) +{ + background_callback_add(&usb_callback, usb_background_do, NULL); +} + void usb_irq_handler(void) { tud_int_handler(0); - background_callback_add(&usb_callback, usb_background_do, NULL); + usb_background_schedule(); } //--------------------------------------------------------------------+ @@ -145,6 +163,62 @@ void tud_cdc_line_state_cb(uint8_t itf, bool dtr, bool rts) { } } +#if CIRCUITPY_USB_VENDOR +//--------------------------------------------------------------------+ +// WebUSB use vendor class +//--------------------------------------------------------------------+ + +bool tud_vendor_connected(void) +{ + return web_serial_connected; +} + +// Invoked when a control transfer occurred on an interface of this class +// Driver response accordingly to the request and the transfer stage (setup/data/ack) +// return false to stall control endpoint (e.g unsupported request) +bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const * request) +{ + // nothing to with DATA & ACK stage + if (stage != CONTROL_STAGE_SETUP ) return true; + + switch (request->bRequest) + { + case VENDOR_REQUEST_WEBUSB: + // match vendor request in BOS descriptor + // Get landing page url + return tud_control_xfer(rhport, request, (void*) &desc_webusb_url, desc_webusb_url.bLength); + + case VENDOR_REQUEST_MICROSOFT: + if ( request->wIndex == 7 ) + { + // Get Microsoft OS 2.0 compatible descriptor + uint16_t total_len; + memcpy(&total_len, desc_ms_os_20+8, 2); + + return tud_control_xfer(rhport, request, (void*) desc_ms_os_20, total_len); + } else + { + return false; + } + + case 0x22: + // Webserial simulate the CDC_REQUEST_SET_CONTROL_LINE_STATE (0x22) to + // connect and disconnect. + web_serial_connected = (request->wValue != 0); + + // response with status OK + return tud_control_status(rhport, request); + + default: + // stall unknown request + return false; + } + + return true; +} +#endif CIRCUITPY_USB_VENDOR + + #if MICROPY_KBD_EXCEPTION /** |
