Windows 10: USB HID Joystick: one device two interfaces conundrum

Discus and support USB HID Joystick: one device two interfaces conundrum in Windows 10 Drivers and Hardware to solve the problem; Hello! I've buit an LUFA/Arduino-based joystick HID device that, due to a ridiculous 32-button max limitation, has got two distinct interfaces in it:... Discussion in 'Windows 10 Drivers and Hardware' started by Dmitry Borets, Feb 24, 2021.

  1. USB HID Joystick: one device two interfaces conundrum


    Hello!


    I've buit an LUFA/Arduino-based joystick HID device that, due to a ridiculous 32-button max limitation, has got two distinct interfaces in it: first one with 32 buttons, the second with the other 14 buttons and 8 axes. The device itself works allright, Windows Device Manager correctly sees one USB composite device, two USB Input Devices and two HID-compliant game controllers, correctly recognises both interfaces and all the controls on each of them.


    But I can't, for the life of me, make Windows - and the other apps that rely on Windows drivers stack or DirectX input, I really don't know which, see these two interfaces as separate joysticks. Why? Because, I believe this gotta be it, for I have turned over every page on the internet trying to find a solution, Windows feeds those progams with the device ID based on VID&PID&Revison, that is - either a Manufacturer string, or a Descriptor string of the first interface only.

    Hence, the apps and games that rely on the info provided by Windows, see only one joystick one interface and I'm getting only half of the functionality.

    Some of the apps, e.g. X-Plane, that, I believe, work with the HID devices directly, bypassing Windows drivers, correctly distinguish the interfaces by their string descriptors.

    I even tried Interface Association Descriptors one IAD - one interface in a futile attempt to make it work; it didn't work without IADs either.


    Now, to the question: is there an official documented way of making Windows enumerate the interfaces based on their individual distictive IDs, and feed the other apps and games with distinctive joustick names/IDs so that the apps would see two joysticks instead of one?


    Help me, guys. I'm really desperate. There has got to be a way.


    Thanks,

    Dmitry.


    Here's the descriptors but again, everything's working just fine if not for this thing with the same name/ID for the two interfaces:


    const USB_Descriptor_HIDReport_Datatype_t PROGMEM JoystickAReport[] =
    {
    /* First 32 buttons */
    0x05, 0x01, /* Usage Page Generic Desktop */
    0x09, 0x04, /* Usage Joystick */
    0xa1, 0x01, /* Collection Application */
    0x09, 0x01, /* Usage Pointer */
    0xa1, 0x00, /* Collection Physical */
    0x05, 0x09, /* Usage Page Button */
    0x19, 0x01, /* Usage Minimum Button 1 */
    0x29, 0x20, /* Usage Maximum Button 32 */
    0x15, 0x00, /* Logical Minimum 0 */
    0x25, 0x01, /* Logical Maximum 1 */
    0x75, 0x01, /* Report Size 1 */
    0x95, 0x20, /* Report Count 32 */
    0x81, 0x02, /* Input Data, Variable, Absolute */
    0xc0, /* End Collection */
    0xc0 /* End Collection */
    };

    const USB_Descriptor_HIDReport_Datatype_t PROGMEM JoystickBReport[] =

    {

    /* Last 14 buttons and 8 axes */

    0x05, 0x01, /* Usage Page Generic Desktop */

    0x09, 0x04, /* Usage Joystick */

    0xa1, 0x01, /* Collection Application */

    0x09, 0x01, /* Usage Pointer */

    0xa1, 0x00, /* Collection Physical */

    0x05, 0x09, /* Usage Page Button */

    0x19, 0x01, /* Usage Minimum Button 1 */

    0x29, 0x0E, /* Usage Maximum Button 14 */

    0x15, 0x00, /* Logical Minimum 0 */

    0x25, 0x01, /* Logical Maximum 1 */

    0x75, 0x01, /* Report Size 1 */

    0x95, 0x0E, /* Report Count 14 */

    0x81, 0x02, /* Input Data, Variable, Absolute */

    0x75, 0x02, /* Report Size 2 */

    0x95, 0x01, /* Report Count 1 */

    0x81, 0x01, /* Input Constant for padding */

    0x05, 0x01, /* Usage Page Generic Desktop */

    0x09, 0x30, /* Usage X Four pairs of coupled axes */

    0x09, 0x31, /* Usage Y */

    0x09, 0x30, /* Usage X */

    0x09, 0x31, /* Usage Y */

    0x09, 0x30, /* Usage X */

    0x09, 0x31, /* Usage Y */

    0x09, 0x30, /* Usage X */

    0x09, 0x31, /* Usage Y */

    0x16, 0x00, 0x00, /* Logical Minimum double byte zero */

    0x26, 0xff, 0x03, /* Logical Maximum 1023 - 5V-based Arduino AD converter's maximum */

    0x75, 0x10, /* Report Size 16 */

    0x95, 0x08, /* Report Count 8 */

    0x81, 0x82, /* Input Data, Variable, Absolute, Volatile */

    0xc0, /* End Collection */

    0xc0 /* End Collection */

    };




    const USB_Descriptor_Device_t PROGMEM DeviceDescriptor =

    {

    .Header = {.Size = sizeofUSB_Descriptor_Device_t, .Type = DTYPE_Device},


    .USBSpecification = VERSION_BCD2,0,0,

    .Class = 0xEF,

    .SubClass = 0x02,

    .Protocol = 0x01,


    .Endpoint0Size = FIXED_CONTROL_ENDPOINT_SIZE,


    .VendorID = 0x03EB,

    .ProductID = 0x2043,

    .ReleaseNumber = VERSION_BCD1,4,1,


    .ManufacturerStrIndex = STRING_ID_Manufacturer,

    .ProductStrIndex = STRING_ID_Product,

    .SerialNumStrIndex = STRING_ID_Serial,


    .NumberOfConfigurations = FIXED_NUM_CONFIGURATIONS

    };


    const USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor =

    {

    .Config =

    {

    .Header = {.Size = sizeofUSB_Descriptor_Configuration_Header_t, .Type = DTYPE_Configuration},



    .TotalConfigurationSize = sizeofUSB_Descriptor_Configuration_t,

    .TotalInterfaces = 0x02,


    .ConfigurationNumber = 0x01,

    .ConfigurationStrIndex = NO_DESCRIPTOR,


    .ConfigAttributes = USB_CONFIG_ATTR_RESERVED USB_CONFIG_ATTR_SELFPOWERED,


    .MaxPowerConsumption = USB_CONFIG_POWER_MA100

    },


    .IAD_A =

    {

    .Header = {.Size = sizeofUSB_Descriptor_Interface_Association_t, .Type = DTYPE_InterfaceAssociation},


    .FirstInterfaceIndex = INTERFACE_ID_Joystick_A,

    .TotalInterfaces = 0x01,


    .Class = 0x03,

    .SubClass = 0x00,

    .Protocol = HID_CSCP_NonBootProtocol,


    .IADStrIndex = STRING_ID_IAD_A

    },


    .HIDA_Interface =

    {

    .Header = {.Size = sizeofUSB_Descriptor_Interface_t, .Type = DTYPE_Interface},



    .InterfaceNumber = INTERFACE_ID_Joystick_A,

    .AlternateSetting = 0x00,


    .TotalEndpoints = 0x01,


    .Class = 0x03,

    .SubClass = 0x00,

    .Protocol = HID_CSCP_NonBootProtocol,


    .InterfaceStrIndex = STRING_ID_Interface_A

    },



    .HIDA_JoystickHID =

    {

    .Header = {.Size = sizeofUSB_HID_Descriptor_HID_t, .Type = HID_DTYPE_HID},


    .HIDSpec = VERSION_BCD1,11,0,

    .CountryCode = 0x00,

    .TotalReportDescriptors = 0x01,

    .HIDReportType = HID_DTYPE_Report,

    .HIDReportLength = sizeofJoystickAReport

    },



    .HIDA_ReportINEndpoint =

    {

    .Header = {.Size = sizeofUSB_Descriptor_Endpoint_t, .Type = DTYPE_Endpoint},


    .EndpointAddress = ENDPOINT_DIR_IN JOYSTICK_A_EPNUM,

    .Attributes = EP_TYPE_INTERRUPT ENDPOINT_ATTR_NO_SYNC ENDPOINT_USAGE_DATA,

    .EndpointSize = JOYSTICK_A_EPSIZE,

    .PollingIntervalMS = 0x02

    },



    .IAD_B =

    {

    .Header = {.Size = sizeofUSB_Descriptor_Interface_Association_t, .Type = DTYPE_InterfaceAssociation},


    .FirstInterfaceIndex = INTERFACE_ID_Joystick_B,

    .TotalInterfaces = 0x01,


    .Class = 0x03,

    .SubClass = 0x00,

    .Protocol = HID_CSCP_NonBootProtocol,


    .IADStrIndex = STRING_ID_IAD_B

    },


    .HIDB_Interface =

    {

    .Header = {.Size = sizeofUSB_Descriptor_Interface_t, .Type = DTYPE_Interface},



    .InterfaceNumber = INTERFACE_ID_Joystick_B,

    .AlternateSetting = 0x00,


    .TotalEndpoints = 1,


    .Class = 0x03,

    .SubClass = 0x00,

    .Protocol = HID_CSCP_NonBootProtocol,


    .InterfaceStrIndex = STRING_ID_Interface_B

    },



    .HIDB_JoystickHID =

    {

    .Header = {.Size = sizeofUSB_HID_Descriptor_HID_t, .Type = HID_DTYPE_HID},


    .HIDSpec = VERSION_BCD1,11,0,

    .CountryCode = 0x00,

    .TotalReportDescriptors = 0x01,

    .HIDReportType = HID_DTYPE_Report,

    .HIDReportLength = sizeofJoystickBReport

    },



    .HIDB_ReportINEndpoint =

    {

    .Header = {.Size = sizeofUSB_Descriptor_Endpoint_t, .Type = DTYPE_Endpoint},


    .EndpointAddress = ENDPOINT_DIR_IN JOYSTICK_B_EPNUM,

    .Attributes = EP_TYPE_INTERRUPT ENDPOINT_ATTR_NO_SYNC ENDPOINT_USAGE_DATA,

    .EndpointSize = JOYSTICK_B_EPSIZE,

    .PollingIntervalMS = 0x02

    }

    };

    :)
     
    Dmitry Borets, Feb 24, 2021
    #1

  2. Problem with HID (Human Interface Device) Drivers Missing

    Hi,

    It doesn't need to have two USB Input HID Driver, only one would work fine.

    To check for possible cause of the issue, we suggest that you run Hardware and Devices troubleshooter. To do so, follow the steps below:

    • Press Windows key. 
    • Type Troubleshooting. 
    • Click Hardware and Sound. 
    • Click Hardware and Devices. 
    • Follow the on-screen instructions. 
    If the issue still persists, uninstall and reinstall the driver.

    Let us know how it goes.
     
    Jesebel Ova, Feb 24, 2021
    #2
  3. BossDweeb Win User
    USB joystick

    Did the joystick work on Win10 prior to v1803 update ?

    Which MS games ?

    What brand and model joystick ? Does the joystick show in Device Manger > Human Interface Devices,

    Universal Serial Bus Devices, or XBOX 360 Peripherals ?

    [ Funny thing about Sound, Video and Game Controllers, is the game controllers don't get listed there. Never have

    on my machine. ]

    .
     
    BossDweeb, Feb 24, 2021
    #3
  4. Gino Des Win User

    USB HID Joystick: one device two interfaces conundrum

    USB Joystick not working on windows 10

    Some gamepads need a powered USB port. If the gamepad is not working correctly, try connecting it to a different USB port. Unpowered hubs or ports might not provide enough power.

    In addition, to help eliminate any possible hardware issues, try using the gamepad on another computer.

    Let's also use Device Manager to help troubleshoot problems with your gamepad and to make sure there are no conflicts. To use Device Manager, follow these steps:

    • Click Start.
    • Type Device Manager, and select it from the list of results.
    • When the gamepad is successfully installed, you should see it under Human Interface Devices.
      For example, HID-compliant game controller or USB Human Interface Device.

    • If you see yellow exclamation points next to any of these entries, there's a problem with the installation.

    Keep us updated with the status of the issue.
     
    Gino Des, Feb 24, 2021
    #4
Thema:

USB HID Joystick: one device two interfaces conundrum

Loading...
  1. USB HID Joystick: one device two interfaces conundrum - Similar Threads - USB HID Joystick

  2. Improper Device Driver HID Assigned to USB Device

    in Windows 10 Gaming
    Improper Device Driver HID Assigned to USB Device: I am writing to seek assistance with a driver issue on my Windows 11 Home version 23H2 system involving the USB-C connected mobile payment card reader. The device is incorrectly recognized by Windows as a Human Interface Device HID, which prevents it from functioning properly...
  3. Improper Device Driver HID Assigned to USB Device

    in Windows 10 Software and Apps
    Improper Device Driver HID Assigned to USB Device: I am writing to seek assistance with a driver issue on my Windows 11 Home version 23H2 system involving the USB-C connected mobile payment card reader. The device is incorrectly recognized by Windows as a Human Interface Device HID, which prevents it from functioning properly...
  4. Problem with Joystick HID descriptor readout

    in Windows 10 Gaming
    Problem with Joystick HID descriptor readout: I bought a used Joystick Speedlink Phantom Hawk, which I can't return. The Z-Rotation Axis twist axis has a weird offset and doesn't read out the full Motion, it is centred at readout 180, and only uses about 20-30% of the IRL range. I tried everything conventional, and...
  5. Problem with Joystick HID descriptor readout

    in Windows 10 Software and Apps
    Problem with Joystick HID descriptor readout: I bought a used Joystick Speedlink Phantom Hawk, which I can't return. The Z-Rotation Axis twist axis has a weird offset and doesn't read out the full Motion, it is centred at readout 180, and only uses about 20-30% of the IRL range. I tried everything conventional, and...
  6. Problem with Joystick HID descriptor readout

    in Windows 10 Drivers and Hardware
    Problem with Joystick HID descriptor readout: I bought a used Joystick Speedlink Phantom Hawk, which I can't return. The Z-Rotation Axis twist axis has a weird offset and doesn't read out the full Motion, it is centred at readout 180, and only uses about 20-30% of the IRL range. I tried everything conventional, and...
  7. Problem with Human Interface Devices HID and Mouse and other pointing devices Drivers...

    in Windows 10 Gaming
    Problem with Human Interface Devices HID and Mouse and other pointing devices Drivers...: Hello,Everyone.I have a problem regarding my touchpad and some drivers. I have ASUS FX505GM laptop, windows 11, core i5 8th gen. My touchpad sometimes suddenly stops working by itself and then comes back on suddenly after sometime/someday. When this happens i try to press my...
  8. Problem with Human Interface Devices HID and Mouse and other pointing devices Drivers...

    in Windows 10 Software and Apps
    Problem with Human Interface Devices HID and Mouse and other pointing devices Drivers...: Hello,Everyone.I have a problem regarding my touchpad and some drivers. I have ASUS FX505GM laptop, windows 11, core i5 8th gen. My touchpad sometimes suddenly stops working by itself and then comes back on suddenly after sometime/someday. When this happens i try to press my...
  9. One copy Two devices

    in Windows 10 Gaming
    One copy Two devices: Hi. I've been playing a game Sea of Thieves on my Windows 10 device. I installed it on a second computer using the same game copy, and logged out. Whenever I try to play it on my second device, it says "Looks like you need to renew Game Pass. If your subscription is current,...
  10. Two interfaces, one VPN - how to access the internet via the other interface?

    in Windows 10 Network and Sharing
    Two interfaces, one VPN - how to access the internet via the other interface?: I would like to know how to configure my laptop so one interface uses the VPN and the wireless interface bypasses the VPN and connects to the internet. At the moment the only way I am able to do this is with VM software, e.g. VMware, but looking for a solution that does not...