Windows System Software -- Consulting, Training, Development -- Unique Expertise, Guaranteed Results

Before Posting...
Please check out the Community Guidelines in the Announcements and Administration Category.

Should I write a driver to disregard the exposed polling interval of a non-HID vendor device ?

2»

Comments

  • Tim_RobertsTim_Roberts Member - All Emails Posts: 12,980

    This is why I'd be surprised to conclude that the USB controller only receives data every 8ms, internally.

    I want to re-emphasize the point I made in the "reply to invalid message" above.

    A USB controller never receives data unprompted. The USB controller is in control. In this case, it ASKS for data every 8ms, and the device responds by sending a packet when it is politely asked to do so. In between invitations, it must be quiet.

    Tim Roberts, [email protected]
    Providenza & Boekelheide, Inc.

  • Pavel_APavel_A Member Posts: 2,672

    Must I conclude from the fact that pipe reads take twice as long, so, 16ms (or more generally, n times as long; 8*n ms) that internally, the device only feeds his USB device controller data every 8ms

    Exactly because of this, you don't want to move large amounts of data over interrupt endpoints. Exactly because of this, they are named "interrupt".
    The purpose of interrupt endpoint is to pass a short message, like "I am ready to send /receive more data".
    Massive data pumping goes over bulk endpoints. As Mr. Roberts noted, interrupt and bulk pipes are absolutely identical -
    except that bulk pipes do not have polling interval. The host controller moves the bulk data whenever the bus is free after the scheduled traffic.
    HID devices use interrupt pipes for their main data, it's understandable why.
    Reports of normal HID devices should fit in the max. packet size ( < 8 bytes low speed, < 64 bytes full speed, such as your STM32).
    Every single typical report is a short packet, and it ends the transfer.

    So you're asking, is this device badly designed? Maybe yes, maybe not.
    All we know from you is that it is not HID, and the direction is OUT.
    May be it indeed cannot consume data at high speed. You don't know until you do the experiment (and use the USB analyzer!).
    Are you the only customer of this vendor? Can you reach them for help or explanation?

    -- pa

  • Peter_Viscarola_(OSR)Peter_Viscarola_(OSR) Administrator Posts: 7,223

    A USB controller never receives data unprompted.

    Nit: Isn’t there a USB 3 protocol situation where this is not strictly true? Something to do with endpoints waking up after being asleep or some such?

    Peter

    Peter Viscarola
    OSR
    @OSRDrivers

  • Pavel_APavel_A Member Posts: 2,672

    Thank you Mr. Viscarola for restoring my post.
    I tried to edit it to add that the original question is in fact very unclear.
    It says that the interrupt endpoint is OUT. Which means from host to device. And the OP asks about moving data from the device to host.
    What is correct? Using OUT endpoints of interrupt type is unusual.

    -- pa

  • Tim_RobertsTim_Roberts Member - All Emails Posts: 12,980
    via Email
    On Apr 13, 2019, at 3:22 PM, Pavel_A wrote:
    >
    > It says that the interrupt endpoint is OUT. Which means from host to device. And the OP asks about moving data from the device to host.
    >
    > What is correct? Using OUT endpoints of interrupt type is unusual.

    I assume he simply misspoke. It's a very common mistake to make, because the data seems to be going "out" of the device. For those following along at home, the IN and OUT directions in USB are always designated from the host's point of view.

    Tim Roberts, [email protected]
    Providenza & Boekelheide, Inc.

    Tim Roberts, [email protected]
    Providenza & Boekelheide, Inc.

  • J_BernardJ_Bernard Member Posts: 8
    edited April 14

    I misspoke indeed, sorry about that. The device actually has 2 endpoints, an interrupt OUT and an interrupt IN, but only one interests me, and it's the IN (device->host), not the OUT (host->device).

    @Tim_Roberts, I was also unclear by saying "USB controller". In this case, I meant the USB device controller.

    To clarify the architecture of the problem, although I'm not sure how much specifics belong here, the device is a controller adapter (used by numerous people that won't be able to mess with hardware - and contacting the vendor isn't an option), which means that there is (in my mind):

    • The controllers (that provide data upon receiving a message using the communication protocol established with the adapter)
    • The main process in the adapter that manages communication with the controllers. (Polls controllers every ~1,4ms)
    • The USB device controller (Exposes a 8ms bInterval, not HID. I am not knowledgeable about how it's implemented. I've seen in another device two chips coexist - one dedicated to USB and one to the main task, but this one appears to only have the STM32L151 chip.)
    • The USB HC + HCD
    • The Windows driver
    • Whatever application is using the data. Said application's engine is most likely similar to a 60Hz state machine that uses one snapshot of controller data per state increment.

    The problem I'm trying to fix in the end is that feeding a 60Hz state machine with an data polled at 62,5Hz (every 8ms) makes things go very wrong. (Think of the "time distortion" that happens when 3 polls, spaced by 8ms, are fed in a single 16,67ms period of the state machine, instead of the usual 2? If we had 1000Hz controller data, we would get time distortions of 16ms or 17ms into 16,67ms - much less harmful than 24ms into 16,67ms. The consequences of this are another subject entirely, though, and I doubt they belong here. In short, it's terrible on the user end.)

    So the problem is the following : is it possible to access the data of the controllers that the adapter chip is pulling every ~1,4ms ?

    And if I understood this correctly, interrupt endpoints on the device side are necessarily implemented using a buffer that the device fills and that the USB device controller reads right away when queried.

    To fix the problems with software only, there is one precondition, and then we have to poll it faster than allowed.

    The precondition is that the buffer the USB device controller is updated at the request of the device's main process, every ~1,4ms, instead of being updated at the request of the USB device controller, at the same frequency as the exposed bInterval, so, every 8ms. If the latter, all is lost. I don't know which case we're in yet.
    And if the former, that means that USB device controller actually could provide more data than what it tells the host and there only remain to disregard the exposed polling interval - so to speak, overclock.

    I digressed earlier, wanting to check if by some alignments of the stars, sending a longer buffer than the returned data would cause the chip to accumulate every 1,4ms data in the buffer and return it every 8ms, but there are numerous reasons this probably wasn't going to work, and actually I had understood nothing. As per Mr. Roberts explanation, if I got it right, data certainly doesn't accumulate in blocks one after another in a buffer too large for the device to internally handle it (how did I ever think this was going to work ?) but is split at the HC/HCD level into requests fit for the device, one after another, and the Windows driver will get all the answers back at once once they're all complete.

    I hope this clarified my various unclear statements from earlier. I'll now try HidUsbF.

    In this case, i just ask for confirmation if i correctly understood your initial request:
    "make 2 or 1ms polling on device with 8ms bInterval in Interrupt Endpoint Descriptor"

    And @SweetLow , I hope this clarifies my request !

    Post edited by J_Bernard on
  • Tim_RobertsTim_Roberts Member - All Emails Posts: 12,980
    via Email
    > The problem I'm trying to fix in the end is that feeding a 60Hz state machine with an data polled at 62,5Hz (every 8ms) makes things go very wrong.

    8ms is 125Hz. That is above the Nyquist frequency for a 60Hz signal. And you certainly have enough timing data to know when those packets were transferred. But if the data is really samples at a near-millisecond rate, then why is the difference important? You have to reconstruct the timing anyway, right?


    > So the problem is the following : is it possible to access the data of the controllers that the adapter chip is pulling every ~1,4ms ?

    In a word, no.


    > And if I understood this correctly, interrupt endpoints on the device side are necessarily implemented using a buffer that the device fills and that the USB device controller reads right away when queried.

    Right.


    > The precondition is that the buffer the USB device controller is updated at the request of the device's main process, every ~1,4ms, instead of being updated at the request of the USB device controller, at the same frequency as the exposed bInterval, so, every 8ms. If the latter, all is lost. I don't know which case we're in yet.

    I don’t know how you would ever determine that without seeing the device firmware from the manufacturer.

    Tim Roberts, [email protected]
    Providenza & Boekelheide, Inc.

    Tim Roberts, [email protected]
    Providenza & Boekelheide, Inc.

  • J_BernardJ_Bernard Member Posts: 8

    It worked !

    SweetLow's driver successfully overclocked the polling of the non-HID device to 1000Hz. From the fact that I can see stick values moving from a millisecond from another repeatedly, internally, the USB device controller's buffer is updated every ~1,4ms. The best part in this is that, as expected, I get NAKs when there is no new data instead of a copy of the previous state, which means I will be able to reconstruct on the software end when the polling happened inside the device, and nullify the damage of the 1000Hz/60Hz frequency misalignement by paying only 1ms of extra input lag.

    Also, yes, I meant 125Hz, my mistake. And there is no Nyquist frequency problem here - I'm not trying to reconstruct a signal. Milliseconds are actually important in my scenario. Picture someone trying to input a button on an engine (state machine) frame, then another button exactly 5 engine frames later (so, 5 time units of the state machine later). And let's say a frame lasts 20ms. In an utopian world, if he presses the second button 98ms after the first, the polling mechanism is such that it will have a 10% chance of being processed as a 4 engine frames difference, and a 90% chance of being processed as a 5 engine frames difference. But now an adapter steps in between, and it polls every - let's say - 15 ms. It doesn't matter which timing you had when you pressed the two buttons, what the PC sees is either a 90ms or 105ms difference. Best case, 105ms, your inputs only have a 75% chance of being processed as 5 engine frames apart. This is where the millisecond precision requirement comes from, and how the adapter would ruin it.

    Thanks a lot to everyone who helped ! Thanks to you, I learnt a lot about USB, saved weeks+ of pointless work and got things to work as well as in my dreams.

Sign In or Register to comment.

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Upcoming OSR Seminars
Developing Minifilters 29 July 2019 OSR Seminar Space
Writing WDF Drivers 23 Sept 2019 OSR Seminar Space
Kernel Debugging 21 Oct 2019 OSR Seminar Space
Internals & Software Drivers 18 Nov 2019 Dulles, VA