webusb work great with linux

This commit is contained in:
hathach 2019-07-26 11:36:30 +07:00
parent 570a2b2053
commit d2b60b6755
5 changed files with 124 additions and 44 deletions

View File

@ -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; i<count; i++)
{
tud_cdc_write_char(buf[i]);
if ( buf[i] == '\r' ) tud_cdc_write_char('\n');
}
tud_cdc_write_flush();
}
}
//--------------------------------------------------------------------+
// WebUSB
// 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)
{
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);
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; i<count; i++)
{
tud_cdc_write_char(buf[i]);
if ( buf[i] == '\r' ) tud_cdc_write_char('\n');
}
tud_cdc_write_flush();
// echo back to both web serial and cdc
echo_all(buf, count);
}
}
}

View File

@ -24,6 +24,7 @@
*/
#include "tusb.h"
#include "usb_descriptors.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.
@ -72,11 +73,6 @@ uint8_t const * tud_descriptor_device_cb(void)
//--------------------------------------------------------------------+
// BOS Descriptor
//--------------------------------------------------------------------+
enum
{
VENDOR_REQUEST_WEBUSB = 1,
};
#define BOS_TOTAL_LEN (TUD_BOS_DESC_LEN + TUD_BOS_WEBUSB_DESC_LEN)
// BOS Descriptor is required for webUSB
@ -192,29 +188,4 @@ uint16_t const* tud_descriptor_string_cb(uint8_t index)
//--------------------------------------------------------------------+
// WebUSB URL Descriptor
//--------------------------------------------------------------------+
#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
};
bool tud_vendor_control_request_cb(uint8_t rhport, tusb_control_request_t const * request)
{
if ( request->bRequest == 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;
}

View File

@ -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_ */

View File

@ -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;

View File

@ -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
},