diff options
| author | Dan Halbert <halbert@halwitz.org> | 2021-02-11 18:50:02 -0500 |
|---|---|---|
| committer | Dan Halbert <halbert@halwitz.org> | 2021-02-11 18:50:02 -0500 |
| commit | f0564b49862eaef0b9752b62d80ef00e3e12a3ee (patch) | |
| tree | 79a48a30955bdc7ae4e1971135809a0593130417 /supervisor | |
| parent | 1b7f3d11e73be5cb0f7a97a528fedad87624b97f (diff) | |
| parent | 206109763f3d8b8dc92a5f5bf1bfabb49ce9c7b7 (diff) | |
merge from upstream; complicated webusb merge
Diffstat (limited to 'supervisor')
| -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 | ||||
| -rw-r--r-- | supervisor/shared/usb/usb_desc.c | 2 | ||||
| -rw-r--r-- | supervisor/supervisor.mk | 26 | ||||
| -rw-r--r-- | supervisor/usb.h | 3 |
7 files changed, 132 insertions, 9 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 6199af379..40151cbf6 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 @@ -103,6 +127,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 0e70367d0..bff7bd6b5 100644 --- a/supervisor/shared/usb/tusb_config.h +++ b/supervisor/shared/usb/tusb_config.h @@ -73,6 +73,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 /** diff --git a/supervisor/shared/usb/usb_desc.c b/supervisor/shared/usb/usb_desc.c index 080187ebc..419a70ab3 100644 --- a/supervisor/shared/usb/usb_desc.c +++ b/supervisor/shared/usb/usb_desc.c @@ -43,12 +43,14 @@ uint8_t const * tud_descriptor_configuration_cb(uint8_t index) { return usb_desc_cfg; } +#if CIRCUITPY_USB_HID // Invoked when received GET HID REPORT DESCRIPTOR // Application return pointer to descriptor // Descriptor contents must exist long enough for transfer to complete uint8_t const * tud_hid_descriptor_report_cb(void) { return hid_report_descriptor; } +#endif // Invoked when received GET STRING DESCRIPTOR request // Application return pointer to descriptor, whose contents must exist long enough for transfer to complete diff --git a/supervisor/supervisor.mk b/supervisor/supervisor.mk index 8fd32fa0b..b36b9bc00 100644 --- a/supervisor/supervisor.mk +++ b/supervisor/supervisor.mk @@ -22,7 +22,7 @@ CFLAGS += -DINTERNAL_FLASH_FILESYSTEM=$(INTERNAL_FLASH_FILESYSTEM) QSPI_FLASH_FILESYSTEM ?= 0 CFLAGS += -DQSPI_FLASH_FILESYSTEM=$(QSPI_FLASH_FILESYSTEM) -SPI_FLASH_FILESYSTEM = 0 +SPI_FLASH_FILESYSTEM ?= 0 CFLAGS += -DSPI_FLASH_FILESYSTEM=$(SPI_FLASH_FILESYSTEM) ifeq ($(CIRCUITPY_BLEIO),1) @@ -94,6 +94,11 @@ else shared-module/usb_midi/PortOut.c endif + ifeq ($(CIRCUITPY_USB_VENDOR), 1) + SRC_SUPERVISOR += \ + lib/tinyusb/src/class/vendor/vendor_device.c + endif + CFLAGS += -DUSB_AVAILABLE endif @@ -117,10 +122,10 @@ CFLAGS += -DUSB_MANUFACTURER=$(USB_MANUFACTURER) CFLAGS += -DUSB_PRODUCT=$(USB_PRODUCT) endif -USB_DEVICES = -ifeq ($(CIRCUITPY_USB_HID),1) -USB_DEVICES += HID -endif +# In the following URL, don't include the https:// prefix. +# It gets added automatically. +USB_WEBUSB_URL ?= "circuitpython.org" + ifeq ($(CIRCUITPY_USB_MIDI),1) USB_DEVICES += AUDIO endif @@ -135,6 +140,9 @@ ifeq ($(CIRCUITPY_USB_SERIAL2),1) CFLAGS += -DCFG_TUD_CDC=2 USB_DEVICES += CDC2 endif +ifeq ($(CIRCUITPY_USB_VENDOR),1) +USB_DEVICES += VENDOR +endif USB_HID_DEVICES = ifeq ($(CIRCUITPY_USB_HID_CONSUMER),1) @@ -163,7 +171,7 @@ endif ifeq ($(CIRCUITPY_USB_HID_RAW),1) ifneq ($(CIRCUITPY_USB_HID_DEVICES,) $(error HID RAW must not be combined with other HID devices) - endif +endif USB_HID_DEVICES += MOUSE endif @@ -202,6 +210,12 @@ USB_DESCRIPTOR_ARGS = \ --output_c_file $(BUILD)/autogen_usb_descriptor.c\ --output_h_file $(BUILD)/genhdr/autogen_usb_descriptor.h +ifeq ($(CIRCUITPY_USB_VENDOR), 1) +USB_DESCRIPTOR_ARGS += \ + --vendor_ep_num_out 0 --vendor_ep_num_in 0 \ + --webusb_url $(USB_WEBUSB_URL) +endif + ifeq ($(USB_RENUMBER_ENDPOINTS), 0) USB_DESCRIPTOR_ARGS += --no-renumber_endpoints endif diff --git a/supervisor/usb.h b/supervisor/usb.h index ccb35470c..1c709926a 100644 --- a/supervisor/usb.h +++ b/supervisor/usb.h @@ -35,6 +35,9 @@ // it may be necessary to call it directly. void usb_background(void); +// Schedule usb background +void usb_background_schedule(void); + // Ports must call this from their particular USB IRQ handler void usb_irq_handler(void); |
