summaryrefslogtreecommitdiff
path: root/supervisor/shared
diff options
context:
space:
mode:
authorKevin Banks <kevin@firia.com>2021-01-25 20:37:58 -0600
committerKevin Banks <kevin@firia.com>2021-01-25 20:37:58 -0600
commitfbfb7b68cce3fbcccc423c1013c0c3cabe6a89d0 (patch)
tree4b2dfe8eebef84fc24d1a9225aa5c4fa2b874488 /supervisor/shared
parent9ce33a5771cd6061e81aeaf2b1c4361490c36b08 (diff)
Most of the code we need has been pulled in from the tinyusb webusb_serial demo. Still LOTS to do regarding descriptors.
Diffstat (limited to 'supervisor/shared')
-rw-r--r--supervisor/shared/serial.c30
-rw-r--r--supervisor/shared/usb/tusb_config.h1
-rw-r--r--supervisor/shared/usb/usb.c76
3 files changed, 107 insertions, 0 deletions
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 ff08ade18..9b0cba8da 100644
--- a/supervisor/shared/usb/usb.c
+++ b/supervisor/shared/usb/usb.c
@@ -37,6 +37,26 @@
#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.
+
+enum
+{
+ VENDOR_REQUEST_WEBUSB = 1,
+ VENDOR_REQUEST_MICROSOFT = 2
+};
+
+extern uint8_t const desc_ms_os_20[];
+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];
@@ -141,6 +161,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
/**