Open FFBoard
Open source force feedback firmware
dcd_khci.c
Go to the documentation of this file.
1/*
2 * The MIT License (MIT)
3 *
4 * Copyright (c) 2020 Koji Kitayama
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 && defined(TUP_USBIP_CHIPIDEA_FS)
30
31#ifdef TUP_USBIP_CHIPIDEA_FS_KINETIS
32 #include "fsl_device_registers.h"
33 #define KHCI USB0
34#else
35 #error "MCU is not supported"
36#endif
37
38#include "device/dcd.h"
39
40//--------------------------------------------------------------------+
41// MACRO TYPEDEF CONSTANT ENUM DECLARATION
42//--------------------------------------------------------------------+
43
44enum {
46 TOK_PID_IN = 0x9u,
48};
49
50typedef struct TU_ATTR_PACKED
51{
52 union {
53 uint32_t head;
54 struct {
55 union {
56 struct {
57 uint16_t : 2;
58 __IO uint16_t tok_pid : 4;
59 uint16_t data : 1;
60 __IO uint16_t own : 1;
61 uint16_t : 8;
62 };
63 struct {
64 uint16_t : 2;
66 uint16_t dts : 1;
67 uint16_t ninc : 1;
68 uint16_t keep : 1;
69 uint16_t : 10;
70 };
71 };
72 __IO uint16_t bc : 10;
73 uint16_t : 6;
74 };
75 };
76 uint8_t *addr;
78
79TU_VERIFY_STATIC( sizeof(buffer_descriptor_t) == 8, "size is not correct" );
80
81typedef struct TU_ATTR_PACKED
82{
83 union {
84 uint32_t state;
85 struct {
86 uint32_t max_packet_size :11;
87 uint32_t : 5;
88 uint32_t odd : 1;
89 uint32_t :15;
90 };
91 };
95
96TU_VERIFY_STATIC( sizeof(endpoint_state_t) == 8, "size is not correct" );
97
98typedef struct
99{
100 union {
101 /* [#EP][OUT,IN][EVEN,ODD] */
102 buffer_descriptor_t bdt[16][2][2];
103 uint16_t bda[512];
104 };
106 endpoint_state_t endpoint[16][2];
107 endpoint_state_t endpoint_unified[16 * 2];
108 };
109 uint8_t setup_packet[8];
110 uint8_t addr;
112
113//--------------------------------------------------------------------+
114// INTERNAL OBJECT & FUNCTION DECLARATION
115//--------------------------------------------------------------------+
116// BDT(Buffer Descriptor Table) must be 256-byte aligned
117CFG_TUD_MEM_SECTION TU_ATTR_ALIGNED(512) static dcd_data_t _dcd;
118
119TU_VERIFY_STATIC( sizeof(_dcd.bdt) == 512, "size is not correct" );
120
121static void prepare_next_setup_packet(uint8_t rhport)
122{
123 const unsigned out_odd = _dcd.endpoint[0][0].odd;
124 const unsigned in_odd = _dcd.endpoint[0][1].odd;
125 TU_ASSERT(0 == _dcd.bdt[0][0][out_odd].own, );
126
127 _dcd.bdt[0][0][out_odd].data = 0;
128 _dcd.bdt[0][0][out_odd ^ 1].data = 1;
129 _dcd.bdt[0][1][in_odd].data = 1;
130 _dcd.bdt[0][1][in_odd ^ 1].data = 0;
132 _dcd.setup_packet, sizeof(_dcd.setup_packet));
133}
134
135static void process_stall(uint8_t rhport)
136{
137 for (int i = 0; i < 16; ++i) {
138 unsigned const endpt = KHCI->ENDPOINT[i].ENDPT;
139
140 if (endpt & USB_ENDPT_EPSTALL_MASK) {
141 // prepare next setup if endpoint0
142 if ( i == 0 ) prepare_next_setup_packet(rhport);
143
144 // clear stall bit
145 KHCI->ENDPOINT[i].ENDPT = endpt & ~USB_ENDPT_EPSTALL_MASK;
146 }
147 }
148}
149
150static void process_tokdne(uint8_t rhport)
151{
152 const unsigned s = KHCI->STAT;
153 KHCI->ISTAT = USB_ISTAT_TOKDNE_MASK; /* fetch the next token if received */
154
155 uint8_t const epnum = (s >> USB_STAT_ENDP_SHIFT);
156 uint8_t const dir = (s & USB_STAT_TX_MASK) >> USB_STAT_TX_SHIFT;
157 unsigned const odd = (s & USB_STAT_ODD_MASK) ? 1 : 0;
158
160 endpoint_state_t *ep = &_dcd.endpoint_unified[s >> 3];
161
162 /* fetch pid before discarded by the next steps */
163 const unsigned pid = bd->tok_pid;
164
165 /* reset values for a next transfer */
166 bd->bdt_stall = 0;
167 bd->dts = 1;
168 bd->ninc = 0;
169 bd->keep = 0;
170 /* update the odd variable to prepare for the next transfer */
171 ep->odd = odd ^ 1;
172 if (pid == TOK_PID_SETUP) {
173 dcd_event_setup_received(rhport, bd->addr, true);
174 KHCI->CTL &= ~USB_CTL_TXSUSPENDTOKENBUSY_MASK;
175 return;
176 }
177
178 const unsigned bc = bd->bc;
179 const unsigned remaining = ep->remaining - bc;
180 if (remaining && bc == ep->max_packet_size) {
181 /* continue the transferring consecutive data */
182 ep->remaining = remaining;
183 const int next_remaining = remaining - ep->max_packet_size;
184 if (next_remaining > 0) {
185 /* prepare to the after next transfer */
186 bd->addr += ep->max_packet_size * 2;
187 bd->bc = next_remaining > ep->max_packet_size ? ep->max_packet_size: next_remaining;
188 __DSB();
189 bd->own = 1; /* the own bit must set after addr */
190 }
191 return;
192 }
193 const unsigned length = ep->length;
195 tu_edpt_addr(epnum, dir),
196 length - remaining, XFER_RESULT_SUCCESS, true);
197 if (0 == epnum && 0 == length) {
198 /* After completion a ZLP of control transfer,
199 * it prepares for the next steup transfer. */
200 if (_dcd.addr) {
201 /* When the transfer was the SetAddress,
202 * the device address should be updated here. */
203 KHCI->ADDR = _dcd.addr;
204 _dcd.addr = 0;
205 }
207 }
208}
209
210static void process_bus_reset(uint8_t rhport)
211{
212 KHCI->USBCTRL &= ~USB_USBCTRL_SUSP_MASK;
213 KHCI->CTL |= USB_CTL_ODDRST_MASK;
214 KHCI->ADDR = 0;
215 KHCI->INTEN = USB_INTEN_USBRSTEN_MASK | USB_INTEN_TOKDNEEN_MASK | USB_INTEN_SLEEPEN_MASK |
216 USB_INTEN_ERROREN_MASK | USB_INTEN_STALLEN_MASK;
217
218 KHCI->ENDPOINT[0].ENDPT = USB_ENDPT_EPHSHK_MASK | USB_ENDPT_EPRXEN_MASK | USB_ENDPT_EPTXEN_MASK;
219 for (unsigned i = 1; i < 16; ++i) {
220 KHCI->ENDPOINT[i].ENDPT = 0;
221 }
222 buffer_descriptor_t *bd = _dcd.bdt[0][0];
223 for (unsigned i = 0; i < sizeof(_dcd.bdt)/sizeof(*bd); ++i, ++bd) {
224 bd->head = 0;
225 }
226 const endpoint_state_t ep0 = {
227 .max_packet_size = CFG_TUD_ENDPOINT0_SIZE,
228 .odd = 0,
229 .length = 0,
230 .remaining = 0,
231 };
232 _dcd.endpoint[0][0] = ep0;
233 _dcd.endpoint[0][1] = ep0;
234 tu_memclr(_dcd.endpoint[1], sizeof(_dcd.endpoint) - sizeof(_dcd.endpoint[0]));
235 _dcd.addr = 0;
237 KHCI->CTL &= ~USB_CTL_ODDRST_MASK;
239}
240
241static void process_bus_sleep(uint8_t rhport)
242{
243 // Enable resume & disable suspend interrupt
244 const unsigned inten = KHCI->INTEN;
245
246 KHCI->INTEN = (inten & ~USB_INTEN_SLEEPEN_MASK) | USB_INTEN_RESUMEEN_MASK;
247 KHCI->USBTRC0 |= USB_USBTRC0_USBRESMEN_MASK;
248 KHCI->USBCTRL |= USB_USBCTRL_SUSP_MASK;
249
250 dcd_event_bus_signal(rhport, DCD_EVENT_SUSPEND, true);
251}
252
253static void process_bus_resume(uint8_t rhport)
254{
255 // Enable suspend & disable resume interrupt
256 const unsigned inten = KHCI->INTEN;
257
258 KHCI->USBCTRL &= ~USB_USBCTRL_SUSP_MASK; // will also clear USB_USBTRC0_USB_RESUME_INT_MASK
259 KHCI->USBTRC0 &= ~USB_USBTRC0_USBRESMEN_MASK;
260 KHCI->INTEN = (inten & ~USB_INTEN_RESUMEEN_MASK) | USB_INTEN_SLEEPEN_MASK;
261
262 dcd_event_bus_signal(rhport, DCD_EVENT_RESUME, true);
263}
264
265/*------------------------------------------------------------------*/
266/* Device API
267 *------------------------------------------------------------------*/
268bool dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) {
269 (void) rhport;
270 (void) rh_init;
271
272 // save crystal-less setting (if available)
273 #if defined(FSL_FEATURE_USB_KHCI_IRC48M_MODULE_CLOCK_ENABLED) && FSL_FEATURE_USB_KHCI_IRC48M_MODULE_CLOCK_ENABLED == 1
274 uint32_t clk_recover_irc_en = KHCI->CLK_RECOVER_IRC_EN;
275 uint32_t clk_recover_ctrl = KHCI->CLK_RECOVER_CTRL;
276 #endif
277
278 KHCI->USBTRC0 |= USB_USBTRC0_USBRESET_MASK;
279 while (KHCI->USBTRC0 & USB_USBTRC0_USBRESET_MASK);
280
281 // restore crystal-less setting (if available)
282 #if defined(FSL_FEATURE_USB_KHCI_IRC48M_MODULE_CLOCK_ENABLED) && FSL_FEATURE_USB_KHCI_IRC48M_MODULE_CLOCK_ENABLED == 1
283 KHCI->CLK_RECOVER_IRC_EN = clk_recover_irc_en;
284 KHCI->CLK_RECOVER_CTRL |= clk_recover_ctrl;
285 #endif
286
287 tu_memclr(&_dcd, sizeof(_dcd));
288 KHCI->USBTRC0 |= TU_BIT(6); /* software must set this bit to 1 */
289 KHCI->BDTPAGE1 = (uint8_t)((uintptr_t)_dcd.bdt >> 8);
290 KHCI->BDTPAGE2 = (uint8_t)((uintptr_t)_dcd.bdt >> 16);
291 KHCI->BDTPAGE3 = (uint8_t)((uintptr_t)_dcd.bdt >> 24);
292
293 KHCI->INTEN = USB_INTEN_USBRSTEN_MASK;
294
295 dcd_connect(rhport);
296 NVIC_ClearPendingIRQ(USB0_IRQn);
297
298 return true;
299}
300
301void dcd_int_enable(uint8_t rhport)
302{
303 (void) rhport;
304 NVIC_EnableIRQ(USB0_IRQn);
305}
306
307void dcd_int_disable(uint8_t rhport)
308{
309 (void) rhport;
310 NVIC_DisableIRQ(USB0_IRQn);
311}
312
313void dcd_set_address(uint8_t rhport, uint8_t dev_addr)
314{
315 _dcd.addr = dev_addr & 0x7F;
316 /* Response with status first before changing device address */
317 dcd_edpt_xfer(rhport, tu_edpt_addr(0, TUSB_DIR_IN), NULL, 0);
318}
319
320void dcd_remote_wakeup(uint8_t rhport)
321{
322 (void) rhport;
323
324 KHCI->CTL |= USB_CTL_RESUME_MASK;
325
326 unsigned cnt = SystemCoreClock / 1000;
327 while (cnt--) __NOP();
328
329 KHCI->CTL &= ~USB_CTL_RESUME_MASK;
330}
331
332void dcd_connect(uint8_t rhport)
333{
334 (void) rhport;
335 KHCI->USBCTRL = 0;
336 KHCI->CONTROL |= USB_CONTROL_DPPULLUPNONOTG_MASK;
337 KHCI->CTL |= USB_CTL_USBENSOFEN_MASK;
338}
339
340void dcd_disconnect(uint8_t rhport)
341{
342 (void) rhport;
343 KHCI->CTL = 0;
344 KHCI->CONTROL &= ~USB_CONTROL_DPPULLUPNONOTG_MASK;
345}
346
347void dcd_sof_enable(uint8_t rhport, bool en)
348{
349 (void) rhport;
350 (void) en;
351
352 // TODO implement later
353}
354
355//--------------------------------------------------------------------+
356// Endpoint API
357//--------------------------------------------------------------------+
358bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * ep_desc)
359{
360 (void) rhport;
361
362 const unsigned ep_addr = ep_desc->bEndpointAddress;
363 const unsigned epn = tu_edpt_number(ep_addr);
364 const unsigned dir = tu_edpt_dir(ep_addr);
365 const unsigned xfer = ep_desc->bmAttributes.xfer;
366 endpoint_state_t *ep = &_dcd.endpoint[epn][dir];
367 const unsigned odd = ep->odd;
368 buffer_descriptor_t *bd = _dcd.bdt[epn][dir];
369
370 /* No support for control transfer */
371 TU_ASSERT(epn && (xfer != TUSB_XFER_CONTROL));
372
374 unsigned val = USB_ENDPT_EPCTLDIS_MASK;
375 val |= (xfer != TUSB_XFER_ISOCHRONOUS) ? USB_ENDPT_EPHSHK_MASK: 0;
376 val |= dir ? USB_ENDPT_EPTXEN_MASK : USB_ENDPT_EPRXEN_MASK;
377 KHCI->ENDPOINT[epn].ENDPT |= val;
378
380 bd[odd].dts = 1;
381 bd[odd].data = 0;
382 bd[odd ^ 1].dts = 1;
383 bd[odd ^ 1].data = 1;
384 }
385
386 return true;
387}
388
389void dcd_edpt_close_all(uint8_t rhport)
390{
391 (void) rhport;
392 const unsigned ie = NVIC_GetEnableIRQ(USB0_IRQn);
393 NVIC_DisableIRQ(USB0_IRQn);
394 for (unsigned i = 1; i < 16; ++i) {
395 KHCI->ENDPOINT[i].ENDPT = 0;
396 }
397 if (ie) NVIC_EnableIRQ(USB0_IRQn);
398 buffer_descriptor_t *bd = _dcd.bdt[1][0];
399 for (unsigned i = 2; i < sizeof(_dcd.bdt)/sizeof(*bd); ++i, ++bd) {
400 bd->head = 0;
401 }
402 endpoint_state_t *ep = &_dcd.endpoint[1][0];
403 for (unsigned i = 2; i < sizeof(_dcd.endpoint)/sizeof(*ep); ++i, ++ep) {
404 /* Clear except the odd */
405 ep->max_packet_size = 0;
406 ep->length = 0;
407 ep->remaining = 0;
408 }
409}
410
411void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr)
412{
413 (void) rhport;
414
415 const unsigned epn = tu_edpt_number(ep_addr);
416 const unsigned dir = tu_edpt_dir(ep_addr);
417 endpoint_state_t *ep = &_dcd.endpoint[epn][dir];
418 buffer_descriptor_t *bd = _dcd.bdt[epn][dir];
419 const unsigned msk = dir ? USB_ENDPT_EPTXEN_MASK : USB_ENDPT_EPRXEN_MASK;
420 const unsigned ie = NVIC_GetEnableIRQ(USB0_IRQn);
421 NVIC_DisableIRQ(USB0_IRQn);
422 KHCI->ENDPOINT[epn].ENDPT &= ~msk;
423 ep->max_packet_size = 0;
424 ep->length = 0;
425 ep->remaining = 0;
426 bd[0].head = 0;
427 bd[1].head = 0;
428 if (ie) NVIC_EnableIRQ(USB0_IRQn);
429}
430
431bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t* buffer, uint16_t total_bytes)
432{
433 (void) rhport;
434 const unsigned epn = tu_edpt_number(ep_addr);
435 const unsigned dir = tu_edpt_dir(ep_addr);
436 endpoint_state_t *ep = &_dcd.endpoint[epn][dir];
437 buffer_descriptor_t *bd = &_dcd.bdt[epn][dir][ep->odd];
438 TU_ASSERT(0 == bd->own);
439
440 const unsigned ie = NVIC_GetEnableIRQ(USB0_IRQn);
441 NVIC_DisableIRQ(USB0_IRQn);
442
443 ep->length = total_bytes;
445
446 const unsigned mps = ep->max_packet_size;
447 if (total_bytes > mps) {
448 buffer_descriptor_t *next = ep->odd ? bd - 1: bd + 1;
449 /* When total_bytes is greater than the max packet size,
450 * it prepares to the next transfer to avoid NAK in advance. */
451 next->bc = total_bytes >= 2 * mps ? mps: total_bytes - mps;
452 next->addr = buffer + mps;
453 next->own = 1;
454 }
455 bd->bc = total_bytes >= mps ? mps: total_bytes;
456 bd->addr = buffer;
457 __DSB();
458 bd->own = 1; /* This bit must be set last */
459
460 if (ie) NVIC_EnableIRQ(USB0_IRQn);
461 return true;
462}
463
464void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr)
465{
466 (void) rhport;
467 const unsigned epn = tu_edpt_number(ep_addr);
468
469 if (0 == epn) {
470 KHCI->ENDPOINT[epn].ENDPT |= USB_ENDPT_EPSTALL_MASK;
471 } else {
472 const unsigned dir = tu_edpt_dir(ep_addr);
473 const unsigned odd = _dcd.endpoint[epn][dir].odd;
474 buffer_descriptor_t *bd = &_dcd.bdt[epn][dir][odd];
475 TU_ASSERT(0 == bd->own,);
476
477 const unsigned ie = NVIC_GetEnableIRQ(USB0_IRQn);
478 NVIC_DisableIRQ(USB0_IRQn);
479
480 bd->bdt_stall = 1;
481 __DSB();
482 bd->own = 1; /* This bit must be set last */
483
484 if (ie) NVIC_EnableIRQ(USB0_IRQn);
485 }
486}
487
488void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr)
489{
490 (void) rhport;
491 const unsigned epn = tu_edpt_number(ep_addr);
492 TU_VERIFY(epn,);
493 const unsigned dir = tu_edpt_dir(ep_addr);
494 const unsigned odd = _dcd.endpoint[epn][dir].odd;
495 buffer_descriptor_t *bd = _dcd.bdt[epn][dir];
496 TU_VERIFY(bd[odd].own,);
497
498 const unsigned ie = NVIC_GetEnableIRQ(USB0_IRQn);
499 NVIC_DisableIRQ(USB0_IRQn);
500
501 bd[odd].own = 0;
502 __DSB();
503
504 // clear stall
505 bd[odd].bdt_stall = 0;
506
507 // Reset data toggle
508 bd[odd ].data = 0;
509 bd[odd ^ 1].data = 1;
510
511 // We already cleared this in ISR, but just clear it here to be safe
512 const unsigned endpt = KHCI->ENDPOINT[epn].ENDPT;
513 if (endpt & USB_ENDPT_EPSTALL_MASK) {
514 KHCI->ENDPOINT[epn].ENDPT = endpt & ~USB_ENDPT_EPSTALL_MASK;
515 }
516
517 if (ie) NVIC_EnableIRQ(USB0_IRQn);
518}
519
520//--------------------------------------------------------------------+
521// ISR
522//--------------------------------------------------------------------+
523void dcd_int_handler(uint8_t rhport)
524{
525 uint32_t is = KHCI->ISTAT;
526 uint32_t msk = KHCI->INTEN;
527
528 // clear non-enabled interrupts
529 KHCI->ISTAT = is & ~msk;
530 is &= msk;
531
532 if (is & USB_ISTAT_ERROR_MASK) {
533 /* TODO: */
534 uint32_t es = KHCI->ERRSTAT;
535 KHCI->ERRSTAT = es;
536 KHCI->ISTAT = is; /* discard any pending events */
537 }
538
539 if (is & USB_ISTAT_USBRST_MASK) {
540 KHCI->ISTAT = is; /* discard any pending events */
541 process_bus_reset(rhport);
542 }
543
544 if (is & USB_ISTAT_SLEEP_MASK) {
545 // TU_LOG3("Suspend: "); TU_LOG2_HEX(is);
546
547 // Note Host usually has extra delay after bus reset (without SOF), which could falsely
548 // detected as Sleep event. Though usbd has debouncing logic so we are good
549 KHCI->ISTAT = USB_ISTAT_SLEEP_MASK;
550 process_bus_sleep(rhport);
551 }
552
553#if 0 // ISTAT_RESUME never trigger, probably for host mode ?
554 if (is & USB_ISTAT_RESUME_MASK) {
555 // TU_LOG2("ISTAT Resume: "); TU_LOG2_HEX(is);
556 KHCI->ISTAT = USB_ISTAT_RESUME_MASK;
557 process_bus_resume(rhport);
558 }
559#endif
560
561 if (KHCI->USBTRC0 & USB_USBTRC0_USB_RESUME_INT_MASK) {
562 // TU_LOG2("USBTRC0 Resume: "); TU_LOG2_HEX(is); TU_LOG2_HEX(KHCI->USBTRC0);
563 process_bus_resume(rhport);
564 }
565
566 if (is & USB_ISTAT_SOFTOK_MASK) {
567 KHCI->ISTAT = USB_ISTAT_SOFTOK_MASK;
568 dcd_event_bus_signal(rhport, DCD_EVENT_SOF, true);
569 }
570
571 if (is & USB_ISTAT_STALL_MASK) {
572 KHCI->ISTAT = USB_ISTAT_STALL_MASK;
573 process_stall(rhport);
574 }
575
576 if (is & USB_ISTAT_TOKDNE_MASK) {
577 process_tokdne(rhport);
578 }
579}
580
581#endif
static TU_ATTR_ALWAYS_INLINE void dcd_event_bus_signal(uint8_t rhport, dcd_eventid_t eid, bool in_isr)
Definition: dcd.h:196
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 struct @149 _dcd
static void process_bus_reset(uint8_t rhport)
Definition: dcd_khci.c:210
struct TU_ATTR_PACKED endpoint_state_t
void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr)
Definition: dcd_khci.c:464
void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr)
Definition: dcd_khci.c:411
void dcd_int_handler(uint8_t rhport)
Definition: dcd_khci.c:523
void dcd_disconnect(uint8_t rhport)
Definition: dcd_khci.c:340
@ TOK_PID_SETUP
Definition: dcd_khci.c:47
@ TOK_PID_IN
Definition: dcd_khci.c:46
@ TOK_PID_OUT
Definition: dcd_khci.c:45
static void process_tokdne(uint8_t rhport)
Definition: dcd_khci.c:150
void dcd_edpt_close_all(uint8_t rhport)
Definition: dcd_khci.c:389
void dcd_int_disable(uint8_t rhport)
Definition: dcd_khci.c:307
bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const *ep_desc)
Definition: dcd_khci.c:358
void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr)
Definition: dcd_khci.c:488
TU_VERIFY_STATIC(sizeof(buffer_descriptor_t)==8, "size is not correct")
static void process_stall(uint8_t rhport)
Definition: dcd_khci.c:135
void dcd_connect(uint8_t rhport)
Definition: dcd_khci.c:332
bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_t total_bytes)
Definition: dcd_khci.c:431
CFG_TUD_MEM_SECTION TU_ATTR_ALIGNED(512)
Definition: dcd_khci.c:117
void dcd_set_address(uint8_t rhport, uint8_t dev_addr)
Definition: dcd_khci.c:313
struct TU_ATTR_PACKED buffer_descriptor_t
bool dcd_init(uint8_t rhport, const tusb_rhport_init_t *rh_init)
Definition: dcd_khci.c:268
static void process_bus_sleep(uint8_t rhport)
Definition: dcd_khci.c:241
void dcd_int_enable(uint8_t rhport)
Definition: dcd_khci.c:301
void dcd_remote_wakeup(uint8_t rhport)
Definition: dcd_khci.c:320
static void process_bus_resume(uint8_t rhport)
Definition: dcd_khci.c:253
void dcd_sof_enable(uint8_t rhport, bool en)
Definition: dcd_khci.c:347
u32 SystemCoreClock
xfer_td_t xfer[EP_CBI_COUNT+1][2]
Definition: dcd_nrf5x.c:119
uint16_t total_bytes
Definition: dcd_nuc505.c:113
uint8_t dev_addr
Definition: dcd_pic32mz.c:81
static void prepare_next_setup_packet(uint8_t rhport)
Definition: dcd_pic.c:312
uint8_t const * buffer
Definition: midi_device.h:100
AUDIO Channel Cluster Descriptor (4.1)
Definition: audio.h:647
__IO uint16_t tok_pid
Definition: dcd_ci_fs.c:60
uint8_t * addr
Definition: dcd_ci_fs.c:78
uint16_t ninc
Definition: dcd_ci_fs.c:69
uint16_t bdt_stall
Definition: dcd_ci_fs.c:67
uint16_t dts
Definition: dcd_ci_fs.c:68
__IO uint16_t bc
Definition: dcd_ci_fs.c:74
uint8_t data[CFG_TUD_NCM_IN_NTB_MAX_SIZE]
Definition: ncm.h:147
uint32_t max_packet_size
Definition: dcd_ci_fs.c:88
uint8_t bmAttributes
See: audio_clock_source_attribute_t.
Definition: audio.h:672
uint16_t length
Definition: dcd_ci_fs.c:94
volatile uint16_t
Definition: hcd_rusb2.c:58
uint32_t odd
Definition: dcd_ci_fs.c:90
uint16_t keep
Definition: dcd_ci_fs.c:70
uint16_t remaining
Definition: dcd_ci_fs.c:95
__IO uint16_t own
Definition: dcd_ci_fs.c:62
uint8_t bEndpointAddress
Definition: video.h:306
uint32_t head
Definition: dcd_ci_fs.c:55
TU_ATTR_ALIGNED(4)
Definition: dcd_khci.c:105
@ 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
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_CONTROL
Definition: tusb_types.h:59
@ 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