Skip to content
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

Send/Read at the same time is not possible. #301

Open
eobalski opened this issue Mar 16, 2020 · 3 comments
Open

Send/Read at the same time is not possible. #301

eobalski opened this issue Mar 16, 2020 · 3 comments

Comments

@eobalski
Copy link

This issue is follow up of #300 and is similar to #226
I am using pyUSB to verify if data stream is correct on my device. My device is an audio headset with 2 endpoints, IN and OUT. Data from OUT ep are copied to IN ep. I want to verify if this happens correctly. Simply speaking if data that Host send to an OUT ep are later received on OUT ep.

I've prepared sample code which runs 2 threads:

  • one for sending
  • one for reading

There are 2 issues I've found:

  1. pyUSB does not support reading & receiving at the same time
    The problem is those threads does not work cooperative with pyUSB backend (probably). I was expecting this logic sequence:
start send thread
start read thread
...
OUT transaction (send)
IN transaction (read)
OUT transaction (send)
IN transaction (read)
OUT transaction (send)
IN transaction (read)
...

What i see:

OUT transaction (send)
OUT transaction (send)
OUT transaction (send)
...
IN transaction (read)
IN transaction (read)
IN transaction (read)
...

It seems that read/write is blocking the backend. Is there any chance to implement asynchronous read/write?

  1. pyUSB has limitation to number of packets that could be send with one write().
    I want to send data that are sine wave with:

    • sampling frequency: 48kHz
    • channels: 2
    • bitResolution: 16b (2B)

Taking into consideration that data are send every 1ms frame interval. Data are send in packets with 48000(sampling_freq)*2(bitRes)*2(channels)/1000(frames/s) = 192B size.

Maximal data length I am able to send with one write() is: 192* 128. It means 128 OUT transaction will happen. If I try to send 192* 129 -> [Errno 22] Invalid parameter

I am enclosing sample code + screenshoot from logic analyzer.

image

The file with the code (note Im not a python expert - this is just script for testing)
test.txt

@eobalski
Copy link
Author

I've checked that it is for sure not the problem with libusb which I am using.
write() function in the end submits a transfer to the pyUSB backed. This call is not blocking as You can read.

It seems that the thing that blocks is the while loop just after the submission. It is pooling for the events from the USB backed. Are there any plans to rework and make pyUSB non blocking?

@mcuee mcuee added the question label Jun 2, 2020
@mcuee
Copy link
Member

mcuee commented Jun 2, 2020

I believe this will be addressed in ticket #63.

@mcuee
Copy link
Member

mcuee commented Aug 2, 2021

@emob-nordic Actually you are using isoc transfer here, which is kind of async in nature. I myself do not have good test results with isoc transfer with pyusb, at least under Windows and macOS. Which OS are you using?

It is not really easy to get isoc transfer correctly done, and libusb itself may have problems with isoc transfer under Windows.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants