Open FFBoard
Open source force feedback firmware
dcd_lpc17_40.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 && \
30 (CFG_TUSB_MCU == OPT_MCU_LPC175X_6X || CFG_TUSB_MCU == OPT_MCU_LPC177X_8X || CFG_TUSB_MCU == OPT_MCU_LPC40XX)
31
32#include "device/dcd.h"
33#include "dcd_lpc17_40.h"
34#include "chip.h"
35
36//--------------------------------------------------------------------+
37// MACRO CONSTANT TYPEDEF
38//--------------------------------------------------------------------+
39#define DCD_ENDPOINT_MAX 32
40
41typedef struct TU_ATTR_ALIGNED(4)
42{
43 //------------- Word 0 -------------//
44 uint32_t next;
45
46 //------------- Word 1 -------------//
47 uint16_t atle_mode : 2; // 00: normal, 01: ATLE (auto length extraction)
48 uint16_t next_valid : 1;
49 uint16_t : 1;
50 uint16_t isochronous : 1; // is an iso endpoint
51 uint16_t max_packet_size : 11;
52
53 volatile uint16_t buflen; // bytes for non-iso, number of packets for iso endpoint
54
55 //------------- Word 2 -------------//
56 volatile uint32_t buffer;
57
58 //------------- Word 3 -------------//
59 volatile uint16_t retired : 1; // initialized to zero
60 volatile uint16_t status : 4;
61 volatile uint16_t iso_last_packet_valid : 1;
62 volatile uint16_t atle_lsb_extracted : 1; // used in ATLE mode
63 volatile uint16_t atle_msb_extracted : 1; // used in ATLE mode
64 volatile uint16_t atle_mess_len_position : 6; // used in ATLE mode
65 uint16_t : 2;
66
67 volatile uint16_t present_count; // For non-iso : The number of bytes transferred by the DMA engine
68 // For iso : number of packets
69
70 //------------- Word 4 -------------//
71 // uint32_t iso_packet_size_addr; // iso only, can be omitted for non-iso
73
74TU_VERIFY_STATIC( sizeof(dma_desc_t) == 16, "size is not correct"); // TODO not support ISO for now
75
76typedef struct
77{
78 // must be 128 byte aligned
79 volatile dma_desc_t* udca[DCD_ENDPOINT_MAX];
80
81 // TODO DMA does not support control transfer (0-1 are not used, offset to reduce memory)
82 dma_desc_t dd[DCD_ENDPOINT_MAX];
83
84 struct
85 {
86 uint8_t* out_buffer;
87 uint8_t out_bytes;
88 volatile bool out_received; // indicate if data is already received in endpoint
89
90 uint8_t in_bytes;
91 } control;
92
94
95CFG_TUD_MEM_SECTION TU_ATTR_ALIGNED(128) static dcd_data_t _dcd;
96
97
98//--------------------------------------------------------------------+
99// SIE Command
100//--------------------------------------------------------------------+
101static void sie_cmd_code (sie_cmdphase_t phase, uint8_t code_data)
102{
103 LPC_USB->DevIntClr = (DEV_INT_COMMAND_CODE_EMPTY_MASK | DEV_INT_COMMAND_DATA_FULL_MASK);
104 LPC_USB->CmdCode = (phase << 8) | (code_data << 16);
105
106 uint32_t const wait_flag = (phase == SIE_CMDPHASE_READ) ? DEV_INT_COMMAND_DATA_FULL_MASK : DEV_INT_COMMAND_CODE_EMPTY_MASK;
107 while ((LPC_USB->DevIntSt & wait_flag) == 0) {}
108
109 LPC_USB->DevIntClr = wait_flag;
110}
111
112static void sie_write (uint8_t cmd_code, uint8_t data_len, uint8_t data)
113{
114 sie_cmd_code(SIE_CMDPHASE_COMMAND, cmd_code);
115
116 if (data_len)
117 {
118 sie_cmd_code(SIE_CMDPHASE_WRITE, data);
119 }
120}
121
122static uint8_t sie_read (uint8_t cmd_code)
123{
124 sie_cmd_code(SIE_CMDPHASE_COMMAND , cmd_code);
125 sie_cmd_code(SIE_CMDPHASE_READ , cmd_code);
126 return (uint8_t) LPC_USB->CmdData;
127}
128
129//--------------------------------------------------------------------+
130// PIPE HELPER
131//--------------------------------------------------------------------+
132static inline uint8_t ep_addr2idx(uint8_t ep_addr)
133{
134 return 2*(ep_addr & 0x0F) + ((ep_addr & TUSB_DIR_IN_MASK) ? 1 : 0);
135}
136
137static void set_ep_size(uint8_t ep_id, uint16_t max_packet_size)
138{
139 // follows example in 11.10.4.2
140 LPC_USB->ReEp |= TU_BIT(ep_id);
141 LPC_USB->EpInd = ep_id; // select index before setting packet size
142 LPC_USB->MaxPSize = max_packet_size;
143
144 while ((LPC_USB->DevIntSt & DEV_INT_ENDPOINT_REALIZED_MASK) == 0) {}
145 LPC_USB->DevIntClr = DEV_INT_ENDPOINT_REALIZED_MASK;
146}
147
148
149//--------------------------------------------------------------------+
150// CONTROLLER API
151//--------------------------------------------------------------------+
152static void bus_reset(void)
153{
154 // step 7 : slave mode set up
155 LPC_USB->EpIntClr = 0xFFFFFFFF; // clear all pending interrupt
156 LPC_USB->DevIntClr = 0xFFFFFFFF; // clear all pending interrupt
157 LPC_USB->EpIntEn = 0x03UL; // control endpoint cannot use DMA, non-control all use DMA
158 LPC_USB->EpIntPri = 0x03UL; // fast for control endpoint
159
160 // step 8 : DMA set up
161 LPC_USB->EpDMADis = 0xFFFFFFFF; // firstly disable all dma
162 LPC_USB->DMARClr = 0xFFFFFFFF; // clear all pending interrupt
163 LPC_USB->EoTIntClr = 0xFFFFFFFF;
164 LPC_USB->NDDRIntClr = 0xFFFFFFFF;
165 LPC_USB->SysErrIntClr = 0xFFFFFFFF;
166
167 tu_memclr(&_dcd, sizeof(dcd_data_t));
168}
169
170bool dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) {
171 (void) rhport;
172 (void) rh_init;
173
174 //------------- user manual 11.13 usb device controller initialization -------------//
175 // step 6 : set up control endpoint
176 set_ep_size(0, CFG_TUD_ENDPOINT0_SIZE);
177 set_ep_size(1, CFG_TUD_ENDPOINT0_SIZE);
178
179 bus_reset();
180
181 LPC_USB->DevIntEn = (DEV_INT_DEVICE_STATUS_MASK | DEV_INT_ENDPOINT_FAST_MASK | DEV_INT_ENDPOINT_SLOW_MASK | DEV_INT_ERROR_MASK);
182 LPC_USB->UDCAH = (uint32_t) _dcd.udca;
183 LPC_USB->DMAIntEn = (DMA_INT_END_OF_XFER_MASK /*| DMA_INT_NEW_DD_REQUEST_MASK*/ | DMA_INT_ERROR_MASK);
184
185 dcd_connect(rhport);
186
187 // Clear pending IRQ
188 NVIC_ClearPendingIRQ(USB_IRQn);
189
190 return true;
191}
192
193void dcd_int_enable(uint8_t rhport)
194{
195 (void) rhport;
196 NVIC_EnableIRQ(USB_IRQn);
197}
198
199void dcd_int_disable(uint8_t rhport)
200{
201 (void) rhport;
202 NVIC_DisableIRQ(USB_IRQn);
203}
204
205void dcd_set_address(uint8_t rhport, uint8_t dev_addr)
206{
207 // Response with status first before changing device address
208 dcd_edpt_xfer(rhport, tu_edpt_addr(0, TUSB_DIR_IN), NULL, 0);
209
210 sie_write(SIE_CMDCODE_SET_ADDRESS, 1, 0x80 | dev_addr); // 7th bit is : device_enable
211
212 // Also Set Configure Device to enable non-control endpoint response
214}
215
216void dcd_remote_wakeup(uint8_t rhport)
217{
218 (void) rhport;
219}
220
221void dcd_connect(uint8_t rhport)
222{
223 (void) rhport;
225}
226
227void dcd_disconnect(uint8_t rhport)
228{
229 (void) rhport;
231}
232
233void dcd_sof_enable(uint8_t rhport, bool en)
234{
235 (void) rhport;
236 (void) en;
237
238 // TODO implement later
239}
240
241//--------------------------------------------------------------------+
242// CONTROL HELPER
243//--------------------------------------------------------------------+
244static inline uint8_t byte2dword(uint8_t bytes)
245{
246 return (bytes + 3) / 4; // length in dwords
247}
248
249static void control_ep_write(void const * buffer, uint8_t len)
250{
251 uint32_t const * buf32 = (uint32_t const *) buffer;
252
253 LPC_USB->Ctrl = USBCTRL_WRITE_ENABLE_MASK; // logical endpoint = 0
254 LPC_USB->TxPLen = (uint32_t) len;
255
256 for (uint8_t count = 0; count < byte2dword(len); count++)
257 {
258 LPC_USB->TxData = *buf32; // NOTE: cortex M3 have no problem with alignment
259 buf32++;
260 }
261
262 LPC_USB->Ctrl = 0;
263
264 // select control IN & validate the endpoint
267}
268
269static uint8_t control_ep_read(void * buffer, uint8_t len)
270{
271 LPC_USB->Ctrl = USBCTRL_READ_ENABLE_MASK; // logical endpoint = 0
272 while ((LPC_USB->RxPLen & USBRXPLEN_PACKET_READY_MASK) == 0) {} // TODO blocking, should have timeout
273
274 len = tu_min8(len, (uint8_t) (LPC_USB->RxPLen & USBRXPLEN_PACKET_LENGTH_MASK) );
275 uint32_t *buf32 = (uint32_t*) buffer;
276
277 for (uint8_t count=0; count < byte2dword(len); count++)
278 {
279 *buf32 = LPC_USB->RxData;
280 buf32++;
281 }
282
283 LPC_USB->Ctrl = 0;
284
285 // select control OUT & clear the endpoint
288
289 return len;
290}
291
292//--------------------------------------------------------------------+
293// DCD Endpoint Port
294//--------------------------------------------------------------------+
295
296bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * p_endpoint_desc)
297{
298 (void) rhport;
299
300 uint8_t const epnum = tu_edpt_number(p_endpoint_desc->bEndpointAddress);
301 uint8_t const ep_id = ep_addr2idx(p_endpoint_desc->bEndpointAddress);
302
303 // Endpoint type is fixed to endpoint number
304 // 1: interrupt, 2: Bulk, 3: Iso and so on
305 switch ( p_endpoint_desc->bmAttributes.xfer )
306 {
308 TU_ASSERT((epnum % 3) == 1);
309 break;
310
311 case TUSB_XFER_BULK:
312 TU_ASSERT((epnum % 3) == 2 || (epnum == 15));
313 break;
314
316 TU_ASSERT((epnum % 3) == 0 && (epnum != 0) && (epnum != 15));
317 break;
318
319 default:
320 break;
321 }
322
323 //------------- Realize Endpoint with Max Packet Size -------------//
324 const uint16_t ep_size = tu_edpt_packet_size(p_endpoint_desc);
325 set_ep_size(ep_id, ep_size);
326
327 //------------- first DD prepare -------------//
328 dma_desc_t* const dd = &_dcd.dd[ep_id];
329 tu_memclr(dd, sizeof(dma_desc_t));
330
331 dd->isochronous = (p_endpoint_desc->bmAttributes.xfer == TUSB_XFER_ISOCHRONOUS) ? 1 : 0;
332 dd->max_packet_size = ep_size;
333 dd->retired = 1; // invalid at first
334
335 sie_write(SIE_CMDCODE_ENDPOINT_SET_STATUS + ep_id, 1, 0); // clear all endpoint status
336
337 return true;
338}
339
340void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr) {
341 (void) rhport; (void) ep_addr;
342 // TODO implement dcd_edpt_close()
343}
344
345void dcd_edpt_close_all (uint8_t rhport)
346{
347 (void) rhport;
348 // TODO implement dcd_edpt_close_all()
349}
350
351void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr)
352{
353 (void) rhport;
354
355 if ( tu_edpt_number(ep_addr) == 0 )
356 {
358 }else
359 {
360 uint8_t ep_id = ep_addr2idx( ep_addr );
362 }
363}
364
365void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr)
366{
367 (void) rhport;
368 uint8_t ep_id = ep_addr2idx(ep_addr);
369
371}
372
373static bool control_xact(uint8_t rhport, uint8_t dir, uint8_t * buffer, uint8_t len)
374{
375 (void) rhport;
376
377 if ( dir )
378 {
379 _dcd.control.in_bytes = len;
381 }else
382 {
383 if ( _dcd.control.out_received )
384 {
385 // Already received the DATA OUT packet
386 _dcd.control.out_received = false;
387 _dcd.control.out_buffer = NULL;
388 _dcd.control.out_bytes = 0;
389
390 uint8_t received = control_ep_read(buffer, len);
392 }else
393 {
394 _dcd.control.out_buffer = buffer;
395 _dcd.control.out_bytes = len;
396 }
397 }
398
399 return true;
400}
401
402bool dcd_edpt_xfer (uint8_t rhport, uint8_t ep_addr, uint8_t* buffer, uint16_t total_bytes)
403{
404 // Control transfer is not DMA support, and must be done in slave mode
405 if ( tu_edpt_number(ep_addr) == 0 )
406 {
407 return control_xact(rhport, tu_edpt_dir(ep_addr), buffer, (uint8_t) total_bytes);
408 }
409 else
410 {
411 uint8_t ep_id = ep_addr2idx(ep_addr);
412 dma_desc_t* dd = &_dcd.dd[ep_id];
413
414 // Prepare DMA descriptor
415 // Isochronous & max packet size must be preserved, Other fields of dd should be clear
416 uint16_t const ep_size = dd->max_packet_size;
417 uint8_t is_iso = dd->isochronous;
418
419 tu_memclr(dd, sizeof(dma_desc_t));
420 dd->isochronous = is_iso;
421 dd->max_packet_size = ep_size;
422 dd->buffer = (uint32_t) buffer;
423 dd->buflen = total_bytes;
424
425 _dcd.udca[ep_id] = dd;
426
427 if ( ep_id % 2 )
428 {
429 // Clear EP interrupt before Enable DMA
430 LPC_USB->EpIntEn &= ~TU_BIT(ep_id);
431 LPC_USB->EpDMAEn = TU_BIT(ep_id);
432
433 // endpoint IN need to actively raise DMA request
434 LPC_USB->DMARSet = TU_BIT(ep_id);
435 }else
436 {
437 // Enable DMA
438 LPC_USB->EpDMAEn = TU_BIT(ep_id);
439 }
440
441 return true;
442 }
443}
444
445//--------------------------------------------------------------------+
446// ISR
447//--------------------------------------------------------------------+
448
449// handle control xfer (slave mode)
450static void control_xfer_isr(uint8_t rhport, uint32_t ep_int_status)
451{
452 // Control out complete
453 if ( ep_int_status & TU_BIT(0) )
454 {
456
457 LPC_USB->EpIntClr = TU_BIT(0);
458
459 if (is_setup)
460 {
461 uint8_t setup_packet[8];
462 control_ep_read(setup_packet, 8); // TODO read before clear setup above
463
464 dcd_event_setup_received(rhport, setup_packet, true);
465 }
466 else if ( _dcd.control.out_buffer )
467 {
468 // software queued transfer previously
469 uint8_t received = control_ep_read(_dcd.control.out_buffer, _dcd.control.out_bytes);
470
471 _dcd.control.out_buffer = NULL;
472 _dcd.control.out_bytes = 0;
473
475 }else
476 {
477 // hardware auto ack packet -> mark as received
478 _dcd.control.out_received = true;
479 }
480 }
481
482 // Control In complete
483 if ( ep_int_status & TU_BIT(1) )
484 {
485 LPC_USB->EpIntClr = TU_BIT(1);
486 dcd_event_xfer_complete(rhport, TUSB_DIR_IN_MASK, _dcd.control.in_bytes, XFER_RESULT_SUCCESS, true);
487 }
488}
489
490// handle bus event signal
491static void bus_event_isr(uint8_t rhport)
492{
493 uint8_t const dev_status = sie_read(SIE_CMDCODE_DEVICE_STATUS);
494 if (dev_status & SIE_DEV_STATUS_RESET_MASK)
495 {
496 bus_reset();
498 }
499
500 if (dev_status & SIE_DEV_STATUS_CONNECT_CHANGE_MASK)
501 {
502 // device is disconnected, require using VBUS (P1_30)
503 dcd_event_bus_signal(rhport, DCD_EVENT_UNPLUGGED, true);
504 }
505
506 if (dev_status & SIE_DEV_STATUS_SUSPEND_CHANGE_MASK)
507 {
508 if (dev_status & SIE_DEV_STATUS_SUSPEND_MASK)
509 {
510 dcd_event_bus_signal(rhport, DCD_EVENT_SUSPEND, true);
511 }
512 else
513 {
514 dcd_event_bus_signal(rhport, DCD_EVENT_RESUME, true);
515 }
516 }
517}
518
519// Helper to complete a DMA descriptor for non-control transfer
520static void dd_complete_isr(uint8_t rhport, uint8_t ep_id)
521{
522 dma_desc_t* const dd = &_dcd.dd[ep_id];
523 uint8_t result = (dd->status == DD_STATUS_NORMAL || dd->status == DD_STATUS_DATA_UNDERUN) ? XFER_RESULT_SUCCESS : XFER_RESULT_FAILED;
524 uint8_t const ep_addr = (ep_id / 2) | ((ep_id & 0x01) ? TUSB_DIR_IN_MASK : 0);
525
526 dcd_event_xfer_complete(rhport, ep_addr, dd->present_count, result, true);
527}
528
529// main USB IRQ handler
530void dcd_int_handler(uint8_t rhport)
531{
532 uint32_t const dev_int_status = LPC_USB->DevIntSt & LPC_USB->DevIntEn;
533 LPC_USB->DevIntClr = dev_int_status;// Acknowledge handled interrupt
534
535 // Bus event
536 if (dev_int_status & DEV_INT_DEVICE_STATUS_MASK)
537 {
538 bus_event_isr(rhport);
539 }
540
541 // Endpoint interrupt
542 uint32_t const ep_int_status = LPC_USB->EpIntSt & LPC_USB->EpIntEn;
543
544 // Control Endpoint are fast
545 if (dev_int_status & DEV_INT_ENDPOINT_FAST_MASK)
546 {
547 // Note clear USBEpIntClr will also clear the setup received bit --> clear after handle setup packet
548 // Only clear USBEpIntClr 1 endpoint each, and should wait for CDFULL bit set
549 control_xfer_isr(rhport, ep_int_status);
550 }
551
552 // non-control IN are slow
553 if (dev_int_status & DEV_INT_ENDPOINT_SLOW_MASK)
554 {
555 for ( uint8_t ep_id = 3; ep_id < DCD_ENDPOINT_MAX; ep_id += 2 )
556 {
557 if ( tu_bit_test(ep_int_status, ep_id) )
558 {
559 LPC_USB->EpIntClr = TU_BIT(ep_id);
560
561 // Clear Ep interrupt for next DMA
562 LPC_USB->EpIntEn &= ~TU_BIT(ep_id);
563
564 dd_complete_isr(rhport, ep_id);
565 }
566 }
567 }
568
569 // DMA transfer complete (RAM <-> EP) for Non-Control
570 // OUT: USB transfer is fully complete
571 // IN : UBS transfer is still on-going -> enable EpIntEn to know when it is complete
572 uint32_t const dma_int_status = LPC_USB->DMAIntSt & LPC_USB->DMAIntEn;
573 if (dma_int_status & DMA_INT_END_OF_XFER_MASK)
574 {
575 uint32_t const eot = LPC_USB->EoTIntSt;
576 LPC_USB->EoTIntClr = eot; // acknowledge interrupt source
577
578 for ( uint8_t ep_id = 2; ep_id < DCD_ENDPOINT_MAX; ep_id++ )
579 {
580 if ( tu_bit_test(eot, ep_id) )
581 {
582 if ( ep_id & 0x01 )
583 {
584 // IN enable EpInt for end of usb transfer
585 LPC_USB->EpIntEn |= TU_BIT(ep_id);
586 }else
587 {
588 // OUT
589 dd_complete_isr(rhport, ep_id);
590 }
591 }
592 }
593 }
594
595 // Errors
596 if ( (dev_int_status & DEV_INT_ERROR_MASK) || (dma_int_status & DMA_INT_ERROR_MASK) )
597 {
598 uint32_t error_status = sie_read(SIE_CMDCODE_READ_ERROR_STATUS);
599 (void) error_status;
600 TU_BREAKPOINT();
601 }
602}
603
604#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 @612 data
bool isochronous[EP_MAX]
static struct @149 _dcd
dma_desc_t
Definition: dcd_lpc17_40.c:72
static void bus_event_isr(uint8_t rhport)
Definition: dcd_lpc17_40.c:491
static void sie_write(uint8_t cmd_code, uint8_t data_len, uint8_t data)
Definition: dcd_lpc17_40.c:112
static bool control_xact(uint8_t rhport, uint8_t dir, uint8_t *buffer, uint8_t len)
Definition: dcd_lpc17_40.c:373
void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr)
Definition: dcd_lpc17_40.c:351
void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr)
Definition: dcd_lpc17_40.c:340
static void bus_reset(void)
Definition: dcd_lpc17_40.c:152
void dcd_int_handler(uint8_t rhport)
Definition: dcd_lpc17_40.c:530
void dcd_disconnect(uint8_t rhport)
Definition: dcd_lpc17_40.c:227
static uint8_t control_ep_read(void *buffer, uint8_t len)
Definition: dcd_lpc17_40.c:269
static void set_ep_size(uint8_t ep_id, uint16_t max_packet_size)
Definition: dcd_lpc17_40.c:137
static uint8_t byte2dword(uint8_t bytes)
Definition: dcd_lpc17_40.c:244
TU_VERIFY_STATIC(sizeof(dma_desc_t)==16, "size is not correct")
void dcd_edpt_close_all(uint8_t rhport)
Definition: dcd_lpc17_40.c:345
static void control_ep_write(void const *buffer, uint8_t len)
Definition: dcd_lpc17_40.c:249
void dcd_int_disable(uint8_t rhport)
Definition: dcd_lpc17_40.c:199
bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const *p_endpoint_desc)
Definition: dcd_lpc17_40.c:296
static void dd_complete_isr(uint8_t rhport, uint8_t ep_id)
Definition: dcd_lpc17_40.c:520
void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr)
Definition: dcd_lpc17_40.c:365
static uint8_t sie_read(uint8_t cmd_code)
Definition: dcd_lpc17_40.c:122
void dcd_connect(uint8_t rhport)
Definition: dcd_lpc17_40.c:221
bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_t total_bytes)
Definition: dcd_lpc17_40.c:402
static uint8_t ep_addr2idx(uint8_t ep_addr)
Definition: dcd_lpc17_40.c:132
void dcd_set_address(uint8_t rhport, uint8_t dev_addr)
Definition: dcd_lpc17_40.c:205
bool dcd_init(uint8_t rhport, const tusb_rhport_init_t *rh_init)
Definition: dcd_lpc17_40.c:170
static void control_xfer_isr(uint8_t rhport, uint32_t ep_int_status)
Definition: dcd_lpc17_40.c:450
struct TU_ATTR_ALIGNED(4)
Definition: dcd_lpc17_40.c:41
void dcd_int_enable(uint8_t rhport)
Definition: dcd_lpc17_40.c:193
void dcd_remote_wakeup(uint8_t rhport)
Definition: dcd_lpc17_40.c:216
void dcd_sof_enable(uint8_t rhport, bool en)
Definition: dcd_lpc17_40.c:233
@ USBRXPLEN_PACKET_READY_MASK
Definition: dcd_lpc17_40.h:80
@ USBRXPLEN_PACKET_LENGTH_MASK
Definition: dcd_lpc17_40.h:78
@ DMA_INT_ERROR_MASK
Definition: dcd_lpc17_40.h:67
@ DMA_INT_END_OF_XFER_MASK
Definition: dcd_lpc17_40.h:65
@ SIE_DEV_STATUS_SUSPEND_MASK
Definition: dcd_lpc17_40.h:114
@ SIE_DEV_STATUS_CONNECT_STATUS_MASK
Definition: dcd_lpc17_40.h:112
@ SIE_DEV_STATUS_CONNECT_CHANGE_MASK
Definition: dcd_lpc17_40.h:113
@ SIE_DEV_STATUS_RESET_MASK
Definition: dcd_lpc17_40.h:116
@ SIE_DEV_STATUS_SUSPEND_CHANGE_MASK
Definition: dcd_lpc17_40.h:115
@ SIE_SET_ENDPOINT_STALLED_MASK
Definition: dcd_lpc17_40.h:132
@ SIE_SET_ENDPOINT_CONDITION_STALLED_MASK
Definition: dcd_lpc17_40.h:135
@ SIE_CMDCODE_ENDPOINT_SELECT
Definition: dcd_lpc17_40.h:103
@ SIE_CMDCODE_BUFFER_CLEAR
Definition: dcd_lpc17_40.h:106
@ SIE_CMDCODE_READ_ERROR_STATUS
Definition: dcd_lpc17_40.h:100
@ SIE_CMDCODE_ENDPOINT_SET_STATUS
Definition: dcd_lpc17_40.h:105
@ SIE_CMDCODE_SET_ADDRESS
Definition: dcd_lpc17_40.h:93
@ SIE_CMDCODE_DEVICE_STATUS
Definition: dcd_lpc17_40.h:98
@ SIE_CMDCODE_BUFFER_VALIDATE
Definition: dcd_lpc17_40.h:107
@ SIE_CMDCODE_CONFIGURE_DEVICE
Definition: dcd_lpc17_40.h:94
sie_cmdphase_t
Definition: dcd_lpc17_40.h:85
@ SIE_CMDPHASE_WRITE
Definition: dcd_lpc17_40.h:86
@ SIE_CMDPHASE_READ
Definition: dcd_lpc17_40.h:87
@ SIE_CMDPHASE_COMMAND
Definition: dcd_lpc17_40.h:88
@ USBCTRL_READ_ENABLE_MASK
Definition: dcd_lpc17_40.h:72
@ USBCTRL_WRITE_ENABLE_MASK
Definition: dcd_lpc17_40.h:73
@ DD_STATUS_NORMAL
Definition: dcd_lpc17_40.h:142
@ DD_STATUS_DATA_UNDERUN
Definition: dcd_lpc17_40.h:143
@ SIE_SELECT_ENDPOINT_SETUP_RECEIVED_MASK
Definition: dcd_lpc17_40.h:123
uint16_t total_bytes
Definition: dcd_nuc505.c:113
uint8_t dev_addr
Definition: dcd_pic32mz.c:81
CFG_TUD_MEM_SECTION CFG_TUSB_MEM_ALIGN tu_static uint8_t received[CFG_TUD_NET_PACKET_PREFIX_LEN+CFG_TUD_NET_MTU+CFG_TUD_NET_PACKET_PREFIX_LEN]
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 * out_buffer
Definition: dcd_lpc17_40.c:86
volatile bool out_received
Definition: dcd_lpc17_40.c:88
uint8_t in_bytes
Definition: dcd_lpc17_40.c:90
uint8_t out_bytes
Definition: dcd_lpc17_40.c:87
static TU_ATTR_ALWAYS_INLINE uint8_t tu_min8(uint8_t x, uint8_t y)
Definition: tusb_common.h:154
static TU_ATTR_ALWAYS_INLINE bool tu_bit_test(uint32_t value, uint8_t pos)
Definition: tusb_common.h:151
@ TUSB_DIR_IN
Definition: tusb_types.h:67
@ TUSB_DIR_IN_MASK
Definition: tusb_types.h:69
@ 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_FAILED
Definition: tusb_types.h:238
@ 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_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_edpt_addr(uint8_t num, uint8_t dir)
Definition: tusb_types.h:511