Hid Descriptor and Report of Space Traveller and Navigator

Post questions, comments and feedback to our 3Dconnexion Windows Development Team.

Moderator: Moderators

Post Reply
shine47
Posts: 3
Joined: Fri Jan 09, 2009 3:18 am

Hid Descriptor and Report of Space Traveller and Navigator

Post by shine47 »

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
jwick
Moderator
Moderator
Posts: 3341
Joined: Wed Dec 20, 2006 2:25 pm
Location: USA
Contact:

Post by jwick »

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
Post Reply