tinyusb icon indicating copy to clipboard operation
tinyusb copied to clipboard

Rp2040 hcd bulk

Open Skyler84 opened this issue 2 years ago • 9 comments

Add support for BULK endpoint transfers. This is achieved by allocating hw_endpoint for bulk transfers, not just interrupt. These endpoints can perform transfers in a non-blocking manner, whereas using EPx would block all other (non interrupt) transfers. This change also allows interrupt transfers in both IN and OUT directions now.

Skyler84 avatar Apr 17 '22 00:04 Skyler84

I can confirm that this patch works with multiple IN/OUT BULK endpoints simultaneously. I am using a raw bare API (tuh_edpt_xfer) to communicate with a custom USB device.

bohdan-tymkiv avatar Apr 27 '22 13:04 bohdan-tymkiv

@Skyler84 I can confirm this patch works with one BULK IN endpoint and and ONE BULK OUT endpoint at the same time with a MIDI Host function.

rppicomidi avatar Apr 27 '22 21:04 rppicomidi

@Skyler84 @bohdan-tymkiv Did you try this patch with a hub? I am finding it works fine when only one device is plugged in but if two devices are plugged in and packets are being sent to both devices, packet corruption occurs. Also, the IN transfers complete on both devices but the second device plugged in has an all-zero packet buffer even though the connected device should be sending data.

rppicomidi avatar Apr 28 '22 17:04 rppicomidi

I have not tested this with a hub yet! Definitely something I can take a look at with my logic analyzer. I've also found that it doesn't work with transfers >64B since that's all that's allocated, and the double buffering is not complete in the HCD i dont think? It's a fairly close solution but I think needs some refinement. edit - I think the corruption may be because the controller isn't waiting long enough for a device to return data?

Skyler84 avatar Apr 28 '22 18:04 Skyler84

I can confirm that this works for direct connection to a CDC device!

johnkjellberg avatar May 04 '22 09:05 johnkjellberg

Have not tried it with the HUB. I think implementing HUB support can be a subject of a different patch. This change works and it basically makes RP2040 Host functional.

bohdan-tymkiv avatar May 19 '22 19:05 bohdan-tymkiv

Any news regarding this? Is the hub support critical for merging, or is there something else that needs to be done before approval?

johnkjellberg avatar Aug 26 '22 08:08 johnkjellberg

I found your patch because my attempts to implement a host for device with a bulk in endpoint and a bulk out endpoint failed. With the patch it actually works, although I've stayed away from complicated setups with hubs.

However, I now have the issue that it's very slow as every new transfer has to wait for the start-of-frame marker because that's the only time where hardware actually polls the endpoint control “register” in DPRAM. If I understand the RP2040 datasheet correctly, the controller would otherwise be able to start a transaction in the middle of a frame if SIE_CTRL.SOF_SYNC is not set. By writing to SIE_CTRL, which is a real register, we can trigger the hardware to do something immediately. I don't see a way to trigger the interrupt endpoints.

So I think we should use the epx endpoint after all, and any transactions that are non-blocking from the point of view of the user should be handled in a software queue somehow.

wrtlprnft avatar Sep 14 '22 12:09 wrtlprnft

I did a proof of concept in https://github.com/wrtlprnft/tinyusb/commit/43a245db80b0f293ab9d3fcb55503e6309feb072.

I don't think it's ready to be a pull request of its own because it requires the user to only have one transfer (tuh_edpt_xfer or tuh_control_xfer) in flight at a time and there are likely many things I didn't think about. Maybe it's useful to someone until there's a better solution.

wrtlprnft avatar Sep 15 '22 11:09 wrtlprnft

I did a proof of concept in wrtlprnft@43a245d.

I don't think it's ready to be a pull request of its own because it requires the user to only have one transfer (tuh_edpt_xfer or tuh_control_xfer) in flight at a time and there are likely many things I didn't think about. Maybe it's useful to someone until there's a better solution.

@wrtlprnft Thanks! This is also the first attempt I have seen that I got working for both CDC and MSC! Seems to be some cleanup bugs though(it crashes/don't work after CDC have been unmounted. Neither CDC or MSC). I will investigate that a bit.

Edit: I found the issue and have put the changes needed as comments in the commit.

johnkjellberg avatar Sep 19 '22 07:09 johnkjellberg

@wrtlprnft Have you seen the discussion #1261? (TL;DR If a bulk IN transfer does not complete (because the device NAKs the transfer), epx is busy until the device sends some data back) I took an admittedly quick look at the PR and did not see such a mechanism. My attempt a while ago in PR #1219 does address receiving NAK on bulk IN, but it is a bit ugly.

rppicomidi avatar Sep 20 '22 04:09 rppicomidi

@rppicomidi I did not see that, but I was wondering about that myself. Thanks for the pointer!

My intended application, which I was doing a quick prototype for to see whether it was feasible and fast enough, was doing JTAG over an FTDI dongle. In that application, I have a clear command/response structure where I know more or less exactly how many Bytes of IN transfer I'll get at what point, so the issue never really arose.

As I said before, my code currently doesn't even attempt to support multiple concurrent transactions, so that's something that will have to be done before I can really consider NAKs in my branch. I'll definitely have a look at your branch because it seems like it solves many of the issues I had.

wrtlprnft avatar Sep 20 '22 07:09 wrtlprnft