Hi,
i write a component, which should be able to integrate generic hid devices. Therefore i
read out the hid descriptor and try to suggest what bits belong to what control and
the incoming values in a report. This automatic mapping works good for the Space Traveller:
Space Traveller:
Button Input
============
UsagePage: Button ($0009)
ReportID: 3
IsAlias: False
BitField: 2
LinkCollection: 3
LinkUsage: Undefined ($0000)
LinkUsagePage: Generic Desktop ($0001)
IsRange: True
IsStringRange: False
IsDesignatorRange: False
IsAbsolute: True
UsageMin: 1 UsageMax: 8
StringMin: 0 StringMax: 0
DesignatorMin: 0 DesignatorMax: 0
DataIndexMin: 6 DataIndexMax: 13
This results in 8 Buttons which occupy the first 8 Bits of the report with the reportid 3. I do always
assume that the bits wich carry information about the state of a control start at index 0 (i do
not count the reportid-byte)
Bit 0 = Button with Data Index 6, Bit 1 = Button with Data Index 7...
But this does not seem to be the case with the Space Navigator.
Space Navigator:
Button Input
============
0)
UsagePage: Button ($0009)
ReportID: 3
IsAlias: False
BitField: 2
LinkCollection: 3
LinkUsage: Undefined ($0000)
LinkUsagePage: Generic Desktop ($0001)
IsRange: True
IsStringRange: False
IsDesignatorRange: False
IsAbsolute: True
UsageMin: 1 UsageMax: 2
StringMin: 0 StringMax: 0
DesignatorMin: 0 DesignatorMax: 0
DataIndexMin: 6 DataIndexMax: 7
Here you have 2 Buttons, i assume them to occupy the bit 0 und 1, but in reality they are on the bit 6 and 7.
For me it seems the Buttons on the physical device were deleted (at change from Traveller to Navigator)
but the position in the report remained. My question is (also because i want to find more generic rules
of how the bits are arranged in a report): Can it be seen in the report descriptor, that the data of
the two buttons are on bitindex 6 and 7 and not 0 and 1?
Example Report for the Space Traveller:
Input Report: 00000011 01000000 00000000 00000000 00000000 00000000 00000000
(the first byte is the reportid 3)
Button 6: 0 0
Button 7: 1 1
Button 8: 0 0
Button 9: 0 0
Button 10: 0 0
Button 11: 0 0
Button 12: 0 0
Button 13: 0 0
Axis
Another question concerns the reportid 1 and reportid 2. The data of one axis occupy 16 bits as
can be suggested by the hid descriptor:
Value Input
===========
0)
UsagePage: Generic Desktop ($0001)
ReportID: 1
IsAlias: False
BitField: 6
LinkCollection: 1
LinkUsage: Undefined ($0000)
LinkUsagePage: Generic Desktop ($0001)
IsRange: False
IsStringRange: False
IsDesignatorRange: False
IsAbsolute: False
HasNull: False
BitSize: 16
ReportCount: 1
UnitsExp: 0
Units: 0
LogicalMin: -500
LogicalMax: 500
PhysicalMin: -32768
PhysicalMax: 32767
Usage: Z Axis ($0032)
StringIndex: 0
DesignatorIndex: 0
DataIndex: 0
when i just look at the bits for one axis, which are arranged like:
Byte 0 & Byte 1 = Z Axis, Byte 2 and Byte 3 = another Axis...
i see something like:
00000001 11111111
I was puzzled for a long time because of a calculated the decimal values of this
they did not make sense.
then i changed the order to
11111111 00000001 and calculated the 2-Complement and the outcoming values were
meaningful. I read in the hid-specification about that sometimes the 2-Complement
has to be taken, but why does the order of the bytes have to be interchanged, is
this a general rule for controls which occupy more the one byte of data?
Thank you very much,
Jens
Hid Descriptor and Report of Space Traveller and Navigator
Moderator: Moderators
Hi Jens,
Button bits for the SpaceNavigator are the two least significant bits. All the buttons bits for all devices start from the right (least signficant end).
E.g.,
char *rpt = buffer read from the device;
button1 = rpt[1] & 0x01; // not 0x80
button2 = rpt[1] & 0x02; // not 0x40
The axis data is little endian (least signficant byte first). Rearrange it and cast it to a short:
short axisX = (((short)rpt[2]) << 8 ) | (unsigned char )rpt[1];
In all cases, where rpt[0] is the packet identifier.
Jim
3Dx Software Development
Button bits for the SpaceNavigator are the two least significant bits. All the buttons bits for all devices start from the right (least signficant end).
E.g.,
char *rpt = buffer read from the device;
button1 = rpt[1] & 0x01; // not 0x80
button2 = rpt[1] & 0x02; // not 0x40
The axis data is little endian (least signficant byte first). Rearrange it and cast it to a short:
short axisX = (((short)rpt[2]) << 8 ) | (unsigned char )rpt[1];
In all cases, where rpt[0] is the packet identifier.
Jim
3Dx Software Development