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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy