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

Relative axis with signed value #14

Open
sonik-br opened this issue May 25, 2022 · 5 comments
Open

Relative axis with signed value #14

sonik-br opened this issue May 25, 2022 · 5 comments
Labels
bug Something isn't working

Comments

@sonik-br
Copy link

sonik-br commented May 25, 2022

Hi.
I'm interfacing with a game controller and it have a "Dial" axis.
It's a relative axis and it's value is signed. It works like an mouse wheel (scrolling can be negative or positive).
But the lib returns it as unsiged. Lib register it with range of 0 to 127 but the correct is -128 to 127

\\?\hid#vid_2341&pid_8036&mi_02#8&7616083&0&0000#{4d1e55b2-f16f-11cf-88cb-001111000030}
Arduino LLC Arduino Leonardo MiSTer-A1 JogCon (VID 9025, PID 32822, version 1.0)
Max Lengths: Input 6, Output 0, Feature 0
Serial Ports: \\.\COM11
Report Descriptor:
  05 01 09 04 A1 01 05 09 19 01 29 10 15 00 25 01 35 00 45 01 65 00 55 00 75 01 95 10 81 03 05 01 09 39 25 07 46 3B 01 65 14 75 08 95 01 81 02 09 37 25 7F 81 06 09 38 15 00 25 FF 81 02 C1 00 (63 bytes)
  UsagePage 1
  Usage 4
  Collection 1
    UsagePage 9
    UsageMinimum 1
    UsageMaximum 16
    LogicalMinimum 0
    LogicalMaximum 1
    PhysicalMinimum 0
    PhysicalMaximum 1
    Unit 0
    UnitExponent 0
    ReportSize 1
    ReportCount 16
    Input 3
    UsagePage 1
    Usage 57
    LogicalMaximum 7
    PhysicalMaximum 315
    Unit 20
    ReportSize 8
    ReportCount 1
    Input 2
    Usage 55
    LogicalMaximum 127
    Input 6
    Usage 56
    LogicalMinimum 0
    LogicalMaximum 255
    Input 2
  EndCollection 0
Usage: 10004 GenericDesktopJoystick
Input: ReportID=0, Length=6, Items=4
  16 Elements x 1 Bits, Units: None, Expected Usage Type: 0, Flags: Constant, Variable, Usages: 90001 Button1, 90002 Button2, 90003 Button3, 90004 Button4, 90005 Button5, 90006 Button6, 90007 Button7, 90008 Button8, 90009 Button9, 9000A Button10, 9000B Button11, 9000C Button12, 9000D Button13, 9000E Button14, 9000F Button15, 90010 Button16
  1 Elements x 8 Bits, Units: EnglishRotation, Expected Usage Type: 0, Flags: Variable, Usages: 10039 GenericDesktopHatSwitch
  1 Elements x 8 Bits, Units: EnglishRotation, Expected Usage Type: 0, Flags: Variable, Relative, Usages: 10037 GenericDesktopDial
  1 Elements x 8 Bits, Units: EnglishRotation, Expected Usage Type: 0, Flags: Variable, Usages: 10038 GenericDesktopWheel

Windows joy.cpl shows it correctly.
By using an HID descriptor viewer (USBlyzer) it shows the range -128 to 127
image

I'm doing something wrong?

@benedekkupper
Copy link
Member

Hi! Can you frame your question/inquiry/report in the terms of this actual library? I have no idea how this "HID Demo" program is associated with HidSharp.

@sonik-br sonik-br changed the title Axis with same name Relative axis with signed value May 26, 2022
@sonik-br
Copy link
Author

Oh sorry. My bad. I was testing two libs and got confused.
I have edited my first.

@benedekkupper
Copy link
Member

So maybe you got here from win-hid-dump or similar, looking to see the same HID report descriptor from your C# application, as your device reports it. Unfortunately that's not how Windows works. The Windows OS doesn't expose the HID report descriptor to its userspace, instead it gives a higher level preprocessed property set. HidSharp attempts to reverse engineer the approximate report descriptor from this information (see WinHidDevice.ReportDescriptorReconstructor.cs), but this will never be accurate. What we would need to find out if the OS is mistaking -128 for 0, or HidSharp.

Before we venture into that, I have to ask, do you have the means to change the report descriptor on your USB device? It's not really justifiable to have an asymmetrical range such as [-128, 127], and most devices use [-127, 127] instead.

@sonik-br
Copy link
Author

It's possible to change as it is an arduino based, open source project.
But it's used to interface with playstation controllers and I think it is this way to make it easier to map the 256 bit range to it as it will just use the raw bits.
Makes sense? signed byte vs unsigned byte.

For the descriptor I used USBlyzer to capture. It installs as a (kernel?) driver and it can capture any kind of usb traffic on windows.

The device descriptor from source code matches the report from USBlyzer.

0x05, 0x01,        // Usage Page (Generic Desktop Ctrls)
0x09, 0x04,        // Usage (Joystick)
0xA1, 0x01,        // Collection (Application)
0xA1, 0x00,        //   Collection (Physical)
0x05, 0x09,        //     Usage Page (Button)
0x19, 0x01,        //     Usage Minimum (0x01)
0x29, 0x0C,        //     Usage Maximum (0x0C)
0x15, 0x00,        //     Logical Minimum (0)
0x25, 0x01,        //     Logical Maximum (1)
0x95, 0x10,        //     Report Count (16)
0x75, 0x01,        //     Report Size (1)
0x81, 0x02,        //     Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x05, 0x01,        //     Usage Page (Generic Desktop Ctrls)
0x09, 0x01,        //     Usage (Pointer)
0xA1, 0x00,        //     Collection (Physical)
0x09, 0x30,        //       Usage (X)
0x09, 0x31,        //       Usage (Y)
0x15, 0x80,        //       Logical Minimum (-128)
0x25, 0x7F,        //       Logical Maximum (127)
0x95, 0x02,        //       Report Count (2)
0x75, 0x08,        //       Report Size (8)
0x81, 0x02,        //       Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0xC0,              //     End Collection
0x09, 0x37,        //     Usage (Dial)
0x15, 0x80,        //     Logical Minimum (-128)
0x25, 0x7F,        //     Logical Maximum (127)
0x95, 0x01,        //     Report Count (1)
0x75, 0x08,        //     Report Size (8)
0x81, 0x06,        //     Input (Data,Var,Rel,No Wrap,Linear,Preferred State,No Null Position)
0x09, 0x38,        //     Usage (Wheel)
0x15, 0x00,        //     Logical Minimum (0)
0x26, 0xFF, 0x00,  //     Logical Maximum (255)
0x95, 0x01,        //     Report Count (1)
0x75, 0x08,        //     Report Size (8)
0x81, 0x02,        //     Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x09, 0x39,        //     Usage (Hat switch)
0x15, 0x00,        //     Logical Minimum (0)
0x25, 0x07,        //     Logical Maximum (7)
0x35, 0x00,        //     Physical Minimum (0)
0x46, 0x3B, 0x01,  //     Physical Maximum (315)
0x75, 0x08,        //     Report Size (8)
0x95, 0x01,        //     Report Count (1)
0x65, 0x14,        //     Unit (System: English Rotation, Length: Centimeter)
0x81, 0x42,        //     Input (Data,Var,Abs,No Wrap,Linear,Preferred State,Null State)
0xC0,              //   End Collection
0xC0,              // End Collection

The GetRawReportDescriptor method returns the preprocessed windows descriptor?
By parsing it I can see how it messes up from the original.

0x05, 0x01,        // Usage Page (Generic Desktop Ctrls)
0x09, 0x04,        // Usage (Joystick)
0xA1, 0x01,        // Collection (Application)
0x05, 0x09,        //   Usage Page (Button)
0x19, 0x01,        //   Usage Minimum (0x01)
0x29, 0x10,        //   Usage Maximum (0x10)
0x15, 0x00,        //   Logical Minimum (0)
0x25, 0x01,        //   Logical Maximum (1)
0x35, 0x00,        //   Physical Minimum (0)
0x45, 0x01,        //   Physical Maximum (1)
0x65, 0x00,        //   Unit (None)
0x55, 0x00,        //   Unit Exponent (0)
0x75, 0x01,        //   Report Size (1)
0x95, 0x10,        //   Report Count (16)
0x81, 0x03,        //   Input (Const,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x05, 0x01,        //   Usage Page (Generic Desktop Ctrls)
0x09, 0x39,        //   Usage (Hat switch)
0x25, 0x07,        //   Logical Maximum (7)
0x46, 0x3B, 0x01,  //   Physical Maximum (315)
0x65, 0x14,        //   Unit (System: English Rotation, Length: Centimeter)
0x75, 0x08,        //   Report Size (8)
0x95, 0x01,        //   Report Count (1)
0x81, 0x02,        //   Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x09, 0x37,        //   Usage (Dial)
0x25, 0x7F,        //   Logical Maximum (127)
0x81, 0x06,        //   Input (Data,Var,Rel,No Wrap,Linear,Preferred State,No Null Position)
0x09, 0x38,        //   Usage (Wheel)
0x15, 0x00,        //   Logical Minimum (0)
0x25, 0xFF,        //   Logical Maximum (-1)
0x81, 0x02,        //   Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0xC1, 0x00,        // End Collection

@sonik-br
Copy link
Author

At least after calling the win32 method it's returning a signed value

image

@benedekkupper benedekkupper added the bug Something isn't working label Jun 20, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants