diff options
| author | Gordon McNab <[email protected]> | 2022-11-30 12:16:52 +0000 |
|---|---|---|
| committer | GitHub <[email protected]> | 2022-11-30 12:16:52 +0000 |
| commit | aceab1dcf3a57d2e789efc0781685beb33e94754 (patch) | |
| tree | 877481517624c02d8da49d2260a40bde1555a8b9 /src | |
| parent | 1437ad1dfb5b48169f680253707821bd9751fc65 (diff) | |
| parent | 2ae6a4d519cdb1d8df7a4c7b9a979b8ad3713e88 (diff) | |
Merge branch 'hathach:master' into port-ft90x
Diffstat (limited to 'src')
| -rw-r--r-- | src/common/tusb_types.h | 2 | ||||
| -rw-r--r-- | src/host/usbh.c | 24 | ||||
| -rw-r--r-- | src/host/usbh.h | 12 | ||||
| -rw-r--r-- | src/portable/raspberrypi/rp2040/rp2040_usb.c | 4 |
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) { |
