twitchyliquid64 / usbd-hid

MIT License
87 stars 37 forks source link

Win10 compatibility. #28

Open perlindgren opened 3 years ago

perlindgren commented 3 years ago

There seems to be some compatibility issue with Win10 and the generated descriptor(s).

#[gen_hid_descriptor(
    (collection = APPLICATION, usage = 0x01, usage_page = 0xff00) = {
        #[item_settings data] data=input;
    }
)]

#[allow(dead_code)]
struct Data {
    data: u8,
}

The generated descriptor looks like this.

data [
    0x6, 0x0, 0xff,      // USEGE PAGE Vendor
    0x9, 0x1,             // USAGE Vendor
    0xa1, 0x1,           // Collection (Application)
    0x15, 0x0,          // Logical minimum
    0x26, 0xff, 0x0,   // Logical maximum
    0x75, 0x8,          // Report size 8
    0x95, 0x1,          // Report count 1
    0x81, 0x0,          // Input
    0xc0,                 // End application collection
]

This works well under Linux (tested under arch) and OSX. Hower under Win10 the device is not properly detected/configured (USB Device Viewer shows the descriptors correctly but claims the devic to be in low power state.

Adding a usage before Input solves the issue.

data [
    0x6, 0x0, 0xff,      // USEGE PAGE Vendor
    0x9, 0x1,             // USAGE Vendor
    0xa1, 0x1,           // Collection (Application)
    0x15, 0x0,          // Logical minimum
    0x26, 0xff, 0x0,   // Logical maximum
    0x75, 0x8,          // Report size 8
    0x95, 0x1,          // Report count 1
    0x09, 0x01,        // USAGE Vendor <---- manually added here
    0x81, 0x0,          // Input
    0xc0,                 // End application collection
]

Either MS is out of specs (the wrapping usage should be inherited) or Linux/OSX just playing nice guessing, not sure.

Maybe there is already some workaround for this problem that I missed. If not, perhaps a syntax extension to the #[item_settings usage = 0x01, ...] would be possible. Or maybe let the proc macro always emit inherited usage from the wrapping collection (in this case).

Admittedly I'm a USB novice, so not sure what's best here. /Per

twitchyliquid64 commented 3 years ago

I think the wrapping usage is meant to be inherited right?

https://github.com/twitchyliquid64/usbd-hid/issues/8 seems similar.

If we can work out what Windows is doing, I'm happy to implement a workaround like what we did for #[quirks allow_short].

perlindgren commented 3 years ago

My understanding is the wrapping usage should be inherited (and that's the behavior of Linux/OSX). To make the generated descriptor work cross platform I can see two ways. Either add explicit syntax in the macro so that you can annotate the wrapped input/output (and possibly feature as well) with usage info, or alternatively have the macro to emit the inherited usage. Not sure what is the best here.

twitchyliquid64 commented 2 years ago

I think a new quirks mode that emits the usage before each input/output element in the report would work?

Not sure how i feel about this as it might make the descriptor huge, but worth a try? wdyt?

perlindgren commented 2 years ago

Hmm, I worked around the problem by manually coding the descriptor, so I don't have a full picture on where its actually required for it to work cross platform. When data is later streamed, does the descriptor size make much difference you think?

hiszd commented 1 year ago

If you make that change to the descriptor and use it in Windows, does it still work in Linux? Also, specifics on how your workaround was achieved would be great.

perlindgren commented 1 year ago

Hi. It's been a while since I fiddled with this. As I recall it worked well on both win10, osx, and linux in the end. I don't have the midi stuff up and running currently. We are traveling tomorrow, but will be back later during the week, at that point I can try to check it for you.

Since its been a while, I assume the ecosystem including the usbdevice have progressed a bit, so maybe less of a hack is needed nowadays.

/Per