Most of the code we need has been pulled in from the tinyusb webusb_serial demo. Still LOTS to do regarding descriptors.
This commit is contained in:
parent
9ce33a5771
commit
fbfb7b68cc
@ -164,7 +164,9 @@ LIBS += -lm
|
||||
endif
|
||||
|
||||
# TinyUSB defines
|
||||
CFLAGS += -DCFG_TUSB_MCU=OPT_MCU_ESP32S2 -DCFG_TUSB_OS=OPT_OS_FREERTOS -DCFG_TUD_CDC_RX_BUFSIZE=1024 -DCFG_TUD_CDC_TX_BUFSIZE=1024 -DCFG_TUD_MSC_BUFSIZE=4096 -DCFG_TUD_MIDI_RX_BUFSIZE=128 -DCFG_TUD_MIDI_TX_BUFSIZE=128
|
||||
CFLAGS += -DCFG_TUSB_MCU=OPT_MCU_ESP32S2 -DCFG_TUSB_OS=OPT_OS_FREERTOS -DCFG_TUD_CDC_RX_BUFSIZE=1024 -DCFG_TUD_CDC_TX_BUFSIZE=1024
|
||||
CFLAGS += -DCFG_TUD_MSC_BUFSIZE=4096 -DCFG_TUD_MIDI_RX_BUFSIZE=128 -DCFG_TUD_MIDI_TX_BUFSIZE=128
|
||||
CFLAGS += -DCFG_TUD_VENDOR_RX_BUFSIZE=128 -DCFG_TUD_VENDOR_TX_BUFSIZE=128
|
||||
|
||||
|
||||
######################################
|
||||
|
@ -30,6 +30,8 @@ CIRCUITPY_ROTARYIO = 1
|
||||
CIRCUITPY_NVM = 1
|
||||
# We don't have enough endpoints to include MIDI.
|
||||
CIRCUITPY_USB_MIDI = 0
|
||||
# We have borrowed the VENDOR nomenclature from tinyusb. VENDOR AKA WEBUSB
|
||||
CIRCUITPY_USB_VENDOR = 1
|
||||
CIRCUITPY_WIFI = 1
|
||||
CIRCUITPY_WATCHDOG ?= 1
|
||||
CIRCUITPY_ESPIDF = 1
|
||||
|
@ -288,6 +288,9 @@ endif
|
||||
ifeq ($(CIRCUITPY_USB_MIDI),1)
|
||||
SRC_PATTERNS += usb_midi/%
|
||||
endif
|
||||
ifeq ($(CIRCUITPY_USB_VENDOR),1)
|
||||
SRC_PATTERNS += usb_vendor/%
|
||||
endif
|
||||
ifeq ($(CIRCUITPY_USTACK),1)
|
||||
SRC_PATTERNS += ustack/%
|
||||
endif
|
||||
|
@ -270,6 +270,9 @@ CFLAGS += -DCIRCUITPY_USB_HID=$(CIRCUITPY_USB_HID)
|
||||
CIRCUITPY_USB_MIDI ?= 1
|
||||
CFLAGS += -DCIRCUITPY_USB_MIDI=$(CIRCUITPY_USB_MIDI)
|
||||
|
||||
CIRCUITPY_USB_VENDOR ?= 1
|
||||
CFLAGS += -DCIRCUITPY_USB_VENDOR=$(CIRCUITPY_USB_VENDOR)
|
||||
|
||||
CIRCUITPY_PEW ?= 0
|
||||
CFLAGS += -DCIRCUITPY_PEW=$(CIRCUITPY_PEW)
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
||||
/*------------------------------------------------------------------*/
|
||||
|
@ -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
|
||||
|
||||
/**
|
||||
|
@ -102,6 +102,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
|
||||
|
||||
@ -119,6 +124,10 @@ ifndef USB_INTERFACE_NAME
|
||||
USB_INTERFACE_NAME = "CircuitPython"
|
||||
endif
|
||||
|
||||
ifndef USB_WEBUSB_URL
|
||||
USB_WEBUSB_URL = "www.circuitpython.org"
|
||||
endif
|
||||
|
||||
USB_DEVICES_COMPUTED := CDC,MSC
|
||||
ifeq ($(CIRCUITPY_USB_MIDI),1)
|
||||
USB_DEVICES_COMPUTED := $(USB_DEVICES_COMPUTED),AUDIO
|
||||
@ -126,6 +135,9 @@ endif
|
||||
ifeq ($(CIRCUITPY_USB_HID),1)
|
||||
USB_DEVICES_COMPUTED := $(USB_DEVICES_COMPUTED),HID
|
||||
endif
|
||||
ifeq ($(CIRCUITPY_USB_VENDOR),1)
|
||||
USB_DEVICES_COMPUTED := $(USB_DEVICES_COMPUTED),VENDOR
|
||||
endif
|
||||
USB_DEVICES ?= "$(USB_DEVICES_COMPUTED)"
|
||||
|
||||
ifndef USB_HID_DEVICES
|
||||
@ -198,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
|
||||
|
@ -484,6 +484,7 @@ h_file = args.output_h_file
|
||||
c_file.write("""\
|
||||
#include <stdint.h>
|
||||
|
||||
#include "tusb.h"
|
||||
#include "py/objtuple.h"
|
||||
#include "shared-bindings/usb_hid/Device.h"
|
||||
#include "{H_FILE_NAME}"
|
||||
@ -628,11 +629,13 @@ extern const uint8_t hid_report_descriptor[{hid_report_descriptor_length}];
|
||||
msc_vendor=args.manufacturer[:8],
|
||||
msc_product=args.product[:16]))
|
||||
|
||||
if 'VENDOR' in args.devices:
|
||||
h_file.write("""\
|
||||
extern const tusb_desc_webusb_url_t desc_webusb_url;
|
||||
|
||||
""")
|
||||
# Currently getting compile-time errors in files like tusb_fifo.c
|
||||
# if we try do define this here (TODO figure this out!)
|
||||
#if 'VENDOR' in args.devices:
|
||||
# h_file.write("""\
|
||||
#extern const tusb_desc_webusb_url_t desc_webusb_url;
|
||||
#
|
||||
#""")
|
||||
|
||||
h_file.write("""\
|
||||
#endif // MICROPY_INCLUDED_AUTOGEN_USB_DESCRIPTOR_H
|
||||
@ -719,4 +722,44 @@ const tusb_desc_webusb_url_t desc_webusb_url =
|
||||
.bScheme = 1, // 0: http, 1: https, 255: ""
|
||||
.url = URL
|
||||
}};
|
||||
|
||||
// This next hardcoded descriptor was pulled from the usb_descriptor.c file of the
|
||||
// tinyusb webusb_serial demo. TODO - this is probably something else to integrate
|
||||
// into the adafruit_usb_descriptors project, especially with this next #define..
|
||||
#define ITF_NUM_VENDOR 6 // SWAG for now.
|
||||
|
||||
#define MS_OS_20_DESC_LEN 0xB2
|
||||
|
||||
uint8_t const desc_ms_os_20[] =
|
||||
{{
|
||||
// Set header: length, type, windows version, total length
|
||||
U16_TO_U8S_LE(0x000A), U16_TO_U8S_LE(MS_OS_20_SET_HEADER_DESCRIPTOR), U32_TO_U8S_LE(0x06030000), U16_TO_U8S_LE(MS_OS_20_DESC_LEN),
|
||||
|
||||
// Configuration subset header: length, type, configuration index, reserved, configuration total length
|
||||
U16_TO_U8S_LE(0x0008), U16_TO_U8S_LE(MS_OS_20_SUBSET_HEADER_CONFIGURATION), 0, 0, U16_TO_U8S_LE(MS_OS_20_DESC_LEN-0x0A),
|
||||
|
||||
// Function Subset header: length, type, first interface, reserved, subset length
|
||||
U16_TO_U8S_LE(0x0008), U16_TO_U8S_LE(MS_OS_20_SUBSET_HEADER_FUNCTION), ITF_NUM_VENDOR, 0, U16_TO_U8S_LE(MS_OS_20_DESC_LEN-0x0A-0x08),
|
||||
|
||||
// MS OS 2.0 Compatible ID descriptor: length, type, compatible ID, sub compatible ID
|
||||
U16_TO_U8S_LE(0x0014), U16_TO_U8S_LE(MS_OS_20_FEATURE_COMPATBLE_ID), 'W', 'I', 'N', 'U', 'S', 'B', 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // sub-compatible
|
||||
|
||||
// MS OS 2.0 Registry property descriptor: length, type
|
||||
U16_TO_U8S_LE(MS_OS_20_DESC_LEN-0x0A-0x08-0x08-0x14), U16_TO_U8S_LE(MS_OS_20_FEATURE_REG_PROPERTY),
|
||||
U16_TO_U8S_LE(0x0007), U16_TO_U8S_LE(0x002A), // wPropertyDataType, wPropertyNameLength and PropertyName "DeviceInterfaceGUIDs\0" in UTF-16
|
||||
'D', 0x00, 'e', 0x00, 'v', 0x00, 'i', 0x00, 'c', 0x00, 'e', 0x00, 'I', 0x00, 'n', 0x00, 't', 0x00, 'e', 0x00,
|
||||
'r', 0x00, 'f', 0x00, 'a', 0x00, 'c', 0x00, 'e', 0x00, 'G', 0x00, 'U', 0x00, 'I', 0x00, 'D', 0x00, 's', 0x00, 0x00, 0x00,
|
||||
U16_TO_U8S_LE(0x0050), // wPropertyDataLength
|
||||
//bPropertyData: “{{975F44D9-0D08-43FD-8B3E-127CA8AFFF9D}}”.
|
||||
'{{', 0x00, '9', 0x00, '7', 0x00, '5', 0x00, 'F', 0x00, '4', 0x00, '4', 0x00, 'D', 0x00, '9', 0x00, '-', 0x00,
|
||||
'0', 0x00, 'D', 0x00, '0', 0x00, '8', 0x00, '-', 0x00, '4', 0x00, '3', 0x00, 'F', 0x00, 'D', 0x00, '-', 0x00,
|
||||
'8', 0x00, 'B', 0x00, '3', 0x00, 'E', 0x00, '-', 0x00, '1', 0x00, '2', 0x00, '7', 0x00, 'C', 0x00, 'A', 0x00,
|
||||
'8', 0x00, 'A', 0x00, 'F', 0x00, 'F', 0x00, 'F', 0x00, '9', 0x00, 'D', 0x00, '}}', 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
}};
|
||||
|
||||
TU_VERIFY_STATIC(sizeof(desc_ms_os_20) == MS_OS_20_DESC_LEN, "Incorrect size");
|
||||
|
||||
// End of section about desc_ms_os_20
|
||||
|
||||
""".format(webusb_url=args.webusb_url))
|
||||
|
Loading…
Reference in New Issue
Block a user