28
28
29
29
#include "tusb_option.h"
30
30
31
- #if (((CFG_TUSB_MCU == OPT_MCU_ESP32S2 ) || (CFG_TUSB_MCU == OPT_MCU_ESP32S3 )) && TUSB_OPT_DEVICE_ENABLED )
31
+ #if (((CFG_TUSB_MCU == OPT_MCU_ESP32S2 ) || (CFG_TUSB_MCU == OPT_MCU_ESP32S3 )) && CFG_TUD_ENABLED )
32
32
33
33
// Espressif
34
- #include "driver/periph_ctrl.h"
35
34
#include "freertos/xtensa_api.h"
36
35
#include "esp_intr_alloc.h"
37
36
#include "esp_log.h"
38
- #include "driver/gpio.h"
39
37
#include "soc/dport_reg.h"
40
38
#include "soc/gpio_sig_map.h"
41
39
#include "soc/usb_periph.h"
40
+ #include "soc/usb_reg.h"
41
+ #include "soc/usb_struct.h"
42
+ #include "soc/periph_defs.h" // for interrupt source
43
+ #include "soc/usb_wrap_struct.h"
42
44
43
45
#include "device/dcd.h"
44
46
47
+ #ifndef USB_OUT_EP_NUM
48
+ #define USB_OUT_EP_NUM ((int) (sizeof(USB0.out_ep_reg) / sizeof(USB0.out_ep_reg[0])))
49
+ #endif
50
+
51
+ #ifndef USB_IN_EP_NUM
52
+ #define USB_IN_EP_NUM ((int) (sizeof(USB0.in_ep_reg) / sizeof(USB0.in_ep_reg[0])))
53
+ #endif
54
+
45
55
// Max number of bi-directional endpoints including EP0
46
56
// Note: ESP32S2 specs say there are only up to 5 IN active endpoints include EP0
47
57
// We should probably prohibit enabling Endpoint IN > 4 (not done yet)
@@ -60,6 +70,7 @@ typedef struct {
60
70
uint16_t queued_len ;
61
71
uint16_t max_size ;
62
72
bool short_packet ;
73
+ uint8_t interval ;
63
74
} xfer_ctl_t ;
64
75
65
76
static const char * TAG = "TUSB:DCD" ;
@@ -284,6 +295,14 @@ void dcd_disconnect(uint8_t rhport)
284
295
USB0 .dctl |= USB_SFTDISCON_M ;
285
296
}
286
297
298
+ void dcd_sof_enable (uint8_t rhport , bool en )
299
+ {
300
+ (void ) rhport ;
301
+ (void ) en ;
302
+
303
+ // TODO implement later
304
+ }
305
+
287
306
/*------------------------------------------------------------------*/
288
307
/* DCD Endpoint port
289
308
*------------------------------------------------------------------*/
@@ -303,6 +322,7 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const *desc_edpt)
303
322
304
323
xfer_ctl_t * xfer = XFER_CTL_BASE (epnum , dir );
305
324
xfer -> max_size = tu_edpt_packet_size (desc_edpt );
325
+ xfer -> interval = desc_edpt -> bInterval ;
306
326
307
327
if (dir == TUSB_DIR_OUT ) {
308
328
out_ep [epnum ].doepctl &= ~(USB_D_EPTYPE0_M | USB_D_MPS0_M );
@@ -423,6 +443,13 @@ bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_t to
423
443
USB0 .in_ep_reg [epnum ].dieptsiz = (num_packets << USB_D_PKTCNT0_S ) | total_bytes ;
424
444
USB0 .in_ep_reg [epnum ].diepctl |= USB_D_EPENA1_M | USB_D_CNAK1_M ; // Enable | CNAK
425
445
446
+ // For ISO endpoint with interval=1 set correct DATA0/DATA1 bit for next frame
447
+ if ((USB0 .in_ep_reg [epnum ].diepctl & USB_D_EPTYPE0_M ) == (1 << USB_D_EPTYPE1_S ) && xfer -> interval == 1 ) {
448
+ // Take odd/even bit from frame counter.
449
+ uint32_t const odd_frame_now = (USB0 .dsts & (1u << USB_SOFFN_S ));
450
+ USB0 .in_ep_reg [epnum ].diepctl |= (odd_frame_now ? USB_DI_SETD0PID1 : USB_DI_SETD1PID1 );
451
+ }
452
+
426
453
// Enable fifo empty interrupt only if there are something to put in the fifo.
427
454
if (total_bytes != 0 ) {
428
455
USB0 .dtknqr4_fifoemptymsk |= (1 << epnum );
@@ -431,6 +458,13 @@ bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_t to
431
458
// Each complete packet for OUT xfers triggers XFRC.
432
459
USB0 .out_ep_reg [epnum ].doeptsiz |= USB_PKTCNT0_M | ((xfer -> max_size & USB_XFERSIZE0_V ) << USB_XFERSIZE0_S );
433
460
USB0 .out_ep_reg [epnum ].doepctl |= USB_EPENA0_M | USB_CNAK0_M ;
461
+
462
+ // For ISO endpoint with interval=1 set correct DATA0/DATA1 bit for next frame
463
+ if ((USB0 .out_ep_reg [epnum ].doepctl & USB_D_EPTYPE0_M ) == (1 << USB_D_EPTYPE1_S ) && xfer -> interval == 1 ) {
464
+ // Take odd/even bit from frame counter.
465
+ uint32_t const odd_frame_now = (USB0 .dsts & (1u << USB_SOFFN_S ));
466
+ USB0 .out_ep_reg [epnum ].doepctl |= (odd_frame_now ? USB_DO_SETD0PID1 : USB_DO_SETD1PID1 );
467
+ }
434
468
}
435
469
return true;
436
470
}
@@ -459,7 +493,8 @@ void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr)
459
493
} else {
460
494
// Stop transmitting packets and NAK IN xfers.
461
495
in_ep [epnum ].diepctl |= USB_DI_SNAK1_M ;
462
- while ((in_ep [epnum ].diepint & USB_DI_SNAK1_M ) == 0 ) ;
496
+ // while ((in_ep[epnum].diepint & USB_DI_SNAK1_M) == 0) ;
497
+ while ((in_ep [epnum ].diepint & USB_D_INEPNAKEFF1_M ) == 0 ) ;
463
498
464
499
// Disable the endpoint. Note that both SNAK and STALL are set here.
465
500
in_ep [epnum ].diepctl |= (USB_DI_SNAK1_M | USB_D_STALL1_M | USB_D_EPDIS1_M );
@@ -469,9 +504,16 @@ void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr)
469
504
470
505
// Flush the FIFO, and wait until we have confirmed it cleared.
471
506
uint8_t const fifo_num = ((in_ep [epnum ].diepctl >> USB_D_TXFNUM1_S ) & USB_D_TXFNUM1_V );
472
- USB0 .grstctl |= (fifo_num << USB_TXFNUM_S );
473
- USB0 .grstctl |= USB_TXFFLSH_M ;
507
+ // USB0.grstctl |= (fifo_num << USB_TXFNUM_S);
508
+ // USB0.grstctl |= USB_TXFFLSH_M;
509
+ // while ((USB0.grstctl & USB_TXFFLSH_M) != 0) ;
510
+ uint32_t rstctl_last = USB0 .grstctl ;
511
+ uint32_t rstctl = USB_TXFFLSH_M ;
512
+ rstctl |= (fifo_num << USB_TXFNUM_S );
513
+ USB0 .grstctl = rstctl ;
474
514
while ((USB0 .grstctl & USB_TXFFLSH_M ) != 0 ) ;
515
+ USB0 .grstctl = rstctl_last ;
516
+ // TODO: Clear grstctl::fifo_num after fifo flsh
475
517
} else {
476
518
// Only disable currently enabled non-control endpoint
477
519
if ((epnum == 0 ) || !(out_ep [epnum ].doepctl & USB_EPENA0_M )) {
0 commit comments