Open FFBoard
Open source force feedback firmware
dcd_samg.c
Go to the documentation of this file.
1/*
2 * The MIT License (MIT)
3 *
4 * Copyright (c) 2018, hathach (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_TUSB_MCU == OPT_MCU_SAMG
30
31#include "sam.h"
32#include "device/dcd.h"
33
34// TODO should support (SAM3S || SAM4S || SAM4E || SAMG55)
35
36//--------------------------------------------------------------------+
37// MACRO TYPEDEF CONSTANT ENUM DECLARATION
38//--------------------------------------------------------------------+
39
40#define EP_COUNT 6
41
42// Transfer descriptor
43typedef struct
44{
45 uint8_t* buffer;
46 // tu_fifo_t* ff; // TODO support dcd_edpt_xfer_fifo API
47 uint16_t total_len;
48 volatile uint16_t actual_len;
49 uint16_t epsize;
51
52// Endpoint 0-5, each can only be either OUT or In
54
55void xfer_epsize_set(xfer_desc_t* xfer, uint16_t epsize)
56{
57 xfer->epsize = epsize;
58}
59
60void xfer_begin(xfer_desc_t* xfer, uint8_t * buffer, uint16_t total_bytes)
61{
63 // xfer->ff = NULL; // TODO support dcd_edpt_xfer_fifo API
65 xfer->actual_len = 0;
66}
67
69{
70 xfer->buffer = NULL;
71 // xfer->ff = NULL; // TODO support dcd_edpt_xfer_fifo API
72 xfer->total_len = 0;
73 xfer->actual_len = 0;
74}
75
77{
78 // also cover zero-length packet
79 return tu_min16(xfer->total_len - xfer->actual_len, xfer->epsize);
80}
81
83{
84 uint16_t const xact_len = xfer_packet_len(xfer);
85
86 xfer->buffer += xact_len;
87 xfer->actual_len += xact_len;
88}
89
90//------------- Transaction helpers -------------//
91
92// Write data to EP FIFO, return number of written bytes
93static void xact_ep_write(uint8_t epnum, uint8_t* buffer, uint16_t xact_len)
94{
95 for(uint16_t i=0; i<xact_len; i++)
96 {
97 UDP->UDP_FDR[epnum] = (uint32_t) buffer[i];
98 }
99}
100
101// Read data from EP FIFO
102static void xact_ep_read(uint8_t epnum, uint8_t* buffer, uint16_t xact_len)
103{
104 for(uint16_t i=0; i<xact_len; i++)
105 {
106 buffer[i] = (uint8_t) UDP->UDP_FDR[epnum];
107 }
108}
109
110
112#define CSR_NO_EFFECT_1_ALL (UDP_CSR_RX_DATA_BK0 | UDP_CSR_RX_DATA_BK1 | UDP_CSR_STALLSENT | UDP_CSR_RXSETUP | UDP_CSR_TXCOMP)
113
114// Per Specs: CSR need synchronization each write
115static inline void csr_write(uint8_t epnum, uint32_t value)
116{
117 uint32_t const csr = value;
118 UDP->UDP_CSR[epnum] = csr;
119
120 volatile uint32_t nop_count;
121 for (nop_count = 0; nop_count < 20; nop_count ++) __NOP();
122}
123
124// Per Specs: CSR need synchronization each write
125static inline void csr_set(uint8_t epnum, uint32_t mask)
126{
127 csr_write(epnum, UDP->UDP_CSR[epnum] | CSR_NO_EFFECT_1_ALL | mask);
128}
129
130// Per Specs: CSR need synchronization each write
131static inline void csr_clear(uint8_t epnum, uint32_t mask)
132{
133 csr_write(epnum, (UDP->UDP_CSR[epnum] | CSR_NO_EFFECT_1_ALL) & ~mask);
134}
135
136/*------------------------------------------------------------------*/
137/* Device API
138 *------------------------------------------------------------------*/
139
140// Set up endpoint 0, clear all other endpoints
141static void bus_reset(void)
142{
143 tu_memclr(_dcd_xfer, sizeof(_dcd_xfer));
144
145 xfer_epsize_set(&_dcd_xfer[0], CFG_TUD_ENDPOINT0_SIZE);
146
147 // Enable EP0 control
148 csr_write(0, UDP_CSR_EPEDS_Msk);
149
150 // Enable interrupt : EP0, Suspend, Resume, Wakeup
151 UDP->UDP_IER = UDP_IER_EP0INT_Msk | UDP_IER_RXSUSP_Msk | UDP_IER_RXRSM_Msk | UDP_IER_WAKEUP_Msk;
152
153 // Enable transceiver
154 UDP->UDP_TXVC &= ~UDP_TXVC_TXVDIS_Msk;
155}
156
157// Initialize controller to device mode
158bool dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) {
159 (void) rhport;
160 (void) rh_init;
161
162 tu_memclr(_dcd_xfer, sizeof(_dcd_xfer));
163 dcd_connect(rhport);
164 return true;
165}
166
167// Enable device interrupt
168void dcd_int_enable (uint8_t rhport)
169{
170 (void) rhport;
171 NVIC_EnableIRQ(UDP_IRQn);
172}
173
174// Disable device interrupt
175void dcd_int_disable (uint8_t rhport)
176{
177 (void) rhport;
178 NVIC_DisableIRQ(UDP_IRQn);
179}
180
181// Receive Set Address request, mcu port must also include status IN response
182void dcd_set_address (uint8_t rhport, uint8_t dev_addr)
183{
184 (void) rhport;
185 (void) dev_addr;
186
187 // Response with zlp status
188 dcd_edpt_xfer(rhport, 0x80, NULL, 0);
189
190 // DCD can only set address after status for this request is complete.
191 // do it at dcd_edpt0_status_complete()
192}
193
194// Wake up host
195void dcd_remote_wakeup (uint8_t rhport)
196{
197 (void) rhport;
198}
199
200void dcd_connect(uint8_t rhport)
201{
202 (void) rhport;
203
204 // Enable pull-up, disable transceiver
205 UDP->UDP_TXVC = UDP_TXVC_PUON | UDP_TXVC_TXVDIS_Msk;
206}
207
208void dcd_disconnect(uint8_t rhport)
209{
210 (void) rhport;
211
212 // disable both pullup and transceiver
213 UDP->UDP_TXVC = UDP_TXVC_TXVDIS_Msk;
214}
215
216void dcd_sof_enable(uint8_t rhport, bool en)
217{
218 (void) rhport;
219 (void) en;
220
221 // TODO implement later
222}
223
224//--------------------------------------------------------------------+
225// Endpoint API
226//--------------------------------------------------------------------+
227
228// Invoked when a control transfer's status stage is complete.
229// May help DCD to prepare for next control transfer, this API is optional.
231{
232 (void) rhport;
233
236 {
238 {
239 uint8_t const dev_addr = (uint8_t) request->wValue;
240
241 // Enable addressed state
242 UDP->UDP_GLB_STAT |= UDP_GLB_STAT_FADDEN_Msk;
243
244 // Set new address & Function enable bit
245 UDP->UDP_FADDR = UDP_FADDR_FEN_Msk | UDP_FADDR_FADD(dev_addr);
246 }
248 {
249 // Configured State
250 UDP->UDP_GLB_STAT |= UDP_GLB_STAT_CONFG_Msk;
251 }
252 }
253}
254
255// Configure endpoint's registers according to descriptor
256// SAMG doesn't support a same endpoint number with IN and OUT
257// e.g EP1 OUT & EP1 IN cannot exist together
258bool dcd_edpt_open (uint8_t rhport, tusb_desc_endpoint_t const * ep_desc)
259{
260 (void) rhport;
261
262 uint8_t const epnum = tu_edpt_number(ep_desc->bEndpointAddress);
263 uint8_t const dir = tu_edpt_dir(ep_desc->bEndpointAddress);
264
265 // TODO Isochronous is not supported yet
266 TU_VERIFY(ep_desc->bmAttributes.xfer != TUSB_XFER_ISOCHRONOUS);
267 TU_VERIFY(epnum < EP_COUNT);
268
269 // Must not already enabled
270 TU_ASSERT((UDP->UDP_CSR[epnum] & UDP_CSR_EPEDS_Msk) == 0);
271
273
274 // Configure type and enable EP
275 csr_write(epnum, UDP_CSR_EPEDS_Msk | UDP_CSR_EPTYPE(ep_desc->bmAttributes.xfer + 4*dir));
276
277 // Enable EP Interrupt for IN
278 if (dir == TUSB_DIR_IN) UDP->UDP_IER |= (1 << epnum);
279
280 return true;
281}
282
283void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr) {
284 (void) rhport; (void) ep_addr;
285 // TODO implement dcd_edpt_close()
286}
287
288void dcd_edpt_close_all (uint8_t rhport)
289{
290 (void) rhport;
291 // TODO implement dcd_edpt_close_all()
292}
293
294// Submit a transfer, When complete dcd_event_xfer_complete() is invoked to notify the stack
295bool dcd_edpt_xfer (uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes)
296{
297 (void) rhport;
298
299 uint8_t const epnum = tu_edpt_number(ep_addr);
300 uint8_t const dir = tu_edpt_dir(ep_addr);
301
302 xfer_desc_t* xfer = &_dcd_xfer[epnum];
304
305 if (dir == TUSB_DIR_OUT)
306 {
307 // Enable interrupt when starting OUT transfer
308 if (epnum != 0) UDP->UDP_IER |= (1 << epnum);
309 }
310 else
311 {
313
314 // TX ready for transfer
315 csr_set(epnum, UDP_CSR_TXPKTRDY_Msk);
316 }
317
318 return true;
319}
320
321#if 0 // TODO support dcd_edpt_xfer_fifo API
322bool dcd_edpt_xfer_fifo (uint8_t rhport, uint8_t ep_addr, tu_fifo_t * ff, uint16_t total_bytes)
323{
324 (void) rhport;
325 return true;
326}
327#endif
328
329// Stall endpoint
330void dcd_edpt_stall (uint8_t rhport, uint8_t ep_addr)
331{
332 (void) rhport;
333
334 // For EP0 USBD will stall both EP0 Out and In with 0x00 and 0x80
335 // only handle one by skipping 0x80
336 if ( ep_addr == tu_edpt_addr(0, TUSB_DIR_IN_MASK) ) return;
337
338 uint8_t const epnum = tu_edpt_number(ep_addr);
339
340 // Set force stall bit
341 csr_set(epnum, UDP_CSR_FORCESTALL_Msk);
342}
343
344// clear stall, data toggle is also reset to DATA0
345void dcd_edpt_clear_stall (uint8_t rhport, uint8_t ep_addr)
346{
347 (void) rhport;
348
349 uint8_t const epnum = tu_edpt_number(ep_addr);
350
351 // clear stall
352 csr_clear(epnum, UDP_CSR_FORCESTALL_Msk);
353
354 // must also reset EP to clear data toggle
355 UDP->UDP_RST_EP |= (1 << epnum);
356 UDP->UDP_RST_EP &= ~(1 << epnum);
357}
358
359//--------------------------------------------------------------------+
360// ISR
361//--------------------------------------------------------------------+
362void dcd_int_handler(uint8_t rhport)
363{
364 uint32_t const intr_mask = UDP->UDP_IMR;
365 uint32_t const intr_status = UDP->UDP_ISR & intr_mask;
366
367 // clear interrupt
368 UDP->UDP_ICR = intr_status;
369
370 // Bus reset
371 if (intr_status & UDP_ISR_ENDBUSRES_Msk)
372 {
373 bus_reset();
375 }
376
377 // SOF
378// if (intr_status & UDP_ISR_SOFINT_Msk) dcd_event_bus_signal(rhport, DCD_EVENT_SOF, true);
379
380 // Suspend
381 if (intr_status & UDP_ISR_RXSUSP_Msk) dcd_event_bus_signal(rhport, DCD_EVENT_SUSPEND, true);
382
383 // Resume
384 if (intr_status & UDP_ISR_RXRSM_Msk) dcd_event_bus_signal(rhport, DCD_EVENT_RESUME, true);
385
386 // Wakeup
387 if (intr_status & UDP_ISR_WAKEUP_Msk) dcd_event_bus_signal(rhport, DCD_EVENT_RESUME, true);
388
389 //------------- Endpoints -------------//
390
391 if ( intr_status & TU_BIT(0) )
392 {
393 // setup packet
394 if ( UDP->UDP_CSR[0] & UDP_CSR_RXSETUP )
395 {
396 // get setup from FIFO
397 uint8_t setup[8];
398 for(uint8_t i=0; i<sizeof(setup); i++)
399 {
400 setup[i] = (uint8_t) UDP->UDP_FDR[0];
401 }
402
403 // notify usbd
404 dcd_event_setup_received(rhport, setup, true);
405
406 // Set EP direction bit according to DATA stage
407 // MUST only be set before RXSETUP is clear per specs
408 if ( tu_edpt_dir(setup[0]) )
409 {
410 csr_set(0, UDP_CSR_DIR_Msk);
411 }
412 else
413 {
414 csr_clear(0, UDP_CSR_DIR_Msk);
415 }
416
417 // Clear Setup, stall and other on-going transfer bits
418 csr_clear(0, UDP_CSR_RXSETUP_Msk | UDP_CSR_TXPKTRDY_Msk | UDP_CSR_TXCOMP_Msk | UDP_CSR_RX_DATA_BK0 | UDP_CSR_RX_DATA_BK1 | UDP_CSR_STALLSENT_Msk | UDP_CSR_FORCESTALL_Msk);
419 }
420 }
421
422 for(uint8_t epnum = 0; epnum < EP_COUNT; epnum++)
423 {
424 if ( intr_status & TU_BIT(epnum) )
425 {
426 xfer_desc_t* xfer = &_dcd_xfer[epnum];
427
428 //------------- Endpoint IN -------------//
429 if (UDP->UDP_CSR[epnum] & UDP_CSR_TXCOMP_Msk)
430 {
432
433 uint16_t const xact_len = xfer_packet_len(xfer);
434
435 if (xact_len)
436 {
437 // write to EP fifo
438#if 0 // TODO support dcd_edpt_xfer_fifo
439 if (xfer->ff)
440 {
441 tu_fifo_read_n_const_addr_full_words(xfer->ff, (void *) &UDP->UDP_FDR[epnum], xact_len);
442 }
443 else
444#endif
445 {
446 xact_ep_write(epnum, xfer->buffer, xact_len);
447 }
448
449 // TX ready for transfer
450 csr_set(epnum, UDP_CSR_TXPKTRDY_Msk);
451 }else
452 {
453 // xfer is complete
455
456 // Required since control OUT can happen right after before stack handle this event
457 xfer_end(xfer);
458 }
459
460 // Clear TX Complete bit
461 csr_clear(epnum, UDP_CSR_TXCOMP_Msk);
462 }
463
464 //------------- Endpoint OUT -------------//
465 // Ping-Pong is a MUST for Bulk/Iso
466 // NOTE: When both Bank0 and Bank1 are both set, there is no way to know which one comes first
467 uint32_t const banks_complete = UDP->UDP_CSR[epnum] & (UDP_CSR_RX_DATA_BK0_Msk | UDP_CSR_RX_DATA_BK1_Msk);
468 if (banks_complete)
469 {
470 uint16_t const xact_len = (uint16_t) ((UDP->UDP_CSR[epnum] & UDP_CSR_RXBYTECNT_Msk) >> UDP_CSR_RXBYTECNT_Pos);
471
472 // Read from EP fifo
473#if 0 // TODO support dcd_edpt_xfer_fifo API
474 if (xfer->ff)
475 {
476 tu_fifo_write_n_const_addr_full_words(xfer->ff, (const void *) &UDP->UDP_FDR[epnum], xact_len);
477 }
478 else
479#endif
480 {
481 xact_ep_read(epnum, xfer->buffer, xact_len);
482 }
483
485
486 if ( 0 == xfer_packet_len(xfer) )
487 {
488 // Disable OUT EP interrupt when transfer is complete
489 if (epnum != 0) UDP->UDP_IDR |= (1 << epnum);
490
492 xfer_end(xfer);
493 }
494
495 // Clear DATA Bank0/1 bit
496 csr_clear(epnum, banks_complete);
497 }
498
499 // Stall sent to host
500 if (UDP->UDP_CSR[epnum] & UDP_CSR_STALLSENT_Msk)
501 {
502 csr_clear(epnum, UDP_CSR_STALLSENT_Msk);
503 }
504 }
505 }
506}
507
508#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
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 csr_clear(uint8_t epnum, uint32_t mask)
Definition: dcd_samg.c:131
bool dcd_edpt_xfer_fifo(uint8_t rhport, uint8_t ep_addr, tu_fifo_t *ff, uint16_t total_bytes)
Definition: dcd_samg.c:322
static void csr_set(uint8_t epnum, uint32_t mask)
Definition: dcd_samg.c:125
void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr)
Definition: dcd_samg.c:330
void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr)
Definition: dcd_samg.c:283
static void bus_reset(void)
Definition: dcd_samg.c:141
xfer_desc_t _dcd_xfer[EP_COUNT]
Definition: dcd_samg.c:53
void xfer_begin(xfer_desc_t *xfer, uint8_t *buffer, uint16_t total_bytes)
Definition: dcd_samg.c:60
void dcd_int_handler(uint8_t rhport)
Definition: dcd_samg.c:362
uint16_t xfer_packet_len(xfer_desc_t *xfer)
Definition: dcd_samg.c:76
void dcd_disconnect(uint8_t rhport)
Definition: dcd_samg.c:208
void xfer_end(xfer_desc_t *xfer)
Definition: dcd_samg.c:68
void dcd_edpt_close_all(uint8_t rhport)
Definition: dcd_samg.c:288
static void xact_ep_write(uint8_t epnum, uint8_t *buffer, uint16_t xact_len)
Definition: dcd_samg.c:93
void dcd_int_disable(uint8_t rhport)
Definition: dcd_samg.c:175
bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const *ep_desc)
Definition: dcd_samg.c:258
void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr)
Definition: dcd_samg.c:345
static void xact_ep_read(uint8_t epnum, uint8_t *buffer, uint16_t xact_len)
Definition: dcd_samg.c:102
void dcd_connect(uint8_t rhport)
Definition: dcd_samg.c:200
static void csr_write(uint8_t epnum, uint32_t value)
Definition: dcd_samg.c:115
bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_t total_bytes)
Definition: dcd_samg.c:295
void xfer_epsize_set(xfer_desc_t *xfer, uint16_t epsize)
Definition: dcd_samg.c:55
void xfer_packet_done(xfer_desc_t *xfer)
Definition: dcd_samg.c:82
void dcd_edpt0_status_complete(uint8_t rhport, tusb_control_request_t const *request)
Definition: dcd_samg.c:230
void dcd_set_address(uint8_t rhport, uint8_t dev_addr)
Definition: dcd_samg.c:182
bool dcd_init(uint8_t rhport, const tusb_rhport_init_t *rh_init)
Definition: dcd_samg.c:158
void dcd_int_enable(uint8_t rhport)
Definition: dcd_samg.c:168
void dcd_remote_wakeup(uint8_t rhport)
Definition: dcd_samg.c:195
void dcd_sof_enable(uint8_t rhport, bool en)
Definition: dcd_samg.c:216
uint8_t const * buffer
Definition: midi_device.h:100
AUDIO Channel Cluster Descriptor (4.1)
Definition: audio.h:647
uint16_t wValue
Definition: audio.h:934
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 bEndpointAddress
Definition: video.h:306
uint8_t bRequest
Request type audio_cs_req_t.
Definition: audio.h:831
volatile uint16_t actual_len
Definition: dcd_samg.c:48
uint8_t * buffer
Definition: dcd_samg.c:45
uint16_t epsize
Definition: dcd_samg.c:49
uint16_t total_len
Definition: dcd_samg.c:47
volatile uint16_t actual_len
Definition: dcd_nrf5x.c:101
uint16_t total_len
Definition: dcd_nrf5x.c:100
uint8_t * buffer
Definition: dcd_nrf5x.c:99
static TU_ATTR_ALWAYS_INLINE uint16_t tu_min16(uint16_t x, uint16_t y)
Definition: tusb_common.h:155
uint16_t tu_fifo_write_n_const_addr_full_words(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:882
uint16_t tu_fifo_read_n_const_addr_full_words(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:753
@ TUSB_DIR_IN
Definition: tusb_types.h:67
@ TUSB_DIR_OUT
Definition: tusb_types.h:66
@ TUSB_DIR_IN_MASK
Definition: tusb_types.h:69
@ TUSB_REQ_SET_ADDRESS
Definition: tusb_types.h:127
@ TUSB_REQ_SET_CONFIGURATION
Definition: tusb_types.h:131
@ 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_REQ_RCPT_DEVICE
Definition: tusb_types.h:151
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
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
@ TUSB_REQ_TYPE_STANDARD
Definition: tusb_types.h:144
CFG_TUH_MEM_ALIGN tusb_control_request_t request
Definition: usbh.c:259