On Apr 7, 2019, at 1:59 PM, Arte wrote:
>
> The surprising bit is that it exposes a Interval of 8, which in the context of Full Speed devices, means it asks for an 8ms polling interval.
> …
> This is surprising because on the other end of this conversion device, the device polls periodically every ~1,4ms, and the data sent to the computer only provides the (post-conversion) data of the last of these ~1,4ms period polls. So I strongly suspect that new data is available in the device-side USB controller every ~1,4ms, and that the 8ms interval exposed in the descriptor is outright a mistake.
Is this a vendor you’re friendly with? They ought to be able to provide one with a different descriptor that sets the interval to 2, unless there is some specific reason they have chosen 8ms. Is there any useful information in those intermediate reads?
> While I am not certain of it, I would very much like to check and obtain all this data. If this is not possible, the next best thing I’m looking for is to be able to choose precisely the USB frame I poll that device at. So, an 8ms interval some times, a 10ms some other time…
That much is not possible. The host controller driver does all of the scheduling based on the descriptor, and it is nothing if not regular.
> Because this doesn’t appear to be possible with WinUSB.
This is not possible with USB, period.
> WinUSB respects the polling interval requested by the device and will block calls and the emission of the request to at least 8ms after the previous request.
No, none of that is under the control of WinUSB. The application just makes a call to WinUsb_ReadPipe. WinUSB submits an IRP. As long as the host controller driver has an empty IRP waiting, it will send an IN token to the device during its timing interval. The timing is all handled by the host controller driver, which schedules every frame in advance.
> And not only does it respect it, but it appears from my tests, both through libusb and directly using WinUSB functions, that WinUSB schedules an interval timer to check, every 8ms, if there’s a new request for data from this device, and proceeds to fire a request if there is.
No. USB is a completely host-driven bus. As long as there is an empty IRP waiting, the host controller driver will schedule a transfer. It’s up to the device to decide whether it has anything to send when it gets that token. If it does, it sends. If not, it send a NAK, and won’t get another chance until the next interval. If there is no waiting IRP, then the host controller won’t send a token, and you miss your slot.
> The consequence of this is that accurately timed WinUSB function calls will be postponed to the next “8ms-period poll”. As an example, if I attempt to read a pipe every 10ms very accurately, the time difference between two calls will be 75% of the time 8ms, and 25% of the time 16ms, in a cycle of [8ms - 8ms - 8ms - 16ms].
That’s a side effect of the host controller scheduling. With an interval of 8, your driver will be assigned to one particular frame in every 8, forever.
> My current beliefs are that this is due to WinUSB’s implementation and not the USB host scheduler,
You are incorrect. The timing is strictly under the control of the host controller driver.
> …if I were to write my own driver, I would probably be able to control the polling rate regardless of the exposed interval, so, up to 1000Hz, and that if I can’t, I would at least be able to schedule transfers on the frames I want as long as they’re at least 8 frames apart.
Sorry, no. The only way to change the scheduling behavior is to change the descriptor.
> So my questions are the following:
>
> * Is it possible ?
No. There are SOME descriptor problems you can fix by using a filter driver to intercept and rewrite the descriptors, but in this case, the descriptor is being read and used by the host controller driver, which is in direct communication with the hardware. There is no slot into which you can insert a filter.
> * Are my assumptions about the role of the driver in the transfer scheduling process correct ? If so, does it mean that writing my own driver will work ?
No, sorry. You must alter the descriptors.
> * Is there any kind of middle-man deception possible where I’d convince the OS that the exposed interval is not actually 8, but 1, without involving an external device ?
No, sorry.
> When @Maxim_S._Shatskih says in the first answer to https://community.osr.com/discussion/190849/usb-polling-rate that “For interrupt pipe, the polling rate it is hardcoded in the config descriptor to be BusPollingRate/( 1 << N ), where N is some small number (1 and up).” - does that mean it’s impossible ? This is the message that had me seek confirmation from experts before spending weeks or more attempting to do the impossible.
Max is correct. What you are attempting is impossible.
—
Tim Roberts, timr@probo.com
Providenza & Boekelheide, Inc.