-
Notifications
You must be signed in to change notification settings - Fork 669
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
pyusb isoc transfer under Windows, macOS and Linux #380
Comments
Run log following the turorial (no issues with the bulkloop and bulksrcsink example):
|
"lsusb -vvv" output
|
Error messages under Linux (Raspberry Pi 400 running Ubuntu Linux 64bit)
|
Same results under Windows as macOS, I am using libusbk driver, as libusb WinUSB does not work well with isoc transfer.
|
But let me try to adapt he C based program to work first under any of the OS, before confirming that pyusb is the issue. Previously I could not adapt the above C based program to work under Windows, so I think libusb-1.0 under Windows is the issue there. I will try under macOS and Linux. |
Looks like it does work under macOS, tested with the pyusb benchmark firmware, I need to explicitly set the alt_setting 2 in this case. It also matches the result with the C based application, where only 32bytes/64bytes testing works but higher number will be faulty (probably FW bug). So pyusb itself seems to be okay.
|
Same thing that it actually works with the pyusb benchmark firmware, pyusb results match the C based code.
|
C based code: 2 packets loopback are okay, more packets will cause problems, looks like FW bug to me. So pyusb is okay with full speed isoc transfer under Linux and macOS. I will try high speed and superspeed later.
|
The benchmark firmware does not really work under Windows with the C based code, so it is also not working under pyusb under Windows. Therefore I will test with the FX3 known good isoloop and isosrcsink FW which is known to work under Windows with libusbK (but may not work well with libusb-1.0 Windows, need to test it out). |
I am seeing some funny results from the FX3 isoloop test (the readback data is funny), but it may not be related to pyusb, but rather libusb-1.0 Windows. WinUSB is totally not working which is kind of in line with the issue reports with libusb github. libusbk isoc transfer works better in 1.0.23 release but not 1.0.24 release or the latest git. So that is a libusb-1.0 Windows issue and not pyusb issue. I will test macOS and Linux, if there are no issues, I will close this one.
|
No issues under macOS, tested with my Mac Mini M1, I also checked returned data (with 1024Bytes transfer) and they seem to be okay.
|
Same results under my Raspberry Pi 400 running Ubuntu 64bit Linux.
|
In summary, pyusb isoc codes seem to work under Linux and macOS. It does not seem to work well under Windows but the issue may well be with libusb-1.0 itself and not pyusb. So I will close this issue. |
On the other hand, real isoc API should really be async, so the improvement for async API should still be applicable. |
Thanks for testing this, and I'm glad to hear that it seems to be mostly working (barring FW or libusb1 limitations).
Can you clarify? I'm not familiar with the use cases for isoc transfers... Implementation wise, as long as it makes sense to have blocking isoc read and write, their current implementations for libusb1 seem to be correct (repeatedly calling |
Yes if there are real use case of block isoc read and write, then the implementation seems to be correct. But majority of the use case of isoc transfer is really for video/audio and other types real time data, blocking transfer may not be good enough. What I mean is that the WIP #303 is not complete and it needs to implement for control transfer and isoc transfer. As for high level API, I am not an expert for Python so I am not so sure what will be good there. For isoc transfer, you can see that libusb-1.0 API is more complicated than interrupt/bulk transfer. So I am not so sure if the approach of #303 can cover isoc transfer well enough or not. And Travis actually creates quite some high level APIs for isoc transfer. Even though libusbk is Windows only, somehow I feel the API is nicer for async transfer and isoc transfer than libusb-1.0. |
Some testing results under Windows with libusb-1.0.26rc1. Isoc transfer seems to work now under Windows with libusbk driver. |
I see in the log in the libusb ticket that it fails in bulk_read. Should that be iso_read? From looking at usb/core.py:1022 it looks like the returned ep must be wrong or has the wrong attributes. Can you please dump the values here? |
I will generate the debug log. 0x82 is an isoc endpoint. The FW is from Cypress and is a known-good firmware (tested with Cypress Windows CySteeam app and libusbk kbench). I believe the problem comes from libusb Windows (isoc problem with WinUSB driver) and not pyusb. |
Great. Yes, since it works with libusbk, the problem is probably in the libusb winusb code. But in any case your debug log might shed some light on what goes wrong. |
I am starting to wonder if it is a pyusb bug, setting the transfer type wrongly to bulk when submitting the transfers, and for some reason this still works fine on libusbk. |
@mcuee can you also enable |
See the order: bulk = 0, intr=1, iso=2 in usb/core.py
EDIT: Sorry, that was not a C array :) |
I tested isochronous transfers with WinUSB with libfreenect/XBox (all C/C++) and it works well. I can see |
Hey, thank you both for looking into this some more. While waiting for mcuee's log, I looked at libusb/libusb#1099 (comment) and there does appear to be a problem in PyUSB: the traceback clearly shows that we're issuing a There isn't anything immediately/obviously wrong with intf, ep = self._ctx.setup_request(self, endpoint) returning the correct endpoint, which I'm no longer convinced it does when altsettings are involved. And that appears to be case (libusb/libusb#1099 (comment)). @mcuee, besides the LibUSB+PyUSB debug log, is it also possible to try with altsetting 0? Footnotes
|
There will always be altsettings with isochronous transfers, because any interface must have a (default?) altsetting without isochronous endpoints. |
Something with self._ep_info going stale? Maybe do ._ep_info.clear() in managed_set_interface() ? |
Okay, I will reopen this ticket. It seems to me pyusb does not work with isoc transfer for this paticular Cystream FW for the Cypress EZUSB FX2LP device. Here is the debug under Linux: Ubuntu 20.04 x64. The following debug is with PYUSB_DEBUG=debug and LIBUSB_DEBUG=3 (it is too much with 4).
|
I think that can also happen, but it's probably not the case here, since no reads or writes were done before the altsetting change. Thanks, I'll take a look. |
Windows libusbk debug log for the FX2LP device running Cystream FW.
|
WinUSB driver debug log.
|
pyusb code:
Device Descriptor of the Cystream FW for the Cypress EZUSB FX2LP.
|
There seems to be no issue with WinUSB or libusbk if I test alt interface 2 (bulk endpoints).
|
I have deleted the SuperSpeed debug log which points to libusb WinUSB issue as mentioned in libusb/libusb#1104. The pyusb issue seems to be with the CyStream FW for FX2LP. |
Endpoints are not shared between different interfaces within a single configuration *except* the endpoint is used by alternate settings of the same interface. Related: #380
@jonasmalacofilho Yes it is better now pyusb submits isoc transfer and not bulk transfer. |
Now there seem to be a few different errors:
Can you take a look at the first two? In the meantime, I'll look into the new finalizer bug. Footnotes |
The reason to use 16384 ( Example debug log for WinUSB if I use 4096 (
libusbk does not have such limitation but it still failed, debug log with LIBUSB_DEBUG=3. The code will immediately exit. libusbk full debug log with LIBUSB_DEBUG=4. It seems to hang and I have to hit control-C to stop. |
The staging branch seems to work fine under Ubuntu 20.04 Linux.
Debug log:
|
The relevant libusb codes are around here:
|
I am not an expert here -- isochronous transfer is hard. Another potential reference is libusbK WinUSB code. @tormodvolden -- please chime in here as well if you can. Thanks. |
I think I can reproduce the issue with C based application, a quick hack of the libusb example.
Debug Log with LIBUSB_DEBUG=4, WinUSB got one time error 87. libusbk got many missing packets. |
@jonasmalacofilho I think the staging tree is good. As for the following, hopefully you can fix it.
@tormodvolden I have add the C example and issue here. Please take a look if the C code is correct or not. Thanks. |
AutoFinalizedObject sets up the finalizer to run using weakref.finalize() within the object allocation – __new__(). This means that the finalizer is set up to run regardless of whether object initialization – __init__() – completed successfully. If __init__() raises an exception, or if it is aborted due to an external reason (e.g. process termination due to an exception on another thread or a KeyboardInterrupt), the finalizer will run with a partially constructed object. Therefore, check the presence (and, when applicable, the validity) of any fields of self used by the finalizer before they are actually used. Related: #380 (comment)
So far I have not been able to get pyusb isoc transfer to work under macOS and Windows. On Windows I think libusb-1.0 itself has some issues. So I will test out macOS and Linux first.
I am using Cyusb FX3 known good Firmware isoloop and isosrcsink.
https://github.com/hantianjz/cy_fx3_sdk/tree/master/cyusb_linux_1.0.5/fx3_images
Issues:
The text was updated successfully, but these errors were encountered: