diff --git a/src/usb/lwip/usb_descriptors.c b/src/usb/lwip/usb_descriptors.c deleted file mode 100644 index c976cb6..0000000 --- a/src/usb/lwip/usb_descriptors.c +++ /dev/null @@ -1,369 +0,0 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2019 Ha Thach (tinyusb.org) - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - */ - -#include "bsp/board_api.h" -#include "class/net/net_device.h" -#include "tusb.h" - -/* A combination of interfaces must have a unique product id, since PC will save device driver after the first plug. - * Same VID/PID with different interface e.g MSC (first), then CDC (later) will possibly cause system error on PC. - * - * Auto ProductID layout's Bitmap: - * [MSB] NET | VENDOR | MIDI | HID | MSC | CDC [LSB] - */ -#define PID_MAP(itf, n) ((CFG_TUD_##itf) ? (1 << (n)) : 0) -#define USB_PID \ - (0x4000 | PID_MAP(CDC, 0) | PID_MAP(MSC, 1) | PID_MAP(HID, 2) | PID_MAP(MIDI, 3) | PID_MAP(VENDOR, 4) | \ - PID_MAP(ECM_RNDIS, 5) | PID_MAP(NCM, 5)) - -// String Descriptor Index -enum { - STRID_LANGID = 0, - STRID_MANUFACTURER, - STRID_PRODUCT, - STRID_SERIAL, - STRID_INTERFACE, - STRID_MAC, - STRID_COUNT -}; - -enum { - ITF_NUM_CDC = 0, - ITF_NUM_CDC_DATA, - ITF_NUM_TOTAL -}; - -enum { -#if CFG_TUD_ECM_RNDIS - CONFIG_ID_RNDIS = 0, - CONFIG_ID_ECM = 1, -#else - CONFIG_ID_NCM = 0, -#endif - CONFIG_ID_COUNT -}; - -//--------------------------------------------------------------------+ -// Device Descriptors -//--------------------------------------------------------------------+ -static const tusb_desc_device_t desc_device = { - .bLength = sizeof(tusb_desc_device_t), - .bDescriptorType = TUSB_DESC_DEVICE, -#if CFG_TUD_NCM - .bcdUSB = 0x0201, -#else - .bcdUSB = 0x0200, -#endif - // Use Interface Association Descriptor (IAD) device class - .bDeviceClass = TUSB_CLASS_MISC, - .bDeviceSubClass = MISC_SUBCLASS_COMMON, - .bDeviceProtocol = MISC_PROTOCOL_IAD, - - .bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE, - - .idVendor = 0xCafe, - .idProduct = USB_PID, - .bcdDevice = 0x0101, - - .iManufacturer = STRID_MANUFACTURER, - .iProduct = STRID_PRODUCT, - .iSerialNumber = STRID_SERIAL, - - .bNumConfigurations = CONFIG_ID_COUNT // multiple configurations -}; - -// Invoked when received GET DEVICE DESCRIPTOR -// Application return pointer to descriptor -const uint8_t *tud_descriptor_device_cb(void) { - return (const uint8_t *)&desc_device; -} - -//--------------------------------------------------------------------+ -// Configuration Descriptor -//--------------------------------------------------------------------+ -#define MAIN_CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_RNDIS_DESC_LEN) -#define ALT_CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_CDC_ECM_DESC_LEN) -#define NCM_CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_CDC_NCM_DESC_LEN) - -#if CFG_TUSB_MCU == OPT_MCU_LPC175X_6X || CFG_TUSB_MCU == OPT_MCU_LPC177X_8X || CFG_TUSB_MCU == OPT_MCU_LPC40XX -// LPC 17xx and 40xx endpoint type (bulk/interrupt/iso) are fixed by its number -// 0 control, 1 In, 2 Bulk, 3 Iso, 4 In etc ... -#define EPNUM_NET_NOTIF 0x81 -#define EPNUM_NET_OUT 0x02 -#define EPNUM_NET_IN 0x82 - -#elif CFG_TUSB_MCU == OPT_MCU_CXD56 -// CXD56 USB driver has fixed endpoint type (bulk/interrupt/iso) and direction (IN/OUT) by its number -// 0 control (IN/OUT), 1 Bulk (IN), 2 Bulk (OUT), 3 In (IN), 4 Bulk (IN), 5 Bulk (OUT), 6 In (IN) -#define EPNUM_NET_NOTIF 0x83 -#define EPNUM_NET_OUT 0x02 -#define EPNUM_NET_IN 0x81 - -#elif defined(TUD_ENDPOINT_ONE_DIRECTION_ONLY) -// MCUs that don't support a same endpoint number with different direction IN and OUT defined in tusb_mcu.h -// e.g EP1 OUT & EP1 IN cannot exist together -#define EPNUM_NET_NOTIF 0x81 -#define EPNUM_NET_OUT 0x02 -#define EPNUM_NET_IN 0x83 - -#else -#define EPNUM_NET_NOTIF 0x81 -#define EPNUM_NET_OUT 0x02 -#define EPNUM_NET_IN 0x82 -#endif - -#if CFG_TUD_ECM_RNDIS - -static uint8_t const rndis_configuration[] = { - // Config number (index+1), interface count, string index, total length, attribute, power in mA - TUD_CONFIG_DESCRIPTOR(CONFIG_ID_RNDIS + 1, ITF_NUM_TOTAL, 0, MAIN_CONFIG_TOTAL_LEN, 0, 100), - - // Interface number, string index, EP notification address and size, EP data address (out, in) and size. - TUD_RNDIS_DESCRIPTOR( - ITF_NUM_CDC, STRID_INTERFACE, EPNUM_NET_NOTIF, 8, EPNUM_NET_OUT, EPNUM_NET_IN, CFG_TUD_NET_ENDPOINT_SIZE), -}; - -static const uint8_t ecm_configuration[] = { - // Config number (index+1), interface count, string index, total length, attribute, power in mA - TUD_CONFIG_DESCRIPTOR(CONFIG_ID_ECM + 1, ITF_NUM_TOTAL, 0, ALT_CONFIG_TOTAL_LEN, 0, 100), - - // Interface number, description string index, MAC address string index, EP notification address and size, EP data address (out, in), and size, max segment size. - TUD_CDC_ECM_DESCRIPTOR( - ITF_NUM_CDC, STRID_INTERFACE, STRID_MAC, EPNUM_NET_NOTIF, 64, EPNUM_NET_OUT, EPNUM_NET_IN, - CFG_TUD_NET_ENDPOINT_SIZE, CFG_TUD_NET_MTU), -}; - -#else - -static uint8_t const ncm_configuration[] = { - // Config number (index+1), interface count, string index, total length, attribute, power in mA - TUD_CONFIG_DESCRIPTOR(CONFIG_ID_NCM + 1, ITF_NUM_TOTAL, 0, NCM_CONFIG_TOTAL_LEN, 0, 100), - - // Interface number, description string index, MAC address string index, EP notification address and size, EP data address (out, in), and size, max segment size. - TUD_CDC_NCM_DESCRIPTOR( - ITF_NUM_CDC, STRID_INTERFACE, STRID_MAC, EPNUM_NET_NOTIF, 64, EPNUM_NET_OUT, EPNUM_NET_IN, - CFG_TUD_NET_ENDPOINT_SIZE, CFG_TUD_NET_MTU), -}; - -#endif - -// Configuration array: RNDIS and CDC-ECM -// - Windows only works with RNDIS -// - MacOS only works with CDC-ECM -// - Linux will work on both -static const uint8_t *const configuration_arr[CONFIG_ID_COUNT] = { -#if CFG_TUD_ECM_RNDIS - [CONFIG_ID_RNDIS] = rndis_configuration, - [CONFIG_ID_ECM] = ecm_configuration -#else - [CONFIG_ID_NCM] = ncm_configuration -#endif -}; - -// Invoked when received GET CONFIGURATION DESCRIPTOR -// Application return pointer to descriptor -// Descriptor contents must exist long enough for transfer to complete -const uint8_t *tud_descriptor_configuration_cb(uint8_t index) { - return (index < CONFIG_ID_COUNT) ? configuration_arr[index] : NULL; -} - -#if CFG_TUD_NCM -//--------------------------------------------------------------------+ -// BOS Descriptor -//--------------------------------------------------------------------+ - -/* Used to automatically load the NCM driver on Windows 10, otherwise manual driver install is needed. - Associate NCM interface with WINNCM driver. */ - -/* Microsoft OS 2.0 registry property descriptor -Per MS requirements https://msdn.microsoft.com/en-us/library/windows/hardware/hh450799(v=vs.85).aspx -device should create DeviceInterfaceGUIDs. It can be done by driver and -in case of real PnP solution device should expose MS "Microsoft OS 2.0 -registry property descriptor". Such descriptor can insert any record -into Windows registry per device/configuration/interface. In our case it -will insert "DeviceInterfaceGUIDs" multistring property. - -GUID is freshly generated and should be OK to use. - -https://developers.google.com/web/fundamentals/native-hardware/build-for-webusb/ -(Section Microsoft OS compatibility descriptors) -*/ - -#define BOS_TOTAL_LEN (TUD_BOS_DESC_LEN + TUD_BOS_MICROSOFT_OS_DESC_LEN) - -#define MS_OS_20_DESC_LEN 0xB2 - -// BOS Descriptor is required for webUSB -const uint8_t desc_bos[] = { - // total length, number of device caps - TUD_BOS_DESCRIPTOR(BOS_TOTAL_LEN, 1), - - // Microsoft OS 2.0 descriptor - TUD_BOS_MS_OS_20_DESCRIPTOR(MS_OS_20_DESC_LEN, 1)}; - -const uint8_t *tud_descriptor_bos_cb(void) { - return desc_bos; -} - -const uint8_t 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_CDC, 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', 'N', 'C', 'M', 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: {12345678-0D08-43FD-8B3E-127CA8AFFF9D} - '{', 0x00, '1', 0x00, '2', 0x00, '3', 0x00, '4', 0x00, '5', 0x00, '6', 0x00, '7', 0x00, '8', 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"); - -// 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, const tusb_control_request_t *request) { - // nothing to with DATA & ACK stage - if (stage != CONTROL_STAGE_SETUP) { - return true; - } - - switch (request->bmRequestType_bit.type) { - case TUSB_REQ_TYPE_VENDOR: - switch (request->bRequest) { - case 1: - 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 *)(uintptr_t)desc_ms_os_20, total_len); - } else { - return false; - } - - default: - break; // nothing to do - } - break; - - default: - break; // nothing to do - } - - // stall unknown request - return false; -} - -#endif -//--------------------------------------------------------------------+ -// String Descriptors -//--------------------------------------------------------------------+ - -// array of pointer to string descriptors -static const char *string_desc_arr[STRID_COUNT] = { - [STRID_LANGID] = (const char[]){0x09, 0x04}, // supported language is English (0x0409) - [STRID_MANUFACTURER] = "TinyUSB", // Manufacturer - [STRID_PRODUCT] = "TinyUSB Device", // Product - [STRID_SERIAL] = NULL, // Serials will use unique ID if possible - [STRID_INTERFACE] = "TinyUSB Network Interface", // Interface Description - [STRID_MAC] = NULL // STRID_MAC index is handled separately -}; - -static uint16_t _desc_str[32 + 1]; - -// Invoked when received GET STRING DESCRIPTOR request -// Application return pointer to descriptor, whose contents must exist long enough for transfer to complete -const uint16_t *tud_descriptor_string_cb(uint8_t index, uint16_t langid) { - (void)langid; - unsigned int chr_count = 0; - - switch (index) { - case STRID_LANGID: - memcpy(&_desc_str[1], string_desc_arr[0], 2); - chr_count = 1; - break; - - case STRID_SERIAL: - chr_count = board_usb_get_serial(_desc_str + 1, 32); - break; - - case STRID_MAC: - // Convert MAC address into UTF-16 - for (unsigned i = 0; i < sizeof(tud_network_mac_address); i++) { - _desc_str[1 + chr_count++] = "0123456789ABCDEF"[(tud_network_mac_address[i] >> 4) & 0xf]; - _desc_str[1 + chr_count++] = "0123456789ABCDEF"[(tud_network_mac_address[i] >> 0) & 0xf]; - } - break; - - default: { - // Note: the 0xEE index string is a Microsoft OS 1.0 Descriptors. - // https://docs.microsoft.com/en-us/windows-hardware/drivers/usbcon/microsoft-defined-usb-descriptors - - if (index >= sizeof(string_desc_arr) / sizeof(string_desc_arr[0])) { - return NULL; - } - - const char *str = string_desc_arr[index]; - - // Cap at max char - chr_count = strlen(str); - - const size_t max_count = sizeof(_desc_str) / sizeof(_desc_str[0]) - 1; // -1 for string type - if (chr_count > max_count) { - chr_count = max_count; - } - - // Convert ASCII string into UTF-16 - for (size_t i = 0; i < chr_count; i++) { - _desc_str[1 + i] = str[i]; - } - break; - } - } - - // first byte is length (including header), second byte is string type - _desc_str[0] = (uint16_t)((TUSB_DESC_STRING << 8) | (2 * chr_count + 2)); - - return _desc_str; -}