HID device drivers

Hello everyone,

I am attempting to write a device driver for a joystick that follows the HID
standard. I was unable to find documentation for writing HID drivers. Hence
I have been trying to do it by myself by looking at the files sys/hiddi.h
and sys/hidut.h and following a procedure similar to the USB mouse driver
example provided as a part of the DDK in QNX 6.2. Currently I am stuck at
not being able to read HID reports. Is there any kind of documentation at
all for the interface provided in hiddi.h. Even example programs that are
similar to hidview in functionality would have been of great help.

Thanks
Vilas

replied via email

Vilas Kumar Chitrakaran <cvilas@ces.clemson.edu> wrote in message
news:c1r24e$ac2$1@inn.qnx.com

Hello everyone,

I am attempting to write a device driver for a joystick that follows the
HID
standard. I was unable to find documentation for writing HID drivers.
Hence
I have been trying to do it by myself by looking at the files sys/hiddi.h
and sys/hidut.h and following a procedure similar to the USB mouse driver
example provided as a part of the DDK in QNX 6.2. Currently I am stuck at
not being able to read HID reports. Is there any kind of documentation at
all for the interface provided in hiddi.h. Even example programs that are
similar to hidview in functionality would have been of great help.

Thanks
Vilas

If you do succeed in writing a USB joystick driver, we’d be
interested in a copy. This has been needed for a long time.
Thanks.

And if it supports force-feedback steering wheels, that
would be great…

John Nagle
Team Overbot
http://www.overbot.com

Vilas Kumar Chitrakaran wrote:

Hello everyone,

I am attempting to write a device driver for a joystick that follows the HID
standard. I was unable to find documentation for writing HID drivers. Hence
I have been trying to do it by myself by looking at the files sys/hiddi.h
and sys/hidut.h and following a procedure similar to the USB mouse driver
example provided as a part of the DDK in QNX 6.2. Currently I am stuck at
not being able to read HID reports. Is there any kind of documentation at
all for the interface provided in hiddi.h. Even example programs that are
similar to hidview in functionality would have been of great help.

Thanks
Vilas

John your making your project sound a tad too fun. If you get a
force feedback steering wheel going with it, I know I’m going to
want to play with this thing along with a handfull of others here.

E.


John Nagle <nagle@downside.com> wrote:

If you do succeed in writing a USB joystick driver, we’d be
interested in a copy. This has been needed for a long time.
Thanks.

And if it supports force-feedback steering wheels, that
would be great…

John Nagle
Team Overbot
http://www.overbot.com

Vilas Kumar Chitrakaran wrote:
Hello everyone,

I am attempting to write a device driver for a joystick that follows the HID
standard. I was unable to find documentation for writing HID drivers. Hence
I have been trying to do it by myself by looking at the files sys/hiddi.h
and sys/hidut.h and following a procedure similar to the USB mouse driver
example provided as a part of the DDK in QNX 6.2. Currently I am stuck at
not being able to read HID reports. Is there any kind of documentation at
all for the interface provided in hiddi.h. Even example programs that are
similar to hidview in functionality would have been of great help.

Thanks
Vilas

Erick Muis
Hardware Group
QNX Software Systems Ltd.
Email: emuis at qnx.com

I’ve been trying to find that documentation, too. I have his
device driver working, and are trying to figure out how to make
it more general. With documetation, it should be straightforward
to make it recognize any USB joystick.

Vilas’s original program ran as super-user.
I don’t want my application running as super-user; it’s
too risky. So I’m trying to get around that.

It appears that if /dev/io-hid/io-hid is made
mode 666, any program can read the USB human interface devices,
and Vilas’ application will run. Is that safe? Is io-hid
trusting that application? Is shared memory involved, or is it a
standard message-passing resource manager interface?

John Nagle
Team Overbot

Henry VanDyke wrote:

replied via email

Vilas Kumar Chitrakaran <> cvilas@ces.clemson.edu> > wrote in message
news:c1r24e$ac2$> 1@inn.qnx.com> …

Hello everyone,

I am attempting to write a device driver for a joystick that follows the

HID

standard. I was unable to find documentation for writing HID drivers.

Hence

I have been trying to do it by myself by looking at the files sys/hiddi.h
and sys/hidut.h and following a procedure similar to the USB mouse driver
example provided as a part of the DDK in QNX 6.2. Currently I am stuck at
not being able to read HID reports. Is there any kind of documentation at
all for the interface provided in hiddi.h. Even example programs that are
similar to hidview in functionality would have been of great help.

Thanks
Vilas

\

I can get the HID system and a generic joystick interface
to work, but a number of issues have emerged.

  1. “hidd_get_usage_value” is supposed to return a 32-bit
    unsigned value. Reading “HIDD_USAGE_X” with the
    joystick I have (a Logitec Attack 3) returns the
    correct X position of the joystick in the low 8 bits.
    The higher bits contain junk which must be masked off.
    It’s not clear how to do this in a generic way, since
    different devices have different ranges.

  2. “hidd_get_buttons” works, but “hidd_get_all_buttons”
    seems to return a button count of 3 or greater
    and incorrect button information.

  3. “hidd_set_idle” if set to “HIDD_TIME_DEFAULT”, does
    result in idle reports, but the numeric values
    returned for input joystick positions are often
    bogus.

Documentation notes:

  1. It’s worth mentioning that, while you get “insertion”
    reports on everything of interest, you don’t get
    “disconnect” reports unless you register for
    HID_INPUT_REPORT callbacks.

  2. The documentation for “hidd_connect” and “hidd_report_attach”
    doesn’t match the function prototypes.

John Nagle
Team Overbot

I now have a more or less generic USB joystick library
working, which I will post on the Overbot web site at
a later date. So far, I’ve tried a Logitech Attack 3
joystick and a Logitech Momo steering wheel. All inputs
work for each of them, and the system self-configures for
the numeric range output by the device for each axis.

No force feedback support, though. Does the QNX
HID stack support the “USB Physical Interface Devices
version 1.0” spec?

John Nagle
Team Overbot


John Nagle wrote:

I can get the HID system and a generic joystick interface
to work, but a number of issues have emerged.

  1. “hidd_get_usage_value” is supposed to return a 32-bit
    unsigned value. Reading “HIDD_USAGE_X” with the
    joystick I have (a Logitec Attack 3) returns the
    correct X position of the joystick in the low 8 bits.
    The higher bits contain junk which must be masked off.
    It’s not clear how to do this in a generic way, since
    different devices have different ranges.

  2. “hidd_get_buttons” works, but “hidd_get_all_buttons”
    seems to return a button count of 3 or greater
    and incorrect button information.

  3. “hidd_set_idle” if set to “HIDD_TIME_DEFAULT”, does
    result in idle reports, but the numeric values
    returned for input joystick positions are often
    bogus.

Documentation notes:

  1. It’s worth mentioning that, while you get “insertion”
    reports on everything of interest, you don’t get
    “disconnect” reports unless you register for
    HID_INPUT_REPORT callbacks.

  2. The documentation for “hidd_connect” and “hidd_report_attach”
    doesn’t match the function prototypes.

John Nagle
Team Overbot

John Nagle <nagle@overbot.com> wrote in message
news:ca3gap$p3v$1@inn.qnx.com

I now have a more or less generic USB joystick library
working, which I will post on the Overbot web site at
a later date. So far, I’ve tried a Logitech Attack 3
joystick and a Logitech Momo steering wheel. All inputs
work for each of them, and the system self-configures for
the numeric range output by the device for each axis.

No force feedback support, though. Does the QNX
HID stack support the “USB Physical Interface Devices
version 1.0” spec?

It currently does not send PID output reports to the Interrupt out endpoint
of
the device.This could be added but I need to get a device that supports
forcefeedback to implement this feature.

There shouldn’t be much else needed to support PID in the HID architecture.
You would need to handle all of the parsing of PID descriptors and sending
of
output reports to the device.

Henry

John Nagle
Team Overbot


John Nagle wrote:
I can get the HID system and a generic joystick interface
to work, but a number of issues have emerged.

  1. “hidd_get_usage_value” is supposed to return a 32-bit
    unsigned value. Reading “HIDD_USAGE_X” with the
    joystick I have (a Logitec Attack 3) returns the
    correct X position of the joystick in the low 8 bits.
    The higher bits contain junk which must be masked off.
    It’s not clear how to do this in a generic way, since
    different devices have different ranges.

  2. “hidd_get_buttons” works, but “hidd_get_all_buttons”
    seems to return a button count of 3 or greater
    and incorrect button information.

  3. “hidd_set_idle” if set to “HIDD_TIME_DEFAULT”, does
    result in idle reports, but the numeric values
    returned for input joystick positions are often
    bogus.

Documentation notes:

  1. It’s worth mentioning that, while you get “insertion”
    reports on everything of interest, you don’t get
    “disconnect” reports unless you register for
    HID_INPUT_REPORT callbacks.

  2. The documentation for “hidd_connect” and “hidd_report_attach”
    doesn’t match the function prototypes.

John Nagle
Team Overbot

John Nagle wrote:

I can get the HID system and a generic joystick interface
to work, but a number of issues have emerged.

  1. “hidd_get_usage_value” is supposed to return a 32-bit
    unsigned value. Reading “HIDD_USAGE_X” with the
    joystick I have (a Logitec Attack 3) returns the
    correct X position of the joystick in the low 8 bits.
    The higher bits contain junk which must be masked off.
    It’s not clear how to do this in a generic way, since
    different devices have different ranges.

  2. “hidd_get_buttons” works, but “hidd_get_all_buttons”
    seems to return a button count of 3 or greater
    and incorrect button information.

  3. “hidd_set_idle” if set to “HIDD_TIME_DEFAULT”, does
    result in idle reports, but the numeric values
    returned for input joystick positions are often
    bogus.

Documentation notes:

  1. It’s worth mentioning that, while you get “insertion”
    reports on everything of interest, you don’t get
    “disconnect” reports unless you register for
    HID_INPUT_REPORT callbacks.

  2. The documentation for “hidd_connect” and “hidd_report_attach”
    doesn’t match the function prototypes.

John Nagle
Team Overbot

John Nagle wrote:

I can get the HID system and a generic joystick interface
to work, but a number of issues have emerged.

An additional bug:

hidd_get_scaled_usage_value doesn’t seem to
change its output “value” argument at all. Even when
returning EOK, it doesn’t return a value. Whatever
I set the output “value” to before the call
is still there after the call. Something
is wrong there.

hidd_get_usage_value, as mentioned yesterday,
has junk data in the high bits of the returned value.
I think the HID library is failing to do some necessary
masking.

I’m working around that problem as follows:

  • The program gets the actual value with hidd_get_usage_value.
    That value has junk in the high bits. (See item #1
    in previous message).

  • It gets the “physical_max” value from the
    properties page, and uses that to build a mask
    to clear the irrelevant bits.

  • The value and the mask are ANDed to get a valid
    value.

  • The values from the properties page are used to scale
    the value into the range 0.0 to 1.0, to provide
    device independence.

That shouldn’t be necessary.

This is working for the two USB joystick devices I’ve tried,
which are a Logitech Attack 3 joystick and a Logitech MOMO wheel.

John Nagle
Team Overbot

John Nagle wrote:

John Nagle wrote:

I can get the HID system and a generic joystick interface
to work, but a number of issues have emerged.

More little stuff:

– The HID library starts off a thread to make callbacks,
and that thread apparently has a rather limited stack size
with no way to increase it.

– Is there some way to force an initial update when
a device is inserted? There’s no incoming data update
until the first time something changes.


John Nagle
Team Overbot

Here’s an example of the HID driver in use. That
MOMO wheel is running through the HID driver, and the joystick
class library I previously sent you. The wheel
is controlling the steering on the robot vehicle in the
background.

When this picture was taken, everything was powered up
and running; that wheel was controlling the steering servomotor.

John Nagle
Team Overbot

Another problem:

If my application is left idle for hours, with no HID activity,
new joystick activity DOES NOT result in input events. Unplugging
the device WILL result in a removal event. Plugging the device
back in WILL result in an insertion event, and thereafter it works.
I’ve seen this three times now, overnight.

Are there any long timeouts in the HID code? Please check.

John Nagle
Team Overbot

John Nagle wrote:

John Nagle wrote:

John Nagle wrote:

I can get the HID system and a generic joystick interface
to work, but a number of issues have emerged.


More little stuff:

– The HID library starts off a thread to make callbacks,
and that thread apparently has a rather limited stack size
with no way to increase it.

– Is there some way to force an initial update when
a device is inserted? There’s no incoming data update
until the first time something changes.


John Nagle
Team Overbot

When this occurs could you run the ‘usb’ utility to see if the device is
still responding. What USB chipset do you have ?

John Nagle <nagle@overbot.com> wrote in message
news:40D8CD89.6080802@overbot.com

Another problem:

If my application is left idle for hours, with no HID activity,
new joystick activity DOES NOT result in input events. Unplugging
the device WILL result in a removal event. Plugging the device
back in WILL result in an insertion event, and thereafter it works.
I’ve seen this three times now, overnight.

Are there any long timeouts in the HID code? Please check.

John Nagle
Team Overbot

John Nagle wrote:
John Nagle wrote:

John Nagle wrote:

I can get the HID system and a generic joystick interface
to work, but a number of issues have emerged.


More little stuff:

– The HID library starts off a thread to make callbacks,
and that thread apparently has a rather limited stack size
with no way to increase it.

– Is there some way to force an initial update when
a device is inserted? There’s no incoming data update
until the first time something changes.


John Nagle
Team Overbot

$ /sbin/usb
USB (UHCI) v1.10, v1.01 DDK

Device Address : 1
Vendor : 0x046d (Logitech )
Product : 0xca03 (Logitech MOMO Racing )
Class : 0x00 (Independant per interface)

/usr/sbin/pci -v

Class = Serial Bus (Universal Serial Bus)
Vendor ID = 8086h, Intel Corporation
Device ID = 24cdh, Unknown Unknown
PCI index = 0h
Class Codes = 0c0320h
Revision ID = 1h
Bus number = 0

John Nagle
Team Overbot


Henry VanDyke wrote:

When this occurs could you run the ‘usb’ utility to see if the device is
still responding. What USB chipset do you have ?

John Nagle <> nagle@overbot.com> > wrote in message
news:> 40D8CD89.6080802@overbot.com> …

Another problem:

If my application is left idle for hours, with no HID activity,
new joystick activity DOES NOT result in input events. Unplugging
the device WILL result in a removal event. Plugging the device
back in WILL result in an insertion event, and thereafter it works.
I’ve seen this three times now, overnight.

Are there any long timeouts in the HID code? Please check.

John Nagle
Team Overbot

This is still happening. And on at least one occasion,
the device seemed to stop responding.

There’s always the possibility that the joystick device
itself is having problems. Is there some way I can send
a command to the joystick that tests if it is responding?
What’s the easiest way to force an HID update event?
I need to do that at startup, anyway, to get the
initial position readings.


John Nagle
Team Overbot

John Nagle wrote:

Another problem:

If my application is left idle for hours, with no HID activity,
new joystick activity DOES NOT result in input events. Unplugging
the device WILL result in a removal event. Plugging the device
back in WILL result in an insertion event, and thereafter it works.
I’ve seen this three times now, overnight.

Are there any long timeouts in the HID code? Please check.

John Nagle
Team Overbot

I have more of a handle on the problem now. We’re
blocking the callback function using Photon’s main lock,
and there are times when the callback might be blocked
for a few seconds. This, apparently, is a Bad Thing,
and results in the HID library stalling or becoming
confused. Try putting “sleep(10)” in a HID update
callback, and see what breaks. Thanks.

John Nagle

John Nagle wrote:

This is still happening. And on at least one occasion,
the device seemed to stop responding.

There’s always the possibility that the joystick device
itself is having problems. Is there some way I can send
a command to the joystick that tests if it is responding?
What’s the easiest way to force an HID update event?
I need to do that at startup, anyway, to get the
initial position readings.


John Nagle
Team Overbot

John Nagle wrote:

Another problem:

If my application is left idle for hours, with no HID activity,
new joystick activity DOES NOT result in input events. Unplugging
the device WILL result in a removal event. Plugging the device
back in WILL result in an insertion event, and thereafter it works.
I’ve seen this three times now, overnight.

Are there any long timeouts in the HID code? Please check.

John Nagle
Team Overbot

John Nagle <nagle@downside.com> wrote in message
news:cbustr$n5i$1@inn.qnx.com

This is still happening. And on at least one occasion,
the device seemed to stop responding.

There’s always the possibility that the joystick device
itself is having problems. Is there some way I can send
a command to the joystick that tests if it is responding?

You could run the usb utility. This will at least make sure the device
is responding.

Also try running ‘hidview -A’ . This will display the raw data coming
from the device.

What’s the easiest way to force an HID update event?
I need to do that at startup, anyway, to get the
initial position readings.

hidd_get_report()

John Nagle
Team Overbot

John Nagle wrote:

Another problem:

If my application is left idle for hours, with no HID activity,
new joystick activity DOES NOT result in input events. Unplugging
the device WILL result in a removal event. Plugging the device
back in WILL result in an insertion event, and thereafter it works.
I’ve seen this three times now, overnight.

Are there any long timeouts in the HID code? Please check.

John Nagle
Team Overbot

OK, thanks.

Here’s the device, nonresponsive after a day of idle:

gcrear1$ ./usb
USB (UHCI) v1.10, v1.01 DDK

device 1 - descriptors - Input/output error

== unplugged USB cable and plugged it back in ==

gcrear1$ ./usb
USB (UHCI) v1.10, v1.01 DDK

Device Address : 1
Vendor : 0x046d (Logitech )
Product : 0xca03 (Logitech MOMO Racing )
Class : 0x00 (Independant per interface)

So either the device or the driver is in some bad state.
Any insights?

Inserting and removing the device brings it back up.
Restarting my application does NOT bring it back up. My
program gets an insertion event for the dead device when
the program is started, but never gets any other events.

“hidview -a” doesn’t produce any output from the device
when it’s in the “Input/output error” state.

John Nagle

Henry VanDyke wrote:

John Nagle <> nagle@downside.com> > wrote in message
news:cbustr$n5i$> 1@inn.qnx.com> …

This is still happening. And on at least one occasion,
the device seemed to stop responding.

There’s always the possibility that the joystick device
itself is having problems. Is there some way I can send
a command to the joystick that tests if it is responding?


You could run the usb utility. This will at least make sure the device
is responding.

Also try running ‘hidview -A’ . This will display the raw data coming
from the device.


What’s the easiest way to force an HID update event?
I need to do that at startup, anyway, to get the
initial position readings.


hidd_get_report()



John Nagle
Team Overbot

John Nagle wrote:


Another problem:

If my application is left idle for hours, with no HID activity,
new joystick activity DOES NOT result in input events. Unplugging
the device WILL result in a removal event. Plugging the device
back in WILL result in an insertion event, and thereafter it works.
I’ve seen this three times now, overnight.

Are there any long timeouts in the HID code? Please check.

John Nagle
Team Overbot


\

John Nagle <nagle@overbot.com> wrote in message
news:ccco9r$b0v$1@inn.qnx.com

OK, thanks.

Here’s the device, nonresponsive after a day of idle:

gcrear1$ ./usb
USB (UHCI) v1.10, v1.01 DDK

device 1 - descriptors - Input/output error

Ok.

Either the device is in a bad state or something is wrong in the USB stack.
I’ll try to reproduce it here. Could you verify that it happens overnight
with just the ‘hidview -a’ running ( Without the joystick driver running)
Also, if you have a usb mouse or keyboard you could plug it in as well
and see if it is still responsive when running hidiview/usb.

== unplugged USB cable and plugged it back in ==

gcrear1$ ./usb
USB (UHCI) v1.10, v1.01 DDK

Device Address : 1
Vendor : 0x046d (Logitech )
Product : 0xca03 (Logitech MOMO Racing )
Class : 0x00 (Independant per interface)

So either the device or the driver is in some bad state.
Any insights?

Inserting and removing the device brings it back up.
Restarting my application does NOT bring it back up. My
program gets an insertion event for the dead device when
the program is started, but never gets any other events.

“hidview -a” doesn’t produce any output from the device
when it’s in the “Input/output error” state.

John Nagle

Henry VanDyke wrote:
John Nagle <> nagle@downside.com> > wrote in message
news:cbustr$n5i$> 1@inn.qnx.com> …

This is still happening. And on at least one occasion,
the device seemed to stop responding.

There’s always the possibility that the joystick device
itself is having problems. Is there some way I can send
a command to the joystick that tests if it is responding?


You could run the usb utility. This will at least make sure the device
is responding.

Also try running ‘hidview -A’ . This will display the raw data coming
from the device.


What’s the easiest way to force an HID update event?
I need to do that at startup, anyway, to get the
initial position readings.


hidd_get_report()



John Nagle
Team Overbot

John Nagle wrote:


Another problem:

If my application is left idle for hours, with no HID activity,
new joystick activity DOES NOT result in input events. Unplugging
the device WILL result in a removal event. Plugging the device
back in WILL result in an insertion event, and thereafter it works.
I’ve seen this three times now, overnight.

Are there any long timeouts in the HID code? Please check.

John Nagle
Team Overbot


\