vpelletier / python-functionfs

Pythonic API for linux's functionfs
GNU General Public License v3.0
40 stars 13 forks source link

[Help Wanted] Isochronous Streaming #13

Closed cgee2 closed 4 years ago

cgee2 commented 4 years ago

Hey all,

I'm trying to write a basic isochronous stream from a device I'm emulating on a raspberry Pi 0. However I came across this comment in the functionfs/init.py file:

` # USBSSPIsocEndpointDescriptor is not implemented in kernel as of this

writing.

USBSSPIsocEndpointDescriptor,`

Is isochronous data streaming supported yet with this API? If so, I'm getting confused with how to set it up. I was able to get bulk transactions functioning but I'm not sure what needs to change in order to send out data isochronously. Do you have a basic example of an isochronous transfer you could link to me? Thanks!

vpelletier commented 4 years ago

Hello,

USBSSPIsocEndpointDescriptor is the USB isochrounous endpoint companion descriptor, which should be only needed for super-speed (usb3) isochronous endpoints.

As this is a separate descriptor type, functionfs implementation in the kernel needs to know how to handle it before its content can be sent to the kernel using functionfs. This means that this switch statement needs to have a USB_DT_SSP_ISOC_ENDPOINT_COMP case, which it still does not (I picked latest available revision for that file as of this writing). This is what is meant by the comment you found in functionfs/__init__.py . So this should only limit you if you need an USB3 isochronous endpoint. This alone should not limit USB2 isochronous endpoints.

There can be other limiting factors though, like UDC's support for gadget isochronous endpoints... Sadly I do not have experience with using them via functionfs, so I cannot point you at an example. Understanding why functionfs kernel interface returns errors (assuming this is what you are experiencing) can be quite frustrating, and I sometimes end up adding debug printks and rebuilding the gadget module to understand exactly which condition is not happy with what I write to its files.

cgee2 commented 4 years ago

Thanks for the quick reply! I'm trying to Iso transactions on USB2, so it sounds like this isn't an issue for me.

I'm still a little confused as to how to put this together though. What endpoint descriptor should I use for this? I don't see another Isochronous option in the repo. Thanks!

vpelletier commented 4 years ago

You need to use a "normal" USB endpoint descriptor, just filled with the correct endpoint type (bmAttributes containing USB_ENDPOINT_XFER_ISOC). I would expect the UDC driver to detect this and and appropriately configure the chip so it handles transactions to this endpoint at isochronous. So at this level isochronous should not be very different from any other endpoint type (you do need to check the USB specs for other descriptor fields, I remember one about setting isochronous rate).

Then there is the question of how to push data to the kernel in a timely fashion, which may be a bit trickier (not sure what the timing constraints are, and what performance you will get from python - it should be possible, unless you are doing expensive processing on it).

cgee2 commented 4 years ago

After investigating this I believe my issues lie in how quickly I was able to push the data to the kernel. Thanks!