Skip to content

RP2040 PIO USB Host does not detect device unplug #2971

@rppicomidi

Description

@rppicomidi

Operating System

Linux

Board

Feather RP2040 with USB A Host

Firmware

https://github.com/rppicomidi/usb_midi_host/tree/main/examples/C-code/usb_midi_host_pio_example

I think the version in GitHub may not have specific support for the Feather board yet, but it will shortly.

What happened ?

I have connected a powered USB 2.0 hub to the USB A port of the Feather board. If I plug a MIDI device to the hub, it enumerates correctly and starts working. If I unplug the hub from the Feather board, the software correctly detects the MIDI device is unplugged. If I plug the hub back in with the MIDI device still connected, it enumerates again and starts working again. However, if I leave the hub plugged in and unplug the device, the software does not detect the MIDI device was unplugged.

If I build firmware that uses the native RP2040 USB hardware for the USB host, I do not see this issue.

How to reproduce ?

  1. Build the firmware above for the Feather board
  2. Connect a USB C cable to the board and the build computer and load the firmware to the Feather board.
  3. Disconnect the Feather board from the computer.
  4. Connect a UART to USB serial adapter to the Feather board's ground pin and the Feather board's UART RX and TX pins
  5. Plug the serial adapter to the PC and launch a terminal program such as minicom.
  6. Plug the Feather board's USB C cable to a 5V power source.
  7. Observe the Pico MIDI Host Example message on the serial terminal
  8. Plug a powered hub with power applied to the Feather's USB A port.
  9. Plug a MIDI device to the USB hub. Observe the connection message on the serial terminal.
  10. Move a control, press a button, etc. on the MIDI device and confirm the serial terminal registers the MIDI events
  11. Unplug the powered hub with the MIDI device still plugged in.
  12. Observe the disconnect message on the serial terminal.
  13. Plug the hub and device back in to the Feather board's USB A port.
  14. Observe the connection message on the serial terminal.
  15. Move a control, press a button, etc. on the MIDI device and confirm the serial terminal registers the MIDI events
  16. Leave the hub connected to the Feather board's USB A port and unplug the MIDI device from the hub.
  17. Observe no disconnect message. Also observe plugging the device back in does not work.

Debug Log as txt file (LOG/CFG_TUSB_DEBUG=2)

I lost my log files, but logs showed first the bulk transfer failed from the MIDI device, which is expected, but then the interrupt IN transfer failed from the hub, which is not. The file hub.c is coded so that if the transfer result is not XFER_RESULT_SUCCESS, then the host stops polling the hub for status change.

bool hub_xfer_cb(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) {
  (void) xferred_bytes; // TODO can be more than 1 for hub with lots of ports
  (void) ep_addr;
  TU_VERIFY(result == XFER_RESULT_SUCCESS);

Screenshots

@hathach I can work around this issue with the following patch to hub.c, but I think that maybe this is not really fixing the bug. If you have advice where to look in the HCD for TinyUSB or in the low-level stuff in the Pico-PIO-USB project, I will try to make a pull request. If you want a pull request with fix below, I can do that too.

diff --git a/src/host/hub.c b/src/host/hub.c
index e97014443..daf036d60 100644
--- a/src/host/hub.c
+++ b/src/host/hub.c
@@ -334,7 +334,18 @@ static void connection_port_reset_complete (tuh_xfer_t* xfer);
 bool hub_xfer_cb(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) {
   (void) xferred_bytes; // TODO can be more than 1 for hub with lots of ports
   (void) ep_addr;
+
+  static uint8_t retries = 0;
+  if (result == XFER_RESULT_FAILED) {
+    // try again up to 3 times.
+    if (retries++ < 3) {
+      hub_edpt_status_xfer(dev_addr);
+      TU_LOG2("HUB Xfer failed; retry %u\r\n", retries);
+    }
+    return 0;
+  }
   TU_VERIFY(result == XFER_RESULT_SUCCESS);
+  retries = 0;
 
   hub_interface_t* p_hub = get_itf(dev_addr);

I have checked existing issues, dicussion and documentation

  • I confirm I have checked existing issues, dicussion and documentation.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions