summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGordon McNab <[email protected]>2022-11-30 12:16:52 +0000
committerGitHub <[email protected]>2022-11-30 12:16:52 +0000
commitaceab1dcf3a57d2e789efc0781685beb33e94754 (patch)
tree877481517624c02d8da49d2260a40bde1555a8b9 /src
parent1437ad1dfb5b48169f680253707821bd9751fc65 (diff)
parent2ae6a4d519cdb1d8df7a4c7b9a979b8ad3713e88 (diff)
Merge branch 'hathach:master' into port-ft90x
Diffstat (limited to 'src')
-rw-r--r--src/common/tusb_types.h2
-rw-r--r--src/host/usbh.c24
-rw-r--r--src/host/usbh.h12
-rw-r--r--src/portable/raspberrypi/rp2040/rp2040_usb.c4
4 files changed, 31 insertions, 11 deletions
diff --git a/src/common/tusb_types.h b/src/common/tusb_types.h
index e11f08dd1..1bfa7c7d1 100644
--- a/src/common/tusb_types.h
+++ b/src/common/tusb_types.h
@@ -225,7 +225,7 @@ enum {
typedef enum
{
- XFER_RESULT_SUCCESS,
+ XFER_RESULT_SUCCESS = 0,
XFER_RESULT_FAILED,
XFER_RESULT_STALLED,
XFER_RESULT_TIMEOUT,
diff --git a/src/host/usbh.c b/src/host/usbh.c
index 9d618db92..d97b160c9 100644
--- a/src/host/usbh.c
+++ b/src/host/usbh.c
@@ -620,9 +620,7 @@ static void _xfer_complete(uint8_t daddr, xfer_result_t result)
.user_data = _ctrl_xfer.user_data
};
- usbh_lock();
- _ctrl_xfer.stage = CONTROL_STAGE_IDLE;
- usbh_unlock();
+ _set_control_xfer_stage(CONTROL_STAGE_IDLE);
if (xfer_temp.complete_cb)
{
@@ -1182,12 +1180,28 @@ static void enum_full_complete(void);
// process device enumeration
static void process_enumeration(tuh_xfer_t* xfer)
{
+ // Retry a few times with transfers in enumeration since device can be unstable when starting up
+ enum {
+ ATTEMPT_COUNT_MAX = 3,
+ ATTEMPT_DELAY_MS = 100
+ };
+ static uint8_t failed_count = 0;
+
if (XFER_RESULT_SUCCESS != xfer->result)
{
- // stop enumeration, maybe we could retry this
- enum_full_complete();
+ // retry if not reaching max attempt
+ if ( failed_count < ATTEMPT_COUNT_MAX )
+ {
+ failed_count++;
+ osal_task_delay(ATTEMPT_DELAY_MS); // delay a bit
+ TU_ASSERT(tuh_control_xfer(xfer), );
+ }else
+ {
+ enum_full_complete();
+ }
return;
}
+ failed_count = 0;
uint8_t const daddr = xfer->daddr;
uintptr_t const state = xfer->user_data;
diff --git a/src/host/usbh.h b/src/host/usbh.h
index 1a26a69b4..37de7093c 100644
--- a/src/host/usbh.h
+++ b/src/host/usbh.h
@@ -51,14 +51,15 @@ struct tuh_xfer_s
{
uint8_t daddr;
uint8_t ep_addr;
-
+ uint8_t TU_RESERVED; // reserved
xfer_result_t result;
+
uint32_t actual_len; // excluding setup packet
union
{
tusb_control_request_t const* setup; // setup packet pointer if control transfer
- uint32_t buflen; // expected length if not control transfer (not available in callback)
+ uint32_t buflen; // expected length if not control transfer (not available in callback)
};
uint8_t* buffer; // not available in callback if not control transfer
@@ -80,10 +81,13 @@ enum
//TU_ATTR_WEAK uint8_t tuh_attach_cb (tusb_desc_device_t const *desc_device);
-// Invoked when device is mounted (configured)
+// Invoked when a device is mounted (configured)
TU_ATTR_WEAK void tuh_mount_cb (uint8_t daddr);
-/// Invoked when device is unmounted (bus reset/unplugged)
+// Invoked when a device failed to mount during enumeration process
+// TU_ATTR_WEAK void tuh_mount_failed_cb (uint8_t daddr);
+
+/// Invoked when a device is unmounted (detached)
TU_ATTR_WEAK void tuh_umount_cb(uint8_t daddr);
//--------------------------------------------------------------------+
diff --git a/src/portable/raspberrypi/rp2040/rp2040_usb.c b/src/portable/raspberrypi/rp2040/rp2040_usb.c
index 25c013bd2..d7895175e 100644
--- a/src/portable/raspberrypi/rp2040/rp2040_usb.c
+++ b/src/portable/raspberrypi/rp2040/rp2040_usb.c
@@ -155,7 +155,9 @@ static void __tusb_irq_path_func(_hw_endpoint_start_next_buffer)(struct hw_endpo
// For now: skip double buffered for Device mode, OUT endpoint since
// host could send < 64 bytes and cause short packet on buffer0
// NOTE this could happen to Host mode IN endpoint
- bool const force_single = !(usb_hw->main_ctrl & USB_MAIN_CTRL_HOST_NDEVICE_BITS) && !tu_edpt_dir(ep->ep_addr);
+ // Also, Host mode interrupt endpoint hardware is only single buffered
+ bool const force_single = (!(usb_hw->main_ctrl & USB_MAIN_CTRL_HOST_NDEVICE_BITS) && !tu_edpt_dir(ep->ep_addr)) ||
+ ((usb_hw->main_ctrl & USB_MAIN_CTRL_HOST_NDEVICE_BITS) && tu_edpt_number(ep->ep_addr) != 0);
if(ep->remaining_len && !force_single)
{