diff --git a/examples/device/webusb/src/main.c b/examples/device/webusb/src/main.c index cfcbf4da5..bf5598b18 100644 --- a/examples/device/webusb/src/main.c +++ b/examples/device/webusb/src/main.c @@ -29,6 +29,7 @@ #include "bsp/board.h" #include "tusb.h" +#include "usb_descriptors.h" //--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF PROTYPES @@ -47,6 +48,19 @@ enum { static uint32_t blink_interval_ms = BLINK_NOT_MOUNTED; +#define URL "github.com/hathach/tinyusb" + +const tusb_desc_webusb_url_t desc_url = +{ + .bLength = 3 + sizeof(URL) - 1, + .bDescriptorType = 3, // WEBUSB URL type + .bScheme = 1, // 0: http, 1: https + .url = URL +}; + +static bool web_serial_connected = false; + +//------------- prototypes -------------// void led_blinking_task(void); void cdc_task(void); void webserial_task(void); @@ -100,14 +114,83 @@ void tud_resume_cb(void) blink_interval_ms = BLINK_MOUNTED; } +// send characters to both CDC and WebUSB +void echo_all(uint8_t buf[], uint32_t count) +{ + // echo to web serial + if ( web_serial_connected ) + { + tud_vendor_write(buf, count); + } + + // echo to cdc + if ( tud_cdc_connected() ) + { + for(uint32_t i=0; ibRequest) + { + 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); + + 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; + } +} + +// 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; + + // nothing to do + return true; +} + void webserial_task(void) { + if ( web_serial_connected ) + { + if ( tud_vendor_available() ) + { + uint8_t buf[64]; + uint32_t count = tud_vendor_read(buf, sizeof(buf)); + // echo back to both web serial and cdc + echo_all(buf, count); + } + } } + //--------------------------------------------------------------------+ // USB CDC //--------------------------------------------------------------------+ @@ -120,17 +203,10 @@ void cdc_task(void) { uint8_t buf[64]; - // read and echo back uint32_t count = tud_cdc_read(buf, sizeof(buf)); - for(uint32_t i=0; ibRequest == VENDOR_REQUEST_WEBUSB ) - { - return tud_control_xfer(rhport, request, (void*) &desc_url, desc_url.bLength); - }else - { - return false; - } -} - -bool tud_vendor_control_complete_cb(uint8_t rhport, tusb_control_request_t const * request) -{ - (void) rhport; - return true; -} diff --git a/examples/device/webusb/src/usb_descriptors.h b/examples/device/webusb/src/usb_descriptors.h new file mode 100644 index 000000000..d45e720df --- /dev/null +++ b/examples/device/webusb/src/usb_descriptors.h @@ -0,0 +1,33 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019 hathach for Adafruit Industries + * + * 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. + */ + +#ifndef USB_DESCRIPTORS_H_ +#define USB_DESCRIPTORS_H_ + +enum +{ + VENDOR_REQUEST_WEBUSB = 1, +}; + +#endif /* USB_DESCRIPTORS_H_ */ diff --git a/src/class/msc/msc_device.c b/src/class/msc/msc_device.c index 07686663b..2ec8962ae 100644 --- a/src/class/msc/msc_device.c +++ b/src/class/msc/msc_device.c @@ -178,10 +178,10 @@ bool mscd_control_request(uint8_t rhport, tusb_control_request_t const * p_reque // Invoked when class request DATA stage is finished. // return false to stall control endpoint (e.g Host send non-sense DATA) -bool mscd_control_complete(uint8_t rhport, tusb_control_request_t const * p_request) +bool mscd_control_complete(uint8_t rhport, tusb_control_request_t const * request) { (void) rhport; - (void) p_request; + (void) request; // nothing to do return true; diff --git a/src/device/usbd.c b/src/device/usbd.c index c94d08a67..f737f5d36 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -136,8 +136,8 @@ static usbd_class_driver_t const usbd_class_drivers[] = .init = vendord_init, .reset = vendord_reset, .open = vendord_open, - .control_request = NULL, // tud_vendor_control_request_cb - .control_complete = NULL, // tud_vendor_control_complete_cb + .control_request = tud_vendor_control_request_cb, + .control_complete = tud_vendor_control_complete_cb, .xfer_cb = vendord_xfer_cb, .sof = NULL },