Open FFBoard
Open source force feedback firmware
hub.c
Go to the documentation of this file.
1/*
2 * The MIT License (MIT)
3 *
4 * Copyright (c) 2019 Ha Thach (tinyusb.org)
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 * THE SOFTWARE.
23 *
24 * This file is part of the TinyUSB stack.
25 */
26
27#include "tusb_option.h"
28
29#if (CFG_TUH_ENABLED && CFG_TUH_HUB)
30
31#include "hcd.h"
32#include "usbh.h"
33#include "usbh_pvt.h"
34#include "hub.h"
35
36// Debug level, TUSB_CFG_DEBUG must be at least this level for debug message
37#define HUB_DEBUG 2
38#define TU_LOG_DRV(...) TU_LOG(HUB_DEBUG, __VA_ARGS__)
39
40//--------------------------------------------------------------------+
41// MACRO CONSTANT TYPEDEF
42//--------------------------------------------------------------------+
43typedef struct
44{
45 uint8_t itf_num;
46 uint8_t ep_in;
47 uint8_t port_count;
48
49 CFG_TUH_MEM_ALIGN uint8_t status_change;
53
54CFG_TUH_MEM_SECTION static hub_interface_t hub_data[CFG_TUH_HUB];
55CFG_TUH_MEM_SECTION CFG_TUH_MEM_ALIGN static uint8_t _hub_buffer[sizeof(descriptor_hub_desc_t)];
56
57TU_ATTR_ALWAYS_INLINE
58static inline hub_interface_t* get_itf(uint8_t dev_addr)
59{
60 return &hub_data[dev_addr-1-CFG_TUH_DEVICE_MAX];
61}
62
63#if CFG_TUSB_DEBUG >= 2
64static char const* const _hub_feature_str[] =
65{
66 [HUB_FEATURE_PORT_CONNECTION ] = "PORT_CONNECTION",
67 [HUB_FEATURE_PORT_ENABLE ] = "PORT_ENABLE",
68 [HUB_FEATURE_PORT_SUSPEND ] = "PORT_SUSPEND",
69 [HUB_FEATURE_PORT_OVER_CURRENT ] = "PORT_OVER_CURRENT",
70 [HUB_FEATURE_PORT_RESET ] = "PORT_RESET",
71 [HUB_FEATURE_PORT_POWER ] = "PORT_POWER",
72 [HUB_FEATURE_PORT_LOW_SPEED ] = "PORT_LOW_SPEED",
73 [HUB_FEATURE_PORT_CONNECTION_CHANGE ] = "PORT_CONNECTION_CHANGE",
74 [HUB_FEATURE_PORT_ENABLE_CHANGE ] = "PORT_ENABLE_CHANGE",
75 [HUB_FEATURE_PORT_SUSPEND_CHANGE ] = "PORT_SUSPEND_CHANGE",
76 [HUB_FEATURE_PORT_OVER_CURRENT_CHANGE ] = "PORT_OVER_CURRENT_CHANGE",
77 [HUB_FEATURE_PORT_RESET_CHANGE ] = "PORT_RESET_CHANGE",
78 [HUB_FEATURE_PORT_TEST ] = "PORT_TEST",
79 [HUB_FEATURE_PORT_INDICATOR ] = "PORT_INDICATOR",
80};
81#endif
82
83//--------------------------------------------------------------------+
84// HUB
85//--------------------------------------------------------------------+
86bool hub_port_clear_feature(uint8_t hub_addr, uint8_t hub_port, uint8_t feature,
88{
90 {
92 {
93 .recipient = (hub_port == 0) ? TUSB_REQ_RCPT_DEVICE : TUSB_REQ_RCPT_OTHER,
94 .type = TUSB_REQ_TYPE_CLASS,
95 .direction = TUSB_DIR_OUT
96 },
97 .bRequest = HUB_REQUEST_CLEAR_FEATURE,
98 .wValue = feature,
99 .wIndex = hub_port,
100 .wLength = 0
101 };
102
104 {
105 .daddr = hub_addr,
106 .ep_addr = 0,
107 .setup = &request,
108 .buffer = NULL,
109 .complete_cb = complete_cb,
110 .user_data = user_data
111 };
112
113 TU_LOG2("HUB Clear Feature: %s, addr = %u port = %u\r\n", _hub_feature_str[feature], hub_addr, hub_port);
114 TU_ASSERT( tuh_control_xfer(&xfer) );
115 return true;
116}
117
118bool hub_port_set_feature(uint8_t hub_addr, uint8_t hub_port, uint8_t feature,
120{
122 {
124 {
125 .recipient = (hub_port == 0) ? TUSB_REQ_RCPT_DEVICE : TUSB_REQ_RCPT_OTHER,
126 .type = TUSB_REQ_TYPE_CLASS,
127 .direction = TUSB_DIR_OUT
128 },
129 .bRequest = HUB_REQUEST_SET_FEATURE,
130 .wValue = feature,
131 .wIndex = hub_port,
132 .wLength = 0
133 };
134
136 {
137 .daddr = hub_addr,
138 .ep_addr = 0,
139 .setup = &request,
140 .buffer = NULL,
141 .complete_cb = complete_cb,
142 .user_data = user_data
143 };
144
145 TU_LOG2("HUB Set Feature: %s, addr = %u port = %u\r\n", _hub_feature_str[feature], hub_addr, hub_port);
146 TU_ASSERT( tuh_control_xfer(&xfer) );
147 return true;
148}
149
150bool hub_port_get_status(uint8_t hub_addr, uint8_t hub_port, void* resp,
152{
154 {
156 {
157 .recipient = (hub_port == 0) ? TUSB_REQ_RCPT_DEVICE : TUSB_REQ_RCPT_OTHER,
158 .type = TUSB_REQ_TYPE_CLASS,
159 .direction = TUSB_DIR_IN
160 },
161 .bRequest = HUB_REQUEST_GET_STATUS,
162 .wValue = 0,
163 .wIndex = hub_port,
164 .wLength = 4
165 };
166
168 {
169 .daddr = hub_addr,
170 .ep_addr = 0,
171 .setup = &request,
172 .buffer = resp,
173 .complete_cb = complete_cb,
174 .user_data = user_data
175 };
176
177 TU_LOG2("HUB Get Port Status: addr = %u port = %u\r\n", hub_addr, hub_port);
178 TU_VERIFY( tuh_control_xfer(&xfer) );
179 return true;
180}
181
182//--------------------------------------------------------------------+
183// CLASS-USBH API (don't require to verify parameters)
184//--------------------------------------------------------------------+
185bool hub_init(void) {
186 tu_memclr(hub_data, sizeof(hub_data));
187 return true;
188}
189
190bool hub_deinit(void) {
191 return true;
192}
193
194bool hub_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *itf_desc, uint16_t max_len)
195{
196 (void) rhport;
197
198 TU_VERIFY(TUSB_CLASS_HUB == itf_desc->bInterfaceClass &&
199 0 == itf_desc->bInterfaceSubClass);
200
201 // hub driver does not support multiple TT yet
202 TU_VERIFY(itf_desc->bInterfaceProtocol <= 1);
203
204 // msc driver length is fixed
205 uint16_t const drv_len = sizeof(tusb_desc_interface_t) + sizeof(tusb_desc_endpoint_t);
206 TU_ASSERT(drv_len <= max_len);
207
208 //------------- Interrupt Status endpoint -------------//
209 tusb_desc_endpoint_t const *desc_ep = (tusb_desc_endpoint_t const *) tu_desc_next(itf_desc);
210
211 TU_ASSERT(TUSB_DESC_ENDPOINT == desc_ep->bDescriptorType &&
212 TUSB_XFER_INTERRUPT == desc_ep->bmAttributes.xfer, 0);
213
214 TU_ASSERT(tuh_edpt_open(dev_addr, desc_ep));
215
217
218 p_hub->itf_num = itf_desc->bInterfaceNumber;
219 p_hub->ep_in = desc_ep->bEndpointAddress;
220
221 return true;
222}
223
224void hub_close(uint8_t dev_addr)
225{
226 TU_VERIFY(dev_addr > CFG_TUH_DEVICE_MAX, );
228
229 if (p_hub->ep_in) {
230 TU_LOG_DRV(" HUB close addr = %d\r\n", dev_addr);
231 tu_memclr(p_hub, sizeof( hub_interface_t));
232 }
233}
234
236{
237 hub_interface_t* hub_itf = get_itf(dev_addr);
238 return usbh_edpt_xfer(dev_addr, hub_itf->ep_in, &hub_itf->status_change, 1);
239}
240
241
242//--------------------------------------------------------------------+
243// Set Configure
244//--------------------------------------------------------------------+
245
248
249bool hub_set_config(uint8_t dev_addr, uint8_t itf_num)
250{
252 TU_ASSERT(itf_num == p_hub->itf_num);
253
254 // Get Hub Descriptor
256 {
258 {
259 .recipient = TUSB_REQ_RCPT_DEVICE,
260 .type = TUSB_REQ_TYPE_CLASS,
261 .direction = TUSB_DIR_IN
262 },
263 .bRequest = HUB_REQUEST_GET_DESCRIPTOR,
264 .wValue = 0,
265 .wIndex = 0,
266 .wLength = sizeof(descriptor_hub_desc_t)
267 };
268
270 {
271 .daddr = dev_addr,
272 .ep_addr = 0,
273 .setup = &request,
275 .complete_cb = config_set_port_power,
276 .user_data = 0
277 };
278
279 TU_ASSERT( tuh_control_xfer(&xfer) );
280
281 return true;
282}
283
285{
286 TU_ASSERT(XFER_RESULT_SUCCESS == xfer->result, );
287
288 uint8_t const daddr = xfer->daddr;
289 hub_interface_t* p_hub = get_itf(daddr);
290
291 // only use number of ports in hub descriptor
292 descriptor_hub_desc_t const* desc_hub = (descriptor_hub_desc_t const*) _hub_buffer;
293 p_hub->port_count = desc_hub->bNbrPorts;
294
295 // May need to GET_STATUS
296
297 // Set Port Power to be able to detect connection, starting with port 1
298 uint8_t const hub_port = 1;
300}
301
303{
304 TU_ASSERT(XFER_RESULT_SUCCESS == xfer->result, );
305
306 uint8_t const daddr = xfer->daddr;
307 hub_interface_t* p_hub = get_itf(daddr);
308
309 if (xfer->setup->wIndex == p_hub->port_count)
310 {
311 // All ports are power -> queue notification status endpoint and
312 // complete the SET CONFIGURATION
313 TU_ASSERT( usbh_edpt_xfer(daddr, p_hub->ep_in, &p_hub->status_change, 1), );
314
316 }else
317 {
318 // power next port
319 uint8_t const hub_port = (uint8_t) (xfer->setup->wIndex + 1);
321 }
322}
323
324//--------------------------------------------------------------------+
325// Connection Changes
326//--------------------------------------------------------------------+
327
332
333// callback as response of interrupt endpoint polling
334bool hub_xfer_cb(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) {
335 (void) xferred_bytes; // TODO can be more than 1 for hub with lots of ports
336 (void) ep_addr;
337 TU_VERIFY(result == XFER_RESULT_SUCCESS);
338
340
341 uint8_t const status_change = p_hub->status_change;
342 TU_LOG2(" Hub Status Change = 0x%02X\r\n", status_change);
343
344 if ( status_change == 0 ) {
345 // The status change event was neither for the hub, nor for any of its ports.
346 // This shouldn't happen, but it does with some devices.
347 // Initiate the next interrupt poll here.
349 }
350
351 if (tu_bit_test(status_change, 0)) {
352 // Hub bit 0 is for the hub device events
353 if (hub_port_get_status(dev_addr, 0, &p_hub->hub_status, hub_get_status_complete, 0) == false) {
354 //Hub status control transfer failed, retry
356 }
357 }
358 else {
359 // Hub bits 1 to n are hub port events
360 for (uint8_t port=1; port <= p_hub->port_count; port++) {
361 if ( tu_bit_test(status_change, port) ) {
362 if (hub_port_get_status(dev_addr, port, &p_hub->port_status, hub_port_get_status_complete, 0) == false) {
363 //Hub status control transfer failed, retry
365 }
366 break;
367 }
368 }
369 }
370
371 // NOTE: next status transfer is queued by usbh.c after handling this request
372 return true;
373}
374
376{
377 TU_ASSERT(xfer->result == XFER_RESULT_SUCCESS, );
379}
380
382{
383 TU_ASSERT(xfer->result == XFER_RESULT_SUCCESS, );
384
385 uint8_t const daddr = xfer->daddr;
386 hub_interface_t* p_hub = get_itf(daddr);
387 uint8_t const port_num = (uint8_t) tu_le16toh(xfer->setup->wIndex);
388 TU_ASSERT(port_num == 0 , );
389
390 TU_LOG2("HUB Got hub status, addr = %u, status = %04x\r\n", daddr, p_hub->hub_status.change.value);
391
393 {
394 TU_LOG2("HUB Local Power Change, addr = %u\r\n", daddr);
396 }
397 else if (p_hub->hub_status.change.over_current)
398 {
399 TU_LOG1("HUB Over Current, addr = %u\r\n", daddr);
401 }
402}
403
405{
406 TU_ASSERT(xfer->result == XFER_RESULT_SUCCESS, );
407
408 uint8_t const daddr = xfer->daddr;
409 hub_interface_t* p_hub = get_itf(daddr);
410 uint8_t const port_num = (uint8_t) tu_le16toh(xfer->setup->wIndex);
411
412 // Connection change
413 if (p_hub->port_status.change.connection)
414 {
415 // Port is powered and enabled
416 //TU_VERIFY(port_status.status_current.port_power && port_status.status_current.port_enable, );
417
418 // Acknowledge Port Connection Change
420 }else
421 {
422 // Clear other port status change interrupts. TODO Not currently handled - just cleared.
423 if (p_hub->port_status.change.port_enable)
424 {
426 }
427 else if (p_hub->port_status.change.suspend)
428 {
430 }
431 else if (p_hub->port_status.change.over_current)
432 {
434 }
435 else if (p_hub->port_status.change.reset)
436 {
438 }
439 // Other changes are: L1 state
440 // TODO clear change
441
442 else
443 {
444 // prepare for next hub status
445 // TODO continue with status_change, or maybe we can do it again with status
447 }
448 }
449}
450
452{
453 TU_ASSERT(xfer->result == XFER_RESULT_SUCCESS, );
454
455 uint8_t const daddr = xfer->daddr;
456 hub_interface_t* p_hub = get_itf(daddr);
457 uint8_t const port_num = (uint8_t) tu_le16toh(xfer->setup->wIndex);
458
459 if ( p_hub->port_status.status.connection )
460 {
461 // Reset port if attach event
463 }else
464 {
465 // submit detach event
466 hcd_event_t event =
467 {
469 .event_id = HCD_EVENT_DEVICE_REMOVE,
470 .connection =
471 {
472 .hub_addr = daddr,
473 .hub_port = port_num
474 }
475 };
476
477 hcd_event_handler(&event, false);
478 }
479}
480
482{
483 TU_ASSERT(xfer->result == XFER_RESULT_SUCCESS, );
484
485 uint8_t const daddr = xfer->daddr;
486 // hub_interface_t* p_hub = get_itf(daddr);
487 uint8_t const port_num = (uint8_t) tu_le16toh(xfer->setup->wIndex);
488
489 // submit attach event
490 hcd_event_t event =
491 {
493 .event_id = HCD_EVENT_DEVICE_ATTACH,
494 .connection =
495 {
496 .hub_addr = daddr,
497 .hub_port = port_num
498 }
499 };
500
501 hcd_event_handler(&event, false);
502}
503
504#endif
xfer_td_t xfer[EP_CBI_COUNT+1][2]
Definition: dcd_nrf5x.c:119
uint8_t dev_addr
Definition: dcd_pic32mz.c:81
bool hub_port_get_status(uint8_t hub_addr, uint8_t hub_port, void *resp, tuh_xfer_cb_t complete_cb, uintptr_t user_data)
Definition: hub.c:150
void hub_close(uint8_t dev_addr)
Definition: hub.c:224
bool hub_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *itf_desc, uint16_t max_len)
Definition: hub.c:194
bool hub_port_clear_feature(uint8_t hub_addr, uint8_t hub_port, uint8_t feature, tuh_xfer_cb_t complete_cb, uintptr_t user_data)
Definition: hub.c:86
bool hub_deinit(void)
Definition: hub.c:190
bool hub_xfer_cb(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes)
Definition: hub.c:334
bool hub_edpt_status_xfer(uint8_t dev_addr)
Definition: hub.c:235
bool hub_init(void)
Definition: hub.c:185
bool hub_port_set_feature(uint8_t hub_addr, uint8_t hub_port, uint8_t feature, tuh_xfer_cb_t complete_cb, uintptr_t user_data)
Definition: hub.c:118
bool hub_set_config(uint8_t dev_addr, uint8_t itf_num)
Definition: hub.c:249
static TU_ATTR_ALWAYS_INLINE bool hub_port_reset(uint8_t hub_addr, uint8_t hub_port, tuh_xfer_cb_t complete_cb, uintptr_t user_data)
Definition: hub.h:191
@ HUB_FEATURE_HUB_LOCAL_POWER_CHANGE
Definition: hub.h:111
@ HUB_FEATURE_HUB_OVER_CURRENT_CHANGE
Definition: hub.h:112
@ HUB_REQUEST_CLEAR_FEATURE
Definition: hub.h:98
@ HUB_REQUEST_SET_FEATURE
Definition: hub.h:100
@ HUB_REQUEST_GET_STATUS
Definition: hub.h:97
@ HUB_REQUEST_GET_DESCRIPTOR
Definition: hub.h:102
@ HUB_FEATURE_PORT_OVER_CURRENT
Definition: hub.h:119
@ HUB_FEATURE_PORT_RESET_CHANGE
Definition: hub.h:129
@ HUB_FEATURE_PORT_SUSPEND_CHANGE
Definition: hub.h:127
@ HUB_FEATURE_PORT_LOW_SPEED
Definition: hub.h:123
@ HUB_FEATURE_PORT_CONNECTION
Definition: hub.h:116
@ HUB_FEATURE_PORT_ENABLE
Definition: hub.h:117
@ HUB_FEATURE_PORT_ENABLE_CHANGE
Definition: hub.h:126
@ HUB_FEATURE_PORT_TEST
Definition: hub.h:130
@ HUB_FEATURE_PORT_CONNECTION_CHANGE
Definition: hub.h:125
@ HUB_FEATURE_PORT_RESET
Definition: hub.h:120
@ HUB_FEATURE_PORT_POWER
Definition: hub.h:122
@ HUB_FEATURE_PORT_SUSPEND
Definition: hub.h:118
@ HUB_FEATURE_PORT_OVER_CURRENT_CHANGE
Definition: hub.h:128
@ HUB_FEATURE_PORT_INDICATOR
Definition: hub.h:131
void hcd_event_handler(hcd_event_t const *event, bool in_isr)
Definition: usbh.c:964
static void hub_port_get_status_complete(tuh_xfer_t *xfer)
Definition: hub.c:404
static void hub_clear_feature_complete_stub(tuh_xfer_t *xfer)
Definition: hub.c:375
static void connection_port_reset_complete(tuh_xfer_t *xfer)
Definition: hub.c:481
static void connection_clear_conn_change_complete(tuh_xfer_t *xfer)
Definition: hub.c:451
static void config_port_power_complete(tuh_xfer_t *xfer)
Definition: hub.c:302
static void hub_get_status_complete(tuh_xfer_t *xfer)
Definition: hub.c:381
static TU_ATTR_ALWAYS_INLINE hub_interface_t * get_itf(uint8_t dev_addr)
Definition: hub.c:58
static CFG_TUH_MEM_SECTION hub_interface_t hub_data[CFG_TUH_HUB]
Definition: hub.c:54
static char const *const _hub_feature_str[]
Definition: hub.c:64
static void config_set_port_power(tuh_xfer_t *xfer)
Definition: hub.c:284
CFG_TUH_MEM_SECTION static CFG_TUH_MEM_ALIGN uint8_t _hub_buffer[sizeof(descriptor_hub_desc_t)]
Definition: hub.c:55
AUDIO Channel Cluster Descriptor (4.1)
Definition: audio.h:647
struct TU_ATTR_PACKED::@16::TU_ATTR_PACKED bmRequestType_bit
uint8_t bmAttributes
See: audio_clock_source_attribute_t.
Definition: audio.h:672
uint8_t * buffer
Definition: video_device.c:111
uint8_t bDescriptorType
Descriptor Type. Value: TUSB_DESC_CS_INTERFACE.
Definition: audio.h:657
uint8_t bInterfaceClass
Class code (assigned by the USB-IF).
Definition: tusb_types.h:349
uint8_t bEndpointAddress
Definition: video.h:306
uint8_t bInterfaceSubClass
Subclass code (assigned by the USB-IF). These codes are qualified by the value of the bInterfaceCla...
Definition: tusb_types.h:350
uint8_t bInterfaceProtocol
Protocol code (assigned by the USB). These codes are qualified by the value of the bInterfaceClass ...
Definition: tusb_types.h:351
uint8_t bInterfaceNumber
Number of this interface. Zero-based value identifying the index in the array of concurrent interface...
Definition: tusb_types.h:346
uint8_t rhport
Definition: hcd.h:66
CFG_TUH_MEM_ALIGN uint8_t status_change
Definition: hub.c:49
uint8_t port_count
Definition: hub.c:47
uint8_t itf_num
Definition: hub.c:45
CFG_TUH_MEM_ALIGN hub_status_response_t hub_status
Definition: hub.c:51
CFG_TUH_MEM_ALIGN hub_port_status_response_t port_status
Definition: hub.c:50
uint8_t ep_in
Definition: hub.c:46
union hub_port_status_response_t::@93 status
union hub_port_status_response_t::@93 change
uint16_t over_current
Definition: hub.h:156
uint16_t port_enable
Definition: hub.h:154
union hub_status_response_t::@91 change
uint16_t local_power_source
Definition: hub.h:138
uint16_t over_current
Definition: hub.h:139
uint16_t value
Definition: hub.h:143
static TU_ATTR_ALWAYS_INLINE bool tu_bit_test(uint32_t value, uint8_t pos)
Definition: tusb_common.h:151
@ TUSB_DIR_IN
Definition: tusb_types.h:67
@ TUSB_DIR_OUT
Definition: tusb_types.h:66
@ TUSB_CLASS_HUB
Definition: tusb_types.h:168
xfer_result_t
Definition: tusb_types.h:236
@ XFER_RESULT_SUCCESS
Definition: tusb_types.h:237
@ TUSB_REQ_RCPT_DEVICE
Definition: tusb_types.h:151
@ TUSB_REQ_RCPT_OTHER
Definition: tusb_types.h:154
@ TUSB_XFER_INTERRUPT
Definition: tusb_types.h:62
@ TUSB_REQ_TYPE_CLASS
Definition: tusb_types.h:145
struct TU_ATTR_PACKED tusb_desc_interface_t
USB Interface Descriptor.
static TU_ATTR_ALWAYS_INLINE uint8_t const * tu_desc_next(void const *desc)
Definition: tusb_types.h:531
@ TUSB_DESC_ENDPOINT
Definition: tusb_types.h:97
void usbh_driver_set_config_complete(uint8_t dev_addr, uint8_t itf_num)
Definition: usbh.c:1717
CFG_TUH_MEM_ALIGN tusb_control_request_t request
Definition: usbh.c:259
uint8_t daddr
Definition: usbh.c:264
uintptr_t user_data
Definition: usbh.c:262
bool tuh_control_xfer(tuh_xfer_t *xfer)
Definition: usbh.c:602
tuh_xfer_cb_t complete_cb
Definition: usbh.c:261
bool tuh_edpt_open(uint8_t dev_addr, tusb_desc_endpoint_t const *desc_ep)
Definition: usbh.c:930
uint8_t usbh_get_rhport(uint8_t dev_addr)
Definition: usbh.c:814
void(* tuh_xfer_cb_t)(tuh_xfer_t *xfer)
Definition: usbh.h:44
static TU_ATTR_ALWAYS_INLINE bool usbh_edpt_xfer(uint8_t dev_addr, uint8_t ep_addr, uint8_t *buffer, uint16_t total_bytes)
Definition: usbh_pvt.h:87