Skip to content

Commit 7c20752

Browse files
committed
esp32 work with webusb
1 parent 028058d commit 7c20752

File tree

2 files changed

+71
-30
lines changed

2 files changed

+71
-30
lines changed

src/arduino/webusb/Adafruit_USBD_WebUSB.cpp

Lines changed: 67 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838

3939
enum { VENDOR_REQUEST_WEBUSB = 1, VENDOR_REQUEST_MICROSOFT = 2 };
4040

41+
// TODO multiple instances
4142
static Adafruit_USBD_WebUSB *_webusb_dev = NULL;
4243

4344
//--------------------------------------------------------------------+
@@ -73,9 +74,8 @@ uint8_t const desc_bos[] = {
7374
TUD_BOS_WEBUSB_DESCRIPTOR(VENDOR_REQUEST_WEBUSB, 1),
7475

7576
// Microsoft OS 2.0 descriptor
76-
TUD_BOS_MS_OS_20_DESCRIPTOR(MS_OS_20_DESC_LEN, VENDOR_REQUEST_MICROSOFT)};
77-
78-
uint8_t const *tud_descriptor_bos_cb(void) { return desc_bos; }
77+
TUD_BOS_MS_OS_20_DESCRIPTOR(MS_OS_20_DESC_LEN, VENDOR_REQUEST_MICROSOFT)
78+
};
7979

8080
uint8_t desc_ms_os_20[] = {
8181
// Set header: length, type, windows version, total length
@@ -118,19 +118,54 @@ uint8_t desc_ms_os_20[] = {
118118

119119
TU_VERIFY_STATIC(sizeof(desc_ms_os_20) == MS_OS_20_DESC_LEN, "Incorrect size");
120120

121-
//------------- IMPLEMENTATION -------------//
121+
//--------------------------------------------------------------------+
122+
// IMPLEMENTATION
123+
//--------------------------------------------------------------------+
124+
125+
#ifdef ARDUINO_ARCH_ESP32
126+
static uint16_t webusb_load_descriptor(uint8_t * dst, uint8_t * itf)
127+
{
128+
// uint8_t str_index = tinyusb_add_string_descriptor("TinyUSB MSC");
129+
uint8_t str_index = 0;
130+
131+
uint8_t ep_in = tinyusb_get_free_in_endpoint();
132+
uint8_t ep_out = tinyusb_get_free_out_endpoint();
133+
TU_VERIFY (ep_in && ep_out);
134+
ep_in |= 0x80;
135+
136+
uint16_t desc_len = _webusb_dev->getInterfaceDescriptor(0, NULL, 0);
137+
138+
desc_len = _webusb_dev->makeItfDesc(*itf, dst, desc_len, ep_in, ep_out);
139+
140+
*itf+=1;
141+
return desc_len;
142+
}
143+
#endif
144+
122145

123-
Adafruit_USBD_WebUSB::Adafruit_USBD_WebUSB(void) {
146+
Adafruit_USBD_WebUSB::Adafruit_USBD_WebUSB(const void *url) {
124147
_connected = false;
125-
_url = NULL;
148+
_url = (const uint8_t *) url;
126149
_linestate_cb = NULL;
150+
151+
#ifdef ARDUINO_ARCH_ESP32
152+
// ESP32 requires setup configuration descriptor within constructor
153+
154+
// WebUSB requires USB version at least 2.1 (or 3.x)
155+
USB.usbVersion(0x0210);
156+
157+
_webusb_dev = this;
158+
uint16_t const desc_len = getInterfaceDescriptor(0, NULL, 0);
159+
tinyusb_enable_interface(USB_INTERFACE_VENDOR, desc_len, webusb_load_descriptor);
160+
#endif
127161
}
128162

129163
bool Adafruit_USBD_WebUSB::begin(void) {
130-
if (!TinyUSBDevice.addInterface(*this))
164+
if (!TinyUSBDevice.addInterface(*this)) {
131165
return false;
166+
}
132167

133-
// WebUSB requires to change USB version from 2.0 to 2.1
168+
// WebUSB requires USB version at least 2.1 (or 3.x)
134169
TinyUSBDevice.setVersion(0x0210);
135170

136171
_webusb_dev = this;
@@ -146,26 +181,33 @@ void Adafruit_USBD_WebUSB::setLineStateCallback(linestate_callback_t fp) {
146181
_linestate_cb = fp;
147182
}
148183

149-
uint16_t Adafruit_USBD_WebUSB::getInterfaceDescriptor(uint8_t itfnum,
150-
uint8_t *buf,
151-
uint16_t bufsize) {
152-
// usb core will automatically update endpoint number
153-
uint8_t desc[] = {TUD_VENDOR_DESCRIPTOR(itfnum, 0, EPOUT, EPIN, 64)};
184+
uint16_t Adafruit_USBD_WebUSB::makeItfDesc(uint8_t itfnum, uint8_t *buf, uint16_t bufsize, uint8_t ep_in, uint8_t ep_out) {
185+
uint8_t desc[] = {TUD_VENDOR_DESCRIPTOR(itfnum, 0, ep_out, ep_in, EPSIZE)};
154186
uint16_t const len = sizeof(desc);
155187

156-
if (bufsize < len) {
157-
return 0;
158-
}
188+
// null buffer for length only
189+
if ( buf ) {
190+
if (bufsize < len) {
191+
return 0;
192+
}
159193

160-
memcpy(buf, desc, len);
194+
memcpy(buf, desc, len);
161195

162-
// update the bFirstInterface in MS OS 2.0 descriptor
163-
// that is binded to WinUSB driver
164-
desc_ms_os_20[0x0a + 0x08 + 4] = itfnum;
196+
// update the bFirstInterface in MS OS 2.0 descriptor
197+
// that is binded to WinUSB driver
198+
desc_ms_os_20[0x0a + 0x08 + 4] = itfnum;
199+
}
165200

166201
return len;
167202
}
168203

204+
uint16_t Adafruit_USBD_WebUSB::getInterfaceDescriptor(uint8_t itfnum,
205+
uint8_t *buf,
206+
uint16_t bufsize) {
207+
// usb core will automatically update endpoint number
208+
return makeItfDesc(itfnum, buf, bufsize, EPIN, EPOUT);
209+
}
210+
169211
bool Adafruit_USBD_WebUSB::connected(void) {
170212
return tud_vendor_mounted() && _connected;
171213
}
@@ -222,8 +264,13 @@ int Adafruit_USBD_WebUSB::peek(void) {
222264

223265
void Adafruit_USBD_WebUSB::flush(void) {}
224266

267+
//--------------------------------------------------------------------+
268+
// TinyUSB stack callbacks
269+
//--------------------------------------------------------------------+
225270
extern "C" {
226271

272+
uint8_t const *tud_descriptor_bos_cb(void) { return desc_bos; }
273+
227274
// Invoked when a control transfer occurred on an interface of this class
228275
// Driver response accordingly to the request and the transfer stage
229276
// (setup/data/ack) return false to stall control endpoint (e.g unsupported
@@ -294,15 +341,6 @@ bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage,
294341
return true;
295342
}
296343

297-
// Invoked when DATA Stage of VENDOR's request is complete
298-
bool tud_vendor_control_complete_cb(uint8_t rhport,
299-
tusb_control_request_t const *request) {
300-
(void)rhport;
301-
(void)request;
302-
303-
// nothing to do
304-
return true;
305-
}
306344
}
307345

308346
#endif // TUSB_OPT_DEVICE_ENABLED

src/arduino/webusb/Adafruit_USBD_WebUSB.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@
3939
class Adafruit_USBD_WebUSB : public Stream, public Adafruit_USBD_Interface {
4040
public:
4141
typedef void (*linestate_callback_t)(bool connected);
42-
Adafruit_USBD_WebUSB(void);
42+
Adafruit_USBD_WebUSB(const void *url = NULL);
4343

4444
bool begin(void);
4545

@@ -65,6 +65,9 @@ class Adafruit_USBD_WebUSB : public Stream, public Adafruit_USBD_Interface {
6565
virtual uint16_t getInterfaceDescriptor(uint8_t itfnum, uint8_t *buf,
6666
uint16_t bufsize);
6767

68+
// internal use only
69+
uint16_t makeItfDesc(uint8_t itfnum, uint8_t *buf, uint16_t bufsize, uint8_t ep_in, uint8_t ep_out);
70+
6871
private:
6972
bool _connected;
7073
const uint8_t *_url;

0 commit comments

Comments
 (0)