35
35
#define DWC2_DEBUG 2
36
36
37
37
#include "device/dcd.h"
38
- #include "dwc2_type.h"
39
-
40
- // Following symbols must be defined by port header
41
- // - _dwc2_controller[]: array of controllers
42
- // - DWC2_EP_MAX: largest EP counts of all controllers
43
- // - dwc2_phy_init/dwc2_phy_update: phy init called before and after core reset
44
- // - dwc2_dcd_int_enable/dwc2_dcd_int_disable
45
- // - dwc2_remote_wakeup_delay
46
-
47
- #if defined(TUP_USBIP_DWC2_STM32 )
48
- #include "dwc2_stm32.h"
49
- #elif defined(TUP_USBIP_DWC2_ESP32 )
50
- #include "dwc2_esp32.h"
51
- #elif TU_CHECK_MCU (OPT_MCU_GD32VF103 )
52
- #include "dwc2_gd32.h"
53
- #elif TU_CHECK_MCU (OPT_MCU_BCM2711 , OPT_MCU_BCM2835 , OPT_MCU_BCM2837 )
54
- #include "dwc2_bcm.h"
55
- #elif TU_CHECK_MCU (OPT_MCU_EFM32GG )
56
- #include "dwc2_efm32.h"
57
- #elif TU_CHECK_MCU (OPT_MCU_XMC4000 )
58
- #include "dwc2_xmc.h"
59
- #else
60
- #error "Unsupported MCUs"
61
- #endif
62
-
63
- enum {
64
- DWC2_CONTROLLER_COUNT = TU_ARRAY_SIZE (_dwc2_controller )
65
- };
66
-
67
- // DWC2 registers
68
- //#define DWC2_REG(_port) ((dwc2_regs_t*) _dwc2_controller[_port].reg_base)
69
-
70
- TU_ATTR_ALWAYS_INLINE static inline dwc2_regs_t * DWC2_REG (uint8_t rhport ) {
71
- if (rhport >= DWC2_CONTROLLER_COUNT ) {
72
- // user mis-configured, ignore and use first controller
73
- rhport = 0 ;
74
- }
75
- return (dwc2_regs_t * ) _dwc2_controller [rhport ].reg_base ;
76
- }
38
+ #include "dwc2_common.h"
77
39
78
40
//--------------------------------------------------------------------+
79
41
// MACRO TYPEDEF CONSTANT ENUM
@@ -94,7 +56,7 @@ static xfer_ctl_t xfer_status[DWC2_EP_MAX][2];
94
56
95
57
// EP0 transfers are limited to 1 packet - larger sizes has to be split
96
58
static uint16_t ep0_pending [2 ]; // Index determines direction as tusb_dir_t type
97
- static uint16_t _dfifo_top ; // top free location in FIFO RAM
59
+ static uint16_t _dfifo_top ; // top free location in DFIFO in words
98
60
99
61
// Number of IN endpoints active
100
62
static uint8_t _allocated_ep_in_count ;
@@ -106,20 +68,10 @@ static bool _sof_en;
106
68
// DMA
107
69
//--------------------------------------------------------------------
108
70
109
- TU_ATTR_ALWAYS_INLINE static inline bool dma_enabled (const dwc2_regs_t * dwc2 ) {
110
- #if !CFG_TUD_DWC2_DMA
71
+ TU_ATTR_ALWAYS_INLINE static inline bool dma_device_enabled (const dwc2_regs_t * dwc2 ) {
111
72
(void ) dwc2 ;
112
- return false;
113
- #else
114
73
// Internal DMA only
115
- return (dwc2 -> ghwcfg2_bm .arch == GHWCFG2_ARCH_INTERNAL_DMA );
116
- #endif
117
- }
118
-
119
- TU_ATTR_ALWAYS_INLINE static inline uint16_t dma_cal_epfifo_base (uint8_t rhport ) {
120
- // Scatter/Gather DMA mode is not yet supported. Buffer DMA only need 1 words per endpoint direction
121
- const dwc2_controller_t * dwc2_controller = & _dwc2_controller [rhport ];
122
- return dwc2_controller -> ep_fifo_size /4 - 2 * dwc2_controller -> ep_count ;
74
+ return CFG_TUD_DWC2_DMA && dwc2 -> ghwcfg2_bm .arch == GHWCFG2_ARCH_INTERNAL_DMA ;
123
75
}
124
76
125
77
static void dma_setup_prepare (uint8_t rhport ) {
@@ -141,18 +93,8 @@ static void dma_setup_prepare(uint8_t rhport) {
141
93
// Data FIFO
142
94
//--------------------------------------------------------------------+
143
95
144
- TU_ATTR_ALWAYS_INLINE static inline void dfifo_flush_tx (dwc2_regs_t * dwc2 , uint8_t epnum ) {
145
- // flush TX fifo and wait for it cleared
146
- dwc2 -> grstctl = GRSTCTL_TXFFLSH | (epnum << GRSTCTL_TXFNUM_Pos );
147
- while (dwc2 -> grstctl & GRSTCTL_TXFFLSH_Msk ) {}
148
- }
149
- TU_ATTR_ALWAYS_INLINE static inline void dfifo_flush_rx (dwc2_regs_t * dwc2 ) {
150
- // flush RX fifo and wait for it cleared
151
- dwc2 -> grstctl = GRSTCTL_RXFFLSH ;
152
- while (dwc2 -> grstctl & GRSTCTL_RXFFLSH_Msk ) {}
153
- }
154
96
155
- /* USB Data FIFO Layout
97
+ /* Device Data FIFO scheme
156
98
157
99
The FIFO is split up into
158
100
- EPInfo: for storing DMA metadata, only required when use DMA. Maximum size is called
@@ -167,11 +109,9 @@ TU_ATTR_ALWAYS_INLINE static inline void dfifo_flush_rx(dwc2_regs_t* dwc2) {
167
109
possible since the free space is located between the RX and TX FIFOs.
168
110
169
111
---------------- ep_fifo_size
170
- | EPInfo |
171
- | for DMA |
112
+ | DxEPIDMAn |
172
113
|-------------|-- gdfifocfg.EPINFOBASE (max is ghwcfg3.dfifo_depth)
173
- | IN FIFO 0 |
174
- | control |
114
+ | IN FIFO 0 | control EP
175
115
|-------------|
176
116
| IN FIFO 1 |
177
117
|-------------|
@@ -190,13 +130,13 @@ TU_ATTR_ALWAYS_INLINE static inline void dfifo_flush_rx(dwc2_regs_t* dwc2) {
190
130
- All EP OUT shared a unique OUT FIFO which uses (for Slave or Buffer DMA, Scatt/Gather DMA use different formula):
191
131
- 13 for setup packets + control words (up to 3 setup packets).
192
132
- 1 for global NAK (not required/used here).
193
- - Largest-EPsize / 4 + 1. ( FS: 64 bytes, HS: 512 bytes). Recommended is "2 x (Largest-EPsize/4) + 1"
133
+ - Largest-EPsize/ 4 + 1. ( FS: 64 bytes, HS: 512 bytes). Recommended is "2 x (Largest-EPsize/4 + 1) "
194
134
- 2 for each used OUT endpoint
195
135
196
136
Therefore GRXFSIZ = 13 + 1 + 2 x (Largest-EPsize/4 + 1) + 2 x EPOUTnum
197
137
*/
198
138
199
- TU_ATTR_ALWAYS_INLINE static inline uint16_t calc_grxfsiz (uint16_t largest_ep_size , uint8_t ep_count ) {
139
+ TU_ATTR_ALWAYS_INLINE static inline uint16_t calc_device_grxfsiz (uint16_t largest_ep_size , uint8_t ep_count ) {
200
140
return 13 + 1 + 2 * ((largest_ep_size / 4 ) + 1 ) + 2 * ep_count ;
201
141
}
202
142
@@ -212,7 +152,7 @@ static bool dfifo_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t packet_size) {
212
152
uint16_t fifo_size = tu_div_ceil (packet_size , 4 );
213
153
if (dir == TUSB_DIR_OUT ) {
214
154
// Calculate required size of RX FIFO
215
- uint16_t const new_sz = calc_grxfsiz (4 * fifo_size , ep_count );
155
+ uint16_t const new_sz = calc_device_grxfsiz (4 * fifo_size , ep_count );
216
156
217
157
// If size_rx needs to be extended check if there is enough free space
218
158
if (dwc2 -> grxfsiz < new_sz ) {
@@ -227,7 +167,7 @@ static bool dfifo_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t packet_size) {
227
167
}
228
168
229
169
// If The TXFELVL is configured as half empty, the fifo must be twice the max_size.
230
- if ((dwc2 -> gahbcfg & GAHBCFG_TXFELVL ) == 0 ) {
170
+ if ((dwc2 -> gahbcfg & GAHBCFG_TX_FIFO_EPMTY_LVL ) == 0 ) {
231
171
fifo_size *= 2 ;
232
172
}
233
173
@@ -248,70 +188,23 @@ static bool dfifo_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t packet_size) {
248
188
return true;
249
189
}
250
190
251
- static void dfifo_init (uint8_t rhport ) {
191
+ static void dfifo_device_init (uint8_t rhport ) {
252
192
const dwc2_controller_t * dwc2_controller = & _dwc2_controller [rhport ];
253
193
dwc2_regs_t * dwc2 = DWC2_REG (rhport );
254
- dwc2 -> grxfsiz = calc_grxfsiz (CFG_TUD_ENDPOINT0_SIZE , dwc2_controller -> ep_count );
194
+ dwc2 -> grxfsiz = calc_device_grxfsiz (CFG_TUD_ENDPOINT0_SIZE , dwc2_controller -> ep_count );
255
195
256
- if ( dma_enabled ( dwc2 )) {
257
- // DMA use last DFIFO to store metadata
258
- _dfifo_top = dma_cal_epfifo_base ( rhport ) ;
259
- } else {
260
- _dfifo_top = dwc2_controller -> ep_fifo_size / 4 ;
196
+ // Scatter/Gather DMA mode is not yet supported. Buffer DMA only need 1 words per endpoint direction
197
+ const bool is_dma = dma_device_enabled ( dwc2 );
198
+ _dfifo_top = dwc2_controller -> ep_fifo_size / 4 ;
199
+ if ( is_dma ) {
200
+ _dfifo_top -= 2 * dwc2_controller -> ep_count ;
261
201
}
202
+ dwc2 -> gdfifocfg = (_dfifo_top << GDFIFOCFG_EPINFOBASE_SHIFT ) | _dfifo_top ;
262
203
263
204
// Allocate FIFO for EP0 IN
264
205
dfifo_alloc (rhport , 0x80 , CFG_TUD_ENDPOINT0_SIZE );
265
206
}
266
207
267
- // Read a single data packet from receive FIFO
268
- static void dfifo_read_packet (uint8_t rhport , uint8_t * dst , uint16_t len ) {
269
- (void ) rhport ;
270
-
271
- dwc2_regs_t * dwc2 = DWC2_REG (rhport );
272
- volatile const uint32_t * rx_fifo = dwc2 -> fifo [0 ];
273
-
274
- // Reading full available 32 bit words from fifo
275
- uint16_t full_words = len >> 2 ;
276
- while (full_words -- ) {
277
- tu_unaligned_write32 (dst , * rx_fifo );
278
- dst += 4 ;
279
- }
280
-
281
- // Read the remaining 1-3 bytes from fifo
282
- uint8_t const bytes_rem = len & 0x03 ;
283
- if (bytes_rem != 0 ) {
284
- uint32_t const tmp = * rx_fifo ;
285
- dst [0 ] = tu_u32_byte0 (tmp );
286
- if (bytes_rem > 1 ) dst [1 ] = tu_u32_byte1 (tmp );
287
- if (bytes_rem > 2 ) dst [2 ] = tu_u32_byte2 (tmp );
288
- }
289
- }
290
-
291
- // Write a single data packet to EPIN FIFO
292
- static void dfifo_write_packet (uint8_t rhport , uint8_t fifo_num , uint8_t const * src , uint16_t len ) {
293
- (void ) rhport ;
294
-
295
- dwc2_regs_t * dwc2 = DWC2_REG (rhport );
296
- volatile uint32_t * tx_fifo = dwc2 -> fifo [fifo_num ];
297
-
298
- // Pushing full available 32 bit words to fifo
299
- uint16_t full_words = len >> 2 ;
300
- while (full_words -- ) {
301
- * tx_fifo = tu_unaligned_read32 (src );
302
- src += 4 ;
303
- }
304
-
305
- // Write the remaining 1-3 bytes into fifo
306
- uint8_t const bytes_rem = len & 0x03 ;
307
- if (bytes_rem ) {
308
- uint32_t tmp_word = src [0 ];
309
- if (bytes_rem > 1 ) tmp_word |= (src [1 ] << 8 );
310
- if (bytes_rem > 2 ) tmp_word |= (src [2 ] << 16 );
311
-
312
- * tx_fifo = tmp_word ;
313
- }
314
- }
315
208
316
209
//--------------------------------------------------------------------
317
210
// Endpoint
@@ -326,7 +219,7 @@ static uint8_t get_free_fifo(void) {
326
219
return 0 ;
327
220
}
328
221
#endif
329
-
222
+
330
223
static void edpt_activate (uint8_t rhport , tusb_desc_endpoint_t const * p_endpoint_desc ) {
331
224
dwc2_regs_t * dwc2 = DWC2_REG (rhport );
332
225
uint8_t const epnum = tu_edpt_number (p_endpoint_desc -> bEndpointAddress );
@@ -434,6 +327,10 @@ static void bus_reset(uint8_t rhport) {
434
327
}
435
328
}
436
329
330
+ #if TU_CHECK_MCU (OPT_MCU_ESP32S2 , OPT_MCU_ESP32S3 )
331
+ _allocated_fifos = 1 ;
332
+ #endif
333
+
437
334
dfifo_flush_tx (dwc2 , 0x10 ); // all tx fifo
438
335
dfifo_flush_rx (dwc2 );
439
336
@@ -443,7 +340,7 @@ static void bus_reset(uint8_t rhport) {
443
340
dwc2 -> diepmsk = DIEPMSK_TOM | DIEPMSK_XFRCM ;
444
341
445
342
// 4. Set up DFIFO
446
- dfifo_init (rhport );
343
+ dfifo_device_init (rhport );
447
344
448
345
// 5. Reset device address
449
346
dwc2 -> dcfg &= ~DCFG_DAD_Msk ;
@@ -455,7 +352,7 @@ static void bus_reset(uint8_t rhport) {
455
352
xfer_status [0 ][TUSB_DIR_OUT ].max_size = 64 ;
456
353
xfer_status [0 ][TUSB_DIR_IN ].max_size = 64 ;
457
354
458
- if (dma_enabled (dwc2 )) {
355
+ if (dma_device_enabled (dwc2 )) {
459
356
dma_setup_prepare (rhport );
460
357
} else {
461
358
dwc2 -> epout [0 ].doeptsiz |= (3 << DOEPTSIZ_STUPCNT_Pos );
@@ -485,9 +382,9 @@ static void edpt_schedule_packets(uint8_t rhport, uint8_t const epnum, uint8_t c
485
382
if (dir == TUSB_DIR_IN ) {
486
383
// A full IN transfer (multiple packets, possibly) triggers XFRC.
487
384
dep -> dieptsiz = (num_packets << DIEPTSIZ_PKTCNT_Pos ) |
488
- ((total_bytes << DIEPTSIZ_XFRSIZ_Pos ) & DIEPTSIZ_XFRSIZ_Msk );
385
+ ((total_bytes << DIEPTSIZ_XFRSIZ_Pos ) & DIEPTSIZ_XFRSIZ_Msk );
489
386
490
- if (dma_enabled (dwc2 )) {
387
+ if (dma_device_enabled (dwc2 )) {
491
388
dep -> diepdma = (uintptr_t )xfer -> buffer ;
492
389
493
390
// For ISO endpoint set correct odd/even bit for next frame.
@@ -525,231 +422,69 @@ static void edpt_schedule_packets(uint8_t rhport, uint8_t const epnum, uint8_t c
525
422
dep -> doepctl |= (odd_frame_now ? DOEPCTL_SD0PID_SEVNFRM_Msk : DOEPCTL_SODDFRM_Msk );
526
423
}
527
424
528
- if (dma_enabled (dwc2 )) {
425
+ if (dma_device_enabled (dwc2 )) {
529
426
dep -> doepdma = (uintptr_t )xfer -> buffer ;
530
427
}
531
428
532
429
dep -> doepctl |= DOEPCTL_EPENA | DOEPCTL_CNAK ;
533
430
}
534
431
}
535
432
536
- /*------------------------------------------------------------------*/
537
- /* Controller API
538
- *------------------------------------------------------------------*/
539
-
540
- static void reset_core (dwc2_regs_t * dwc2 ) {
541
- // reset core
542
- dwc2 -> grstctl |= GRSTCTL_CSRST ;
543
-
544
- // wait for reset bit is cleared
545
- // TODO version 4.20a should wait for RESET DONE mask
546
- while (dwc2 -> grstctl & GRSTCTL_CSRST ) {}
547
-
548
- // wait for AHB master IDLE
549
- while (!(dwc2 -> grstctl & GRSTCTL_AHBIDL )) {}
550
-
551
- // wait for device mode ?
552
- }
553
-
554
- static bool phy_hs_supported (dwc2_regs_t * dwc2 ) {
555
- (void ) dwc2 ;
556
-
557
- #if !TUD_OPT_HIGH_SPEED
558
- return false;
559
- #else
560
- return dwc2 -> ghwcfg2_bm .hs_phy_type != GHWCFG2_HSPHY_NOT_SUPPORTED ;
561
- #endif
562
- }
563
-
564
- static void phy_fs_init (dwc2_regs_t * dwc2 ) {
565
- TU_LOG (DWC2_DEBUG , "Fullspeed PHY init\r\n" );
566
-
567
- // Select FS PHY
568
- dwc2 -> gusbcfg |= GUSBCFG_PHYSEL ;
569
-
570
- // MCU specific PHY init before reset
571
- dwc2_phy_init (dwc2 , GHWCFG2_HSPHY_NOT_SUPPORTED );
572
-
573
- // Reset core after selecting PHY
574
- reset_core (dwc2 );
575
-
576
- // USB turnaround time is critical for certification where long cables and 5-Hubs are used.
577
- // So if you need the AHB to run at less than 30 MHz, and if USB turnaround time is not critical,
578
- // these bits can be programmed to a larger value. Default is 5
579
- dwc2 -> gusbcfg = (dwc2 -> gusbcfg & ~GUSBCFG_TRDT_Msk ) | (5u << GUSBCFG_TRDT_Pos );
580
-
581
- // MCU specific PHY update post reset
582
- dwc2_phy_update (dwc2 , GHWCFG2_HSPHY_NOT_SUPPORTED );
583
-
584
- // set max speed
585
- dwc2 -> dcfg = (dwc2 -> dcfg & ~DCFG_DSPD_Msk ) | (DCFG_DSPD_FS << DCFG_DSPD_Pos );
586
- }
587
-
588
- static void phy_hs_init (dwc2_regs_t * dwc2 ) {
589
- uint32_t gusbcfg = dwc2 -> gusbcfg ;
590
-
591
- // De-select FS PHY
592
- gusbcfg &= ~GUSBCFG_PHYSEL ;
593
-
594
- if (dwc2 -> ghwcfg2_bm .hs_phy_type == GHWCFG2_HSPHY_ULPI ) {
595
- TU_LOG (DWC2_DEBUG , "Highspeed ULPI PHY init\r\n" );
596
-
597
- // Select ULPI
598
- gusbcfg |= GUSBCFG_ULPI_UTMI_SEL ;
599
-
600
- // ULPI 8-bit interface, single data rate
601
- gusbcfg &= ~(GUSBCFG_PHYIF16 | GUSBCFG_DDRSEL );
602
-
603
- // default internal VBUS Indicator and Drive
604
- gusbcfg &= ~(GUSBCFG_ULPIEVBUSD | GUSBCFG_ULPIEVBUSI );
605
-
606
- // Disable FS/LS ULPI
607
- gusbcfg &= ~(GUSBCFG_ULPIFSLS | GUSBCFG_ULPICSM );
608
- } else {
609
- TU_LOG (DWC2_DEBUG , "Highspeed UTMI+ PHY init\r\n" );
610
-
611
- // Select UTMI+ with 8-bit interface
612
- gusbcfg &= ~(GUSBCFG_ULPI_UTMI_SEL | GUSBCFG_PHYIF16 );
613
-
614
- // Set 16-bit interface if supported
615
- if (dwc2 -> ghwcfg4_bm .phy_data_width ) {
616
- gusbcfg |= GUSBCFG_PHYIF16 ;
617
- }
618
- }
619
-
620
- // Apply config
621
- dwc2 -> gusbcfg = gusbcfg ;
622
-
623
- // mcu specific phy init
624
- dwc2_phy_init (dwc2 , dwc2 -> ghwcfg2_bm .hs_phy_type );
625
-
626
- // Reset core after selecting PHY
627
- reset_core (dwc2 );
628
-
629
- // Set turn-around, must after core reset otherwise it will be clear
630
- // - 9 if using 8-bit PHY interface
631
- // - 5 if using 16-bit PHY interface
632
- gusbcfg &= ~GUSBCFG_TRDT_Msk ;
633
- gusbcfg |= (dwc2 -> ghwcfg4_bm .phy_data_width ? 5u : 9u ) << GUSBCFG_TRDT_Pos ;
634
- dwc2 -> gusbcfg = gusbcfg ;
635
-
636
- // MCU specific PHY update post reset
637
- dwc2_phy_update (dwc2 , dwc2 -> ghwcfg2_bm .hs_phy_type );
638
-
639
- // Set max speed
640
- uint32_t dcfg = dwc2 -> dcfg ;
641
- dcfg &= ~DCFG_DSPD_Msk ;
642
- dcfg |= DCFG_DSPD_HS << DCFG_DSPD_Pos ;
643
-
644
- // XCVRDLY: transceiver delay between xcvr_sel and txvalid during device chirp is required
645
- // when using with some PHYs such as USB334x (USB3341, USB3343, USB3346, USB3347)
646
- if (dwc2 -> ghwcfg2_bm .hs_phy_type == GHWCFG2_HSPHY_ULPI ) {
647
- dcfg |= DCFG_XCVRDLY ;
648
- }
649
-
650
- dwc2 -> dcfg = dcfg ;
651
- }
652
-
653
- static bool check_dwc2 (dwc2_regs_t * dwc2 ) {
654
- #if CFG_TUSB_DEBUG >= DWC2_DEBUG
655
- // print guid, gsnpsid, ghwcfg1, ghwcfg2, ghwcfg3, ghwcfg4
656
- // Run 'python dwc2_info.py' and check dwc2_info.md for bit-field value and comparison with other ports
657
- volatile uint32_t const * p = (volatile uint32_t const * ) & dwc2 -> guid ;
658
- TU_LOG1 ("guid, gsnpsid, ghwcfg1, ghwcfg2, ghwcfg3, ghwcfg4\r\n" );
659
- for (size_t i = 0 ; i < 5 ; i ++ ) {
660
- TU_LOG1 ("0x%08" PRIX32 ", " , p [i ]);
661
- }
662
- TU_LOG1 ("0x%08" PRIX32 "\r\n" , p [5 ]);
663
- #endif
664
-
665
- // For some reason: GD32VF103 snpsid and all hwcfg register are always zero (skip it)
666
- (void ) dwc2 ;
667
- #if !TU_CHECK_MCU (OPT_MCU_GD32VF103 )
668
- uint32_t const gsnpsid = dwc2 -> gsnpsid & GSNPSID_ID_MASK ;
669
- TU_ASSERT (gsnpsid == DWC2_OTG_ID || gsnpsid == DWC2_FS_IOT_ID || gsnpsid == DWC2_HS_IOT_ID );
670
- #endif
671
-
672
- return true;
673
- }
674
-
433
+ //--------------------------------------------------------------------
434
+ // Controller API
435
+ //--------------------------------------------------------------------
675
436
bool dcd_init (uint8_t rhport , const tusb_rhport_init_t * rh_init ) {
676
- (void ) rhport ;
677
437
(void ) rh_init ;
678
- // Programming model begins in the last section of the chapter on the USB
679
- // peripheral in each Reference Manual.
680
438
dwc2_regs_t * dwc2 = DWC2_REG (rhport );
681
439
682
- // Check Synopsys ID register, failed if controller clock/power is not enabled
683
- TU_ASSERT ( check_dwc2 ( dwc2 ) );
684
- dcd_disconnect ( rhport );
440
+ // Core Initialization
441
+ const bool is_highspeed = dwc2_core_is_highspeed ( dwc2 , TUSB_ROLE_DEVICE );
442
+ TU_ASSERT ( dwc2_core_init ( rhport , is_highspeed ) );
685
443
686
- if (phy_hs_supported (dwc2 )) {
687
- phy_hs_init (dwc2 ); // Highspeed
444
+ if (dma_device_enabled (dwc2 )) {
445
+ // DMA seems to be only settable after a core reset, and not possible to switch on-the-fly
446
+ dwc2 -> gahbcfg |= GAHBCFG_DMAEN | GAHBCFG_HBSTLEN_2 ;
688
447
} else {
689
- phy_fs_init ( dwc2 ); // core does not support highspeed or hs phy is not present
448
+ dwc2 -> gintmsk |= GINTSTS_RXFLVL ;
690
449
}
691
450
692
- // Restart PHY clock
693
- dwc2 -> pcgctl &= ~( PCGCTL_STOPPCLK | PCGCTL_GATEHCLK | PCGCTL_PWRCLMP | PCGCTL_RSTPDWNMODULE );
451
+ // Device Initialization
452
+ dcd_disconnect ( rhport );
694
453
695
- /* Set HS/FS Timeout Calibration to 7 (max available value).
696
- * The number of PHY clocks that the application programs in
697
- * this field is added to the high/full speed interpacket timeout
698
- * duration in the core to account for any additional delays
699
- * introduced by the PHY. This can be required, because the delay
700
- * introduced by the PHY in generating the linestate condition
701
- * can vary from one PHY to another.
702
- */
703
- dwc2 -> gusbcfg |= (7ul << GUSBCFG_TOCAL_Pos );
454
+ // Set device max speed
455
+ uint32_t dcfg = dwc2 -> dcfg & ~DCFG_DSPD_Msk ;
456
+ if (is_highspeed ) {
457
+ dcfg |= DCFG_DSPD_HS << DCFG_DSPD_Pos ;
458
+
459
+ // XCVRDLY: transceiver delay between xcvr_sel and txvalid during device chirp is required
460
+ // when using with some PHYs such as USB334x (USB3341, USB3343, USB3346, USB3347)
461
+ if (dwc2 -> ghwcfg2_bm .hs_phy_type == GHWCFG2_HSPHY_ULPI ) {
462
+ dcfg |= DCFG_XCVRDLY ;
463
+ }
464
+ }else {
465
+ dcfg |= DCFG_DSPD_FS << DCFG_DSPD_Pos ;
466
+ }
467
+ dwc2 -> dcfg = dcfg ;
704
468
705
469
// Force device mode
706
470
dwc2 -> gusbcfg = (dwc2 -> gusbcfg & ~GUSBCFG_FHMOD ) | GUSBCFG_FDMOD ;
707
471
708
472
// Clear A override, force B Valid
709
473
dwc2 -> gotgctl = (dwc2 -> gotgctl & ~GOTGCTL_AVALOEN ) | GOTGCTL_BVALOEN | GOTGCTL_BVALOVAL ;
710
474
711
- // If USB host misbehaves during status portion of control xfer
712
- // (non zero-length packet), send STALL back and discard.
475
+ // If USB host misbehaves during status portion of control xfer (non zero-length packet), send STALL back and discard
713
476
dwc2 -> dcfg |= DCFG_NZLSOHSK ;
714
477
715
- dfifo_flush_tx (dwc2 , 0x10 ); // all tx fifo
716
- dfifo_flush_rx (dwc2 );
717
-
718
- // Clear all interrupts
719
- uint32_t int_mask = dwc2 -> gintsts ;
720
- dwc2 -> gintsts |= int_mask ;
721
- int_mask = dwc2 -> gotgint ;
722
- dwc2 -> gotgint |= int_mask ;
723
-
724
- // Required as part of core initialization.
725
- dwc2 -> gintmsk = GINTMSK_OTGINT | GINTMSK_USBSUSPM | GINTMSK_USBRST | GINTMSK_ENUMDNEM | GINTMSK_WUIM ;
726
-
727
- // Configure TX FIFO empty level for interrupt. Default is complete empty
728
- dwc2 -> gahbcfg |= GAHBCFG_TXFELVL ;
729
-
730
- if (dma_enabled (dwc2 )) {
731
- const uint16_t epinfo_base = dma_cal_epfifo_base (rhport );
732
- dwc2 -> gdfifocfg = (epinfo_base << GDFIFOCFG_EPINFOBASE_SHIFT ) | epinfo_base ;
478
+ // Enable required interrupts
479
+ dwc2 -> gintmsk |= GINTMSK_OTGINT | GINTMSK_USBSUSPM | GINTMSK_USBRST | GINTMSK_ENUMDNEM | GINTMSK_WUIM ;
733
480
734
- // DMA seems to be only settable after a core reset
735
- dwc2 -> gahbcfg |= GAHBCFG_DMAEN | GAHBCFG_HBSTLEN_2 ;
736
- }else {
737
- dwc2 -> gintmsk |= GINTMSK_RXFLVLM ;
738
- }
739
-
740
- // Enable global interrupt
741
- dwc2 -> gahbcfg |= GAHBCFG_GINT ;
742
-
743
- // make sure we are in device mode
744
- // TU_ASSERT(!(dwc2->gintsts & GINTSTS_CMOD), );
745
-
746
- // TU_LOG_HEX(DWC2_DEBUG, dwc2->gotgctl);
747
- // TU_LOG_HEX(DWC2_DEBUG, dwc2->gusbcfg);
748
- // TU_LOG_HEX(DWC2_DEBUG, dwc2->dcfg);
749
- // TU_LOG_HEX(DWC2_DEBUG, dwc2->gahbcfg);
481
+ // TX FIFO empty level for interrupt is complete empty
482
+ uint32_t gahbcfg = dwc2 -> gahbcfg ;
483
+ gahbcfg |= GAHBCFG_TX_FIFO_EPMTY_LVL ;
484
+ gahbcfg |= GAHBCFG_GINT ; // Enable global interrupt
485
+ dwc2 -> gahbcfg = gahbcfg ;
750
486
751
487
dcd_connect (rhport );
752
-
753
488
return true;
754
489
}
755
490
@@ -873,7 +608,7 @@ void dcd_edpt_close_all(uint8_t rhport) {
873
608
dfifo_flush_tx (dwc2 , 0x10 ); // all tx fifo
874
609
dfifo_flush_rx (dwc2 );
875
610
876
- dfifo_init (rhport ); // re-init dfifo
611
+ dfifo_device_init (rhport ); // re-init dfifo
877
612
}
878
613
879
614
bool dcd_edpt_iso_alloc (uint8_t rhport , uint8_t ep_addr , uint16_t largest_packet_size ) {
@@ -904,11 +639,10 @@ bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t* buffer, uint16_t to
904
639
// Schedule the first transaction for EP0 transfer
905
640
edpt_schedule_packets (rhport , epnum , dir , 1 , ep0_pending [dir ]);
906
641
} else {
907
- uint16_t num_packets = (total_bytes / xfer -> max_size );
908
- uint16_t const short_packet_size = total_bytes % xfer -> max_size ;
909
-
910
- // Zero-size packet is special case.
911
- if ((short_packet_size > 0 ) || (total_bytes == 0 )) num_packets ++ ;
642
+ uint16_t num_packets = tu_div_ceil (total_bytes , xfer -> max_size );
643
+ if (num_packets == 0 ) {
644
+ num_packets = 1 ; // zero length packet still count as 1
645
+ }
912
646
913
647
// Schedule packets to be sent within interrupt
914
648
edpt_schedule_packets (rhport , epnum , dir , num_packets , total_bytes );
@@ -952,8 +686,9 @@ void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr) {
952
686
}
953
687
954
688
void dcd_edpt_stall (uint8_t rhport , uint8_t ep_addr ) {
689
+ dwc2_regs_t * dwc2 = DWC2_REG (rhport );
955
690
edpt_disable (rhport , ep_addr , true);
956
- if ((tu_edpt_number (ep_addr ) == 0 ) && dma_enabled ( DWC2_REG ( rhport ) )) {
691
+ if ((tu_edpt_number (ep_addr ) == 0 ) && dma_device_enabled ( dwc2 )) {
957
692
dma_setup_prepare (rhport );
958
693
}
959
694
}
@@ -976,16 +711,15 @@ void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) {
976
711
// Process shared receive FIFO, this interrupt is only used in Slave mode
977
712
static void handle_rxflvl_irq (uint8_t rhport ) {
978
713
dwc2_regs_t * dwc2 = DWC2_REG (rhport );
979
- volatile uint32_t const * rx_fifo = dwc2 -> fifo [0 ];
714
+ const volatile uint32_t * rx_fifo = dwc2 -> fifo [0 ];
980
715
981
716
// Pop control word off FIFO
982
- uint32_t const grxstsp = dwc2 -> grxstsp ;
983
- uint8_t const pktsts = (grxstsp & GRXSTSP_PKTSTS_Msk ) >> GRXSTSP_PKTSTS_Pos ;
984
- uint8_t const epnum = (grxstsp & GRXSTSP_EPNUM_Msk ) >> GRXSTSP_EPNUM_Pos ;
985
- uint16_t const bcnt = (grxstsp & GRXSTSP_BCNT_Msk ) >> GRXSTSP_BCNT_Pos ;
717
+ const dwc2_grxstsp_t grxstsp_bm = dwc2 -> grxstsp_bm ;
718
+ const uint8_t epnum = grxstsp_bm .ep_ch_num ;
719
+ const uint16_t byte_count = grxstsp_bm .byte_count ;
986
720
dwc2_epout_t * epout = & dwc2 -> epout [epnum ];
987
721
988
- switch (pktsts ) {
722
+ switch (grxstsp_bm . packet_status ) {
989
723
// Global OUT NAK: do nothing
990
724
case GRXSTS_PKTSTS_GLOBALOUTNAK :
991
725
break ;
@@ -1010,18 +744,18 @@ static void handle_rxflvl_irq(uint8_t rhport) {
1010
744
// Read packet off RxFIFO
1011
745
if (xfer -> ff ) {
1012
746
// Ring buffer
1013
- tu_fifo_write_n_const_addr_full_words (xfer -> ff , (const void * ) (uintptr_t ) rx_fifo , bcnt );
747
+ tu_fifo_write_n_const_addr_full_words (xfer -> ff , (const void * ) (uintptr_t ) rx_fifo , byte_count );
1014
748
} else {
1015
749
// Linear buffer
1016
- dfifo_read_packet (rhport , xfer -> buffer , bcnt );
750
+ dfifo_read_packet (dwc2 , xfer -> buffer , byte_count );
1017
751
1018
752
// Increment pointer to xfer data
1019
- xfer -> buffer += bcnt ;
753
+ xfer -> buffer += byte_count ;
1020
754
}
1021
755
1022
- // Truncate transfer length in case of short packet
1023
- if (bcnt < xfer -> max_size ) {
1024
- xfer -> total_len -= ( epout -> doeptsiz & DOEPTSIZ_XFRSIZ_Msk ) >> DOEPTSIZ_XFRSIZ_Pos ;
756
+ // short packet, minus remaining bytes (xfer_size)
757
+ if (byte_count < xfer -> max_size ) {
758
+ xfer -> total_len -= epout -> doeptsiz_bm . xfer_size ;
1025
759
if (epnum == 0 ) {
1026
760
xfer -> total_len -= ep0_pending [TUSB_DIR_OUT ];
1027
761
ep0_pending [TUSB_DIR_OUT ] = 0 ;
@@ -1070,7 +804,7 @@ static void handle_epout_irq(uint8_t rhport) {
1070
804
if (doepint & DOEPINT_SETUP ) {
1071
805
epout -> doepint = DOEPINT_SETUP ;
1072
806
1073
- if (dma_enabled (dwc2 )) {
807
+ if (dma_device_enabled (dwc2 )) {
1074
808
dma_setup_prepare (rhport );
1075
809
}
1076
810
@@ -1086,7 +820,7 @@ static void handle_epout_irq(uint8_t rhport) {
1086
820
if (!(doepint & (DOEPINT_SETUP | DOEPINT_STPKTRX | DOEPINT_STSPHSRX ))) {
1087
821
xfer_ctl_t * xfer = XFER_CTL_BASE (epnum , TUSB_DIR_OUT );
1088
822
1089
- if (dma_enabled (dwc2 )) {
823
+ if (dma_device_enabled (dwc2 )) {
1090
824
if ((epnum == 0 ) && ep0_pending [TUSB_DIR_OUT ]) {
1091
825
// EP0 can only handle one packet Schedule another packet to be received.
1092
826
edpt_schedule_packets (rhport , epnum , TUSB_DIR_OUT , 1 , ep0_pending [TUSB_DIR_OUT ]);
@@ -1118,65 +852,64 @@ static void handle_epout_irq(uint8_t rhport) {
1118
852
1119
853
static void handle_epin_irq (uint8_t rhport ) {
1120
854
dwc2_regs_t * dwc2 = DWC2_REG (rhport );
1121
- uint8_t const ep_count = _dwc2_controller [rhport ].ep_count ;
1122
- dwc2_epin_t * epin = dwc2 -> epin ;
855
+ const uint8_t ep_count = _dwc2_controller [rhport ].ep_count ;
1123
856
1124
857
// DAINT for a given EP clears when DIEPINTx is cleared.
1125
858
// IEPINT will be cleared when DAINT's out bits are cleared.
1126
859
for (uint8_t n = 0 ; n < ep_count ; n ++ ) {
1127
860
if (dwc2 -> daint & TU_BIT (DAINT_IEPINT_Pos + n )) {
1128
861
// IN XFER complete (entire xfer).
1129
862
xfer_ctl_t * xfer = XFER_CTL_BASE (n , TUSB_DIR_IN );
863
+ dwc2_epin_t * epin = & dwc2 -> epin [n ];
1130
864
1131
- if (epin [ n ]. diepint & DIEPINT_XFRC ) {
1132
- epin [ n ]. diepint = DIEPINT_XFRC ;
865
+ if (epin -> diepint & DIEPINT_XFRC ) {
866
+ epin -> diepint = DIEPINT_XFRC ;
1133
867
1134
868
// EP0 can only handle one packet
1135
869
if ((n == 0 ) && ep0_pending [TUSB_DIR_IN ]) {
1136
870
// Schedule another packet to be transmitted.
1137
871
edpt_schedule_packets (rhport , n , TUSB_DIR_IN , 1 , ep0_pending [TUSB_DIR_IN ]);
1138
872
} else {
1139
- if ((n == 0 ) && dma_enabled (dwc2 )) {
873
+ if ((n == 0 ) && dma_device_enabled (dwc2 )) {
1140
874
dma_setup_prepare (rhport );
1141
875
}
1142
876
dcd_event_xfer_complete (rhport , n | TUSB_DIR_IN_MASK , xfer -> total_len , XFER_RESULT_SUCCESS , true);
1143
877
}
1144
878
}
1145
879
1146
880
// XFER FIFO empty
1147
- if ((epin [ n ]. diepint & DIEPINT_TXFE ) && (dwc2 -> diepempmsk & (1 << n ))) {
881
+ if ((epin -> diepint & DIEPINT_TXFE ) && (dwc2 -> diepempmsk & (1 << n ))) {
1148
882
// diepint's TXFE bit is read-only, software cannot clear it.
1149
883
// It will only be cleared by hardware when written bytes is more than
1150
884
// - 64 bytes or
1151
- // - Half of TX FIFO size (configured by DIEPTXF)
1152
-
1153
- uint16_t remaining_packets = (epin [n ].dieptsiz & DIEPTSIZ_PKTCNT_Msk ) >> DIEPTSIZ_PKTCNT_Pos ;
885
+ // - Half/Empty of TX FIFO size (configured by GAHBCFG.TXFELVL)
886
+ const uint16_t remain_packets = epin -> dieptsiz_bm .packet_count ;
1154
887
1155
888
// Process every single packet (only whole packets can be written to fifo)
1156
- for (uint16_t i = 0 ; i < remaining_packets ; i ++ ) {
1157
- uint16_t const remaining_bytes = (epin [ n ]. dieptsiz & DIEPTSIZ_XFRSIZ_Msk ) >> DIEPTSIZ_XFRSIZ_Pos ;
889
+ for (uint16_t i = 0 ; i < remain_packets ; i ++ ) {
890
+ const uint16_t remain_bytes = (uint16_t ) epin -> dieptsiz_bm . xfer_size ;
1158
891
1159
892
// Packet can not be larger than ep max size
1160
- uint16_t const packet_size = tu_min16 (remaining_bytes , xfer -> max_size );
893
+ const uint16_t xact_bytes = tu_min16 (remain_bytes , xfer -> max_size );
1161
894
1162
895
// It's only possible to write full packets into FIFO. Therefore DTXFSTS register of current
1163
896
// EP has to be checked if the buffer can take another WHOLE packet
1164
- if (packet_size > ((epin [n ].dtxfsts & DTXFSTS_INEPTFSAV_Msk ) << 2 )) break ;
897
+ if (xact_bytes > ((epin -> dtxfsts & DTXFSTS_INEPTFSAV_Msk ) << 2 )) {
898
+ break ;
899
+ }
1165
900
1166
901
// Push packet to Tx-FIFO
1167
902
if (xfer -> ff ) {
1168
903
volatile uint32_t * tx_fifo = dwc2 -> fifo [n ];
1169
- tu_fifo_read_n_const_addr_full_words (xfer -> ff , (void * ) (uintptr_t ) tx_fifo , packet_size );
904
+ tu_fifo_read_n_const_addr_full_words (xfer -> ff , (void * ) (uintptr_t ) tx_fifo , xact_bytes );
1170
905
} else {
1171
- dfifo_write_packet (rhport , n , xfer -> buffer , packet_size );
1172
-
1173
- // Increment pointer to xfer data
1174
- xfer -> buffer += packet_size ;
906
+ dfifo_write_packet (dwc2 , n , xfer -> buffer , xact_bytes );
907
+ xfer -> buffer += xact_bytes ;
1175
908
}
1176
909
}
1177
910
1178
911
// Turn off TXFE if all bytes are written.
1179
- if ((( epin [ n ]. dieptsiz & DIEPTSIZ_XFRSIZ_Msk ) >> DIEPTSIZ_XFRSIZ_Pos ) == 0 ) {
912
+ if (epin -> dieptsiz_bm . xfer_size == 0 ) {
1180
913
dwc2 -> diepempmsk &= ~(1 << n );
1181
914
}
1182
915
}
@@ -1186,21 +919,11 @@ static void handle_epin_irq(uint8_t rhport) {
1186
919
1187
920
/* Interrupt Hierarchy
1188
921
1189
- DxEPMSK.XferComplMsk DxEPINTn.XferCompl
1190
- | |
1191
- +---------- AND --------+
1192
- |
1193
- DAINT.xEPnInt DAINTMSK.xEPnMsk
1194
- | |
1195
- +---------- AND --------+
1196
- |
1197
- GINTSTS.xEPInt GINTMSK.xEPIntMsk
1198
- | |
1199
- +---------- AND --------+
1200
- |
1201
- GAHBCFG.GblIntrMsk
1202
- |
1203
- IRQn
922
+ DxEPINTn
923
+ |
924
+ DAINT.xEPn
925
+ |
926
+ GINTSTS: xEPInt
1204
927
1205
928
Note: when OTG_MULTI_PROC_INTRPT = 1, Device Each endpoint interrupt deachint/deachmsk/diepeachmsk/doepeachmsk
1206
929
are combined to generate dedicated interrupt line for each endpoint.
0 commit comments