Skip to content

Commit 6a87063

Browse files
committed
update tinyusb to fix race condition hathach/tinyusb#2310
1 parent 1708cff commit 6a87063

File tree

7 files changed

+75
-62
lines changed

7 files changed

+75
-62
lines changed

src/arduino/Adafruit_TinyUSB_API.cpp

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -57,22 +57,16 @@ void TinyUSB_Device_FlushCDC(void) {
5757

5858
// Debug log with Serial1
5959
#if CFG_TUSB_DEBUG && defined(CFG_TUSB_DEBUG_PRINTF)
60+
6061
// #define USE_SEGGER_RTT
62+
#define SERIAL_TUSB_DEBUG Serial1
6163

6264
#ifdef USE_SEGGER_RTT
6365
#include "SEGGER_RTT/RTT/SEGGER_RTT.h"
6466
#endif
6567

6668
__attribute__((used)) int CFG_TUSB_DEBUG_PRINTF(const char *__restrict format,
6769
...) {
68-
#ifndef USE_SEGGER_RTT
69-
static bool ser1_inited = false;
70-
if (!ser1_inited) {
71-
ser1_inited = true;
72-
Serial1.begin(115200);
73-
}
74-
#endif
75-
7670
char buf[256];
7771
int len;
7872
va_list ap;
@@ -82,7 +76,13 @@ __attribute__((used)) int CFG_TUSB_DEBUG_PRINTF(const char *__restrict format,
8276
#ifdef USE_SEGGER_RTT
8377
SEGGER_RTT_Write(0, buf, len);
8478
#else
85-
Serial1.write(buf);
79+
static volatile bool ser_inited = false;
80+
if (!ser_inited) {
81+
ser_inited = true;
82+
SERIAL_TUSB_DEBUG.begin(115200);
83+
// SERIAL_TUSB_DEBUG.begin(921600);
84+
}
85+
SERIAL_TUSB_DEBUG.write(buf);
8686
#endif
8787

8888
va_end(ap);

src/arduino/ports/rp2040/tusb_config_rp2040.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ extern "C" {
5454

5555
// For selectively disable device log (when > CFG_TUSB_DEBUG)
5656
// #define CFG_TUD_LOG_LEVEL 3
57+
// #define CFG_TUH_LOG_LEVEL 3
5758

5859
#define CFG_TUSB_MEM_SECTION
5960
#define CFG_TUSB_MEM_ALIGN TU_ATTR_ALIGNED(4)

src/common/tusb_mcu.h

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -217,9 +217,7 @@
217217

218218
// TypeC controller
219219
#define TUP_USBIP_TYPEC_STM32
220-
221220
#define TUP_DCD_ENDPOINT_MAX 8
222-
223221
#define TUP_TYPEC_RHPORTS_NUM 1
224222

225223
#elif TU_CHECK_MCU(OPT_MCU_STM32G0)
@@ -261,14 +259,21 @@
261259
#elif TU_CHECK_MCU(OPT_MCU_STM32U5)
262260
#define TUP_USBIP_DWC2
263261
#define TUP_USBIP_DWC2_STM32
264-
#define TUP_DCD_ENDPOINT_MAX 6
262+
263+
// U59x/5Ax/5Fx/5Gx are highspeed with built-in HS PHY
264+
#if defined(STM32U595xx) || defined(STM32U599xx) || defined(STM32U5A5xx) || defined(STM32U5A9xx) || \
265+
defined(STM32U5F7xx) || defined(STM32U5F9xx) || defined(STM32U5G7xx) || defined(STM32U5G9xx)
266+
#define TUP_DCD_ENDPOINT_MAX 9
267+
#define TUP_RHPORT_HIGHSPEED 1
268+
#else
269+
#define TUP_DCD_ENDPOINT_MAX 6
270+
#endif
265271

266272
#elif TU_CHECK_MCU(OPT_MCU_STM32L5)
267273
#define TUP_USBIP_FSDEV
268274
#define TUP_USBIP_FSDEV_STM32
269275
#define TUP_DCD_ENDPOINT_MAX 8
270276

271-
272277
//--------------------------------------------------------------------+
273278
// Sony
274279
//--------------------------------------------------------------------+

src/device/usbd.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -465,7 +465,7 @@ TU_ATTR_WEAK bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb
465465
/* Type I Format Type Descriptor(2.3.1.6 - Audio Formats) */\
466466
TUD_AUDIO_DESC_TYPE_I_FORMAT(_nBytesPerSample, _nBitsUsedPerSample),\
467467
/* Standard AS Isochronous Audio Data Endpoint Descriptor(4.10.1.1) */\
468-
TUD_AUDIO_DESC_STD_AS_ISO_EP(/*_ep*/ _epin, /*_attr*/ (uint8_t) (TUSB_XFER_ISOCHRONOUS | TUSB_ISO_EP_ATT_ASYNCHRONOUS | TUSB_ISO_EP_ATT_DATA), /*_maxEPsize*/ _epsize, /*_interval*/ TUD_OPT_HIGH_SPEED ? 0x04 : 0x01),\
468+
TUD_AUDIO_DESC_STD_AS_ISO_EP(/*_ep*/ _epin, /*_attr*/ (uint8_t) (TUSB_XFER_ISOCHRONOUS | TUSB_ISO_EP_ATT_ASYNCHRONOUS | TUSB_ISO_EP_ATT_DATA), /*_maxEPsize*/ _epsize, /*_interval*/ 0x01),\
469469
/* Class-Specific AS Isochronous Audio Data Endpoint Descriptor(4.10.1.2) */\
470470
TUD_AUDIO_DESC_CS_AS_ISO_EP(/*_attr*/ AUDIO_CS_AS_ISO_DATA_EP_ATT_NON_MAX_PACKETS_OK, /*_ctrl*/ AUDIO_CTRL_NONE, /*_lockdelayunit*/ AUDIO_CS_AS_ISO_DATA_EP_LOCK_DELAY_UNIT_UNDEFINED, /*_lockdelay*/ 0x0000)
471471

@@ -514,7 +514,7 @@ TU_ATTR_WEAK bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb
514514
/* Type I Format Type Descriptor(2.3.1.6 - Audio Formats) */\
515515
TUD_AUDIO_DESC_TYPE_I_FORMAT(_nBytesPerSample, _nBitsUsedPerSample),\
516516
/* Standard AS Isochronous Audio Data Endpoint Descriptor(4.10.1.1) */\
517-
TUD_AUDIO_DESC_STD_AS_ISO_EP(/*_ep*/ _epin, /*_attr*/ (uint8_t) (TUSB_XFER_ISOCHRONOUS | TUSB_ISO_EP_ATT_ASYNCHRONOUS | TUSB_ISO_EP_ATT_DATA), /*_maxEPsize*/ _epsize, /*_interval*/ TUD_OPT_HIGH_SPEED ? 0x04 : 0x01),\
517+
TUD_AUDIO_DESC_STD_AS_ISO_EP(/*_ep*/ _epin, /*_attr*/ (uint8_t) (TUSB_XFER_ISOCHRONOUS | TUSB_ISO_EP_ATT_ASYNCHRONOUS | TUSB_ISO_EP_ATT_DATA), /*_maxEPsize*/ _epsize, /*_interval*/ 0x01),\
518518
/* Class-Specific AS Isochronous Audio Data Endpoint Descriptor(4.10.1.2) */\
519519
TUD_AUDIO_DESC_CS_AS_ISO_EP(/*_attr*/ AUDIO_CS_AS_ISO_DATA_EP_ATT_NON_MAX_PACKETS_OK, /*_ctrl*/ AUDIO_CTRL_NONE, /*_lockdelayunit*/ AUDIO_CS_AS_ISO_DATA_EP_LOCK_DELAY_UNIT_UNDEFINED, /*_lockdelay*/ 0x0000)
520520

@@ -562,7 +562,7 @@ TU_ATTR_WEAK bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb
562562
/* Type I Format Type Descriptor(2.3.1.6 - Audio Formats) */\
563563
TUD_AUDIO_DESC_TYPE_I_FORMAT(_nBytesPerSample, _nBitsUsedPerSample),\
564564
/* Standard AS Isochronous Audio Data Endpoint Descriptor(4.10.1.1) */\
565-
TUD_AUDIO_DESC_STD_AS_ISO_EP(/*_ep*/ _epout, /*_attr*/ (uint8_t) (TUSB_XFER_ISOCHRONOUS | TUSB_ISO_EP_ATT_ASYNCHRONOUS | TUSB_ISO_EP_ATT_DATA), /*_maxEPsize*/ _epsize, /*_interval*/ TUD_OPT_HIGH_SPEED ? 0x04 : 0x01),\
565+
TUD_AUDIO_DESC_STD_AS_ISO_EP(/*_ep*/ _epout, /*_attr*/ (uint8_t) (TUSB_XFER_ISOCHRONOUS | TUSB_ISO_EP_ATT_ASYNCHRONOUS | TUSB_ISO_EP_ATT_DATA), /*_maxEPsize*/ _epsize, /*_interval*/ 0x01),\
566566
/* Class-Specific AS Isochronous Audio Data Endpoint Descriptor(4.10.1.2) */\
567567
TUD_AUDIO_DESC_CS_AS_ISO_EP(/*_attr*/ AUDIO_CS_AS_ISO_DATA_EP_ATT_NON_MAX_PACKETS_OK, /*_ctrl*/ AUDIO_CTRL_NONE, /*_lockdelayunit*/ AUDIO_CS_AS_ISO_DATA_EP_LOCK_DELAY_UNIT_UNDEFINED, /*_lockdelay*/ 0x0000),\
568568
/* Standard AS Isochronous Feedback Endpoint Descriptor(4.10.2.1) */\

src/host/usbh.c

Lines changed: 41 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -86,16 +86,12 @@ typedef struct
8686
uint8_t rhport;
8787
uint8_t hub_addr;
8888
uint8_t hub_port;
89-
uint8_t speed;
90-
91-
// enumeration is in progress, done when all interfaces are configured
92-
volatile uint8_t enumerating;
9389

94-
// struct TU_ATTR_PACKED {
95-
// uint8_t speed : 4; // packed speed to save footprint
96-
// volatile uint8_t enumerating : 1;
97-
// uint8_t TU_RESERVED : 3;
98-
// };
90+
struct TU_ATTR_PACKED {
91+
uint8_t speed : 4; // packed speed to save footprint
92+
volatile uint8_t enumerating : 1; // enumeration is in progress, false if not connected or all interfaces are configured
93+
uint8_t TU_RESERVED : 3;
94+
};
9995
} usbh_dev0_t;
10096

10197
typedef struct {
@@ -462,8 +458,8 @@ void tuh_task_ext(uint32_t timeout_ms, bool in_isr) {
462458
switch (event.event_id)
463459
{
464460
case HCD_EVENT_DEVICE_ATTACH:
465-
// due to the shared _usbh_ctrl_buf, we must complete enumerating
466-
// one device before enumerating another one.
461+
// due to the shared _usbh_ctrl_buf, we must complete enumerating one device before enumerating another one.
462+
// TODO better to have an separated queue for newly attached devices
467463
if ( _dev0.enumerating ) {
468464
TU_LOG_USBH("[%u:] USBH Defer Attach until current enumeration complete\r\n", event.rhport);
469465

@@ -587,11 +583,17 @@ bool tuh_control_xfer (tuh_xfer_t* xfer) {
587583
// EP0 with setup packet
588584
TU_VERIFY(xfer->ep_addr == 0 && xfer->setup);
589585

590-
// pre-check to help reducing mutex lock
591-
TU_VERIFY(_ctrl_xfer.stage == CONTROL_STAGE_IDLE);
592-
586+
// Check if device is still connected (enumerating for dev0)
593587
uint8_t const daddr = xfer->daddr;
588+
if ( daddr == 0 ) {
589+
if (!_dev0.enumerating) return false;
590+
} else {
591+
usbh_device_t const* dev = get_device(daddr);
592+
if (dev && dev->connected == 0) return false;
593+
}
594594

595+
// pre-check to help reducing mutex lock
596+
TU_VERIFY(_ctrl_xfer.stage == CONTROL_STAGE_IDLE);
595597
(void) osal_mutex_lock(_usbh_mutex, OSAL_TIMEOUT_WAIT_FOREVER);
596598

597599
bool const is_idle = (_ctrl_xfer.stage == CONTROL_STAGE_IDLE);
@@ -691,7 +693,7 @@ static bool usbh_control_xfer_cb (uint8_t dev_addr, uint8_t ep_addr, xfer_result
691693

692694
if (XFER_RESULT_SUCCESS != result) {
693695
TU_LOG1("[%u:%u] Control %s, xferred_bytes = %lu\r\n", rhport, dev_addr, result == XFER_RESULT_STALLED ? "STALLED" : "FAILED", xferred_bytes);
694-
TU_LOG_BUF(1, request, 8);
696+
TU_LOG1_BUF(request, 8);
695697
TU_LOG1("\r\n");
696698

697699
// terminate transfer if any stage failed
@@ -948,19 +950,23 @@ void hcd_devtree_get_info(uint8_t dev_addr, hcd_devtree_info_t* devtree_info)
948950
}
949951
}
950952

951-
TU_ATTR_FAST_FUNC void hcd_event_handler(hcd_event_t const* event, bool in_isr)
952-
{
953-
switch (event->event_id)
954-
{
955-
// case HCD_EVENT_DEVICE_REMOVE:
956-
// // FIXME device remove from a hub need an HCD API for hcd to free up endpoint
957-
// // mark device as removing to prevent further xfer before the event is processed in usbh task
958-
// break;
953+
TU_ATTR_FAST_FUNC void hcd_event_handler(hcd_event_t const* event, bool in_isr) {
954+
switch (event->event_id) {
955+
case HCD_EVENT_DEVICE_REMOVE:
956+
// FIXME device remove from a hub need an HCD API for hcd to free up endpoint
957+
// mark device as removing to prevent further xfer before the event is processed in usbh task
959958

960-
default:
961-
osal_queue_send(_usbh_q, event, in_isr);
962-
break;
959+
// Check if dev0 is removed
960+
if ((event->rhport == _dev0.rhport) && (event->connection.hub_addr == _dev0.hub_addr) &&
961+
(event->connection.hub_port == _dev0.hub_port)) {
962+
_dev0.enumerating = 0;
963+
}
964+
break;
965+
966+
default: break;
963967
}
968+
969+
osal_queue_send(_usbh_q, event, in_isr);
964970
}
965971

966972
//--------------------------------------------------------------------+
@@ -1325,28 +1331,28 @@ static bool _parse_configuration_descriptor (uint8_t dev_addr, tusb_desc_configu
13251331
static void enum_full_complete(void);
13261332

13271333
// process device enumeration
1328-
static void process_enumeration(tuh_xfer_t* xfer)
1329-
{
1334+
static void process_enumeration(tuh_xfer_t* xfer) {
13301335
// Retry a few times with transfers in enumeration since device can be unstable when starting up
13311336
enum {
13321337
ATTEMPT_COUNT_MAX = 3,
13331338
ATTEMPT_DELAY_MS = 100
13341339
};
13351340
static uint8_t failed_count = 0;
13361341

1337-
if (XFER_RESULT_SUCCESS != xfer->result)
1338-
{
1342+
if (XFER_RESULT_SUCCESS != xfer->result) {
13391343
// retry if not reaching max attempt
1340-
if ( failed_count < ATTEMPT_COUNT_MAX )
1341-
{
1344+
bool retry = _dev0.enumerating && (failed_count < ATTEMPT_COUNT_MAX);
1345+
if ( retry ) {
13421346
failed_count++;
13431347
osal_task_delay(ATTEMPT_DELAY_MS); // delay a bit
13441348
TU_LOG1("Enumeration attempt %u\r\n", failed_count);
1345-
TU_ASSERT(tuh_control_xfer(xfer), );
1346-
}else
1347-
{
1349+
retry = tuh_control_xfer(xfer);
1350+
}
1351+
1352+
if (!retry) {
13481353
enum_full_complete();
13491354
}
1355+
13501356
return;
13511357
}
13521358
failed_count = 0;

src/portable/raspberrypi/pio_usb/hcd_pio_usb.c

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -182,14 +182,6 @@ void __no_inline_not_in_flash_func(pio_usb_host_irq_handler)(uint8_t root_id) {
182182
root_port_t *rport = PIO_USB_ROOT_PORT(root_id);
183183
uint32_t const ints = rport->ints;
184184

185-
if ( ints & PIO_USB_INTS_CONNECT_BITS ) {
186-
hcd_event_device_attach(tu_rhport, true);
187-
}
188-
189-
if ( ints & PIO_USB_INTS_DISCONNECT_BITS ) {
190-
hcd_event_device_remove(tu_rhport, true);
191-
}
192-
193185
if ( ints & PIO_USB_INTS_ENDPOINT_COMPLETE_BITS ) {
194186
handle_endpoint_irq(rport, XFER_RESULT_SUCCESS, &rport->ep_complete);
195187
}
@@ -202,6 +194,14 @@ void __no_inline_not_in_flash_func(pio_usb_host_irq_handler)(uint8_t root_id) {
202194
handle_endpoint_irq(rport, XFER_RESULT_FAILED, &rport->ep_error);
203195
}
204196

197+
if ( ints & PIO_USB_INTS_CONNECT_BITS ) {
198+
hcd_event_device_attach(tu_rhport, true);
199+
}
200+
201+
if ( ints & PIO_USB_INTS_DISCONNECT_BITS ) {
202+
hcd_event_device_remove(tu_rhport, true);
203+
}
204+
205205
// clear all
206206
rport->ints &= ~ints;
207207
}

src/tusb_option.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -174,10 +174,10 @@
174174
// NXP LPC MCX
175175
#define OPT_MCU_MCXN9 2300 ///< NXP MCX N9 Series
176176

177-
// Helper to check if configured MCU is one of listed
177+
// Check if configured MCU is one of listed
178178
// Apply _TU_CHECK_MCU with || as separator to list of input
179-
#define _TU_CHECK_MCU(_m) (CFG_TUSB_MCU == _m)
180-
#define TU_CHECK_MCU(...) (TU_ARGS_APPLY(_TU_CHECK_MCU, ||, __VA_ARGS__))
179+
#define _TU_CHECK_MCU(_m) (CFG_TUSB_MCU == _m)
180+
#define TU_CHECK_MCU(...) (TU_ARGS_APPLY(_TU_CHECK_MCU, ||, __VA_ARGS__))
181181

182182
//--------------------------------------------------------------------+
183183
// Supported OS
@@ -273,6 +273,7 @@
273273
// highspeed support indicator
274274
#define TUH_OPT_HIGH_SPEED (CFG_TUH_MAX_SPEED ? (CFG_TUH_MAX_SPEED & OPT_MODE_HIGH_SPEED) : TUP_RHPORT_HIGHSPEED)
275275

276+
276277
//--------------------------------------------------------------------+
277278
// TODO move later
278279
//--------------------------------------------------------------------+

0 commit comments

Comments
 (0)