38
38
39
39
enum { VENDOR_REQUEST_WEBUSB = 1 , VENDOR_REQUEST_MICROSOFT = 2 };
40
40
41
+ // TODO multiple instances
41
42
static Adafruit_USBD_WebUSB *_webusb_dev = NULL ;
42
43
43
44
// --------------------------------------------------------------------+
@@ -73,9 +74,8 @@ uint8_t const desc_bos[] = {
73
74
TUD_BOS_WEBUSB_DESCRIPTOR (VENDOR_REQUEST_WEBUSB, 1 ),
74
75
75
76
// 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
+ };
79
79
80
80
uint8_t desc_ms_os_20[] = {
81
81
// Set header: length, type, windows version, total length
@@ -118,19 +118,54 @@ uint8_t desc_ms_os_20[] = {
118
118
119
119
TU_VERIFY_STATIC (sizeof (desc_ms_os_20) == MS_OS_20_DESC_LEN, "Incorrect size");
120
120
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
+
122
145
123
- Adafruit_USBD_WebUSB::Adafruit_USBD_WebUSB (void ) {
146
+ Adafruit_USBD_WebUSB::Adafruit_USBD_WebUSB (const void *url ) {
124
147
_connected = false ;
125
- _url = NULL ;
148
+ _url = ( const uint8_t *) url ;
126
149
_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
127
161
}
128
162
129
163
bool Adafruit_USBD_WebUSB::begin (void ) {
130
- if (!TinyUSBDevice.addInterface (*this ))
164
+ if (!TinyUSBDevice.addInterface (*this )) {
131
165
return false ;
166
+ }
132
167
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)
134
169
TinyUSBDevice.setVersion (0x0210 );
135
170
136
171
_webusb_dev = this ;
@@ -146,26 +181,33 @@ void Adafruit_USBD_WebUSB::setLineStateCallback(linestate_callback_t fp) {
146
181
_linestate_cb = fp;
147
182
}
148
183
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)};
154
186
uint16_t const len = sizeof (desc);
155
187
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
+ }
159
193
160
- memcpy (buf, desc, len);
194
+ memcpy (buf, desc, len);
161
195
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
+ }
165
200
166
201
return len;
167
202
}
168
203
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
+
169
211
bool Adafruit_USBD_WebUSB::connected (void ) {
170
212
return tud_vendor_mounted () && _connected;
171
213
}
@@ -222,8 +264,13 @@ int Adafruit_USBD_WebUSB::peek(void) {
222
264
223
265
void Adafruit_USBD_WebUSB::flush (void ) {}
224
266
267
+ // --------------------------------------------------------------------+
268
+ // TinyUSB stack callbacks
269
+ // --------------------------------------------------------------------+
225
270
extern " C" {
226
271
272
+ uint8_t const *tud_descriptor_bos_cb (void ) { return desc_bos; }
273
+
227
274
// Invoked when a control transfer occurred on an interface of this class
228
275
// Driver response accordingly to the request and the transfer stage
229
276
// (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,
294
341
return true ;
295
342
}
296
343
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
- }
306
344
}
307
345
308
346
#endif // TUSB_OPT_DEVICE_ENABLED
0 commit comments