Open FFBoard
Open source force feedback firmware
dcd_da146xx.c
Go to the documentation of this file.
1/*
2 * The MIT License (MIT)
3 *
4 * Copyright (c) 2020 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_DA1469X
30
31#include "mcu/mcu.h"
32
33#include "device/dcd.h"
34
35/*------------------------------------------------------------------*/
36/* MACRO TYPEDEF CONSTANT ENUM
37 *------------------------------------------------------------------*/
38
39// Since TinyUSB doesn't use SOF for now, and this interrupt too often (1ms interval)
40// We disable SOF for now until needed later on
41#define USE_SOF 0
42
43// Size of RX or TX FIFO.
44#define FIFO_SIZE 64
45
46#ifndef TU_DA1469X_FIFO_READ_THRESHOLD
47// RX FIFO is 64 bytes. When endpoint size is greater then 64, FIFO warning interrupt
48// is enabled to allow read incoming data during frame reception.
49// It is possible to stay in interrupt reading whole packet at once, but it may be
50// more efficient for MCU to read as much data as possible and when FIFO is hardly
51// filled exit interrupt handler waiting for next FIFO warning level interrupt
52// or packet end.
53// When running at 96MHz code that reads FIFO based on number of bytes stored in
54// USB_RXSx_REG.USB_RXCOUNT takes enough time to fill FIFO with two additional bytes.
55// Settings this threshold above this allows to leave interrupt handler and wait
56// for more bytes to before next ISR. This allows reduce overall ISR time to 1/3
57// of time that would be needed if ISR read as fast as possible.
58#define TU_DA1469X_FIFO_READ_THRESHOLD 4
59#endif
60
61#define EP_MAX 4
62
63// Node functional states
64#define NFSR_NODE_RESET 0
65#define NFSR_NODE_RESUME 1
66#define NFSR_NODE_OPERATIONAL 2
67#define NFSR_NODE_SUSPEND 3
68// Those two following states are added to allow going out of sleep mode
69// using frame interrupt. On remove wakeup RESUME state must be kept for
70// at least 1ms. It is accomplished by using FRAME interrupt that goes
71// through those two fake states before entering OPERATIONAL state.
72#define NFSR_NODE_WAKING (0x10 | (NFSR_NODE_RESUME))
73#define NFSR_NODE_WAKING2 (0x20 | (NFSR_NODE_RESUME))
74
75static TU_ATTR_ALIGNED(4) uint8_t _setup_packet[8];
76
77typedef struct
78{
79 union
80 {
81 __IOM uint32_t epc_in;
82 __IOM uint32_t USB_EPC0_REG;
83 __IOM uint32_t USB_EPC1_REG;
84 __IOM uint32_t USB_EPC3_REG;
85 __IOM uint32_t USB_EPC5_REG;
86 };
87 union
88 {
89 __IOM uint32_t txd;
90 __IOM uint32_t USB_TXD0_REG;
91 __IOM uint32_t USB_TXD1_REG;
92 __IOM uint32_t USB_TXD2_REG;
93 __IOM uint32_t USB_TXD3_REG;
94 };
95 union
96 {
97 __IOM uint32_t txs;
98 __IOM uint32_t USB_TXS0_REG;
99 __IOM uint32_t USB_TXS1_REG;
100 __IOM uint32_t USB_TXS2_REG;
101 __IOM uint32_t USB_TXS3_REG;
102 };
103 union
104 {
105 __IOM uint32_t txc;
106 __IOM uint32_t USB_TXC0_REG;
107 __IOM uint32_t USB_TXC1_REG;
108 __IOM uint32_t USB_TXC2_REG;
109 __IOM uint32_t USB_TXC3_REG;
110 };
111 union
112 {
113 __IOM uint32_t epc_out;
114 __IOM uint32_t USB_EP0_NAK_REG;
115 __IOM uint32_t USB_EPC2_REG;
116 __IOM uint32_t USB_EPC4_REG;
117 __IOM uint32_t USB_EPC6_REG;
118 };
119 union
120 {
121 __IOM uint32_t rxd;
122 __IOM uint32_t USB_RXD0_REG;
123 __IOM uint32_t USB_RXD1_REG;
124 __IOM uint32_t USB_RXD2_REG;
125 __IOM uint32_t USB_RXD3_REG;
126 };
127 union
128 {
129 __IOM uint32_t rxs;
130 __IOM uint32_t USB_RXS0_REG;
131 __IOM uint32_t USB_RXS1_REG;
132 __IOM uint32_t USB_RXS2_REG;
133 __IOM uint32_t USB_RXS3_REG;
134 };
135 union
136 {
137 __IOM uint32_t rxc;
138 __IOM uint32_t USB_RXC0_REG;
139 __IOM uint32_t USB_RXC1_REG;
140 __IOM uint32_t USB_RXC2_REG;
141 __IOM uint32_t USB_RXC3_REG;
142 };
143} volatile EPx_REGS;
144
145#define EP_REGS(first_ep_reg) (EPx_REGS*)(&USB->first_ep_reg)
146
147// DMA channel pair to use, channel 6 will be used for RX channel 7 for TX direction.
148#ifndef TU_DA146XX_DMA_RX_CHANNEL
149#define TU_DA146XX_DMA_RX_CHANNEL 6
150#endif
151#define DA146XX_DMA_USB_MUX (0x6 << (TU_DA146XX_DMA_RX_CHANNEL * 2))
152#define DA146XX_DMA_USB_MUX_MASK (0xF << (TU_DA146XX_DMA_RX_CHANNEL * 2))
153
154typedef struct
155{
156 __IOM uint32_t DMAx_A_START_REG;
157 __IOM uint32_t DMAx_B_START_REG;
158 __IOM uint32_t DMAx_INT_REG;
159 __IOM uint32_t DMAx_LEN_REG;
160 __IOM uint32_t DMAx_CTRL_REG;
161 __IOM uint32_t DMAx_IDX_REG;
162 __IM uint32_t RESERVED[2]; // Extend structure size for array like usage, registers for each channel are 0x20 bytes apart.
164
165#define DMA_CHANNEL_REGS(n) ((da146xx_dma_channel_t *)(DMA) + n)
166#define RX_DMA_REGS DMA_CHANNEL_REGS(TU_DA146XX_DMA_RX_CHANNEL)
167#define TX_DMA_REGS DMA_CHANNEL_REGS((TU_DA146XX_DMA_RX_CHANNEL) + 1)
168
169#define RX_DMA_START ((1 << DMA_DMA0_CTRL_REG_DMA_ON_Pos) |\
170 (0 << DMA_DMA0_CTRL_REG_BW_Pos) | \
171 (1 << DMA_DMA0_CTRL_REG_DREQ_MODE_Pos) | \
172 (1 << DMA_DMA0_CTRL_REG_BINC_Pos) | \
173 (0 << DMA_DMA0_CTRL_REG_AINC_Pos) | \
174 (0 << DMA_DMA0_CTRL_REG_CIRCULAR_Pos) | \
175 (2 << DMA_DMA0_CTRL_REG_DMA_PRIO_Pos) | \
176 (0 << DMA_DMA0_CTRL_REG_DMA_IDLE_Pos) | \
177 (0 << DMA_DMA0_CTRL_REG_DMA_INIT_Pos) | \
178 (0 << DMA_DMA0_CTRL_REG_REQ_SENSE_Pos) | \
179 (0 << DMA_DMA0_CTRL_REG_BURST_MODE_Pos) | \
180 (0 << DMA_DMA0_CTRL_REG_BUS_ERROR_DETECT_Pos))
181
182#define TX_DMA_START ((1 << DMA_DMA0_CTRL_REG_DMA_ON_Pos) |\
183 (0 << DMA_DMA0_CTRL_REG_BW_Pos) | \
184 (1 << DMA_DMA0_CTRL_REG_DREQ_MODE_Pos) | \
185 (0 << DMA_DMA0_CTRL_REG_BINC_Pos) | \
186 (1 << DMA_DMA0_CTRL_REG_AINC_Pos) | \
187 (0 << DMA_DMA0_CTRL_REG_CIRCULAR_Pos) | \
188 (2 << DMA_DMA0_CTRL_REG_DMA_PRIO_Pos) | \
189 (0 << DMA_DMA0_CTRL_REG_DMA_IDLE_Pos) | \
190 (0 << DMA_DMA0_CTRL_REG_DMA_INIT_Pos) | \
191 (1 << DMA_DMA0_CTRL_REG_REQ_SENSE_Pos) | \
192 (0 << DMA_DMA0_CTRL_REG_BURST_MODE_Pos) | \
193 (0 << DMA_DMA0_CTRL_REG_BUS_ERROR_DETECT_Pos))
194
195// Dialog register fields and bit mask are very long. Filed masks repeat register names.
196// Those convenience macros are a way to reduce complexity of register modification lines.
197#define GET_BIT(val, field) (val & field ## _Msk) >> field ## _Pos
198#define REG_GET_BIT(reg, field) (USB->reg & USB_ ## reg ## _ ## field ## _Msk)
199#define REG_SET_BIT(reg, field) USB->reg |= USB_ ## reg ## _ ## field ## _Msk
200#define REG_CLR_BIT(reg, field) USB->reg &= ~USB_ ## reg ## _ ## field ## _Msk
201#define REG_SET_VAL(reg, field, val) USB->reg = (USB->reg & ~USB_ ## reg ## _ ## field ## _Msk) | (val << USB_ ## reg ## _ ## field ## _Pos)
202
203static EPx_REGS * const ep_regs[EP_MAX] = {
204 EP_REGS(USB_EPC0_REG),
205 EP_REGS(USB_EPC1_REG),
206 EP_REGS(USB_EPC3_REG),
207 EP_REGS(USB_EPC5_REG),
208};
209
210typedef struct {
211 uint8_t * buffer;
212 // Total length of current transfer
213 uint16_t total_len;
214 // Bytes transferred so far
215 uint16_t transferred;
217 // Packet size sent or received so far. It is used to modify transferred field
218 // after ACK is received or when filling ISO endpoint with size larger then
219 // FIFO size.
221 uint8_t ep_addr;
222 // DATA0/1 toggle bit 1 DATA1 is expected or transmitted
223 uint8_t data1 : 1;
224 // Endpoint is stalled
225 uint8_t stall : 1;
226 // ISO endpoint
227 uint8_t iso : 1;
228} xfer_ctl_t;
229
230static struct
231{
234 uint8_t nfsr;
236 // Endpoints that use DMA, one for each direction
237 uint8_t dma_ep[2];
238} _dcd =
239{
240 .vbus_present = false,
241 .init_called = false,
243
244// Converts xfer pointer to epnum (0,1,2,3) regardless of xfer direction
245#define XFER_EPNUM(xfer) ((xfer - &_dcd.xfer_status[0][0]) >> 1)
246// Converts xfer pointer to EPx_REGS pointer (returns same pointer for IN and OUT with same endpoint number)
247#define XFER_REGS(xfer) ep_regs[XFER_EPNUM(xfer)]
248// Converts epnum (0,1,2,3) to EPx_REGS pointer
249#define EPNUM_REGS(epnum) ep_regs[epnum]
250
251// Two endpoint 0 descriptor definition for unified dcd_edpt_open()
253{
254 .bLength = sizeof(tusb_desc_endpoint_t),
255 .bDescriptorType = TUSB_DESC_ENDPOINT,
256
257 .bEndpointAddress = 0x00,
258 .bmAttributes = { .xfer = TUSB_XFER_CONTROL },
259 .wMaxPacketSize = CFG_TUD_ENDPOINT0_SIZE,
260 .bInterval = 0
261};
262
264{
265 .bLength = sizeof(tusb_desc_endpoint_t),
266 .bDescriptorType = TUSB_DESC_ENDPOINT,
267
268 .bEndpointAddress = 0x80,
269 .bmAttributes = { .xfer = TUSB_XFER_CONTROL },
270 .wMaxPacketSize = CFG_TUD_ENDPOINT0_SIZE,
271 .bInterval = 0
272};
273
274#define XFER_CTL_BASE(_ep, _dir) &_dcd.xfer_status[_ep][_dir]
275
276static void set_nfsr(uint8_t val)
277{
278 _dcd.nfsr = val;
279 // Write only lower 2 bits to register, higher bits are used
280 // to count down till OPERATIONAL state can be entered when
281 // remote wakeup activated.
282 USB->USB_NFSR_REG = val & 3;
283}
284
286{
287 int left_to_send;
288 uint8_t const *src;
289 uint8_t const epnum = tu_edpt_number(xfer->ep_addr);
290 EPx_REGS *regs = EPNUM_REGS(epnum);
291
292 src = &xfer->buffer[xfer->transferred];
293 left_to_send = xfer->total_len - xfer->transferred;
294 if (left_to_send > xfer->max_packet_size - xfer->last_packet_size)
295 {
296 left_to_send = xfer->max_packet_size - xfer->last_packet_size;
297 }
298
299 // Loop checks TCOUNT all the time since this value is saturated to 31
300 // and can't be read just once before.
301 while ((regs->txs & USB_USB_TXS1_REG_USB_TCOUNT_Msk) > 0 && left_to_send > 0)
302 {
303 regs->txd = *src++;
304 xfer->last_packet_size++;
305 left_to_send--;
306 }
307 if (epnum != 0)
308 {
309 if (left_to_send > 0)
310 {
311 // Max packet size is set to value greater then FIFO. Enable fifo level warning
312 // to handle larger packets.
313 regs->txc |= (3 << USB_USB_TXC1_REG_USB_TFWL_Pos);
314 USB->USB_FWMSK_REG |= 1 << (epnum - 1 + USB_USB_FWMSK_REG_USB_M_TXWARN31_Pos);
315 }
316 else
317 {
318 regs->txc &= ~USB_USB_TXC1_REG_USB_TFWL_Msk;
319 USB->USB_FWMSK_REG &= ~(1 << (epnum - 1 + USB_USB_FWMSK_REG_USB_M_TXWARN31_Pos));
320 // Whole packet already in fifo, no need to refill it later. Mark last.
321 regs->txc |= USB_USB_TXC1_REG_USB_LAST_Msk;
322 }
323 }
324}
325
326static bool try_allocate_dma(uint8_t epnum, uint8_t dir)
327{
328 // TODO: Disable interrupts while checking
329 if (_dcd.dma_ep[dir] == 0)
330 {
331 _dcd.dma_ep[dir] = epnum;
332 if (dir == TUSB_DIR_OUT)
333 USB->USB_DMA_CTRL_REG = (USB->USB_DMA_CTRL_REG & ~USB_USB_DMA_CTRL_REG_USB_DMA_RX_Msk) |
334 ((epnum - 1) << USB_USB_DMA_CTRL_REG_USB_DMA_RX_Pos);
335 else
336 USB->USB_DMA_CTRL_REG = (USB->USB_DMA_CTRL_REG & ~USB_USB_DMA_CTRL_REG_USB_DMA_TX_Msk) |
337 ((epnum - 1) << USB_USB_DMA_CTRL_REG_USB_DMA_TX_Pos);
338 USB->USB_DMA_CTRL_REG |= USB_USB_DMA_CTRL_REG_USB_DMA_EN_Msk;
339 }
340 return _dcd.dma_ep[dir] == epnum;
341}
342
343static void start_rx_dma(volatile void *src, void *dst, uint16_t size)
344{
345 // Setup SRC and DST registers
346 RX_DMA_REGS->DMAx_A_START_REG = (uint32_t)src;
347 RX_DMA_REGS->DMAx_B_START_REG = (uint32_t)dst;
348 // Don't need DMA interrupt, read end is determined by RX_LAST or RX_ERR events.
349 RX_DMA_REGS->DMAx_INT_REG = size - 1;
350 RX_DMA_REGS->DMAx_LEN_REG = size - 1;
351 RX_DMA_REGS->DMAx_CTRL_REG = RX_DMA_START;
352}
353
355{
356 uint8_t const epnum = tu_edpt_number(xfer->ep_addr);
357 uint16_t remaining = xfer->total_len - xfer->transferred;
358 uint16_t size = tu_min16(remaining, xfer->max_packet_size);
359 EPx_REGS *regs = XFER_REGS(xfer);
360
361 xfer->last_packet_size = 0;
362 if (xfer->max_packet_size > FIFO_SIZE && remaining > FIFO_SIZE)
363 {
364 if (try_allocate_dma(epnum, TUSB_DIR_OUT))
365 {
366 start_rx_dma(&regs->rxd, xfer->buffer + xfer->transferred, size);
367 }
368 else
369 {
370 // Other endpoint is using DMA in that direction, fall back to interrupts.
371 // For endpoint size greater than FIFO size enable FIFO level warning interrupt
372 // when FIFO has less than 17 bytes free.
373 regs->rxc |= USB_USB_RXC1_REG_USB_RFWL_Msk;
374 USB->USB_FWMSK_REG |= 1 << (epnum - 1 + USB_USB_FWMSK_REG_USB_M_RXWARN31_Pos);
375 }
376 }
377 else if (epnum != 0)
378 {
379 // If max_packet_size would fit in FIFO no need for FIFO level warning interrupt.
380 regs->rxc &= ~USB_USB_RXC1_REG_USB_RFWL_Msk;
381 USB->USB_FWMSK_REG &= ~(1 << (epnum - 1 + USB_USB_FWMSK_REG_USB_M_RXWARN31_Pos));
382 }
383 regs->rxc |= USB_USB_RXC1_REG_USB_RX_EN_Msk;
384}
385
386static void start_tx_dma(void *src, volatile void *dst, uint16_t size)
387{
388 // Setup SRC and DST registers
389 TX_DMA_REGS->DMAx_A_START_REG = (uint32_t)src;
390 TX_DMA_REGS->DMAx_B_START_REG = (uint32_t)dst;
391 // Interrupt not needed
392 TX_DMA_REGS->DMAx_INT_REG = size;
393 TX_DMA_REGS->DMAx_LEN_REG = size - 1;
394 TX_DMA_REGS->DMAx_CTRL_REG = TX_DMA_START;
395}
396
398{
399 uint8_t const epnum = tu_edpt_number(xfer->ep_addr);
400 uint16_t remaining = xfer->total_len - xfer->transferred;
401 uint16_t size = tu_min16(remaining, xfer->max_packet_size);
402 EPx_REGS *regs = EPNUM_REGS(epnum);
403
404 xfer->last_packet_size = 0;
405
406 regs->txc = USB_USB_TXC1_REG_USB_FLUSH_Msk;
407 regs->txc = USB_USB_TXC1_REG_USB_IGN_ISOMSK_Msk;
408 if (xfer->data1) regs->txc |= USB_USB_TXC1_REG_USB_TOGGLE_TX_Msk;
409
410 if (xfer->max_packet_size > FIFO_SIZE && remaining > FIFO_SIZE && try_allocate_dma(epnum, TUSB_DIR_IN))
411 {
412 // Whole packet will be put in FIFO by DMA. Set LAST bit before start.
413 start_tx_dma(xfer->buffer + xfer->transferred, &regs->txd, size);
414 regs->txc |= USB_USB_TXC1_REG_USB_LAST_Msk;
415 }
416 else
417 {
419 }
420 regs->txc |= USB_USB_TXC1_REG_USB_TX_EN_Msk;
421}
422
423static uint16_t read_rx_fifo(xfer_ctl_t *xfer, uint16_t bytes_in_fifo)
424{
425 EPx_REGS *regs = XFER_REGS(xfer);
426 uint16_t remaining = xfer->total_len - xfer->transferred - xfer->last_packet_size;
427 uint16_t receive_this_time = bytes_in_fifo;
428
429 if (remaining < bytes_in_fifo) receive_this_time = remaining;
430
431 uint8_t *buf = xfer->buffer + xfer->transferred + xfer->last_packet_size;
432
433 for (int i = 0; i < receive_this_time; ++i) buf[i] = regs->rxd;
434
435 xfer->last_packet_size += receive_this_time;
436
437 return bytes_in_fifo - receive_this_time;
438}
439
440static void handle_ep0_rx(void)
441{
442 int fifo_bytes;
443 uint32_t rxs0 = USB->USB_RXS0_REG;
444
445 xfer_ctl_t *xfer = XFER_CTL_BASE(0, TUSB_DIR_OUT);
446
447 fifo_bytes = GET_BIT(rxs0, USB_USB_RXS0_REG_USB_RCOUNT);
448 if (rxs0 & USB_USB_RXS0_REG_USB_SETUP_Msk)
449 {
450 xfer_ctl_t *xfer_in = XFER_CTL_BASE(0, TUSB_DIR_IN);
451 // Setup packet is in
452 for (int i = 0; i < fifo_bytes; ++i) _setup_packet[i] = USB->USB_RXD0_REG;
453
454 xfer->stall = 0;
455 xfer->data1 = 1;
456 xfer_in->stall = 0;
457 xfer_in->data1 = 1;
458 REG_SET_BIT(USB_TXC0_REG, USB_TOGGLE_TX0);
459 REG_CLR_BIT(USB_EPC0_REG, USB_STALL);
461 }
462 else
463 {
464 if (GET_BIT(rxs0, USB_USB_RXS0_REG_USB_TOGGLE_RX0) != xfer->data1)
465 {
466 // Toggle bit does not match discard packet
467 REG_SET_BIT(USB_RXC0_REG, USB_FLUSH);
468 xfer->last_packet_size = 0;
469 }
470 else
471 {
472 read_rx_fifo(xfer, fifo_bytes);
473 if (rxs0 & USB_USB_RXS0_REG_USB_RX_LAST_Msk)
474 {
475 xfer->transferred += xfer->last_packet_size;
476 xfer->data1 ^= 1;
477
478 if (xfer->total_len == xfer->transferred || xfer->last_packet_size < xfer->max_packet_size)
479 {
480 dcd_event_xfer_complete(0, 0, xfer->transferred, XFER_RESULT_SUCCESS, true);
481 }
482 else
483 {
484 // Re-enable reception
485 REG_SET_BIT(USB_RXC0_REG, USB_RX_EN);
486 }
487 xfer->last_packet_size = 0;
488 }
489 }
490 }
491}
492
493static void handle_ep0_tx(void)
494{
495 uint32_t txs0;
496 xfer_ctl_t *xfer = XFER_CTL_BASE(0, TUSB_DIR_IN);
497 EPx_REGS *regs = XFER_REGS(xfer);
498
499 txs0 = regs->USB_TXS0_REG;
500
501 if (GET_BIT(txs0, USB_USB_TXS0_REG_USB_TX_DONE))
502 {
503 // ACK received
504 if (GET_BIT(txs0, USB_USB_TXS0_REG_USB_ACK_STAT))
505 {
506 xfer->transferred += xfer->last_packet_size;
507 xfer->last_packet_size = 0;
508 xfer->data1 ^= 1;
509 REG_SET_VAL(USB_TXC0_REG, USB_TOGGLE_TX0, xfer->data1);
510 if (xfer->transferred == xfer->total_len)
511 {
513 return;
514 }
515 }
516 else
517 {
518 // Start from the beginning
519 xfer->last_packet_size = 0;
520 }
522 }
523}
524
525static void handle_epx_rx_ev(uint8_t ep)
526{
527 uint32_t rxs;
528 int fifo_bytes;
529 xfer_ctl_t *xfer = XFER_CTL_BASE(ep, TUSB_DIR_OUT);
530
531 EPx_REGS *regs = EPNUM_REGS(ep);
532
533 do
534 {
535 rxs = regs->rxs;
536
537 if (GET_BIT(rxs, USB_USB_RXS1_REG_USB_RX_ERR))
538 {
539 regs->rxc |= USB_USB_RXC1_REG_USB_FLUSH_Msk;
540 xfer->last_packet_size = 0;
541 if (_dcd.dma_ep[TUSB_DIR_OUT] == ep)
542 {
543 // Stop DMA
544 RX_DMA_REGS->DMAx_CTRL_REG &= ~DMA_DMA0_CTRL_REG_DMA_ON_Msk;
545 // Restart DMA since packet was dropped, all parameters should still work.
546 RX_DMA_REGS->DMAx_CTRL_REG |= DMA_DMA0_CTRL_REG_DMA_ON_Msk;
547 }
548 break;
549 }
550 else
551 {
552 if (_dcd.dma_ep[TUSB_DIR_OUT] == ep)
553 {
554 // Disable DMA and update last_packet_size with what DMA reported.
555 RX_DMA_REGS->DMAx_CTRL_REG &= ~DMA_DMA0_CTRL_REG_DMA_ON_Msk;
556 xfer->last_packet_size = RX_DMA_REGS->DMAx_IDX_REG;
557 // When DMA did not finished (packet was smaller then MPS), DMAx_IDX_REG holds exact number of bytes transmitted.
558 // When DMA finished value in DMAx_IDX_REG is one less then actual number of transmitted bytes.
559 if (xfer->last_packet_size == RX_DMA_REGS->DMAx_LEN_REG) xfer->last_packet_size++;
560 // Release DMA to use by other endpoints.
561 _dcd.dma_ep[TUSB_DIR_OUT] = 0;
562 }
563 fifo_bytes = GET_BIT(rxs, USB_USB_RXS1_REG_USB_RXCOUNT);
564 // FIFO maybe empty if DMA read it before or it's final iteration and function already read all that was to read.
565 if (fifo_bytes > 0)
566 {
567 fifo_bytes = read_rx_fifo(xfer, fifo_bytes);
568 }
569 if (GET_BIT(rxs, USB_USB_RXS1_REG_USB_RX_LAST))
570 {
571 if (!xfer->iso && GET_BIT(rxs, USB_USB_RXS1_REG_USB_TOGGLE_RX) != xfer->data1)
572 {
573 // Toggle bit does not match discard packet
574 regs->rxc |= USB_USB_RXC1_REG_USB_FLUSH_Msk;
575 }
576 else
577 {
578 xfer->data1 ^= 1;
579 xfer->transferred += xfer->last_packet_size;
580 if (xfer->total_len == xfer->transferred || xfer->last_packet_size < xfer->max_packet_size || xfer->iso)
581 {
582 if (fifo_bytes)
583 {
584 // There are extra bytes in the FIFO just flush them
585 regs->rxc |= USB_USB_RXC1_REG_USB_FLUSH_Msk;
586 fifo_bytes = 0;
587 }
588
589 dcd_event_xfer_complete(0, xfer->ep_addr, xfer->transferred, XFER_RESULT_SUCCESS, true);
590 }
591 else
592 {
593 // Re-enable reception
595 }
596 }
597 xfer->last_packet_size = 0;
598 }
599 }
600 } while (fifo_bytes > TU_DA1469X_FIFO_READ_THRESHOLD);
601}
602
603static void handle_rx_ev(void)
604{
605 if (USB->USB_RXEV_REG & 1)
607 if (USB->USB_RXEV_REG & 2)
609 if (USB->USB_RXEV_REG & 4)
611}
612
614{
615 uint8_t const epnum = tu_edpt_number(xfer->ep_addr);
616 uint32_t txs;
617 EPx_REGS *regs = EPNUM_REGS(epnum);
618
619 txs = regs->txs;
620
621 if (GET_BIT(txs, USB_USB_TXS1_REG_USB_TX_DONE))
622 {
623 if (_dcd.dma_ep[TUSB_DIR_IN] == epnum)
624 {
625 // Disable DMA and update last_packet_size with what DMA reported.
626 TX_DMA_REGS->DMAx_CTRL_REG &= ~DMA_DMA1_CTRL_REG_DMA_ON_Msk;
627 xfer->last_packet_size = TX_DMA_REGS->DMAx_IDX_REG + 1;
628 // Release DMA to used by other endpoints.
629 _dcd.dma_ep[TUSB_DIR_IN] = 0;
630 }
631 if (GET_BIT(txs, USB_USB_TXS1_REG_USB_ACK_STAT))
632 {
633 // ACK received, update transfer state and DATA0/1 bit
634 xfer->transferred += xfer->last_packet_size;
635 xfer->last_packet_size = 0;
636 xfer->data1 ^= 1;
637
638 if (xfer->transferred == xfer->total_len)
639 {
641 return;
642 }
643 }
644 else if (regs->epc_in & USB_USB_EPC1_REG_USB_STALL_Msk)
645 {
646 // TX_DONE also indicates that STALL packet was just sent, there is
647 // no point to put anything into transmit FIFO. It could result in
648 // empty packet being scheduled.
649 return;
650 }
651 }
652 if (txs & USB_USB_TXS1_REG_USB_TX_URUN_Msk)
653 {
654 TU_LOG1("EP %d FIFO underrun\r\n", epnum);
655 }
656 // Start next or repeated packet.
658}
659
660static void handle_tx_ev(void)
661{
662 if (USB->USB_TXEV_REG & 1)
663 handle_epx_tx_ev(XFER_CTL_BASE(1, TUSB_DIR_IN));
664 if (USB->USB_TXEV_REG & 2)
665 handle_epx_tx_ev(XFER_CTL_BASE(2, TUSB_DIR_IN));
666 if (USB->USB_TXEV_REG & 4)
667 handle_epx_tx_ev(XFER_CTL_BASE(3, TUSB_DIR_IN));
668}
669
670static uint32_t check_reset_end(uint32_t alt_ev)
671{
672 if (_dcd.nfsr == NFSR_NODE_RESET)
673 {
674 if (GET_BIT(alt_ev, USB_USB_ALTEV_REG_USB_RESET))
675 {
676 // Could be still in reset, but since USB_M_RESET is disabled it can
677 // be also old reset state that was not cleared yet.
678 // If (after reading USB_ALTEV_REG register again) bit is cleared
679 // reset state just ended.
680 // Keep non-reset bits combined from two previous ALTEV read and
681 // one from the next line.
682 alt_ev = (alt_ev & ~USB_USB_ALTEV_REG_USB_RESET_Msk) | USB->USB_ALTEV_REG;
683 }
684 if (GET_BIT(alt_ev, USB_USB_ALTEV_REG_USB_RESET) == 0)
685 {
686 USB->USB_ALTMSK_REG = USB_USB_ALTMSK_REG_USB_M_RESET_Msk |
687 USB_USB_ALTEV_REG_USB_SD3_Msk;
688 set_nfsr(NFSR_NODE_OPERATIONAL);
691 }
692 }
693 return alt_ev;
694}
695
696static void handle_bus_reset(void)
697{
698 uint32_t alt_ev;
699
700 USB->USB_NFSR_REG = 0;
701 USB->USB_FAR_REG = 0x80;
702 USB->USB_ALTMSK_REG = 0;
703 USB->USB_NFSR_REG = NFSR_NODE_RESET;
704 USB->USB_TXMSK_REG = 0;
705 USB->USB_RXMSK_REG = 0;
706 set_nfsr(NFSR_NODE_RESET);
707
709 USB->USB_DMA_CTRL_REG = 0;
710
711 USB->USB_MAMSK_REG = USB_USB_MAMSK_REG_USB_M_INTR_Msk |
712 USB_USB_MAMSK_REG_USB_M_FRAME_Msk |
713 USB_USB_MAMSK_REG_USB_M_WARN_Msk |
714 USB_USB_MAMSK_REG_USB_M_ALT_Msk;
715 USB->USB_ALTMSK_REG = USB_USB_ALTMSK_REG_USB_M_RESUME_Msk;
716 alt_ev = USB->USB_ALTEV_REG;
717 check_reset_end(alt_ev);
718}
719
720static void handle_alt_ev(void)
721{
722 uint32_t alt_ev = USB->USB_ALTEV_REG;
723
724 alt_ev = check_reset_end(alt_ev);
725 if (GET_BIT(alt_ev, USB_USB_ALTEV_REG_USB_RESET) && _dcd.nfsr != NFSR_NODE_RESET)
726 {
728 }
729 else if (GET_BIT(alt_ev, USB_USB_ALTEV_REG_USB_RESUME))
730 {
731 if (USB->USB_NFSR_REG == NFSR_NODE_SUSPEND)
732 {
733 set_nfsr(NFSR_NODE_OPERATIONAL);
734 USB->USB_ALTMSK_REG = USB_USB_ALTMSK_REG_USB_M_RESET_Msk |
735 USB_USB_ALTMSK_REG_USB_M_SD3_Msk;
736 // Re-enable reception of endpoint with pending transfer
737 for (int epnum = 1; epnum <= 3; ++epnum)
738 {
739 xfer_ctl_t * xfer = XFER_CTL_BASE(epnum, TUSB_DIR_OUT);
740 if (xfer->total_len > xfer->transferred)
741 {
743 }
744 }
745 dcd_event_bus_signal(0, DCD_EVENT_RESUME, true);
746 }
747 }
748 else if (GET_BIT(alt_ev, USB_USB_ALTEV_REG_USB_SD3))
749 {
750 set_nfsr(NFSR_NODE_SUSPEND);
751 USB->USB_ALTMSK_REG = USB_USB_ALTMSK_REG_USB_M_RESET_Msk |
752 USB_USB_ALTMSK_REG_USB_M_RESUME_Msk;
753 dcd_event_bus_signal(0, DCD_EVENT_SUSPEND, true);
754 }
755}
756
757static void handle_epx_tx_warn_ev(uint8_t ep)
758{
759 fill_tx_fifo(XFER_CTL_BASE(ep, TUSB_DIR_IN));
760}
761
762static void handle_fifo_warning(void)
763{
764 uint32_t fifo_warning = USB->USB_FWEV_REG;
765
766 if (fifo_warning & 0x01)
768 if (fifo_warning & 0x02)
770 if (fifo_warning & 0x04)
772 if (fifo_warning & 0x10)
774 if (fifo_warning & 0x20)
776 if (fifo_warning & 0x40)
778}
779
780static void handle_ep0_nak(void)
781{
782 uint32_t ep0_nak = USB->USB_EP0_NAK_REG;
783
784 if (REG_GET_BIT(USB_EPC0_REG, USB_STALL))
785 {
786 if (GET_BIT(ep0_nak, USB_USB_EP0_NAK_REG_USB_EP0_INNAK))
787 {
788 // EP0 is stalled and NAK was sent, it means that RX is enabled
789 // Disable RX for now.
790 REG_CLR_BIT(USB_RXC0_REG, USB_RX_EN);
791 REG_SET_BIT(USB_TXC0_REG, USB_TX_EN);
792 }
793 if (GET_BIT(ep0_nak, USB_USB_EP0_NAK_REG_USB_EP0_OUTNAK))
794 {
795 REG_SET_BIT(USB_RXC0_REG, USB_RX_EN);
796 }
797 }
798 else
799 {
800 REG_CLR_BIT(USB_MAMSK_REG, USB_M_EP0_NAK);
801 }
802}
803
804/*------------------------------------------------------------------*/
805/* Controller API
806 *------------------------------------------------------------------*/
807bool dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) {
808 (void) rhport;
809 (void) rh_init;
810
811 _dcd.init_called = true;
812 if (_dcd.vbus_present) {
813 dcd_connect(rhport);
814 }
815
816 return true;
817}
818
819void dcd_int_enable(uint8_t rhport)
820{
821 (void)rhport;
822
823 NVIC_EnableIRQ(USB_IRQn);
824}
825
826void dcd_int_disable(uint8_t rhport)
827{
828 (void)rhport;
829
830 NVIC_DisableIRQ(USB_IRQn);
831}
832
833void dcd_set_address(uint8_t rhport, uint8_t dev_addr)
834{
835 (void)rhport;
836
837 // Set default address for one ZLP
838 USB->USB_EPC0_REG = USB_USB_EPC0_REG_USB_DEF_Msk;
839 USB->USB_FAR_REG = (dev_addr & USB_USB_FAR_REG_USB_AD_Msk) | USB_USB_FAR_REG_USB_AD_EN_Msk;
840 dcd_edpt_xfer(rhport, tu_edpt_addr(0, TUSB_DIR_IN), NULL, 0);
841}
842
843void dcd_remote_wakeup(uint8_t rhport)
844{
845 (void)rhport;
846 if (_dcd.nfsr == NFSR_NODE_SUSPEND)
847 {
848 // Enter fake state that will use FRAME interrupt to wait before going operational.
849 set_nfsr(NFSR_NODE_WAKING);
850 USB->USB_MAMSK_REG |= USB_USB_MAMSK_REG_USB_M_FRAME_Msk;
851 }
852}
853
854void dcd_connect(uint8_t rhport)
855{
856 (void)rhport;
857
858 if (GET_BIT(USB->USB_MCTRL_REG, USB_USB_MCTRL_REG_USB_NAT) == 0)
859 {
860 USB->USB_MCTRL_REG = USB_USB_MCTRL_REG_USBEN_Msk;
861 USB->USB_NFSR_REG = 0;
862 USB->USB_FAR_REG = 0x80;
863 USB->USB_TXMSK_REG = 0;
864 USB->USB_RXMSK_REG = 0;
865
866 USB->USB_MAMSK_REG = USB_USB_MAMSK_REG_USB_M_INTR_Msk |
867 USB_USB_MAMSK_REG_USB_M_ALT_Msk |
868 USB_USB_MAMSK_REG_USB_M_WARN_Msk;
869 USB->USB_ALTMSK_REG = USB_USB_ALTMSK_REG_USB_M_RESET_Msk |
870 USB_USB_ALTEV_REG_USB_SD3_Msk;
871
872 USB->USB_MCTRL_REG = USB_USB_MCTRL_REG_USBEN_Msk | USB_USB_MCTRL_REG_USB_NAT_Msk;
873
874 // Select chosen DMA to be triggered by USB.
875 DMA->DMA_REQ_MUX_REG = (DMA->DMA_REQ_MUX_REG & ~DA146XX_DMA_USB_MUX_MASK) | DA146XX_DMA_USB_MUX;
876 }
877}
878
879void dcd_disconnect(uint8_t rhport)
880{
881 (void)rhport;
882
883 REG_CLR_BIT(USB_MCTRL_REG, USB_NAT);
884}
885
886void dcd_sof_enable(uint8_t rhport, bool en)
887{
888 (void) rhport;
889 (void) en;
890
891 // TODO implement later
892}
893
894TU_ATTR_ALWAYS_INLINE static inline bool is_in_isr(void)
895{
896 return (SCB->ICSR & SCB_ICSR_VECTACTIVE_Msk) != 0;
897}
898
899void tusb_vbus_changed(bool present)
900{
901 if (present && !_dcd.vbus_present)
902 {
903 _dcd.vbus_present = true;
904 // If power event happened before USB started, delay dcd_connect
905 // until dcd_init is called.
906 if (_dcd.init_called)
907 {
908 dcd_connect(0);
909 }
910 }
911 else if (!present && _dcd.vbus_present)
912 {
913 _dcd.vbus_present = false;
914 USB->USB_MCTRL_REG = 0;
915 dcd_event_bus_signal(0, DCD_EVENT_UNPLUGGED, is_in_isr());
916 }
917}
918
919/*------------------------------------------------------------------*/
920/* DCD Endpoint port
921 *------------------------------------------------------------------*/
922
923bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * desc_edpt)
924{
925 (void)rhport;
926
927 uint8_t const epnum = tu_edpt_number(desc_edpt->bEndpointAddress);
928 uint8_t const dir = tu_edpt_dir(desc_edpt->bEndpointAddress);
929 xfer_ctl_t * xfer = XFER_CTL_BASE(epnum, dir);
930 EPx_REGS *regs = EPNUM_REGS(epnum);
931 uint8_t iso_mask = 0;
932
933 TU_ASSERT(epnum < EP_MAX);
934
935 xfer->max_packet_size = tu_edpt_packet_size(desc_edpt);
936 xfer->ep_addr = desc_edpt->bEndpointAddress;
937 xfer->data1 = 0;
938 xfer->iso = 0;
939
940 if (epnum != 0 && desc_edpt->bmAttributes.xfer == 1)
941 {
942 iso_mask = USB_USB_EPC1_REG_USB_ISO_Msk;
943 xfer->iso = 1;
944 }
945
946 if (epnum == 0)
947 {
948 USB->USB_MAMSK_REG |= USB_USB_MAMSK_REG_USB_M_EP0_RX_Msk |
949 USB_USB_MAMSK_REG_USB_M_EP0_TX_Msk;
950 }
951 else
952 {
953 if (dir == TUSB_DIR_OUT)
954 {
955 regs->epc_out = epnum | USB_USB_EPC1_REG_USB_EP_EN_Msk | iso_mask;
956 USB->USB_RXMSK_REG |= 0x11 << (epnum - 1);
957 REG_SET_BIT(USB_MAMSK_REG, USB_M_RX_EV);
958 }
959 else
960 {
961 regs->epc_in = epnum | USB_USB_EPC1_REG_USB_EP_EN_Msk | iso_mask;
962 USB->USB_TXMSK_REG |= 0x11 << (epnum - 1);
963 REG_SET_BIT(USB_MAMSK_REG, USB_M_TX_EV);
964 }
965 }
966
967 return true;
968}
969
970void dcd_edpt_close_all (uint8_t rhport)
971{
972 (void) rhport;
973
974 for (int epnum = 1; epnum < EP_MAX; ++epnum)
975 {
976 dcd_edpt_close(0, epnum | TUSB_DIR_OUT);
977 dcd_edpt_close(0, epnum | TUSB_DIR_IN);
978 }
979}
980
981void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr)
982{
983 uint8_t const epnum = tu_edpt_number(ep_addr);
984 uint8_t const dir = tu_edpt_dir(ep_addr);
985 EPx_REGS *regs = EPNUM_REGS(epnum);
986 xfer_ctl_t * xfer = XFER_CTL_BASE(epnum, dir);
987
988 (void)rhport;
989
990 TU_ASSERT(epnum < EP_MAX,);
991
992 if (epnum == 0)
993 {
994 USB->USB_MAMSK_REG &= ~(USB_USB_MAMSK_REG_USB_M_EP0_RX_Msk |
995 USB_USB_MAMSK_REG_USB_M_EP0_TX_Msk);
996 }
997 else
998 {
999 if (dir == TUSB_DIR_OUT)
1000 {
1001 regs->rxc = USB_USB_RXC1_REG_USB_FLUSH_Msk;
1002 regs->epc_out = 0;
1003 USB->USB_RXMSK_REG &= ~(0x11 << (epnum - 1));
1004 // Release DMA if needed
1005 if (_dcd.dma_ep[TUSB_DIR_OUT] == epnum)
1006 {
1007 RX_DMA_REGS->DMAx_CTRL_REG &= ~DMA_DMA0_CTRL_REG_DMA_ON_Msk;
1008 _dcd.dma_ep[TUSB_DIR_OUT] = 0;
1009 }
1010 }
1011 else
1012 {
1013 regs->txc = USB_USB_TXC1_REG_USB_FLUSH_Msk;
1014 regs->epc_in = 0;
1015 USB->USB_TXMSK_REG &= ~(0x11 << (epnum - 1));
1016 // Release DMA if needed
1017 if (_dcd.dma_ep[TUSB_DIR_IN] == epnum)
1018 {
1019 TX_DMA_REGS->DMAx_CTRL_REG &= ~DMA_DMA1_CTRL_REG_DMA_ON_Msk;
1020 _dcd.dma_ep[TUSB_DIR_IN] = 0;
1021 }
1022 }
1023 }
1024 tu_memclr(xfer, sizeof(*xfer));
1025}
1026
1027bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes)
1028{
1029 uint8_t const epnum = tu_edpt_number(ep_addr);
1030 uint8_t const dir = tu_edpt_dir(ep_addr);
1031 xfer_ctl_t * xfer = XFER_CTL_BASE(epnum, dir);
1032
1033 (void)rhport;
1034
1035 xfer->buffer = buffer;
1037 xfer->last_packet_size = 0;
1038 xfer->transferred = 0;
1039
1040 if (dir == TUSB_DIR_OUT)
1041 {
1043 }
1044 else // IN
1045 {
1047 }
1048
1049 return true;
1050}
1051
1052void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr)
1053{
1054 uint8_t const epnum = tu_edpt_number(ep_addr);
1055 uint8_t const dir = tu_edpt_dir(ep_addr);
1056
1057 (void)rhport;
1058
1059 xfer_ctl_t * xfer = XFER_CTL_BASE(epnum, dir);
1060 EPx_REGS *regs = EPNUM_REGS(epnum);
1061 xfer->stall = 1;
1062
1063 if (epnum == 0)
1064 {
1065 // EP0 has just one registers to control stall for IN and OUT
1066 REG_SET_BIT(USB_EPC0_REG, USB_STALL);
1067 if (dir == TUSB_DIR_OUT)
1068 {
1069 regs->USB_RXC0_REG = USB_USB_RXC0_REG_USB_RX_EN_Msk;
1070 }
1071 else
1072 {
1073 if (regs->USB_RXC0_REG & USB_USB_RXC0_REG_USB_RX_EN_Msk)
1074 {
1075 // If RX is also enabled TX will not be stalled since RX has
1076 // higher priority. Enable NAK interrupt to handle stall.
1077 REG_SET_BIT(USB_MAMSK_REG, USB_M_EP0_NAK);
1078 }
1079 else
1080 {
1081 regs->USB_TXC0_REG |= USB_USB_TXC0_REG_USB_TX_EN_Msk;
1082 }
1083 }
1084 }
1085 else
1086 {
1087 if (dir == TUSB_DIR_OUT)
1088 {
1089 regs->epc_out |= USB_USB_EPC1_REG_USB_STALL_Msk;
1090 regs->rxc |= USB_USB_RXC1_REG_USB_RX_EN_Msk;
1091 }
1092 else
1093 {
1094 regs->epc_in |= USB_USB_EPC1_REG_USB_STALL_Msk;
1095 regs->txc |= USB_USB_TXC1_REG_USB_TX_EN_Msk | USB_USB_TXC1_REG_USB_LAST_Msk;
1096 }
1097 }
1098}
1099
1100void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr)
1101{
1102 uint8_t const epnum = tu_edpt_number(ep_addr);
1103 uint8_t const dir = tu_edpt_dir(ep_addr);
1104
1105 (void)rhport;
1106
1107 xfer_ctl_t * xfer = XFER_CTL_BASE(epnum, dir);
1108 EPx_REGS *regs = EPNUM_REGS(epnum);
1109
1110 // Clear stall is called in response to Clear Feature ENDPOINT_HALT, reset toggle
1111 xfer->data1 = 0;
1112 xfer->stall = 0;
1113
1114 if (dir == TUSB_DIR_OUT)
1115 {
1116 regs->epc_out &= ~USB_USB_EPC1_REG_USB_STALL_Msk;
1117 }
1118 else
1119 {
1120 regs->epc_in &= ~USB_USB_EPC1_REG_USB_STALL_Msk;
1121 }
1122 if (epnum == 0)
1123 {
1124 REG_CLR_BIT(USB_MAMSK_REG, USB_M_EP0_NAK);
1125 }
1126}
1127
1128/*------------------------------------------------------------------*/
1129/* Interrupt Handler
1130 *------------------------------------------------------------------*/
1131
1132void dcd_int_handler(uint8_t rhport)
1133{
1134 uint32_t int_status = USB->USB_MAEV_REG & USB->USB_MAMSK_REG;
1135
1136 (void)rhport;
1137
1138 if (GET_BIT(int_status, USB_USB_MAEV_REG_USB_WARN))
1139 {
1141 }
1142
1143 if (GET_BIT(int_status, USB_USB_MAEV_REG_USB_CH_EV))
1144 {
1145 // TODO: for now just clear interrupt
1146 (void)USB->USB_CHARGER_STAT_REG;
1147 }
1148
1149 if (GET_BIT(int_status, USB_USB_MAEV_REG_USB_EP0_NAK))
1150 {
1152 }
1153
1154 if (GET_BIT(int_status, USB_USB_MAEV_REG_USB_EP0_RX))
1155 {
1156 handle_ep0_rx();
1157 }
1158
1159 if (GET_BIT(int_status, USB_USB_MAEV_REG_USB_EP0_TX))
1160 {
1161 handle_ep0_tx();
1162 }
1163
1164 if (GET_BIT(int_status, USB_USB_MAEV_REG_USB_RX_EV))
1165 {
1166 handle_rx_ev();
1167 }
1168
1169 if (GET_BIT(int_status, USB_USB_MAEV_REG_USB_NAK))
1170 {
1171 (void)USB->USB_NAKEV_REG;
1172 }
1173
1174 if (GET_BIT(int_status, USB_USB_MAEV_REG_USB_FRAME))
1175 {
1176 if (_dcd.nfsr == NFSR_NODE_RESET)
1177 {
1178 // During reset FRAME interrupt is enabled to periodically
1179 // check when reset state ends.
1180 // FRAME interrupt is generated every 1ms without host sending
1181 // actual SOF.
1182 check_reset_end(USB_USB_ALTEV_REG_USB_RESET_Msk);
1183 }
1184 else if (_dcd.nfsr == NFSR_NODE_WAKING)
1185 {
1186 // No need to call set_nfsr, just set state
1187 _dcd.nfsr = NFSR_NODE_WAKING2;
1188 }
1189 else if (_dcd.nfsr == NFSR_NODE_WAKING2)
1190 {
1191 // No need to call set_nfsr, just set state
1192 _dcd.nfsr = NFSR_NODE_RESUME;
1193 }
1194 else if (_dcd.nfsr == NFSR_NODE_RESUME)
1195 {
1196 set_nfsr(NFSR_NODE_OPERATIONAL);
1197 }
1198 else
1199 {
1200#if USE_SOF
1201 dcd_event_bus_signal(0, DCD_EVENT_SOF, true);
1202#else
1203 // FRAME interrupt was used to re-enable reset detection or remote
1204 // wakeup no need to keep it enabled when USE_SOF is off.
1205 USB->USB_MAMSK_REG &= ~USB_USB_MAMSK_REG_USB_M_FRAME_Msk;
1206#endif
1207 }
1208 }
1209
1210 if (GET_BIT(int_status, USB_USB_MAEV_REG_USB_TX_EV))
1211 {
1212 handle_tx_ev();
1213 }
1214
1215 if (GET_BIT(int_status, USB_USB_MAEV_REG_USB_ALT))
1216 {
1217 handle_alt_ev();
1218 }
1219}
1220
1221#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 void handle_rx_ev(void)
Definition: dcd_da146xx.c:603
static void handle_epx_rx_ev(uint8_t ep)
Definition: dcd_da146xx.c:525
static bool try_allocate_dma(uint8_t epnum, uint8_t dir)
Definition: dcd_da146xx.c:326
static void start_tx_dma(void *src, volatile void *dst, uint16_t size)
Definition: dcd_da146xx.c:386
static void handle_epx_tx_ev(xfer_ctl_t *xfer)
Definition: dcd_da146xx.c:613
static uint16_t read_rx_fifo(xfer_ctl_t *xfer, uint16_t bytes_in_fifo)
Definition: dcd_da146xx.c:423
static void handle_epx_tx_warn_ev(uint8_t ep)
Definition: dcd_da146xx.c:757
static void handle_alt_ev(void)
Definition: dcd_da146xx.c:720
bool init_called
Definition: dcd_da146xx.c:233
static void handle_ep0_rx(void)
Definition: dcd_da146xx.c:440
void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr)
Definition: dcd_da146xx.c:1052
void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr)
Definition: dcd_da146xx.c:981
static EPx_REGS *const ep_regs[EP_MAX]
Definition: dcd_da146xx.c:203
static void fill_tx_fifo(xfer_ctl_t *xfer)
Definition: dcd_da146xx.c:285
uint8_t nfsr
Definition: dcd_da146xx.c:234
void dcd_int_handler(uint8_t rhport)
Definition: dcd_da146xx.c:1132
static void handle_bus_reset(void)
Definition: dcd_da146xx.c:696
static uint32_t check_reset_end(uint32_t alt_ev)
Definition: dcd_da146xx.c:670
void dcd_disconnect(uint8_t rhport)
Definition: dcd_da146xx.c:879
static void handle_tx_ev(void)
Definition: dcd_da146xx.c:660
static void handle_ep0_nak(void)
Definition: dcd_da146xx.c:780
xfer_ctl_t xfer_status[EP_MAX][2]
Definition: dcd_da146xx.c:235
void dcd_edpt_close_all(uint8_t rhport)
Definition: dcd_da146xx.c:970
static TU_ATTR_ALWAYS_INLINE bool is_in_isr(void)
Definition: dcd_da146xx.c:894
void tusb_vbus_changed(bool present)
Definition: dcd_da146xx.c:899
static TU_ATTR_ALIGNED(4)
Definition: dcd_da146xx.c:75
void dcd_int_disable(uint8_t rhport)
Definition: dcd_da146xx.c:826
static void start_rx_dma(volatile void *src, void *dst, uint16_t size)
Definition: dcd_da146xx.c:343
static void start_rx_packet(xfer_ctl_t *xfer)
Definition: dcd_da146xx.c:354
static struct @149 _dcd
static const tusb_desc_endpoint_t ep0IN_desc
Definition: dcd_da146xx.c:263
void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr)
Definition: dcd_da146xx.c:1100
static void start_tx_packet(xfer_ctl_t *xfer)
Definition: dcd_da146xx.c:397
void dcd_connect(uint8_t rhport)
Definition: dcd_da146xx.c:854
bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const *desc_edpt)
Definition: dcd_da146xx.c:923
bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_t total_bytes)
Definition: dcd_da146xx.c:1027
static const tusb_desc_endpoint_t ep0OUT_desc
Definition: dcd_da146xx.c:252
uint8_t dma_ep[2]
Definition: dcd_da146xx.c:237
void dcd_set_address(uint8_t rhport, uint8_t dev_addr)
Definition: dcd_da146xx.c:833
bool vbus_present
Definition: dcd_da146xx.c:232
bool dcd_init(uint8_t rhport, const tusb_rhport_init_t *rh_init)
Definition: dcd_da146xx.c:807
volatile EPx_REGS
Definition: dcd_da146xx.c:143
static void set_nfsr(uint8_t val)
Definition: dcd_da146xx.c:276
static void handle_fifo_warning(void)
Definition: dcd_da146xx.c:762
void dcd_int_enable(uint8_t rhport)
Definition: dcd_da146xx.c:819
void dcd_remote_wakeup(uint8_t rhport)
Definition: dcd_da146xx.c:843
void dcd_sof_enable(uint8_t rhport, bool en)
Definition: dcd_da146xx.c:886
static void handle_ep0_tx(void)
Definition: dcd_da146xx.c:493
xfer_ctl_t
Definition: dcd_dwc2.c:52
uint8_t _setup_packet[8]
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
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 bLength
Size of this descriptor in bytes: 9.
Definition: audio.h:656
uint8_t bEndpointAddress
Definition: video.h:306
__IOM uint32_t DMAx_CTRL_REG
Definition: dcd_da146xx.c:160
__IOM uint32_t DMAx_LEN_REG
Definition: dcd_da146xx.c:159
__IOM uint32_t DMAx_INT_REG
Definition: dcd_da146xx.c:158
__IOM uint32_t DMAx_A_START_REG
Definition: dcd_da146xx.c:156
__IOM uint32_t DMAx_B_START_REG
Definition: dcd_da146xx.c:157
__IOM uint32_t DMAx_IDX_REG
Definition: dcd_da146xx.c:161
uint16_t last_packet_size
Definition: dcd_da146xx.c:220
uint16_t transferred
Definition: dcd_da146xx.c:215
uint8_t data1
Definition: dcd_da146xx.c:223
uint16_t total_len
Definition: dcd_da146xx.c:213
uint8_t ep_addr
Definition: dcd_da146xx.c:221
uint16_t max_packet_size
Definition: dcd_da146xx.c:216
uint8_t stall
Definition: dcd_da146xx.c:225
uint8_t iso
Definition: dcd_da146xx.c:227
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_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_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.
static TU_ATTR_ALWAYS_INLINE uint8_t tu_edpt_addr(uint8_t num, uint8_t dir)
Definition: tusb_types.h:511
@ TUSB_DESC_ENDPOINT
Definition: tusb_types.h:97