Open FFBoard
Open source force feedback firmware
tusb.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_TUD_ENABLED
30
31#include "tusb.h"
32#include "common/tusb_private.h"
33
34#if CFG_TUD_ENABLED
35#include "device/usbd_pvt.h"
36#endif
37
38#if CFG_TUH_ENABLED
39#include "host/usbh_pvt.h"
40#endif
41
42tusb_role_t _tusb_rhport_role[TUP_USBIP_CONTROLLER_NUM] = { TUSB_ROLE_INVALID };
43
44//--------------------------------------------------------------------
45// Weak/Default API, can be overwritten by Application
46//--------------------------------------------------------------------
47
48TU_ATTR_WEAK void tusb_time_delay_ms_api(uint32_t ms) {
49#if CFG_TUSB_OS != OPT_OS_NONE
51#else
52 // delay using millis() (if implemented) and/or frame number if possible
53 const uint32_t time_ms = tusb_time_millis_api();
54 while ((tusb_time_millis_api() - time_ms) < ms) {}
55#endif
56}
57
58//--------------------------------------------------------------------+
59// Public API
60//--------------------------------------------------------------------+
61bool tusb_rhport_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) {
62 // backward compatible called with tusb_init(void)
63 #if defined(TUD_OPT_RHPORT) || defined(TUH_OPT_RHPORT)
64 if (rh_init == NULL) {
65 #if CFG_TUD_ENABLED && defined(TUD_OPT_RHPORT)
66 // init device stack CFG_TUSB_RHPORTx_MODE must be defined
67 const tusb_rhport_init_t dev_init = {
68 .role = TUSB_ROLE_DEVICE,
69 .speed = TUD_OPT_HIGH_SPEED ? TUSB_SPEED_HIGH : TUSB_SPEED_FULL
70 };
71 TU_ASSERT ( tud_rhport_init(TUD_OPT_RHPORT, &dev_init) );
72 _tusb_rhport_role[TUD_OPT_RHPORT] = TUSB_ROLE_DEVICE;
73 #endif
74
75 #if CFG_TUH_ENABLED && defined(TUH_OPT_RHPORT)
76 // init host stack CFG_TUSB_RHPORTx_MODE must be defined
77 const tusb_rhport_init_t host_init = {
78 .role = TUSB_ROLE_HOST,
79 .speed = TUH_OPT_HIGH_SPEED ? TUSB_SPEED_HIGH : TUSB_SPEED_FULL
80 };
81 TU_ASSERT( tuh_rhport_init(TUH_OPT_RHPORT, &host_init) );
82 _tusb_rhport_role[TUH_OPT_RHPORT] = TUSB_ROLE_HOST;
83 #endif
84
85 return true;
86 }
87 #endif
88
89 // new API with explicit rhport and role
90 TU_ASSERT(rhport < TUP_USBIP_CONTROLLER_NUM && rh_init->role != TUSB_ROLE_INVALID);
91 _tusb_rhport_role[rhport] = rh_init->role;
92
93 #if CFG_TUD_ENABLED
94 if (rh_init->role == TUSB_ROLE_DEVICE) {
95 TU_ASSERT(tud_rhport_init(rhport, rh_init));
96 }
97 #endif
98
99 #if CFG_TUH_ENABLED
100 if (rh_init->role == TUSB_ROLE_HOST) {
101 TU_ASSERT(tuh_rhport_init(rhport, rh_init));
102 }
103 #endif
104
105 return true;
106}
107
108bool tusb_inited(void) {
109 bool ret = false;
110
111 #if CFG_TUD_ENABLED
112 ret = ret || tud_inited();
113 #endif
114
115 #if CFG_TUH_ENABLED
116 ret = ret || tuh_inited();
117 #endif
118
119 return ret;
120}
121
122void tusb_int_handler(uint8_t rhport, bool in_isr) {
123 TU_VERIFY(rhport < TUP_USBIP_CONTROLLER_NUM,);
124
125 #if CFG_TUD_ENABLED
126 if (_tusb_rhport_role[rhport] == TUSB_ROLE_DEVICE) {
127 (void) in_isr;
128 dcd_int_handler(rhport);
129 }
130 #endif
131
132 #if CFG_TUH_ENABLED
133 if (_tusb_rhport_role[rhport] == TUSB_ROLE_HOST) {
134 hcd_int_handler(rhport, in_isr);
135 }
136 #endif
137}
138
139//--------------------------------------------------------------------+
140// Descriptor helper
141//--------------------------------------------------------------------+
142
143uint8_t const* tu_desc_find(uint8_t const* desc, uint8_t const* end, uint8_t byte1) {
144 while (desc + 1 < end) {
145 if (desc[1] == byte1) return desc;
147 }
148 return NULL;
149}
150
151uint8_t const* tu_desc_find2(uint8_t const* desc, uint8_t const* end, uint8_t byte1, uint8_t byte2) {
152 while (desc + 2 < end) {
153 if (desc[1] == byte1 && desc[2] == byte2) return desc;
155 }
156 return NULL;
157}
158
159uint8_t const* tu_desc_find3(uint8_t const* desc, uint8_t const* end, uint8_t byte1, uint8_t byte2, uint8_t byte3) {
160 while (desc + 3 < end) {
161 if (desc[1] == byte1 && desc[2] == byte2 && desc[3] == byte3) return desc;
163 }
164 return NULL;
165}
166
167//--------------------------------------------------------------------+
168// Endpoint Helper for both Host and Device stack
169//--------------------------------------------------------------------+
170
172 (void) mutex;
173
174 // pre-check to help reducing mutex lock
175 TU_VERIFY((ep_state->busy == 0) && (ep_state->claimed == 0));
176 (void) osal_mutex_lock(mutex, OSAL_TIMEOUT_WAIT_FOREVER);
177
178 // can only claim the endpoint if it is not busy and not claimed yet.
179 bool const available = (ep_state->busy == 0) && (ep_state->claimed == 0);
180 if (available) {
181 ep_state->claimed = 1;
182 }
183
184 (void) osal_mutex_unlock(mutex);
185 return available;
186}
187
189 (void) mutex;
190 (void) osal_mutex_lock(mutex, OSAL_TIMEOUT_WAIT_FOREVER);
191
192 // can only release the endpoint if it is claimed and not busy
193 bool const ret = (ep_state->claimed == 1) && (ep_state->busy == 0);
194 if (ret) {
195 ep_state->claimed = 0;
196 }
197
198 (void) osal_mutex_unlock(mutex);
199 return ret;
200}
201
203 uint16_t const max_packet_size = tu_edpt_packet_size(desc_ep);
204 TU_LOG2(" Open EP %02X with Size = %u\r\n", desc_ep->bEndpointAddress, max_packet_size);
205
206 switch (desc_ep->bmAttributes.xfer) {
208 uint16_t const spec_size = (speed == TUSB_SPEED_HIGH ? 1024 : 1023);
209 TU_ASSERT(max_packet_size <= spec_size);
210 break;
211 }
212
213 case TUSB_XFER_BULK:
214 if (speed == TUSB_SPEED_HIGH) {
215 // Bulk highspeed must be EXACTLY 512
216 TU_ASSERT(max_packet_size == 512);
217 } else {
218 // TODO Bulk fullspeed can only be 8, 16, 32, 64
219 TU_ASSERT(max_packet_size <= 64);
220 }
221 break;
222
223 case TUSB_XFER_INTERRUPT: {
224 uint16_t const spec_size = (speed == TUSB_SPEED_HIGH ? 1024 : 64);
225 TU_ASSERT(max_packet_size <= spec_size);
226 break;
227 }
228
229 default:
230 return false;
231 }
232
233 return true;
234}
235
236void tu_edpt_bind_driver(uint8_t ep2drv[][2], tusb_desc_interface_t const* desc_itf, uint16_t desc_len,
237 uint8_t driver_id) {
238 uint8_t const* p_desc = (uint8_t const*) desc_itf;
239 uint8_t const* desc_end = p_desc + desc_len;
240
241 while (p_desc < desc_end) {
242 if (TUSB_DESC_ENDPOINT == tu_desc_type(p_desc)) {
243 uint8_t const ep_addr = ((tusb_desc_endpoint_t const*) p_desc)->bEndpointAddress;
244 TU_LOG(2, " Bind EP %02x to driver id %u\r\n", ep_addr, driver_id);
245 ep2drv[tu_edpt_number(ep_addr)][tu_edpt_dir(ep_addr)] = driver_id;
246 }
247 p_desc = tu_desc_next(p_desc);
248 }
249}
250
251uint16_t tu_desc_get_interface_total_len(tusb_desc_interface_t const* desc_itf, uint8_t itf_count, uint16_t max_len) {
252 uint8_t const* p_desc = (uint8_t const*) desc_itf;
253 uint16_t len = 0;
254
255 while (itf_count--) {
256 // Next on interface desc
257 len += tu_desc_len(desc_itf);
258 p_desc = tu_desc_next(p_desc);
259
260 while (len < max_len) {
261 // return on IAD regardless of itf count
263 return len;
264 }
265 if ((tu_desc_type(p_desc) == TUSB_DESC_INTERFACE) &&
266 ((tusb_desc_interface_t const*) p_desc)->bAlternateSetting == 0) {
267 break;
268 }
269
270 len += tu_desc_len(p_desc);
271 p_desc = tu_desc_next(p_desc);
272 }
273 }
274
275 return len;
276}
277
278//--------------------------------------------------------------------+
279// Endpoint Stream Helper for both Host and Device stack
280//--------------------------------------------------------------------+
281
282bool tu_edpt_stream_init(tu_edpt_stream_t* s, bool is_host, bool is_tx, bool overwritable,
283 void* ff_buf, uint16_t ff_bufsize, uint8_t* ep_buf, uint16_t ep_bufsize) {
284 (void) is_tx;
285
286 s->is_host = is_host;
287 tu_fifo_config(&s->ff, ff_buf, ff_bufsize, 1, overwritable);
288
289 #if OSAL_MUTEX_REQUIRED
290 if (ff_buf && ff_bufsize) {
291 osal_mutex_t new_mutex = osal_mutex_create(&s->ff_mutexdef);
292 tu_fifo_config_mutex(&s->ff, is_tx ? new_mutex : NULL, is_tx ? NULL : new_mutex);
293 }
294 #endif
295
296 s->ep_buf = ep_buf;
297 s->ep_bufsize = ep_bufsize;
298
299 return true;
300}
301
303 (void) s;
304 #if OSAL_MUTEX_REQUIRED
307 #endif
308 return true;
309}
310
311TU_ATTR_ALWAYS_INLINE static inline bool stream_claim(uint8_t hwid, tu_edpt_stream_t* s) {
312 if (s->is_host) {
313 #if CFG_TUH_ENABLED
314 return usbh_edpt_claim(hwid, s->ep_addr);
315 #endif
316 } else {
317 #if CFG_TUD_ENABLED
318 return usbd_edpt_claim(hwid, s->ep_addr);
319 #endif
320 }
321 return false;
322}
323
324TU_ATTR_ALWAYS_INLINE static inline bool stream_xfer(uint8_t hwid, tu_edpt_stream_t* s, uint16_t count) {
325 if (s->is_host) {
326 #if CFG_TUH_ENABLED
327 return usbh_edpt_xfer(hwid, s->ep_addr, count ? s->ep_buf : NULL, count);
328 #endif
329 } else {
330 #if CFG_TUD_ENABLED
331 return usbd_edpt_xfer(hwid, s->ep_addr, count ? s->ep_buf : NULL, count);
332 #endif
333 }
334 return false;
335}
336
337TU_ATTR_ALWAYS_INLINE static inline bool stream_release(uint8_t hwid, tu_edpt_stream_t* s) {
338 if (s->is_host) {
339 #if CFG_TUH_ENABLED
340 return usbh_edpt_release(hwid, s->ep_addr);
341 #endif
342 } else {
343 #if CFG_TUD_ENABLED
344 return usbd_edpt_release(hwid, s->ep_addr);
345 #endif
346 }
347 return false;
348}
349
350//--------------------------------------------------------------------+
351// Stream Write
352//--------------------------------------------------------------------+
353bool tu_edpt_stream_write_zlp_if_needed(uint8_t hwid, tu_edpt_stream_t* s, uint32_t last_xferred_bytes) {
354 // ZLP condition: no pending data, last transferred bytes is multiple of packet size
355 const uint16_t mps = s->is_mps512 ? TUSB_EPSIZE_BULK_HS : TUSB_EPSIZE_BULK_FS;
356 TU_VERIFY(!tu_fifo_count(&s->ff) && last_xferred_bytes && (0 == (last_xferred_bytes & (mps - 1))));
357 TU_VERIFY(stream_claim(hwid, s));
358 TU_ASSERT(stream_xfer(hwid, s, 0));
359 return true;
360}
361
362uint32_t tu_edpt_stream_write_xfer(uint8_t hwid, tu_edpt_stream_t* s) {
363 // skip if no data
364 TU_VERIFY(tu_fifo_count(&s->ff), 0);
365
366 TU_VERIFY(stream_claim(hwid, s), 0);
367
368 // Pull data from FIFO -> EP buf
369 uint16_t const count = tu_fifo_read_n(&s->ff, s->ep_buf, s->ep_bufsize);
370
371 if (count) {
372 TU_ASSERT(stream_xfer(hwid, s, count), 0);
373 return count;
374 } else {
375 // Release endpoint since we don't make any transfer
376 // Note: data is dropped if terminal is not connected
377 stream_release(hwid, s);
378 return 0;
379 }
380}
381
382uint32_t tu_edpt_stream_write(uint8_t hwid, tu_edpt_stream_t* s, void const* buffer, uint32_t bufsize) {
383 TU_VERIFY(bufsize); // TODO support ZLP
384
385 if (0 == tu_fifo_depth(&s->ff)) {
386 // no fifo for buffered
387 TU_VERIFY(stream_claim(hwid, s), 0);
388 const uint32_t xact_len = tu_min32(bufsize, s->ep_bufsize);
389 memcpy(s->ep_buf, buffer, xact_len);
390 TU_ASSERT(stream_xfer(hwid, s, (uint16_t) xact_len), 0);
391 return xact_len;
392 } else {
393 const uint16_t ret = tu_fifo_write_n(&s->ff, buffer, (uint16_t) bufsize);
394
395 // flush if fifo has more than packet size or
396 // in rare case: fifo depth is configured too small (which never reach packet size)
397 const uint16_t mps = s->is_mps512 ? TUSB_EPSIZE_BULK_HS : TUSB_EPSIZE_BULK_FS;
398 if ((tu_fifo_count(&s->ff) >= mps) || (tu_fifo_depth(&s->ff) < mps)) {
400 }
401 return ret;
402 }
403}
404
406 if (tu_fifo_depth(&s->ff)) {
407 return (uint32_t) tu_fifo_remaining(&s->ff);
408 } else {
409 bool is_busy = true;
410 if (s->is_host) {
411 #if CFG_TUH_ENABLED
412 is_busy = usbh_edpt_busy(hwid, s->ep_addr);
413 #endif
414 } else {
415 #if CFG_TUD_ENABLED
416 is_busy = usbd_edpt_busy(hwid, s->ep_addr);
417 #endif
418 }
419 return is_busy ? 0 : s->ep_bufsize;
420 }
421}
422
423//--------------------------------------------------------------------+
424// Stream Read
425//--------------------------------------------------------------------+
426uint32_t tu_edpt_stream_read_xfer(uint8_t hwid, tu_edpt_stream_t* s) {
427 if (0 == tu_fifo_depth(&s->ff)) {
428 // no fifo for buffered
429 TU_VERIFY(stream_claim(hwid, s), 0);
430 TU_ASSERT(stream_xfer(hwid, s, s->ep_bufsize), 0);
431 return s->ep_bufsize;
432 } else {
433 const uint16_t mps = s->is_mps512 ? TUSB_EPSIZE_BULK_HS : TUSB_EPSIZE_BULK_FS;
434 uint16_t available = tu_fifo_remaining(&s->ff);
435
436 // Prepare for incoming data but only allow what we can store in the ring buffer.
437 // TODO Actually we can still carry out the transfer, keeping count of received bytes
438 // and slowly move it to the FIFO when read().
439 // This pre-check reduces endpoint claiming
440 TU_VERIFY(available >= mps);
441
442 TU_VERIFY(stream_claim(hwid, s), 0);
443
444 // get available again since fifo can be changed before endpoint is claimed
445 available = tu_fifo_remaining(&s->ff);
446
447 if (available >= mps) {
448 // multiple of packet size limit by ep bufsize
449 uint16_t count = (uint16_t) (available & ~(mps - 1));
450 count = tu_min16(count, s->ep_bufsize);
451 TU_ASSERT(stream_xfer(hwid, s, count), 0);
452 return count;
453 } else {
454 // Release endpoint since we don't make any transfer
455 stream_release(hwid, s);
456 return 0;
457 }
458 }
459}
460
461uint32_t tu_edpt_stream_read(uint8_t hwid, tu_edpt_stream_t* s, void* buffer, uint32_t bufsize) {
462 uint32_t num_read = tu_fifo_read_n(&s->ff, buffer, (uint16_t) bufsize);
464 return num_read;
465}
466
467//--------------------------------------------------------------------+
468// Debug
469//--------------------------------------------------------------------+
470
471#if CFG_TUSB_DEBUG
472#include <ctype.h>
473
474#if CFG_TUSB_DEBUG >= CFG_TUH_LOG_LEVEL || CFG_TUSB_DEBUG >= CFG_TUD_LOG_LEVEL
475char const* const tu_str_speed[] = {"Full", "Low", "High"};
476char const* const tu_str_std_request[] = {
477 "Get Status",
478 "Clear Feature",
479 "Reserved",
480 "Set Feature",
481 "Reserved",
482 "Set Address",
483 "Get Descriptor",
484 "Set Descriptor",
485 "Get Configuration",
486 "Set Configuration",
487 "Get Interface",
488 "Set Interface",
489 "Synch Frame"
490};
491
492char const* const tu_str_xfer_result[] = {
493 "OK", "FAILED", "STALLED", "TIMEOUT"
494};
495#endif
496
497static void dump_str_line(uint8_t const* buf, uint16_t count) {
498 tu_printf(" |");
499 // each line is 16 bytes
500 for (uint16_t i = 0; i < count; i++) {
501 int ch = buf[i];
502 tu_printf("%c", isprint(ch) ? ch : '.');
503 }
504 tu_printf("|\r\n");
505}
506
507/* Print out memory contents
508 * - buf : buffer
509 * - count : number of item
510 * - indent: prefix spaces on every line
511 */
512void tu_print_mem(void const* buf, uint32_t count, uint8_t indent) {
513 uint8_t const size = 1; // fixed 1 byte for now
514 if (!buf || !count) {
515 tu_printf("NULL\r\n");
516 return;
517 }
518
519 uint8_t const* buf8 = (uint8_t const*) buf;
520 char format[] = "%00X";
521 format[2] += (uint8_t) (2 * size); // 1 byte = 2 hex digits
522 const uint8_t item_per_line = 16 / size;
523
524 for (unsigned int i = 0; i < count; i++) {
525 unsigned int value = 0;
526
527 if (i % item_per_line == 0) {
528 // Print Ascii
529 if (i != 0) dump_str_line(buf8 - 16, 16);
530 for (uint8_t s = 0; s < indent; s++) tu_printf(" ");
531 // print offset or absolute address
532 tu_printf("%04X: ", 16 * i / item_per_line);
533 }
534
535 tu_memcpy_s(&value, sizeof(value), buf8, size);
536 buf8 += size;
537
538 tu_printf(" ");
539 tu_printf(format, value);
540 }
541
542 // fill up last row to 16 for printing ascii
543 const uint32_t remain = count % 16;
544 uint8_t nback = (uint8_t) (remain ? remain : 16);
545 if (remain) {
546 for (uint32_t i = 0; i < 16 - remain; i++) {
547 tu_printf(" ");
548 for (int j = 0; j < 2 * size; j++) tu_printf(" ");
549 }
550 }
551
552 dump_str_line(buf8 - nback, nback);
553}
554
555#endif
556
557#endif // host or device enabled
void dcd_int_handler(uint8_t rhport)
Definition: dcd_ft9xx.c:954
static bool in_isr
static usb_descriptor_buffers_t desc
Definition: dcd_pio_usb.c:46
void hcd_int_handler(uint8_t rhport, bool in_isr)
Definition: hcd_max3421.c:1002
uint8_t const * buffer
Definition: midi_device.h:100
uint32_t bufsize
Definition: midi_device.h:95
static TU_ATTR_ALWAYS_INLINE bool osal_mutex_lock(osal_mutex_t mutex_hdl, uint32_t msec)
static TU_ATTR_ALWAYS_INLINE bool osal_mutex_unlock(osal_mutex_t mutex_hdl)
static TU_ATTR_ALWAYS_INLINE bool osal_mutex_delete(osal_mutex_t mutex_hdl)
SemaphoreHandle_t osal_mutex_t
Definition: osal_freertos.h:54
static TU_ATTR_ALWAYS_INLINE osal_mutex_t osal_mutex_create(osal_mutex_def_t *mdef)
TU_ATTR_WEAK void osal_task_delay(uint32_t msec)
static void * memcpy(void *dst, const void *src, size_t n)
Definition: ringbuffer.c:8
AUDIO Channel Cluster Descriptor (4.1)
Definition: audio.h:647
volatile uint8_t busy
Definition: tusb_private.h:44
uint8_t bmAttributes
See: audio_clock_source_attribute_t.
Definition: audio.h:672
volatile uint8_t claimed
Definition: tusb_private.h:46
uint8_t bEndpointAddress
Definition: video.h:306
uint8_t * ep_buf
Definition: tusb_private.h:57
uint16_t ep_bufsize
Definition: tusb_private.h:55
osal_mutex_t mutex_wr
Definition: tusb_fifo.h:119
osal_mutex_t mutex_rd
Definition: tusb_fifo.h:120
tusb_role_t role
Definition: tusb_types.h:281
uint8_t const * tu_desc_find(uint8_t const *desc, uint8_t const *end, uint8_t byte1)
Definition: tusb.c:143
tusb_role_t _tusb_rhport_role[TUP_USBIP_CONTROLLER_NUM]
Definition: tusb.c:42
bool tu_edpt_validate(tusb_desc_endpoint_t const *desc_ep, tusb_speed_t speed)
Definition: tusb.c:202
uint8_t const * tu_desc_find2(uint8_t const *desc, uint8_t const *end, uint8_t byte1, uint8_t byte2)
Definition: tusb.c:151
uint8_t const * tu_desc_find3(uint8_t const *desc, uint8_t const *end, uint8_t byte1, uint8_t byte2, uint8_t byte3)
Definition: tusb.c:159
bool tu_edpt_stream_write_zlp_if_needed(uint8_t hwid, tu_edpt_stream_t *s, uint32_t last_xferred_bytes)
Definition: tusb.c:353
bool tu_edpt_claim(tu_edpt_state_t *ep_state, osal_mutex_t mutex)
Definition: tusb.c:171
void tu_edpt_bind_driver(uint8_t ep2drv[][2], tusb_desc_interface_t const *desc_itf, uint16_t desc_len, uint8_t driver_id)
Definition: tusb.c:236
static void dump_str_line(uint8_t const *buf, uint16_t count)
Definition: tusb.c:497
char const *const tu_str_speed[]
Definition: tusb.c:475
static TU_ATTR_ALWAYS_INLINE bool stream_xfer(uint8_t hwid, tu_edpt_stream_t *s, uint16_t count)
Definition: tusb.c:324
void tusb_int_handler(uint8_t rhport, bool in_isr)
Definition: tusb.c:122
uint32_t tu_edpt_stream_read_xfer(uint8_t hwid, tu_edpt_stream_t *s)
Definition: tusb.c:426
static TU_ATTR_ALWAYS_INLINE bool stream_claim(uint8_t hwid, tu_edpt_stream_t *s)
Definition: tusb.c:311
char const *const tu_str_std_request[]
Definition: tusb.c:476
uint32_t tu_edpt_stream_read(uint8_t hwid, tu_edpt_stream_t *s, void *buffer, uint32_t bufsize)
Definition: tusb.c:461
uint32_t tu_edpt_stream_write_available(uint8_t hwid, tu_edpt_stream_t *s)
Definition: tusb.c:405
uint32_t tu_edpt_stream_write_xfer(uint8_t hwid, tu_edpt_stream_t *s)
Definition: tusb.c:362
uint32_t tu_edpt_stream_write(uint8_t hwid, tu_edpt_stream_t *s, void const *buffer, uint32_t bufsize)
Definition: tusb.c:382
void tu_print_mem(void const *buf, uint32_t count, uint8_t indent)
Definition: tusb.c:512
char const *const tu_str_xfer_result[]
Definition: tusb.c:492
bool tu_edpt_release(tu_edpt_state_t *ep_state, osal_mutex_t mutex)
Definition: tusb.c:188
uint16_t tu_desc_get_interface_total_len(tusb_desc_interface_t const *desc_itf, uint8_t itf_count, uint16_t max_len)
Definition: tusb.c:251
bool tu_edpt_stream_init(tu_edpt_stream_t *s, bool is_host, bool is_tx, bool overwritable, void *ff_buf, uint16_t ff_bufsize, uint8_t *ep_buf, uint16_t ep_bufsize)
Definition: tusb.c:282
static TU_ATTR_ALWAYS_INLINE bool stream_release(uint8_t hwid, tu_edpt_stream_t *s)
Definition: tusb.c:337
bool tu_edpt_stream_deinit(tu_edpt_stream_t *s)
Definition: tusb.c:302
bool tusb_rhport_init(uint8_t rhport, const tusb_rhport_init_t *rh_init)
Definition: tusb.c:61
bool tusb_inited(void)
Definition: tusb.c:108
TU_ATTR_WEAK void tusb_time_delay_ms_api(uint32_t ms)
Definition: tusb.c:48
uint32_t tusb_time_millis_api(void)
static TU_ATTR_ALWAYS_INLINE uint16_t tu_min16(uint16_t x, uint16_t y)
Definition: tusb_common.h:155
static TU_ATTR_ALWAYS_INLINE uint32_t tu_min32(uint32_t x, uint32_t y)
Definition: tusb_common.h:156
static TU_ATTR_ALWAYS_INLINE int tu_memcpy_s(void *dest, size_t destsz, const void *src, size_t count)
Definition: tusb_common.h:114
uint16_t tu_fifo_count(tu_fifo_t *f)
Get number of items in FIFO.
Definition: tusb_fifo.c:590
bool tu_fifo_config(tu_fifo_t *f, void *buffer, uint16_t depth, uint16_t item_size, bool overwritable)
Definition: tusb_fifo.c:70
uint16_t tu_fifo_write_n(tu_fifo_t *f, const void *data, uint16_t n)
This function will write n elements into the array index specified by the write pointer and increment...
Definition: tusb_fifo.c:861
uint16_t tu_fifo_read_n(tu_fifo_t *f, void *buffer, uint16_t n)
This function will read n elements from the array index specified by the read pointer and increment t...
Definition: tusb_fifo.c:730
uint16_t tu_fifo_remaining(tu_fifo_t *f)
Get remaining space in FIFO.
Definition: tusb_fifo.c:644
static TU_ATTR_ALWAYS_INLINE uint16_t tu_fifo_depth(tu_fifo_t *f)
Definition: tusb_fifo.h:180
static TU_ATTR_ALWAYS_INLINE void tu_fifo_config_mutex(tu_fifo_t *f, osal_mutex_t wr_mutex, osal_mutex_t rd_mutex)
Definition: tusb_fifo.h:149
@ TUSB_EPSIZE_BULK_HS
Definition: tusb_types.h:74
@ TUSB_EPSIZE_BULK_FS
Definition: tusb_types.h:73
tusb_speed_t
defined base on EHCI specs value for Endpoint Speed
Definition: tusb_types.h:49
@ TUSB_SPEED_FULL
Definition: tusb_types.h:50
@ TUSB_SPEED_HIGH
Definition: tusb_types.h:52
static TU_ATTR_ALWAYS_INLINE uint8_t tu_edpt_number(uint8_t addr)
Definition: tusb_types.h:507
static TU_ATTR_ALWAYS_INLINE uint8_t tu_desc_len(void const *desc)
Definition: tusb_types.h:542
@ DESC_OFFSET_LEN
Definition: tusb_types.h:246
static TU_ATTR_ALWAYS_INLINE uint16_t tu_edpt_packet_size(tusb_desc_endpoint_t const *desc_ep)
Definition: tusb_types.h:515
@ TUSB_XFER_ISOCHRONOUS
Definition: tusb_types.h:60
@ TUSB_XFER_INTERRUPT
Definition: tusb_types.h:62
@ TUSB_XFER_BULK
Definition: tusb_types.h:61
TU_ATTR_PACKED_END TU_ATTR_BIT_FIELD_ORDER_END static TU_ATTR_ALWAYS_INLINE tusb_dir_t tu_edpt_dir(uint8_t addr)
Definition: tusb_types.h:502
static TU_ATTR_ALWAYS_INLINE uint8_t tu_desc_type(void const *desc)
Definition: tusb_types.h:537
static TU_ATTR_ALWAYS_INLINE uint8_t const * tu_desc_next(void const *desc)
Definition: tusb_types.h:531
@ TUSB_DESC_INTERFACE_ASSOCIATION
Definition: tusb_types.h:103
@ TUSB_DESC_ENDPOINT
Definition: tusb_types.h:97
@ TUSB_DESC_INTERFACE
Definition: tusb_types.h:96
bool usbd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_t total_bytes)
Definition: usbd.c:1309
bool usbd_edpt_claim(uint8_t rhport, uint8_t ep_addr)
Definition: usbd.c:1286
bool usbd_edpt_busy(uint8_t rhport, uint8_t ep_addr)
Definition: usbd.c:1376
bool tud_rhport_init(uint8_t rhport, const tusb_rhport_init_t *rh_init)
Definition: usbd.c:451
bool usbd_edpt_release(uint8_t rhport, uint8_t ep_addr)
Definition: usbd.c:1299
bool tud_inited(void)
Definition: usbd.c:447
bool usbh_edpt_release(uint8_t dev_addr, uint8_t ep_addr)
Definition: usbh.c:861
bool tuh_inited(void)
Definition: usbh.c:342
bool tuh_rhport_init(uint8_t rhport, const tusb_rhport_init_t *rh_init)
Definition: usbh.c:346
bool usbh_edpt_claim(uint8_t dev_addr, uint8_t ep_addr)
Definition: usbh.c:846
bool usbh_edpt_busy(uint8_t dev_addr, uint8_t ep_addr)
Definition: usbh.c:935
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