-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Implement EPx-only RP2040 USB Host #2814
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
This commit fixes issue hathach#2776 hathach#2776. The HCD now routes all USB transfers through the EPx endpoint. It no longer uses the "interrupt" endpoint hardware to handle INTERRUPT and BULK endpoints. The fix avoids the data sequence error handling bug in the RP2040 USB IP's "interrupt" endpoint hardware and allows the host to correctly drop the IN packet with the error without locking up. That fixes rppicomidi/usb_midi_host#14 This fix requires the CPU to handle the SOF interrupt (every ms). That might be an issue for some systems. A benefit of this fix is that BULK transfers are more than 2x faster. There is an opportunity to speed them up further by forcing BULK transfer to begin immediately instead of waiting for the next SOF interrupt. This code has been tested with MSC flash drives, HID devices, and USB Hubs. It works with full speed and low speed HID devices connected at the same time through a hub. With the usb_midi_host application host driver, 4 MIDI devices plugged to a hub can send messages to each other (see the midi2usbhub project).
@hathach The hardware test seems to fail because the flash download failed. Is that a problem with the build system? Flash download worked fine on my system. |
that is my bad, I was migrating HIL machine from pi5 to an VM. Merged with latest should fix this. Please give me a bit of time, I will review and test this as soon as I could |
Anything helpful in this young repo? => https://github.com/shreeve/picousb |
@shreeve Helpful to this code, or to picousb? My testing shows that this code works better than the TinyUSB host controller driver code for the RP2040 that is currently in TinyUSB. It works around a RP2040 hardware issue and it makes bulk transfers faster than what you get with the current HCD. Do you see an area for improvement in this pull request? |
@rppicomidi - It's hard for me to grok the code since it is very compact and there is a lot going on. I've started the other project to try to create a simpler and dynamic version of USB Host. Ha Thach has done an AMAZING job with TinyUSB though and has had a huge impact. My small little library is primarily nowhere near close to a fraction of what he has done, but it is a small effort to understand how the rp2040 USB Host mode works and hopefully it will inspire someone else. Thank you for your work on this patch! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The PR works on my test system.
is still PR still on the test list? would be great, thx :) |
Force transfers requested from the application to start as soon as possible. No need to wait for SOF. Use as much of the frame as possible for pending transfers. If there is time left in the frame, can retry NAK'd BULK transfers.
@hathach I pushed some changes to remove dead code and make this HCD even faster. Even if you don't care about the original data sequence error bug, the speed improvement should make this worth the time to merge. I do understand that the pull request is complicated, that it will take time to review, and that you are very busy, so I will remain patient if you do not have time. Thank you for this project. |
With some MIDI devices, forcing the HCD scheduler to run using an unused interrupt source causes data corruption.
Hello everyone, and thank you all for the effort of speeding up USB host on the Raspberry Pi Pico! Unfortunately, after testing the proposed re-implementation of the RP2xxx HCD, I've found a couple of bugs and potentional issues that would be nice to have fixed:
I really hope these issues will be addressed and resolved, as this patch already shows a vast improvement on bulk transactions on the RP2040 USB Host - my tests already show around 1.0-1.1 MBytes/second for reading 4K/8K sectors from the USB stick, so it would be awesome to have this patch fixed and eventually merged to the mainstream TinyUSB. Thanks in advance! :) |
@wbcbz7 Thank you for taking the time to review this in detail.
Yes, that is because multiple hub support is a relatively new feature. I will address that.
Can you post evidence of that happening? For example, a USB sniffer trace, a log, or a file diff? It will help me root cause the issues you are seeing.
Auto-retry is a "feature" of the RP2040 chip for Control endpoint transfers that I can do nothing about. This HCD has to assume Control endpoint transfers are rare. I agree that the RP2350 has a workaround feature for this, but this is a RP2040 HCD. If that gets merged, I (or you) can implement a RP2350 HCD. The RP2040 will also auto-retry Bulk endpoint transfers; however, the workaround for that is supposed to be to configure Bulk endpoint transfers as Interrupt endpoint transfers; Interrrupt endpoint transfers to EPx are not supposed to auto-retry after NAK. I thought I already did that, but if not, I will fix it. |
This code seems to work fine with the mainline TunyUSB, but with your branch, all transfers, including MSC reads/writes, ocassionally stop until reboot after new device being connected, or an assert in
(please ignore the I've been tinkering with your branch's code in a local repo - unfortunately I've first merged it with latest TinyUSB by manually copying the driver files so original commit history is lost. If you're interested, I can put it online :) |
@wbcbz7 Thank you for the additional information. I will try your experiment. By design, the HCD first tries pending Control transfers, then pending Interrupt transfers, and only if there is any time left in the frame does it try pending Bulk transfers. If you are seeing large bulk transfers slowing down HID interrupt polling rate, then there is a problem. Control transfers that NAK for a long time could potentially slow down the polling interval because RP2040 auto-retry cannot be disabled for Control endpoints, but Bulk transfers should not. The function that tells the RP2040 that both Interrupt and Bulk transfers are to be handled as Interrupt endpoint transfers is |
@wbcbz7 I have addressed the hub issue and have done a git merge with the latest TinyUSB and pushed it up. I am trying your test code now and find no evidence of issues yet. I am using a powered 4-port hub, a USB mouse plus 2 USB flash drives. Is there a particular block size or blocks per transfer number that causes issues in your testing? Is it possible that the merged code you created introduced some other issue? |
@rppicomidi, I've just linked the test application with your latest commit, and while it seems to bie slightly more stable, it still appears to occasionally hang during bulk transfers if control transfers are executed concurrently. I've tried usb-sniffer-lite to capture USB frame data but even with an external trigger it seems to not have enough buffer memory to capture the exact moment of hang, so I had to revert back to my logic analyzer. Attached there are two PulseView sessions with bulk in transfers gets intervened by control transfers, which leads to former being stuck - i've also attached USB packet text annotations exported. rp2040_tinyusb_bulk_hang_after_setup_2.zip |
I installed the changed files in a PICO 2W with FreeRTOS (running on 2 cores) and it does seem to prevent the run away NAKs. |
This commit fixes issue #2776
#2776.
The HCD now routes all USB transfers through the EPx endpoint. It no longer uses the "interrupt" endpoint hardware to handle INTERRUPT and BULK endpoints. The fix avoids the data sequence error handling bug in the RP2040 USB IP's "interrupt" endpoint hardware
and allows the host to correctly drop the IN packet with the error without locking up. That fixes
rppicomidi/usb_midi_host#14
This fix requires the CPU to handle the SOF interrupt (every ms). That might be an issue for some systems.
A benefit of this fix is that BULK transfers are
more than 2x faster. There is an opportunity to speed them up further by forcing BULK transfer to begin
immediately instead of waiting for the next SOF interrupt.
This code has been tested with MSC flash drives, HID devices, and USB Hubs. It works with full speed and low speed HID devices connected at the same time through a hub. With the usb_midi_host application host driver, 4 MIDI devices plugged to a hub can send messages to each other (see the [midi2usbhub](https://github.com/rppicomidi/midi2usbhub project).
Describe the PR
See description, above
Additional context
rppicomidi/usb_midi_host#14
raspberrypi/pico-feedback#394