Skip to content

Commit 3eb9cb0

Browse files
committed
Update dcd_esp32sx.c
1 parent 956a355 commit 3eb9cb0

File tree

1 file changed

+48
-6
lines changed

1 file changed

+48
-6
lines changed

components/arduino_tinyusb/src/dcd_esp32sx.c

+48-6
Original file line numberDiff line numberDiff line change
@@ -28,20 +28,30 @@
2828

2929
#include "tusb_option.h"
3030

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)
3232

3333
// Espressif
34-
#include "driver/periph_ctrl.h"
3534
#include "freertos/xtensa_api.h"
3635
#include "esp_intr_alloc.h"
3736
#include "esp_log.h"
38-
#include "driver/gpio.h"
3937
#include "soc/dport_reg.h"
4038
#include "soc/gpio_sig_map.h"
4139
#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"
4244

4345
#include "device/dcd.h"
4446

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+
4555
// Max number of bi-directional endpoints including EP0
4656
// Note: ESP32S2 specs say there are only up to 5 IN active endpoints include EP0
4757
// We should probably prohibit enabling Endpoint IN > 4 (not done yet)
@@ -60,6 +70,7 @@ typedef struct {
6070
uint16_t queued_len;
6171
uint16_t max_size;
6272
bool short_packet;
73+
uint8_t interval;
6374
} xfer_ctl_t;
6475

6576
static const char *TAG = "TUSB:DCD";
@@ -284,6 +295,14 @@ void dcd_disconnect(uint8_t rhport)
284295
USB0.dctl |= USB_SFTDISCON_M;
285296
}
286297

298+
void dcd_sof_enable(uint8_t rhport, bool en)
299+
{
300+
(void) rhport;
301+
(void) en;
302+
303+
// TODO implement later
304+
}
305+
287306
/*------------------------------------------------------------------*/
288307
/* DCD Endpoint port
289308
*------------------------------------------------------------------*/
@@ -303,6 +322,7 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const *desc_edpt)
303322

304323
xfer_ctl_t *xfer = XFER_CTL_BASE(epnum, dir);
305324
xfer->max_size = tu_edpt_packet_size(desc_edpt);
325+
xfer->interval = desc_edpt->bInterval;
306326

307327
if (dir == TUSB_DIR_OUT) {
308328
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
423443
USB0.in_ep_reg[epnum].dieptsiz = (num_packets << USB_D_PKTCNT0_S) | total_bytes;
424444
USB0.in_ep_reg[epnum].diepctl |= USB_D_EPENA1_M | USB_D_CNAK1_M; // Enable | CNAK
425445

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+
426453
// Enable fifo empty interrupt only if there are something to put in the fifo.
427454
if(total_bytes != 0) {
428455
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
431458
// Each complete packet for OUT xfers triggers XFRC.
432459
USB0.out_ep_reg[epnum].doeptsiz |= USB_PKTCNT0_M | ((xfer->max_size & USB_XFERSIZE0_V) << USB_XFERSIZE0_S);
433460
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+
}
434468
}
435469
return true;
436470
}
@@ -459,7 +493,8 @@ void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr)
459493
} else {
460494
// Stop transmitting packets and NAK IN xfers.
461495
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) ;
463498

464499
// Disable the endpoint. Note that both SNAK and STALL are set here.
465500
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)
469504

470505
// Flush the FIFO, and wait until we have confirmed it cleared.
471506
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;
474514
while ((USB0.grstctl & USB_TXFFLSH_M) != 0) ;
515+
USB0.grstctl = rstctl_last;
516+
// TODO: Clear grstctl::fifo_num after fifo flsh
475517
} else {
476518
// Only disable currently enabled non-control endpoint
477519
if ((epnum == 0) || !(out_ep[epnum].doepctl & USB_EPENA0_M)) {

0 commit comments

Comments
 (0)