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