Open FFBoard
Open source force feedback firmware
dcd_pic32mz.c
Go to the documentation of this file.
1/*
2 * The MIT License (MIT)
3 *
4 * Copyright (c) 2022 Jerzy Kasenberg
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_PIC32MZ
30
31#include <common/tusb_common.h>
32#include <device/dcd.h>
33
34#include <xc.h>
35#include "usbhs_registers.h"
36
37#define USB_REGS ((usbhs_registers_t *) (_USB_BASE_ADDRESS))
38
39// Maximum number of endpoints, could be trimmed down in tusb_config to reduce RAM usage.
40#ifndef EP_MAX
41#define EP_MAX 8
42#endif
43
44
45typedef enum {
58
59typedef struct {
60 uint8_t * buffer;
61 // Total length of current transfer
62 uint16_t total_len;
63 // Bytes transferred so far
64 uint16_t transferred;
65 uint16_t max_packet_size;
66 uint16_t fifo_size;
67 // Packet size sent or received so far. It is used to modify transferred field
68 // after ACK is received or when filling ISO endpoint with size larger then
69 // FIFO size.
70 uint16_t last_packet_size;
71 uint8_t ep_addr;
73
74static struct
75{
76 // Current FIFO RAM address used for FIFO allocation
77 uint16_t fifo_addr_top;
78 // EP0 transfer stage
80 // Device address
81 uint8_t dev_addr;
84
85// Two endpoint 0 descriptor definition for unified dcd_edpt_open()
87{
89 .bDescriptorType = TUSB_DESC_ENDPOINT,
90
91 .bEndpointAddress = 0x00,
92 .bmAttributes = { .xfer = TUSB_XFER_CONTROL },
93 .wMaxPacketSize = CFG_TUD_ENDPOINT0_SIZE,
94 .bInterval = 0
95};
96
98{
100 .bDescriptorType = TUSB_DESC_ENDPOINT,
101
102 .bEndpointAddress = 0x80,
103 .bmAttributes = { .xfer = TUSB_XFER_CONTROL },
104 .wMaxPacketSize = CFG_TUD_ENDPOINT0_SIZE,
105 .bInterval = 0
106};
107
108#define XFER_CTL_BASE(_ep, _dir) &_dcd.xfer_status[_ep][_dir]
109
111{
112 _dcd.ep0_stage = stage;
113}
114
116{
117 return _dcd.ep0_stage;
118}
119
120/*------------------------------------------------------------------*/
121/* Controller API
122 *------------------------------------------------------------------*/
123bool dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) {
124 (void) rh_init;
125 // Disable endpoint interrupts for now
126 USB_REGS->INTRRXEbits.w = 0;
127 USB_REGS->INTRTXEbits.w = 0;
128 // Enable Reset/Suspend/Resume interrupts only
129 USB_REGS->INTRUSBEbits.w = 7;
130
131 dcd_connect(rhport);
132 return true;
133}
134
135void dcd_int_enable(uint8_t rhport)
136{
137 (void) rhport;
138
139 USBCRCONbits.USBIE = 1;
140}
141
142void dcd_int_disable(uint8_t rhport)
143{
144 (void) rhport;
145
146 USBCRCONbits.USBIE = 0;
147}
148
149void dcd_set_address(uint8_t rhport, uint8_t dev_addr)
150{
151 (void) rhport;
152
154 // Store address it will be used later after status stage is done
155 _dcd.dev_addr = dev_addr;
156 // Confirm packet now, address will be set when status stage is detected
157 USB_REGS->EPCSR[0].CSR0L_DEVICEbits.w = (USBHS_EP0_DEVICE_SERVICED_RXPKTRDY | USBHS_EP0_DEVICE_DATAEND);
158}
159
160void dcd_remote_wakeup(uint8_t rhport)
161{
162 (void) rhport;
163
164 USB_REGS->POWERbits.RESUME = 1;
165#if CFG_TUSB_OS != OPT_OS_NONE
166 osal_task_delay(10);
167#else
168 // TODO: Wait in non blocking mode
169 unsigned cnt = 2000;
170 while (cnt--) __asm__("nop");
171#endif
172 USB_REGS->POWERbits.RESUME = 0;
173}
174
175void dcd_connect(uint8_t rhport)
176{
177 (void) rhport;
178
179 USB_REGS->POWERbits.HSEN = TUD_OPT_HIGH_SPEED ? 1 : 0;
180 USB_REGS->POWERbits.SOFTCONN = 1;
181}
182
183void dcd_disconnect(uint8_t rhport)
184{
185 (void) rhport;
186
187 USB_REGS->POWERbits.SOFTCONN = 1;
188}
189
190void dcd_sof_enable(uint8_t rhport, bool en)
191{
192 (void) rhport;
193 (void) en;
194
195 // TODO implement later
196}
197
198TU_ATTR_ALWAYS_INLINE static inline bool is_in_isr(void)
199{
200 return (_CP0_GET_STATUS() & (_CP0_STATUS_EXL_MASK | _CP0_STATUS_IPL_MASK)) != 0;
201}
202
203static void epn_rx_configure(uint8_t endpoint, uint16_t endpointSize,
204 uint16_t fifoAddress, uint8_t fifoSize,
205 uint32_t transferType)
206{
207 uint8_t old_index = USB_REGS->INDEXbits.ENDPOINT;
208
209 // Select endpoint register set (same register address is used for all endpoints.
210 USB_REGS->INDEXbits.ENDPOINT = endpoint;
211
212 // Configure the Endpoint size
213 USB_REGS->INDEXED_EPCSR.RXMAXPbits.RXMAXP = endpointSize;
214
215 // Set up the fifo address.
216 USB_REGS->RXFIFOADDbits.RXFIFOAD = fifoAddress;
217
218 // Resets the endpoint data toggle to 0
219 USB_REGS->INDEXED_EPCSR.RXCSRL_DEVICEbits.CLRDT = 1;
220
221 // Set up the FIFO size
222 USB_REGS->RXFIFOSZbits.RXFIFOSZ = fifoSize;
223
224 USB_REGS->INDEXED_EPCSR.RXCSRH_DEVICEbits.ISO = transferType == 1 ? 1 : 0;
225 // Disable NYET Handshakes for interrupt endpoints
226 USB_REGS->INDEXED_EPCSR.RXCSRH_DEVICEbits.DISNYET = transferType == 3 ? 1 : 0;
227
228 // Restore the index register.
229 USB_REGS->INDEXbits.ENDPOINT = old_index;
230
231 // Enable the endpoint interrupt.
232 USB_REGS->INTRRXEbits.w |= (1 << endpoint);
233}
234
235static void epn_tx_configure(uint8_t endpoint, uint16_t endpointSize,
236 uint16_t fifoAddress, uint8_t fifoSize,
237 uint32_t transferType)
238{
239 uint8_t old_index = USB_REGS->INDEXbits.ENDPOINT;
240
241 // Select endpoint register set (same register address is used for all endpoints.
242 USB_REGS->INDEXbits.ENDPOINT = endpoint;
243
244 // Configure the Endpoint size
245 USB_REGS->INDEXED_EPCSR.TXMAXPbits.TXMAXP = endpointSize;
246
247 // Set up the fifo address
248 USB_REGS->TXFIFOADDbits.TXFIFOAD = fifoAddress;
249
250 // Resets the endpoint data toggle to 0
251 USB_REGS->INDEXED_EPCSR.TXCSRL_DEVICEbits.CLRDT = 1;
252
253 // Set up the FIFO size
254 USB_REGS->TXFIFOSZbits.TXFIFOSZ = fifoSize;
255
256 USB_REGS->INDEXED_EPCSR.TXCSRH_DEVICEbits.ISO = 1 == transferType ? 1 : 0;
257
258 // Restore the index register
259 USB_REGS->INDEXbits.ENDPOINT = old_index;
260
261 // Enable the interrupt
262 USB_REGS->INTRTXEbits.w |= (1 << endpoint);
263}
264
265static void tx_fifo_write(uint8_t endpoint, uint8_t const * buffer, size_t count)
266{
267 size_t i;
268 volatile uint8_t * fifo_reg;
269
270 fifo_reg = (volatile uint8_t *) (&USB_REGS->FIFO[endpoint]);
271
272 for (i = 0; i < count; i++)
273 {
274 *fifo_reg = buffer[i];
275 }
276}
277
278static int rx_fifo_read(uint8_t epnum, uint8_t * buffer)
279{
280 uint32_t i;
281 uint32_t count;
282 volatile uint8_t * fifo_reg;
283
284 fifo_reg = (volatile uint8_t *) (&USB_REGS->FIFO[epnum]);
285
286 count = USB_REGS->EPCSR[epnum].RXCOUNTbits.RXCNT;
287
288 for (i = 0; i < count; i++)
289 {
290 buffer[i] = fifo_reg[i & 3];
291 }
292
293 return count;
294}
295
296static void xfer_complete(xfer_ctl_t * xfer, uint8_t result, bool in_isr)
297{
298 dcd_event_xfer_complete(0, xfer->ep_addr, xfer->transferred, result, in_isr);
299}
300
301static void ep0_fill_tx(xfer_ctl_t * xfer_in)
302{
303 uint16_t left = xfer_in->total_len - xfer_in->transferred;
304
305 if (left)
306 {
307 xfer_in->last_packet_size = tu_min16(xfer_in->max_packet_size, left);
308 tx_fifo_write(0, xfer_in->buffer + xfer_in->transferred, xfer_in->last_packet_size);
309 xfer_in->transferred += xfer_in->last_packet_size;
310 left = xfer_in->total_len - xfer_in->transferred;
311 }
312
313 if (xfer_in->last_packet_size < xfer_in->max_packet_size || left == 0)
314 {
315 switch (ep0_get_stage())
316 {
321 USB_REGS->EPCSR[0].CSR0L_DEVICEbits.TXPKTRDY = 1;
322 break;
325 USB_REGS->EPCSR[0].CSR0L_DEVICEbits.w = (USBHS_EP0_DEVICE_SERVICED_RXPKTRDY | USBHS_EP0_DEVICE_DATAEND);
326 break;
329 USB_REGS->EPCSR[0].CSR0L_DEVICEbits.w = (USBHS_EP0_DEVICE_SERVICED_RXPKTRDY | USBHS_EP0_DEVICE_DATAEND);
330 break;
331 default:
332 break;
333 }
334 }
335 else
336 {
337 switch (ep0_get_stage())
338 {
341 // fall through
343 USB_REGS->EPCSR[0].CSR0L_DEVICEbits.TXPKTRDY = 1;
344 break;
345 default:
346 break;
347 }
348 }
349}
350
351static void epn_fill_tx(xfer_ctl_t * xfer_in, uint8_t epnum)
352{
353 uint16_t left = xfer_in->total_len - xfer_in->transferred;
354 if (left)
355 {
356 xfer_in->last_packet_size = tu_min16(xfer_in->max_packet_size, left);
357 tx_fifo_write(epnum, xfer_in->buffer + xfer_in->transferred, xfer_in->last_packet_size);
358 }
359 USB_REGS->EPCSR[epnum].TXCSRL_DEVICEbits.TXPKTRDY = 1;
360}
361
362static bool ep0_xfer(xfer_ctl_t * xfer, int dir)
363{
364 if (dir == TUSB_DIR_OUT)
365 {
366 if (xfer->total_len)
367 {
368 switch (_dcd.ep0_stage)
369 {
373 USB_REGS->EPCSR[0].CSR0L_DEVICEbits.SVCRPR = 1;
374 break;
375 default:
376 TU_ASSERT(0);
377 }
378 }
379 else
380 {
381 switch (_dcd.ep0_stage)
382 {
385 // fall through
386 case EP0_STAGE_NONE:
388 break;
389 default:
390 break;
391 }
392 }
393 }
394 else // IN
395 {
397 }
398
399 return true;
400}
401
402/*------------------------------------------------------------------*/
403/* DCD Endpoint port
404 *------------------------------------------------------------------*/
405
406bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * desc_edpt)
407{
408 (void) rhport;
409 uint8_t const epnum = tu_edpt_number(desc_edpt->bEndpointAddress);
410 uint8_t const dir = tu_edpt_dir(desc_edpt->bEndpointAddress);
411 xfer_ctl_t * xfer = XFER_CTL_BASE(epnum, dir);
412
413 TU_ASSERT(epnum < EP_MAX);
414
415 xfer->max_packet_size = tu_edpt_packet_size(desc_edpt);
416 xfer->fifo_size = xfer->max_packet_size;
417 xfer->ep_addr = desc_edpt->bEndpointAddress;
418
419 if (epnum != 0)
420 {
421 if (dir == TUSB_DIR_OUT)
422 {
423 epn_rx_configure(epnum, xfer->max_packet_size, _dcd.fifo_addr_top, __builtin_ctz(xfer->fifo_size) - 3, desc_edpt->bmAttributes.xfer);
424 _dcd.fifo_addr_top += (xfer->fifo_size + 7) >> 3;
425 }
426 else
427 {
428 epn_tx_configure(epnum, xfer->max_packet_size, _dcd.fifo_addr_top, __builtin_ctz(xfer->fifo_size) - 3, desc_edpt->bmAttributes.xfer);
429 _dcd.fifo_addr_top += (xfer->fifo_size + 7) >> 3;
430 }
431 }
432 return true;
433}
434
435void dcd_edpt_close_all (uint8_t rhport)
436{
437 (void) rhport;
438
439 // Reserve EP0 FIFO address
440 _dcd.fifo_addr_top = 64 >> 3;
441 for (int i = 1; i < EP_MAX; ++i)
442 {
443 tu_memclr(&_dcd.xfer_status[i], sizeof(_dcd.xfer_status[i]));
444 }
445}
446
447void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr)
448{
449 (void) rhport;
450 (void) ep_addr;
451}
452
453bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes)
454{
455 uint8_t const epnum = tu_edpt_number(ep_addr);
456 uint8_t const dir = tu_edpt_dir(ep_addr);
457 xfer_ctl_t * xfer = XFER_CTL_BASE(epnum, dir);
458 (void) rhport;
459
460 xfer->buffer = buffer;
462 xfer->last_packet_size = 0;
463 xfer->transferred = 0;
464
465 if (epnum == 0)
466 {
467 return ep0_xfer(xfer, dir);
468 }
469 if (dir == TUSB_DIR_OUT)
470 {
471 USB_REGS->INTRRXEbits.w |= (1u << epnum);
472 }
473 else // IN
474 {
475 epn_fill_tx(xfer, epnum);
476 }
477
478 return true;
479}
480
481void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr)
482{
483 uint8_t const epnum = tu_edpt_number(ep_addr);
484 uint8_t const dir = tu_edpt_dir(ep_addr);
485 (void) rhport;
486
487 if (epnum == 0)
488 {
489 USB_REGS->EPCSR[0].CSR0L_DEVICEbits.SENDSTALL = 1;
490 }
491 else
492 {
493 if (dir == TUSB_DIR_OUT)
494 {
495 USB_REGS->EPCSR[epnum].RXCSRL_DEVICEbits.SENDSTALL = 1;
496 }
497 else
498 {
499 USB_REGS->EPCSR[epnum].TXCSRL_DEVICEbits.SENDSTALL = 1;
500 }
501 }
502}
503
504void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr)
505{
506 uint8_t const epnum = tu_edpt_number(ep_addr);
507 uint8_t const dir = tu_edpt_dir(ep_addr);
508 (void) rhport;
509
510 if (epnum == 0)
511 {
512 USB_REGS->EPCSR[0].CSR0L_DEVICEbits.SENDSTALL = 0;
513 }
514 else
515 {
516 if (dir == TUSB_DIR_OUT)
517 {
518 USB_REGS->EPCSR[epnum].RXCSRL_DEVICEbits.w &= ~(USBHS_EP_DEVICE_RX_SENT_STALL | USBHS_EP_DEVICE_RX_SEND_STALL);
519 USB_REGS->EPCSR[epnum].RXCSRL_DEVICEbits.CLRDT = 1;
520 }
521 else
522 {
523 USB_REGS->EPCSR[epnum].TXCSRL_DEVICEbits.w &= ~(USBHS_EP_DEVICE_TX_SENT_STALL | USBHS_EP_DEVICE_TX_SEND_STALL);
524 USB_REGS->EPCSR[epnum].TXCSRL_DEVICEbits.CLRDT = 1;
525 }
526 }
527}
528
529/*------------------------------------------------------------------*/
530/* Interrupt Handler
531 *------------------------------------------------------------------*/
532
533static void ep0_handle_rx(void)
534{
535 int transferred;
536 xfer_ctl_t * xfer = XFER_CTL_BASE(0, TUSB_DIR_OUT);
537
538 TU_ASSERT(xfer->buffer,);
539
540 transferred = rx_fifo_read(0, xfer->buffer + xfer->transferred);
541 xfer->transferred += transferred;
542 TU_ASSERT(xfer->transferred <= xfer->total_len,);
543 if (transferred < xfer->max_packet_size || xfer->transferred == xfer->total_len)
544 {
547 }
548 else
549 {
550 USB_REGS->EPCSR[0].CSR0L_DEVICEbits.SVCRPR = 1;
551 }
552}
553
554static void epn_handle_rx_int(uint8_t epnum)
555{
556 uint8_t ep_status;
557 int transferred;
558 xfer_ctl_t * xfer = XFER_CTL_BASE(epnum, TUSB_DIR_OUT);
559
560 ep_status = USB_REGS->EPCSR[epnum].RXCSRL_DEVICEbits.w;
561 if (ep_status & USBHS_EP_DEVICE_RX_SENT_STALL)
562 {
563 USB_REGS->EPCSR[epnum].RXCSRL_DEVICEbits.w &= ~USBHS_EP_DEVICE_RX_SENT_STALL;
564 }
565
566 if (ep_status & USBHS_EP0_HOST_RXPKTRDY)
567 {
568 TU_ASSERT(xfer->buffer != NULL,);
569
570 transferred = rx_fifo_read(epnum, xfer->buffer + xfer->transferred);
571 USB_REGS->EPCSR[epnum].RXCSRL_HOSTbits.RXPKTRDY = 0;
572 xfer->transferred += transferred;
573 TU_ASSERT(xfer->transferred <= xfer->total_len,);
574 if (transferred < xfer->max_packet_size || xfer->transferred == xfer->total_len)
575 {
576 USB_REGS->INTRRXEbits.w &= ~(1u << epnum);
578 }
579 }
580}
581
582static void epn_handle_tx_int(uint8_t epnum)
583{
584 uint8_t ep_status = USB_REGS->EPCSR[epnum].TXCSRL_DEVICEbits.w;
585 xfer_ctl_t * xfer = XFER_CTL_BASE(epnum, TUSB_DIR_IN);
586
587 if (ep_status & USBHS_EP_DEVICE_TX_SENT_STALL)
588 {
589 USB_REGS->EPCSR[epnum].TXCSRL_DEVICEbits.w &= ~USBHS_EP_DEVICE_TX_SENT_STALL;
590 }
591 else
592 {
593 xfer->transferred += xfer->last_packet_size;
594 TU_ASSERT(xfer->transferred <= xfer->total_len,);
595 if (xfer->last_packet_size < xfer->max_packet_size || xfer->transferred == xfer->total_len)
596 {
597 xfer->last_packet_size = 0;
599 }
600 else
601 {
602 epn_fill_tx(xfer, epnum);
603 }
604 }
605}
606
607static void ep0_handle_int(void)
608{
609 __USBHS_CSR0L_DEVICE_t ep0_status;
610 union {
612 uint32_t setup_buffer[2];
613 } setup_packet;
614 xfer_ctl_t * xfer_in = XFER_CTL_BASE(0, TUSB_DIR_IN);
615 uint8_t old_index = USB_REGS->INDEXbits.ENDPOINT;
616
617 // Select EP0 registers
618 USB_REGS->INDEXbits.ENDPOINT = 0;
619
620 ep0_status = USB_REGS->EPCSR[0].CSR0L_DEVICEbits;
621
622 if (ep0_status.SENTSTALL)
623 {
624 // Stall was sent. Reset the endpoint 0 state.
625 // Clear the sent stall bit.
627 USB_REGS->EPCSR[0].CSR0L_DEVICEbits.SENTSTALL = 0;
628 }
629
630 if (ep0_status.SETUPEND)
631 {
632 // This means the current control transfer end prematurely. We don't
633 // need to end any transfers. The device layer will manage the
634 // premature transfer end. We clear the SetupEnd bit and reset the
635 // driver control transfer state machine to waiting for next setup
636 // packet from host.
637 USB_REGS->EPCSR[0].CSR0L_DEVICEbits.SVSSETEND = 1;
639 }
640
641 if (ep0_status.RXPKTRDY)
642 {
643 switch (ep0_get_stage())
644 {
645 default:
646 // Data arrived at unexpected state, this must be setup stage packet after all.
647 // Fall through
648 case EP0_STAGE_NONE:
649 // This means we were expecting a SETUP packet and we got one.
650 setup_packet.setup_buffer[0] = USB_REGS->FIFO[0];
651 setup_packet.setup_buffer[1] = USB_REGS->FIFO[0];
652 if (setup_packet.request.bmRequestType_bit.direction == TUSB_DIR_OUT)
653 {
654 // SVCRPR is not set yet, it will be set later when out xfer is started
655 // Till then NAKs will hold incommint data
656 ep0_set_stage(setup_packet.request.wLength == 0 ? EP0_STAGE_SETUP_OUT_NO_DATA : EP0_STAGE_SETUP_OUT_DATA);
657 }
658 else
659 {
660 USB_REGS->EPCSR[0].CSR0L_DEVICEbits.SVCRPR = 1;
662 }
663 dcd_event_setup_received(0, &setup_packet.request.bmRequestType, true);
664 break;
667 break;
668 }
669 }
670 else
671 {
672 switch (ep0_get_stage())
673 {
675 // Status was just sent, this concludes request, notify client
677 xfer_complete(xfer_in, XFER_RESULT_SUCCESS, true);
678 break;
680 // Packet sent, fill more data
681 ep0_fill_tx(xfer_in);
682 break;
685 xfer_complete(xfer_in, XFER_RESULT_SUCCESS, true);
686 break;
688 // Status stage after set address request finished, address can be changed
689 USB_REGS->FADDRbits.FUNC = _dcd.dev_addr;
691 break;
692 default:
693 break;
694 }
695 }
696 // Restore register index
697 USB_REGS->INDEXbits.ENDPOINT = old_index;
698}
699
700void dcd_int_handler(uint8_t rhport)
701{
702 int i;
703 uint8_t mask;
704 __USBCSR2bits_t csr2_bits;
705 uint16_t rxints = USB_REGS->INTRRX & USB_REGS->INTRRXEbits.w;
706 uint16_t txints = USB_REGS->INTRTX;
707 csr2_bits = USBCSR2bits;
708 (void) rhport;
709
710 IFS4CLR = _IFS4_USBIF_MASK;
711
712 if (csr2_bits.SOFIF && csr2_bits.SOFIE)
713 {
714 dcd_event_bus_signal(0, DCD_EVENT_SOF, true);
715 }
716 if (csr2_bits.RESETIF)
717 {
720 dcd_event_bus_reset(0, USB_REGS->POWERbits.HSMODE ? TUSB_SPEED_HIGH : TUSB_SPEED_FULL, true);
721 }
722 if (csr2_bits.SUSPIF)
723 {
724 dcd_event_bus_signal(0, DCD_EVENT_SUSPEND, true);
725 }
726 if (csr2_bits.RESUMEIF)
727 {
728 dcd_event_bus_signal(0, DCD_EVENT_RESUME, true);
729 }
730 // INTRTX has bit for EP0
731 if (txints & 1)
732 {
733 txints ^= 1;
735 }
736 for (mask = 0x02, i = 1; rxints != 0 && mask != 0; mask <<= 1, ++i)
737 {
738 if (rxints & mask)
739 {
740 rxints ^= mask;
742 }
743 }
744 for (mask = 0x02, i = 1; txints != 0 && mask != 0; mask <<= 1, ++i)
745 {
746 if (txints & mask)
747 {
748 txints ^= mask;
750 }
751 }
752}
753
754#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_ctl_t
Definition: dcd_dwc2.c:52
static bool in_isr
xfer_td_t xfer[EP_CBI_COUNT+1][2]
Definition: dcd_nrf5x.c:119
uint16_t total_bytes
Definition: dcd_nuc505.c:113
static void ep0_set_stage(ep0_stage_t stage)
Definition: dcd_pic32mz.c:110
static ep0_stage_t ep0_get_stage(void)
Definition: dcd_pic32mz.c:115
uint8_t dev_addr
Definition: dcd_pic32mz.c:81
static int rx_fifo_read(uint8_t epnum, uint8_t *buffer)
Definition: dcd_pic32mz.c:278
static void ep0_handle_int(void)
Definition: dcd_pic32mz.c:607
void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr)
Definition: dcd_pic32mz.c:481
void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr)
Definition: dcd_pic32mz.c:447
static void xfer_complete(xfer_ctl_t *xfer, uint8_t result, bool in_isr)
Definition: dcd_pic32mz.c:296
ep0_stage_t
Definition: dcd_pic32mz.c:45
@ EP0_STAGE_NONE
Definition: dcd_pic32mz.c:46
@ EP0_STAGE_DATA_IN_SENT
Definition: dcd_pic32mz.c:52
@ EP0_STAGE_DATA_OUT_COMPLETE
Definition: dcd_pic32mz.c:54
@ EP0_STAGE_ADDRESS_CHANGE
Definition: dcd_pic32mz.c:56
@ EP0_STAGE_SETUP_OUT_DATA
Definition: dcd_pic32mz.c:49
@ EP0_STAGE_STATUS_IN
Definition: dcd_pic32mz.c:55
@ EP0_STAGE_SETUP_OUT_NO_DATA
Definition: dcd_pic32mz.c:48
@ EP0_STAGE_DATA_IN
Definition: dcd_pic32mz.c:50
@ EP0_STAGE_DATA_IN_LAST_PACKET_FILLED
Definition: dcd_pic32mz.c:51
@ EP0_STAGE_DATA_OUT
Definition: dcd_pic32mz.c:53
@ EP0_STAGE_SETUP_IN_DATA
Definition: dcd_pic32mz.c:47
static void epn_handle_tx_int(uint8_t epnum)
Definition: dcd_pic32mz.c:582
void dcd_int_handler(uint8_t rhport)
Definition: dcd_pic32mz.c:700
void dcd_disconnect(uint8_t rhport)
Definition: dcd_pic32mz.c:183
static bool ep0_xfer(xfer_ctl_t *xfer, int dir)
Definition: dcd_pic32mz.c:362
static struct @176 _dcd
xfer_ctl_t xfer_status[EP_MAX][2]
Definition: dcd_pic32mz.c:82
void dcd_edpt_close_all(uint8_t rhport)
Definition: dcd_pic32mz.c:435
static TU_ATTR_ALWAYS_INLINE bool is_in_isr(void)
Definition: dcd_pic32mz.c:198
ep0_stage_t ep0_stage
Definition: dcd_pic32mz.c:79
void dcd_int_disable(uint8_t rhport)
Definition: dcd_pic32mz.c:142
static void epn_tx_configure(uint8_t endpoint, uint16_t endpointSize, uint16_t fifoAddress, uint8_t fifoSize, uint32_t transferType)
Definition: dcd_pic32mz.c:235
void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr)
Definition: dcd_pic32mz.c:504
static void ep0_handle_rx(void)
Definition: dcd_pic32mz.c:533
static void ep0_fill_tx(xfer_ctl_t *xfer_in)
Definition: dcd_pic32mz.c:301
void dcd_connect(uint8_t rhport)
Definition: dcd_pic32mz.c:175
bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const *desc_edpt)
Definition: dcd_pic32mz.c:406
bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_t total_bytes)
Definition: dcd_pic32mz.c:453
static void epn_fill_tx(xfer_ctl_t *xfer_in, uint8_t epnum)
Definition: dcd_pic32mz.c:351
static void epn_handle_rx_int(uint8_t epnum)
Definition: dcd_pic32mz.c:554
uint16_t fifo_addr_top
Definition: dcd_pic32mz.c:77
static tusb_desc_endpoint_t const ep0OUT_desc
Definition: dcd_pic32mz.c:86
static void tx_fifo_write(uint8_t endpoint, uint8_t const *buffer, size_t count)
Definition: dcd_pic32mz.c:265
static tusb_desc_endpoint_t const ep0IN_desc
Definition: dcd_pic32mz.c:97
void dcd_set_address(uint8_t rhport, uint8_t dev_addr)
Definition: dcd_pic32mz.c:149
bool dcd_init(uint8_t rhport, const tusb_rhport_init_t *rh_init)
Definition: dcd_pic32mz.c:123
static void epn_rx_configure(uint8_t endpoint, uint16_t endpointSize, uint16_t fifoAddress, uint8_t fifoSize, uint32_t transferType)
Definition: dcd_pic32mz.c:203
void dcd_int_enable(uint8_t rhport)
Definition: dcd_pic32mz.c:135
void dcd_remote_wakeup(uint8_t rhport)
Definition: dcd_pic32mz.c:160
void dcd_sof_enable(uint8_t rhport, bool en)
Definition: dcd_pic32mz.c:190
static TU_ATTR_ALWAYS_INLINE unsigned __builtin_ctz(unsigned int value)
Definition: dcd_rusb2.c:923
uint8_t const * buffer
Definition: midi_device.h:100
TU_ATTR_WEAK void osal_task_delay(uint32_t msec)
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 bLength
Size of this descriptor in bytes: 9.
Definition: audio.h:656
uint8_t bEndpointAddress
Definition: video.h:306
uint16_t last_packet_size
Definition: dcd_da146xx.c:220
uint16_t transferred
Definition: dcd_da146xx.c:215
uint16_t total_len
Definition: dcd_da146xx.c:213
uint16_t max_packet_size
Definition: dcd_da146xx.c:216
uint16_t fifo_size
Definition: dcd_pic32mz.c:66
uint8_t * buffer
Definition: dcd_da146xx.c:211
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
@ TUSB_DIR_IN
Definition: tusb_types.h:67
@ TUSB_DIR_OUT
Definition: tusb_types.h:66
@ TUSB_SPEED_FULL
Definition: tusb_types.h:50
@ TUSB_SPEED_HIGH
Definition: tusb_types.h:52
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
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
struct TU_ATTR_PACKED tusb_desc_endpoint_t
USB Endpoint Descriptor.
@ TUSB_DESC_ENDPOINT
Definition: tusb_types.h:97
CFG_TUH_MEM_ALIGN tusb_control_request_t request
Definition: usbh.c:259
volatile uint8_t stage
Definition: usbh.c:265