Skip to content

Commit fdb4a87

Browse files
committed
Update TinyUSB DWC2 patch and source
1 parent d2d6d95 commit fdb4a87

File tree

2 files changed

+53
-22
lines changed

2 files changed

+53
-22
lines changed

components/arduino_tinyusb/patches/dcd_dwc2.patch

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,9 +56,9 @@
5656
+#if TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3)
5757
+ _allocated_fifos = 1;
5858
+#endif
59+
60+
usbd_spin_lock(true);
5961
handle_bus_reset(rhport);
60-
}
61-
6262
@@ -1008,7 +1037,11 @@
6363

6464
if (gintsts & GINTSTS_USBSUSP) {

components/arduino_tinyusb/src/dcd_dwc2.c

Lines changed: 51 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
#define DWC2_DEBUG 2
4040

4141
#include "device/dcd.h"
42+
#include "device/usbd_pvt.h"
4243
#include "dwc2_common.h"
4344

4445
//--------------------------------------------------------------------+
@@ -52,6 +53,7 @@ typedef struct {
5253
uint8_t interval;
5354
} xfer_ctl_t;
5455

56+
// This variable is modified from ISR context, so it must be protected by critical section
5557
static xfer_ctl_t xfer_status[DWC2_EP_MAX][2];
5658
#define XFER_CTL_BASE(_ep, _dir) (&xfer_status[_ep][_dir])
5759

@@ -343,6 +345,9 @@ static void edpt_disable(uint8_t rhport, uint8_t ep_addr, bool stall) {
343345
}
344346
}
345347

348+
// Since this function returns void, it is not possible to return a boolean success message
349+
// We must make sure that this function is not called when the EP is disabled
350+
// Must be called from critical section
346351
static void edpt_schedule_packets(uint8_t rhport, const uint8_t epnum, const uint8_t dir) {
347352
dwc2_regs_t* dwc2 = DWC2_REG(rhport);
348353
xfer_ctl_t* const xfer = XFER_CTL_BASE(epnum, dir);
@@ -553,6 +558,8 @@ void dcd_edpt_close_all(uint8_t rhport) {
553558
dwc2_regs_t* dwc2 = DWC2_REG(rhport);
554559
uint8_t const ep_count = _dwc2_controller[rhport].ep_count;
555560

561+
usbd_spin_lock(false);
562+
556563
_dcd_data.allocated_epin_count = 0;
557564

558565
// Disable non-control interrupt
@@ -574,8 +581,9 @@ void dcd_edpt_close_all(uint8_t rhport) {
574581

575582
dfifo_flush_tx(dwc2, 0x10); // all tx fifo
576583
dfifo_flush_rx(dwc2);
577-
578584
dfifo_device_init(rhport); // re-init dfifo
585+
586+
usbd_spin_unlock(false);
579587
}
580588

581589
bool dcd_edpt_iso_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t largest_packet_size) {
@@ -593,21 +601,31 @@ bool dcd_edpt_iso_activate(uint8_t rhport, tusb_desc_endpoint_t const * p_endpo
593601
bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t* buffer, uint16_t total_bytes) {
594602
uint8_t const epnum = tu_edpt_number(ep_addr);
595603
uint8_t const dir = tu_edpt_dir(ep_addr);
596-
597604
xfer_ctl_t* xfer = XFER_CTL_BASE(epnum, dir);
598-
xfer->buffer = buffer;
599-
xfer->ff = NULL;
600-
xfer->total_len = total_bytes;
605+
bool ret;
601606

602-
// EP0 can only handle one packet
603-
if (epnum == 0) {
604-
_dcd_data.ep0_pending[dir] = total_bytes;
607+
usbd_spin_lock(false);
608+
609+
if (xfer->max_size == 0) {
610+
ret = false; // Endpoint is closed
611+
} else {
612+
xfer->buffer = buffer;
613+
xfer->ff = NULL;
614+
xfer->total_len = total_bytes;
615+
616+
// EP0 can only handle one packet
617+
if (epnum == 0) {
618+
_dcd_data.ep0_pending[dir] = total_bytes;
619+
}
620+
621+
// Schedule packets to be sent within interrupt
622+
edpt_schedule_packets(rhport, epnum, dir);
623+
ret = true;
605624
}
606625

607-
// Schedule packets to be sent within interrupt
608-
edpt_schedule_packets(rhport, epnum, dir);
626+
usbd_spin_unlock(false);
609627

610-
return true;
628+
return ret;
611629
}
612630

613631
// The number of bytes has to be given explicitly to allow more flexible control of how many
@@ -620,17 +638,27 @@ bool dcd_edpt_xfer_fifo(uint8_t rhport, uint8_t ep_addr, tu_fifo_t* ff, uint16_t
620638

621639
uint8_t const epnum = tu_edpt_number(ep_addr);
622640
uint8_t const dir = tu_edpt_dir(ep_addr);
623-
624641
xfer_ctl_t* xfer = XFER_CTL_BASE(epnum, dir);
625-
xfer->buffer = NULL;
626-
xfer->ff = ff;
627-
xfer->total_len = total_bytes;
642+
bool ret;
628643

629-
// Schedule packets to be sent within interrupt
630-
// TODO xfer fifo may only available for slave mode
631-
edpt_schedule_packets(rhport, epnum, dir);
644+
usbd_spin_lock(false);
632645

633-
return true;
646+
if (xfer->max_size == 0) {
647+
ret = false; // Endpoint is closed
648+
} else {
649+
xfer->buffer = NULL;
650+
xfer->ff = ff;
651+
xfer->total_len = total_bytes;
652+
653+
// Schedule packets to be sent within interrupt
654+
// TODO xfer fifo may only available for slave mode
655+
edpt_schedule_packets(rhport, epnum, dir);
656+
ret = true;
657+
}
658+
659+
usbd_spin_unlock(false);
660+
661+
return ret;
634662
}
635663

636664
void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) {
@@ -657,6 +685,7 @@ void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) {
657685
//--------------------------------------------------------------------
658686

659687
// 7.4.1 Initialization on USB Reset
688+
// Must be called from critical section
660689
static void handle_bus_reset(uint8_t rhport) {
661690
dwc2_regs_t *dwc2 = DWC2_REG(rhport);
662691
const uint8_t ep_count = dwc2_ep_count(dwc2);
@@ -1009,7 +1038,6 @@ static void handle_ep_irq(uint8_t rhport, uint8_t dir) {
10091038
*/
10101039
void dcd_int_handler(uint8_t rhport) {
10111040
dwc2_regs_t* dwc2 = DWC2_REG(rhport);
1012-
10131041
const uint32_t gintmask = dwc2->gintmsk;
10141042
const uint32_t gintsts = dwc2->gintsts & gintmask;
10151043

@@ -1019,7 +1047,10 @@ void dcd_int_handler(uint8_t rhport) {
10191047
#if TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3)
10201048
_allocated_fifos = 1;
10211049
#endif
1050+
1051+
usbd_spin_lock(true);
10221052
handle_bus_reset(rhport);
1053+
usbd_spin_unlock(true);
10231054
}
10241055

10251056
if (gintsts & GINTSTS_ENUMDNE) {

0 commit comments

Comments
 (0)