Open FFBoard
Open source force feedback firmware
dcd_eptri.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_TUD_ENABLED && (CFG_TUSB_MCU == OPT_MCU_VALENTYUSB_EPTRI)
30
31#ifndef DEBUG
32#define DEBUG 0
33#endif
34
35#ifndef LOG_USB
36#define LOG_USB 0
37#endif
38
39#include "device/dcd.h"
40#include "dcd_eptri.h"
41#include "csr.h"
42#include "irq.h"
43void fomu_error(uint32_t line);
44
45#if LOG_USB
46struct usb_log {
47 uint8_t ep_num;
48 uint8_t size;
49 uint8_t data[66];
50};
52struct usb_log usb_log[128];
53__attribute__((used))
54uint8_t usb_log_offset;
55
56struct xfer_log {
57 uint8_t ep_num;
58 uint16_t size;
59};
60__attribute__((used))
61struct xfer_log xfer_log[64];
62__attribute__((used))
63uint8_t xfer_log_offset;
64
65__attribute__((used))
66struct xfer_log queue_log[64];
67__attribute__((used))
68uint8_t queue_log_offset;
69#endif
70
71//--------------------------------------------------------------------+
72// SIE Command
73//--------------------------------------------------------------------+
74
75#define EP_SIZE 64
76
77uint16_t volatile rx_buffer_offset[16];
78uint8_t* volatile rx_buffer[16];
79uint16_t volatile rx_buffer_max[16];
80
81volatile uint8_t tx_ep;
82volatile bool tx_active;
83volatile uint16_t tx_buffer_offset[16];
84uint8_t* volatile tx_buffer[16];
85volatile uint16_t tx_buffer_max[16];
86volatile uint8_t reset_count;
87
88#if DEBUG
89__attribute__((used)) uint8_t volatile * last_tx_buffer;
90__attribute__((used)) volatile uint8_t last_tx_ep;
91uint8_t setup_packet_bfr[10];
92#endif
93
94//--------------------------------------------------------------------+
95// PIPE HELPER
96//--------------------------------------------------------------------+
97
98static bool advance_tx_ep(void) {
99 // Move on to the next transmit buffer in a round-robin manner
100 uint8_t prev_tx_ep = tx_ep;
101 for (tx_ep = (tx_ep + 1) & 0xf; tx_ep != prev_tx_ep; tx_ep = ((tx_ep + 1) & 0xf)) {
102 if (tx_buffer[tx_ep])
103 return true;
104 }
105 if (!tx_buffer[tx_ep])
106 return false;
107 return true;
108}
109
110#if LOG_USB
111void xfer_log_append(uint8_t ep_num, uint16_t sz) {
112 xfer_log[xfer_log_offset].ep_num = ep_num;
113 xfer_log[xfer_log_offset].size = sz;
114 xfer_log_offset++;
115 if (xfer_log_offset >= sizeof(xfer_log)/sizeof(*xfer_log))
116 xfer_log_offset = 0;
117}
118
119void queue_log_append(uint8_t ep_num, uint16_t sz) {
120 queue_log[queue_log_offset].ep_num = ep_num;
121 queue_log[queue_log_offset].size = sz;
122 queue_log_offset++;
123 if (queue_log_offset >= sizeof(queue_log)/sizeof(*queue_log))
124 queue_log_offset = 0;
125}
126#endif
127
128static void tx_more_data(void) {
129 // Send more data
130 uint8_t added_bytes;
131 for (added_bytes = 0; (added_bytes < EP_SIZE) && (tx_buffer_offset[tx_ep] < tx_buffer_max[tx_ep]); added_bytes++) {
132#if LOG_USB
133 usb_log[usb_log_offset].data[added_bytes] = tx_buffer[tx_ep][tx_buffer_offset[tx_ep]];
134#endif
135 usb_in_data_write(tx_buffer[tx_ep][tx_buffer_offset[tx_ep]++]);
136 }
137
138#if LOG_USB
139 usb_log[usb_log_offset].ep_num = tu_edpt_addr(tx_ep, TUSB_DIR_IN);
140 usb_log[usb_log_offset].size = added_bytes;
141 usb_log_offset++;
142 if (usb_log_offset >= sizeof(usb_log)/sizeof(*usb_log))
143 usb_log_offset = 0;
144#endif
145
146 // Updating the epno queues the data
147 usb_in_ctrl_write(tx_ep & 0xf);
148}
149
150static void process_tx(void) {
151#if DEBUG
152 // If the system isn't idle, then something is very wrong.
153 uint8_t in_status = usb_in_status_read();
154 if (!(in_status & (1 << CSR_USB_IN_STATUS_IDLE_OFFSET)))
155 fomu_error(__LINE__);
156#endif
157
158 // If the buffer is now empty, search for the next buffer to fill.
159 if (!tx_buffer[tx_ep]) {
160 if (advance_tx_ep())
161 tx_more_data();
162 else
163 tx_active = false;
164 return;
165 }
166
167 if (tx_buffer_offset[tx_ep] >= tx_buffer_max[tx_ep]) {
168#if DEBUG
169 last_tx_buffer = tx_buffer[tx_ep];
170 last_tx_ep = tx_ep;
171#endif
172 tx_buffer[tx_ep] = NULL;
173 uint16_t xferred_bytes = tx_buffer_max[tx_ep];
174 uint8_t xferred_ep = tx_ep;
175
176 if (!advance_tx_ep())
177 tx_active = false;
178#if LOG_USB
179 xfer_log_append(tu_edpt_addr(xferred_ep, TUSB_DIR_IN), xferred_bytes);
180#endif
181 dcd_event_xfer_complete(0, tu_edpt_addr(xferred_ep, TUSB_DIR_IN), xferred_bytes, XFER_RESULT_SUCCESS, true);
182 if (!tx_active)
183 return;
184 }
185
186 tx_more_data();
187 return;
188}
189
190static void process_rx(void) {
191 uint8_t out_status = usb_out_status_read();
192#if DEBUG
193 // If the OUT handler is still waiting to send, don't do anything.
194 if (!(out_status & (1 << CSR_USB_OUT_STATUS_HAVE_OFFSET)))
195 fomu_error(__LINE__);
196 // return;
197#endif
198 uint8_t rx_ep = (out_status >> CSR_USB_OUT_STATUS_EPNO_OFFSET) & 0xf;
199
200 // If the destination buffer doesn't exist, don't drain the hardware
201 // fifo. Note that this can cause deadlocks if the host is waiting
202 // on some other endpoint's data!
203#if DEBUG
204 if (rx_buffer[rx_ep] == NULL) {
205 fomu_error(__LINE__);
206 return;
207 }
208#endif
209
210 // Drain the FIFO into the destination buffer
211 uint32_t total_read = 0;
212 uint32_t current_offset = rx_buffer_offset[rx_ep];
213#if DEBUG
214 uint8_t test_buffer[256];
215 memset(test_buffer, 0, sizeof(test_buffer));
216 if (current_offset > rx_buffer_max[rx_ep])
217 fomu_error(__LINE__);
218#endif
219#if LOG_USB
220 usb_log[usb_log_offset].ep_num = tu_edpt_addr(rx_ep, TUSB_DIR_OUT);
221 usb_log[usb_log_offset].size = 0;
222#endif
223 while (usb_out_status_read() & (1 << CSR_USB_OUT_STATUS_HAVE_OFFSET)) {
224 uint8_t c = usb_out_data_read();
225#if DEBUG
226 test_buffer[total_read] = c;
227#endif
228 total_read++;
229 if (current_offset < rx_buffer_max[rx_ep]) {
230#if LOG_USB
231 usb_log[usb_log_offset].data[usb_log[usb_log_offset].size++] = c;
232#endif
233 if (rx_buffer[rx_ep] != (volatile uint8_t *)0xffffffff)
234 rx_buffer[rx_ep][current_offset++] = c;
235 }
236 }
237#if LOG_USB
238 usb_log_offset++;
239 if (usb_log_offset >= sizeof(usb_log)/sizeof(*usb_log))
240 usb_log_offset = 0;
241#endif
242#if DEBUG
243 if (total_read > 66)
244 fomu_error(__LINE__);
245 if (total_read < 2)
246 total_read = 2;
247 // fomu_error(__LINE__);
248#endif
249
250 // Strip off the CRC16
251 rx_buffer_offset[rx_ep] += (total_read - 2);
252 if (rx_buffer_offset[rx_ep] > rx_buffer_max[rx_ep])
253 rx_buffer_offset[rx_ep] = rx_buffer_max[rx_ep];
254
255 // If there's no more data, complete the transfer to tinyusb
256 if ((rx_buffer_max[rx_ep] == rx_buffer_offset[rx_ep])
257 // ZLP with less than the total amount of data
258 || ((total_read == 2) && ((rx_buffer_offset[rx_ep] & 63) == 0))
259 // Short read, but not a full packet
260 || (((rx_buffer_offset[rx_ep] & 63) != 0) && (total_read < 66))) {
261#if DEBUG
262 if (rx_buffer[rx_ep] == NULL)
263 fomu_error(__LINE__);
264#endif
265
266 // Free up this buffer.
267 rx_buffer[rx_ep] = NULL;
268 uint16_t len = rx_buffer_offset[rx_ep];
269
270#if DEBUG
271 // Validate that all enabled endpoints have buffers,
272 // and no disabled endpoints have buffers.
273 uint16_t ep_en_mask = usb_out_enable_status_read();
274 int i;
275 for (i = 0; i < 16; i++) {
276 if ((!!(ep_en_mask & (1 << i))) ^ (!!(rx_buffer[i]))) {
277 uint8_t new_status = usb_out_status_read();
278 // Another IRQ came in while we were processing, so ignore this endpoint.
279 if ((new_status & 0x20) && ((new_status & 0xf) == i))
280 continue;
281 fomu_error(__LINE__);
282 }
283 }
284#endif
285#if LOG_USB
287#endif
289 }
290 else {
291 // If there's more data, re-enable data reception on this endpoint
292 usb_out_ctrl_write((1 << CSR_USB_OUT_CTRL_ENABLE_OFFSET) | rx_ep);
293 }
294
295 // Now that the buffer is drained, clear the pending IRQ.
296 usb_out_ev_pending_write(usb_out_ev_pending_read());
297}
298
299//--------------------------------------------------------------------+
300// CONTROLLER API
301//--------------------------------------------------------------------+
302
303static void dcd_reset(void)
304{
305 reset_count++;
306 usb_setup_ev_enable_write(0);
307 usb_in_ev_enable_write(0);
308 usb_out_ev_enable_write(0);
309
310 usb_address_write(0);
311
312 // Reset all three FIFO handlers
313 usb_setup_ctrl_write(1 << CSR_USB_SETUP_CTRL_RESET_OFFSET);
314 usb_in_ctrl_write(1 << CSR_USB_IN_CTRL_RESET_OFFSET);
315 usb_out_ctrl_write(1 << CSR_USB_OUT_CTRL_RESET_OFFSET);
316
317 memset((void *)(uintptr_t) rx_buffer, 0, sizeof(rx_buffer));
318 memset((void *)(uintptr_t) rx_buffer_max, 0, sizeof(rx_buffer_max));
319 memset((void *)(uintptr_t) rx_buffer_offset, 0, sizeof(rx_buffer_offset));
320
321 memset((void *)(uintptr_t) tx_buffer, 0, sizeof(tx_buffer));
322 memset((void *)(uintptr_t) tx_buffer_max, 0, sizeof(tx_buffer_max));
323 memset((void *)(uintptr_t) tx_buffer_offset, 0, sizeof(tx_buffer_offset));
324 tx_ep = 0;
325 tx_active = false;
326
327 // Enable all event handlers and clear their contents
328 usb_setup_ev_pending_write(0xff);
329 usb_in_ev_pending_write(0xff);
330 usb_out_ev_pending_write(0xff);
331 usb_in_ev_enable_write(1);
332 usb_out_ev_enable_write(1);
333 usb_setup_ev_enable_write(3);
334
336}
337
338// Initializes the USB peripheral for device mode and enables it.
339bool dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) {
340 (void) rhport;
341 (void) rh_init;
342
343 usb_pullup_out_write(0);
344
345 // Enable all event handlers and clear their contents
346 usb_setup_ev_pending_write(usb_setup_ev_pending_read());
347 usb_in_ev_pending_write(usb_in_ev_pending_read());
348 usb_out_ev_pending_write(usb_out_ev_pending_read());
349 usb_in_ev_enable_write(1);
350 usb_out_ev_enable_write(1);
351 usb_setup_ev_enable_write(3);
352
353 // Turn on the external pullup
354 usb_pullup_out_write(1);
355
356 return true;
357}
358
359// Enables or disables the USB device interrupt(s). May be used to
360// prevent concurrency issues when mutating data structures shared
361// between main code and the interrupt handler.
362void dcd_int_enable(uint8_t rhport)
363{
364 (void) rhport;
365 irq_setmask(irq_getmask() | (1 << USB_INTERRUPT));
366}
367
368void dcd_int_disable(uint8_t rhport)
369{
370 (void) rhport;
371 irq_setmask(irq_getmask() & ~(1 << USB_INTERRUPT));
372}
373
374// Called when the device is given a new bus address.
375void dcd_set_address(uint8_t rhport, uint8_t dev_addr)
376{
377 // Respond with ACK status first before changing device address
378 dcd_edpt_xfer(rhport, tu_edpt_addr(0, TUSB_DIR_IN), NULL, 0);
379
380 // Wait for the response packet to get sent
381 while (tx_active)
382 ;
383
384 // Activate the new address
385 usb_address_write(dev_addr);
386}
387
388// Called to remote wake up host when suspended (e.g hid keyboard)
389void dcd_remote_wakeup(uint8_t rhport)
390{
391 (void) rhport;
392}
393
394void dcd_connect(uint8_t rhport)
395{
396 (void) rhport;
397 usb_pullup_out_write(1);
398}
399
400void dcd_disconnect(uint8_t rhport)
401{
402 (void) rhport;
403 usb_pullup_out_write(0);
404}
405
406void dcd_sof_enable(uint8_t rhport, bool en)
407{
408 (void) rhport;
409 (void) en;
410
411 // TODO implement later
412}
413
414//--------------------------------------------------------------------+
415// DCD Endpoint Port
416//--------------------------------------------------------------------+
417bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * p_endpoint_desc)
418{
419 (void) rhport;
420 uint8_t ep_num = tu_edpt_number(p_endpoint_desc->bEndpointAddress);
421 uint8_t ep_dir = tu_edpt_dir(p_endpoint_desc->bEndpointAddress);
422
423 if (p_endpoint_desc->bmAttributes.xfer == TUSB_XFER_ISOCHRONOUS)
424 return false; // Not supported
425
426 if (ep_dir == TUSB_DIR_OUT) {
427 rx_buffer_offset[ep_num] = 0;
428 rx_buffer_max[ep_num] = 0;
429 rx_buffer[ep_num] = NULL;
430 }
431
432 else if (ep_dir == TUSB_DIR_IN) {
433 tx_buffer_offset[ep_num] = 0;
434 tx_buffer_max[ep_num] = 0;
435 tx_buffer[ep_num] = NULL;
436 }
437
438 return true;
439}
440
441void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr) {
442 (void) rhport; (void) ep_addr;
443 // TODO implement dcd_edpt_close()
444}
445
446void dcd_edpt_close_all (uint8_t rhport)
447{
448 (void) rhport;
449 // TODO implement dcd_edpt_close_all()
450}
451
452void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr)
453{
454 (void) rhport;
455
456 if (tu_edpt_dir(ep_addr) == TUSB_DIR_OUT) {
457 uint8_t enable = 0;
458 if (rx_buffer[ep_addr])
459 enable = 1;
460 usb_out_ctrl_write((1 << CSR_USB_OUT_CTRL_STALL_OFFSET) | (enable << CSR_USB_OUT_CTRL_ENABLE_OFFSET) | tu_edpt_number(ep_addr));
461 }
462 else
463 usb_in_ctrl_write((1 << CSR_USB_IN_CTRL_STALL_OFFSET) | tu_edpt_number(ep_addr));
464}
465
466void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr)
467{
468 (void) rhport;
469 if (tu_edpt_dir(ep_addr) == TUSB_DIR_OUT) {
470 uint8_t enable = 0;
471 if (rx_buffer[ep_addr])
472 enable = 1;
473 usb_out_ctrl_write((0 << CSR_USB_OUT_CTRL_STALL_OFFSET) | (enable << CSR_USB_OUT_CTRL_ENABLE_OFFSET) | tu_edpt_number(ep_addr));
474 }
475 // IN endpoints will get un-stalled when more data is written.
476}
477
478bool dcd_edpt_xfer (uint8_t rhport, uint8_t ep_addr, uint8_t* buffer, uint16_t total_bytes)
479{
480 (void)rhport;
481 uint8_t ep_num = tu_edpt_number(ep_addr);
482 uint8_t ep_dir = tu_edpt_dir(ep_addr);
483 TU_ASSERT(ep_num < 16);
484
485 // Give a nonzero buffer when we transmit 0 bytes, so that the
486 // system doesn't think the endpoint is idle.
487 if ((buffer == NULL) && (total_bytes == 0)) {
488 buffer = (uint8_t *)0xffffffff;
489 }
490
491 TU_ASSERT(buffer != NULL);
492
493 if (ep_dir == TUSB_DIR_IN) {
494 // Wait for the tx pipe to free up
495 uint8_t previous_reset_count = reset_count;
496 // Continue until the buffer is empty, the system is idle, and the fifo is empty.
497 while (tx_buffer[ep_num] != NULL)
498 ;
499
501#if LOG_USB
503#endif
504 // If a reset happens while we're waiting, abort the transfer
505 if (previous_reset_count != reset_count)
506 return true;
507
508 TU_ASSERT(tx_buffer[ep_num] == NULL);
509 tx_buffer_offset[ep_num] = 0;
510 tx_buffer_max[ep_num] = total_bytes;
511 tx_buffer[ep_num] = buffer;
512
513 // If the current buffer is NULL, then that means the tx logic is idle.
514 // Update the tx_ep to point to our endpoint number and queue the data.
515 // Otherwise, let it be and it'll get picked up after the next transfer
516 // finishes.
517 if (!tx_active) {
518 tx_ep = ep_num;
519 tx_active = true;
520 tx_more_data();
521 }
523 }
524
525 else if (ep_dir == TUSB_DIR_OUT) {
526 while (rx_buffer[ep_num] != NULL)
527 ;
528
529 TU_ASSERT(rx_buffer[ep_num] == NULL);
531#if LOG_USB
533#endif
534 rx_buffer[ep_num] = buffer;
535 rx_buffer_offset[ep_num] = 0;
536 rx_buffer_max[ep_num] = total_bytes;
537
538 // Enable receiving on this particular endpoint
539 usb_out_ctrl_write((1 << CSR_USB_OUT_CTRL_ENABLE_OFFSET) | ep_num);
540#if DEBUG
541 uint16_t ep_en_mask = usb_out_enable_status_read();
542 int i;
543 for (i = 0; i < 16; i++) {
544 if ((!!(ep_en_mask & (1 << i))) ^ (!!(rx_buffer[i]))) {
545 if (rx_buffer[i] && usb_out_ev_pending_read() && (usb_out_status_read() & 0xf) == i)
546 continue;
547 fomu_error(__LINE__);
548 }
549 }
550#endif
552 }
553 return true;
554}
555
556//--------------------------------------------------------------------+
557// ISR
558//--------------------------------------------------------------------+
559
560static void handle_out(void)
561{
562 // An "OUT" transaction just completed so we have new data.
563 // (But only if we can accept the data)
564#if DEBUG
565 if (!usb_out_ev_pending_read())
566 fomu_error(__LINE__);
567 if (!usb_out_ev_enable_read())
568 fomu_error(__LINE__);
569#endif
570 process_rx();
571}
572
573static void handle_in(void)
574{
575#if DEBUG
576 if (!usb_in_ev_pending_read())
577 fomu_error(__LINE__);
578 if (!usb_in_ev_enable_read())
579 fomu_error(__LINE__);
580#endif
581 usb_in_ev_pending_write(usb_in_ev_pending_read());
582 process_tx();
583}
584
585static void handle_reset(void)
586{
587#if DEBUG
588 uint8_t setup_pending = usb_setup_ev_pending_read() & usb_setup_ev_enable_read();
589 if (!(setup_pending & 2))
590 fomu_error(__LINE__);
591#endif
592 usb_setup_ev_pending_write(2);
593
594 // This event means a bus reset occurred. Reset everything, and
595 // abandon any further processing.
596 dcd_reset();
597}
598
599static void handle_setup(void)
600{
601#if !DEBUG
602 uint8_t setup_packet_bfr[10];
603#endif
604
605#if DEBUG
606 uint8_t setup_pending = usb_setup_ev_pending_read() & usb_setup_ev_enable_read();
607 if (!(setup_pending & 1))
608 fomu_error(__LINE__);
609#endif
610
611 // We got a SETUP packet. Copy it to the setup buffer and clear
612 // the "pending" bit.
613 // Setup packets are always 8 bytes, plus two bytes of crc16.
614 uint32_t setup_length = 0;
615
616#if DEBUG
617 if (!(usb_setup_status_read() & (1 << CSR_USB_SETUP_STATUS_HAVE_OFFSET)))
618 fomu_error(__LINE__);
619#endif
620
621 while (usb_setup_status_read() & (1 << CSR_USB_SETUP_STATUS_HAVE_OFFSET)) {
622 uint8_t c = usb_setup_data_read();
623 if (setup_length < sizeof(setup_packet_bfr))
624 setup_packet_bfr[setup_length] = c;
625 setup_length++;
626 }
627
628 // If we have 10 bytes, that's a full SETUP packet plus CRC16.
629 // Otherwise, it was an RX error.
630 if (setup_length == 10) {
631 dcd_event_setup_received(0, setup_packet_bfr, true);
632 }
633#if DEBUG
634 else {
635 fomu_error(__LINE__);
636 }
637#endif
638
639 usb_setup_ev_pending_write(1);
640}
641void dcd_int_handler(uint8_t rhport)
642{
643 (void)rhport;
644 uint8_t next_ev;
645 while ((next_ev = usb_next_ev_read())) {
646 switch (next_ev) {
647 case 1 << CSR_USB_NEXT_EV_IN_OFFSET:
648 handle_in();
649 break;
650 case 1 << CSR_USB_NEXT_EV_OUT_OFFSET:
651 handle_out();
652 break;
653 case 1 << CSR_USB_NEXT_EV_SETUP_OFFSET:
654 handle_setup();
655 break;
656 case 1 << CSR_USB_NEXT_EV_RESET_OFFSET:
657 handle_reset();
658 break;
659 }
660 }
661}
662
663#endif
static TU_ATTR_ALWAYS_INLINE void dcd_event_xfer_complete(uint8_t rhport, uint8_t ep_addr, uint32_t xferred_bytes, uint8_t result, bool in_isr)
Definition: dcd.h:222
static TU_ATTR_ALWAYS_INLINE void dcd_event_setup_received(uint8_t rhport, uint8_t const *setup, bool in_isr)
Definition: dcd.h:213
static TU_ATTR_ALWAYS_INLINE void dcd_event_bus_reset(uint8_t rhport, tusb_speed_t speed, bool in_isr)
Definition: dcd.h:204
static void handle_out(void)
Definition: dcd_eptri.c:560
__attribute__((used))
Definition: dcd_eptri.c:51
static void handle_setup(void)
Definition: dcd_eptri.c:599
void xfer_log_append(uint8_t ep_num, uint16_t sz)
Definition: dcd_eptri.c:111
void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr)
Definition: dcd_eptri.c:452
void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr)
Definition: dcd_eptri.c:441
void dcd_int_handler(uint8_t rhport)
Definition: dcd_eptri.c:641
void dcd_disconnect(uint8_t rhport)
Definition: dcd_eptri.c:400
void dcd_edpt_close_all(uint8_t rhport)
Definition: dcd_eptri.c:446
void dcd_int_disable(uint8_t rhport)
Definition: dcd_eptri.c:368
bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const *p_endpoint_desc)
Definition: dcd_eptri.c:417
void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr)
Definition: dcd_eptri.c:466
void dcd_connect(uint8_t rhport)
Definition: dcd_eptri.c:394
bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_t total_bytes)
Definition: dcd_eptri.c:478
static void process_tx(void)
Definition: dcd_eptri.c:150
static void handle_in(void)
Definition: dcd_eptri.c:573
void dcd_set_address(uint8_t rhport, uint8_t dev_addr)
Definition: dcd_eptri.c:375
static void tx_more_data(void)
Definition: dcd_eptri.c:128
static void handle_reset(void)
Definition: dcd_eptri.c:585
bool dcd_init(uint8_t rhport, const tusb_rhport_init_t *rh_init)
Definition: dcd_eptri.c:339
void fomu_error(uint32_t line)
static void process_rx(void)
Definition: dcd_eptri.c:190
void dcd_int_enable(uint8_t rhport)
Definition: dcd_eptri.c:362
void dcd_remote_wakeup(uint8_t rhport)
Definition: dcd_eptri.c:389
static void dcd_reset(void)
Definition: dcd_eptri.c:303
void dcd_sof_enable(uint8_t rhport, bool en)
Definition: dcd_eptri.c:406
void queue_log_append(uint8_t ep_num, uint16_t sz)
Definition: dcd_eptri.c:119
uint16_t total_bytes
Definition: dcd_nuc505.c:113
uint8_t dev_addr
Definition: dcd_pic32mz.c:81
uint8_t const * buffer
Definition: midi_device.h:100
AUDIO Channel Cluster Descriptor (4.1)
Definition: audio.h:647
uint8_t bmAttributes
See: audio_clock_source_attribute_t.
Definition: audio.h:672
uint8_t bEndpointAddress
Definition: video.h:306
uint8_t size
Definition: dcd_eptri.c:48
uint8_t ep_num
Definition: dcd_eptri.c:47
uint8_t data[66]
Definition: dcd_eptri.c:49
@ TUSB_DIR_IN
Definition: tusb_types.h:67
@ TUSB_DIR_OUT
Definition: tusb_types.h:66
@ TUSB_SPEED_FULL
Definition: tusb_types.h:50
static TU_ATTR_ALWAYS_INLINE uint8_t tu_edpt_number(uint8_t addr)
Definition: tusb_types.h:507
@ XFER_RESULT_SUCCESS
Definition: tusb_types.h:237
@ TUSB_XFER_ISOCHRONOUS
Definition: tusb_types.h:60
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_edpt_addr(uint8_t num, uint8_t dir)
Definition: tusb_types.h:511