diff options
| author | nxf58843 <[email protected]> | 2021-08-23 09:55:04 -0700 |
|---|---|---|
| committer | GitHub <[email protected]> | 2021-08-23 09:55:04 -0700 |
| commit | fb16e80e575a44828f5367f4fb7380162b0354f0 (patch) | |
| tree | bb965cc935083d99e083667d4f0f1533d50a29f5 /examples/device/webusb_serial/src | |
| parent | 616562a48aa1d8ce2f4ca71f6e780a8bec9fb5eb (diff) | |
| parent | ea902493db49843dcdeca6bfa2b2efe540f44b2f (diff) | |
Merge pull request #2 from hathach/master
Pulling latest from source
Diffstat (limited to 'examples/device/webusb_serial/src')
| -rw-r--r-- | examples/device/webusb_serial/src/main.c | 118 | ||||
| -rw-r--r-- | examples/device/webusb_serial/src/tusb_config.h | 39 | ||||
| -rw-r--r-- | examples/device/webusb_serial/src/usb_descriptors.c | 35 |
3 files changed, 126 insertions, 66 deletions
diff --git a/examples/device/webusb_serial/src/main.c b/examples/device/webusb_serial/src/main.c index e1a098048..aba4aedff 100644 --- a/examples/device/webusb_serial/src/main.c +++ b/examples/device/webusb_serial/src/main.c @@ -23,6 +23,26 @@ * */ +/* This example demonstrates WebUSB as web serial with browser with WebUSB support (e.g Chrome). + * After enumerated successfully, browser will pop-up notification + * with URL to landing page, click on it to test + * - Click "Connect" and select device, When connected the on-board LED will litted up. + * - Any charters received from either webusb/Serial will be echo back to webusb and Serial + * + * Note: + * - The WebUSB landing page notification is currently disabled in Chrome + * on Windows due to Chromium issue 656702 (https://crbug.com/656702). You have to + * go to landing page (below) to test + * + * - On Windows 7 and prior: You need to use Zadig tool to manually bind the + * WebUSB interface with the WinUSB driver for Chrome to access. From windows 8 and 10, this + * is done automatically by firmware. + * + * - On Linux/macOS, udev permission may need to be updated by + * - copying '/examples/device/99-tinyusb.rules' file to /etc/udev/rules.d/ then + * - run 'sudo udevadm control --reload-rules && sudo udevadm trigger' + */ + #include <stdlib.h> #include <stdio.h> #include <string.h> @@ -51,7 +71,7 @@ enum { static uint32_t blink_interval_ms = BLINK_NOT_MOUNTED; -#define URL "www.tinyusb.org/examples/webusb-serial" +#define URL "example.tinyusb.org/webusb-serial/" const tusb_desc_webusb_url_t desc_url = { @@ -143,65 +163,69 @@ void tud_resume_cb(void) // WebUSB use vendor class //--------------------------------------------------------------------+ -// Invoked when received VENDOR control request -bool tud_vendor_control_request_cb(uint8_t rhport, tusb_control_request_t const * request) +// 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) { - 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_url, desc_url.bLength); + // nothing to with DATA & ACK stage + if (stage != CONTROL_STAGE_SETUP) return true; - case VENDOR_REQUEST_MICROSOFT: - if ( request->wIndex == 7 ) + switch (request->bmRequestType_bit.type) + { + case TUSB_REQ_TYPE_VENDOR: + switch (request->bRequest) { - // Get Microsoft OS 2.0 compatible descriptor - uint16_t total_len; - memcpy(&total_len, desc_ms_os_20+8, 2); + case VENDOR_REQUEST_WEBUSB: + // match vendor request in BOS descriptor + // Get landing page url + return tud_control_xfer(rhport, request, (void*) &desc_url, desc_url.bLength); - return tud_control_xfer(rhport, request, (void*) desc_ms_os_20, total_len); - }else - { - return false; - } + 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); - case 0x22: - // Webserial simulate the CDC_REQUEST_SET_CONTROL_LINE_STATE (0x22) to - // connect and disconnect. - web_serial_connected = (request->wValue != 0); + return tud_control_xfer(rhport, request, (void*) desc_ms_os_20, total_len); + }else + { + return false; + } - // Always lit LED if connected - if ( web_serial_connected ) - { - board_led_write(true); - blink_interval_ms = BLINK_ALWAYS_ON; + default: break; + } + break; - tud_vendor_write_str("\r\nTinyUSB WebUSB device example\r\n"); - }else + case TUSB_REQ_TYPE_CLASS: + if (request->bRequest == 0x22) { - blink_interval_ms = BLINK_MOUNTED; - } + // 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); + // Always lit LED if connected + if ( web_serial_connected ) + { + board_led_write(true); + blink_interval_ms = BLINK_ALWAYS_ON; - default: - // stall unknown request - return false; - } + tud_vendor_write_str("\r\nTinyUSB WebUSB device example\r\n"); + }else + { + blink_interval_ms = BLINK_MOUNTED; + } - return true; -} + // response with status OK + return tud_control_status(rhport, request); + } + break; -// Invoked when DATA Stage of VENDOR's request is complete -bool tud_vendor_control_complete_cb(uint8_t rhport, tusb_control_request_t const * request) -{ - (void) rhport; - (void) request; + default: break; + } - // nothing to do - return true; + // stall unknown request + return false; } void webserial_task(void) diff --git a/examples/device/webusb_serial/src/tusb_config.h b/examples/device/webusb_serial/src/tusb_config.h index 30acdaccf..26b81b389 100644 --- a/examples/device/webusb_serial/src/tusb_config.h +++ b/examples/device/webusb_serial/src/tusb_config.h @@ -34,18 +34,39 @@ // COMMON CONFIGURATION //-------------------------------------------------------------------- -// defined by compiler flags for flexibility +// defined by board.mk #ifndef CFG_TUSB_MCU #error CFG_TUSB_MCU must be defined #endif -#if CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX -#define CFG_TUSB_RHPORT0_MODE (OPT_MODE_DEVICE | OPT_MODE_HIGH_SPEED) +// RHPort number used for device can be defined by board.mk, default to port 0 +#ifndef BOARD_DEVICE_RHPORT_NUM + #define BOARD_DEVICE_RHPORT_NUM 0 +#endif + +// RHPort max operational speed can defined by board.mk +// Default to Highspeed for MCU with internal HighSpeed PHY (can be port specific), otherwise FullSpeed +#ifndef BOARD_DEVICE_RHPORT_SPEED + #if (CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX || \ + CFG_TUSB_MCU == OPT_MCU_NUC505 || CFG_TUSB_MCU == OPT_MCU_CXD56) + #define BOARD_DEVICE_RHPORT_SPEED OPT_MODE_HIGH_SPEED + #else + #define BOARD_DEVICE_RHPORT_SPEED OPT_MODE_FULL_SPEED + #endif +#endif + +// Device mode with rhport and speed defined by board.mk +#if BOARD_DEVICE_RHPORT_NUM == 0 + #define CFG_TUSB_RHPORT0_MODE (OPT_MODE_DEVICE | BOARD_DEVICE_RHPORT_SPEED) +#elif BOARD_DEVICE_RHPORT_NUM == 1 + #define CFG_TUSB_RHPORT1_MODE (OPT_MODE_DEVICE | BOARD_DEVICE_RHPORT_SPEED) #else -#define CFG_TUSB_RHPORT0_MODE OPT_MODE_DEVICE + #error "Incorrect RHPort configuration" #endif -#define CFG_TUSB_OS OPT_OS_NONE +#ifndef CFG_TUSB_OS +#define CFG_TUSB_OS OPT_OS_NONE +#endif // CFG_TUSB_DEBUG is defined by compiler in DEBUG build // #define CFG_TUSB_DEBUG 0 @@ -81,13 +102,13 @@ #define CFG_TUD_VENDOR 1 // CDC FIFO size of TX and RX -#define CFG_TUD_CDC_RX_BUFSIZE 64 -#define CFG_TUD_CDC_TX_BUFSIZE 64 +#define CFG_TUD_CDC_RX_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) +#define CFG_TUD_CDC_TX_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) // Vendor FIFO size of TX and RX // If not configured vendor endpoints will not be buffered -#define CFG_TUD_VENDOR_RX_BUFSIZE 64 -#define CFG_TUD_VENDOR_TX_BUFSIZE 64 +#define CFG_TUD_VENDOR_RX_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) +#define CFG_TUD_VENDOR_TX_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) #ifdef __cplusplus diff --git a/examples/device/webusb_serial/src/usb_descriptors.c b/examples/device/webusb_serial/src/usb_descriptors.c index 740defe4e..d1539488f 100644 --- a/examples/device/webusb_serial/src/usb_descriptors.c +++ b/examples/device/webusb_serial/src/usb_descriptors.c @@ -86,23 +86,34 @@ enum #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_CDC 2 - #define EPNUM_VENDOR 5 + #define EPNUM_CDC_IN 2 + #define EPNUM_CDC_OUT 2 + #define EPNUM_VENDOR_IN 5 + #define EPNUM_VENDOR_OUT 5 +#elif CFG_TUSB_MCU == OPT_MCU_SAMG || CFG_TUSB_MCU == OPT_MCU_SAMX7X + // SAMG & SAME70 don't support a same endpoint number with different direction IN and OUT + // e.g EP1 OUT & EP1 IN cannot exist together + #define EPNUM_CDC_IN 2 + #define EPNUM_CDC_OUT 3 + #define EPNUM_VENDOR_IN 4 + #define EPNUM_VENDOR_OUT 5 #else - #define EPNUM_CDC 2 - #define EPNUM_VENDOR 3 + #define EPNUM_CDC_IN 2 + #define EPNUM_CDC_OUT 2 + #define EPNUM_VENDOR_IN 3 + #define EPNUM_VENDOR_OUT 3 #endif uint8_t const desc_configuration[] = { - // Interface count, string index, total length, attribute, power in mA - TUD_CONFIG_DESCRIPTOR(ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP, 100), + // Config number, interface count, string index, total length, attribute, power in mA + TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP, 100), // Interface number, string index, EP notification address and size, EP data address (out, in) and size. - TUD_CDC_DESCRIPTOR(ITF_NUM_CDC, 4, 0x81, 8, EPNUM_CDC, 0x80 | EPNUM_CDC, 64), + TUD_CDC_DESCRIPTOR(ITF_NUM_CDC, 4, 0x81, 8, EPNUM_CDC_OUT, 0x80 | EPNUM_CDC_IN, TUD_OPT_HIGH_SPEED ? 512 : 64), // Interface number, string index, EP Out & IN address, EP size - TUD_VENDOR_DESCRIPTOR(ITF_NUM_VENDOR, 5, EPNUM_VENDOR, 0x80 | EPNUM_VENDOR, 64) + TUD_VENDOR_DESCRIPTOR(ITF_NUM_VENDOR, 5, EPNUM_VENDOR_OUT, 0x80 | EPNUM_VENDOR_IN, TUD_OPT_HIGH_SPEED ? 512 : 64) }; // Invoked when received GET CONFIGURATION DESCRIPTOR @@ -204,8 +215,10 @@ static uint16_t _desc_str[32]; // Invoked when received GET STRING DESCRIPTOR request // Application return pointer to descriptor, whose contents must exist long enough for transfer to complete -uint16_t const* tud_descriptor_string_cb(uint8_t index) +uint16_t const* tud_descriptor_string_cb(uint8_t index, uint16_t langid) { + (void) langid; + uint8_t chr_count; if ( index == 0) @@ -214,7 +227,8 @@ uint16_t const* tud_descriptor_string_cb(uint8_t index) chr_count = 1; }else { - // Convert ASCII string into UTF-16 + // 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; @@ -224,6 +238,7 @@ uint16_t const* tud_descriptor_string_cb(uint8_t index) chr_count = strlen(str); if ( chr_count > 31 ) chr_count = 31; + // Convert ASCII string into UTF-16 for(uint8_t i=0; i<chr_count; i++) { _desc_str[1+i] = str[i]; |
