Bill Kendrick | 6 Nov 19:21 2007
Picon

Digital Arts & Crafts Studio - HID help needed


Hi there, I just subscribed.  I'm author of the open source kid's
drawing program "Tux Paint" ( http://www.tuxpaint.org/ )

Recently while at a store, I noticed the Fisher-Price "Digital Arts & Crafts
Studio," a USB-based drawing tablet ('digitizer', as some call them) for
kids.  It has a basic, non-pressure-sensitive pad and stylus, and a number
of buttons for doing things like changing tools, choosing a color, etc.

I thought it would be a cool thing to support under Tux Paint, and as a
gift, my wife bought me one.  (They're about $50USD.)  It comes with
Windows software, which I've not tried yet, but upon plugging it into a
Linux 2.6.22 system (a Kubuntu 7.10 laptop), a device node at
"/dev/usb/hiddev0" appeared.  It sends a continuous stream of data
when I read it (e.g., using "xxd"), which repeats every 88 bytes.
The data changes when I press buttons or move the stylus on the device,
so I was pretty confident I'd get it to do something under Linux.

Some folks directed me to libhid, and I've begun (began?) creating a small
test app to read from the device.  I'm finally to the point where I can
call "hid_get_input_report()", but at the moment, I'm getting nothing but
zeros.  I think I'm using the wrong 'usage' path, so came here to get help.

Here's the output from "lsusb -vvv" for the specific device
("-d 0x0813:0x1006").  Based on this, I thought I'd only need to
specify one path for input, "0xff000001", but...?

Bus 003 Device 007: ID 0813:1006 Mattel, Inc. 
Device Descriptor:
  bLength                18
(Continue reading)

Peter Stuge | 7 Nov 00:02 2007

Re: Digital Arts & Crafts Studio - HID help needed

On Tue, Nov 06, 2007 at 10:21:54AM -0800, Bill Kendrick wrote:
> The data changes when I press buttons or move the stylus on the
> device, so I was pretty confident I'd get it to do something under
> Linux.

Have you checked if the kernel HID driver understands the data?

See if there is something created under /dev/input as well as hiddev.
If so, you may be able to just use the normal input layer API to read
from the tablet.

> Can someone assist? :)  Thanks!

Sorry, I'm not sure about the usage stuff, maybe Charles or someone
else will fill in.

//Peter
Charles Lepple | 7 Nov 02:00 2007

Re: Digital Arts & Crafts Studio - HID help needed

On Nov 6, 2007, at 1:21 PM, Bill Kendrick wrote:

> Hi there, I just subscribed.  I'm author of the open source kid's
> drawing program "Tux Paint" ( http://www.tuxpaint.org/ )

Hi!

Tux Paint looks pretty nice... and it's not every day that we hear  
from people wanting to add HID functionality to a fully working project.

> I thought it would be a cool thing to support under Tux Paint, and  
> as a
> gift, my wife bought me one.  (They're about $50USD.)  It comes with
> Windows software, which I've not tried yet, but upon plugging it  
> into a
> Linux 2.6.22 system (a Kubuntu 7.10 laptop), a device node at
> "/dev/usb/hiddev0" appeared.  It sends a continuous stream of data
> when I read it (e.g., using "xxd"), which repeats every 88 bytes.
> The data changes when I press buttons or move the stylus on the  
> device,
> so I was pretty confident I'd get it to do something under Linux.

As a developer, I'm sure this is second nature to you, but thank you  
for giving us a good idea about what system you are working with.

> Some folks directed me to libhid, and I've begun (began?) creating  
> a small
> test app to read from the device.  I'm finally to the point where I  
> can
> call "hid_get_input_report()", but at the moment, I'm getting  
(Continue reading)

Bill Kendrick | 7 Nov 02:13 2007
Picon

Re: Digital Arts & Crafts Studio - HID help needed

On Wed, Nov 07, 2007 at 12:02:43AM +0100, Peter Stuge wrote:
> On Tue, Nov 06, 2007 at 10:21:54AM -0800, Bill Kendrick wrote:
> > The data changes when I press buttons or move the stylus on the
> > device, so I was pretty confident I'd get it to do something under
> > Linux.
> 
> Have you checked if the kernel HID driver understands the data?
> 
> See if there is something created under /dev/input as well as hiddev.
> If so, you may be able to just use the normal input layer API to read
> from the tablet.

I don't believe it does -- nothing appears under /dev/input and
X didn't see it as a Wacom or mouse or anything...

I am a newbie at these kind of things, though.

In the end, it'd be good if this were managed more as a mouse
or tablet (based on the raw data, I believe it only has position and click,
no pressure-sensitivity, tilt or anything else fancy that more professional
tablets/digitizers have)... and the various buttons could be seen as joystick
buttons.

In the meantime, though, I'd like Tux Paint to support it sooner, rather
than later, so am happy to do it directly via libhid, esp. considering it
appears to be a multiplatform library. :)

Thx!

--

-- 
(Continue reading)

Bill Kendrick | 8 Nov 09:21 2007
Picon

Re: Digital Arts & Crafts Studio - HID help needed

On Tue, Nov 06, 2007 at 08:00:35PM -0500, Charles Lepple wrote:
> 
> As a developer, I'm sure this is second nature to you, but thank you  
> for giving us a good idea about what system you are working with.

You're welcome! :)

<snip>
> Also, if you were just doing a simple read() on /dev/usb/hiddev0, it  
> was probably doing interrupt transfers, and hid_get_input_report()  
> uses control transfers.

Ah, I see.  Obviously, I haven't had time to properly learn about USB,
and was struggling from the top-down with libraries first. :)
(Currently, the main time I have to work on the device is during a 3hr
train ride I take 2x per week.  BTW, I'll be doing so on 2007-11-09 from
7am to 10am Pacific time, and will be online.  Find me in #tux4kids on
irc.freenode.net if you'd like! :^) )

> In theory, the only difference is that interrupt reads will get  
> whatever report is available next, and a control transfer will allow  
> you to select a specific report.
<snip
> 
> But then again, you don't actually need usage paths for interrupt  
> reads. (With a report structure this simple, I will admit that libhid  
> is overkill, and you can just use the code as a guide for how to call  
> libusb directly.)

Indeed.  I've decided to start using libusb directly, but currently have
(Continue reading)

Charles Lepple | 8 Nov 13:39 2007

Re: Digital Arts & Crafts Studio - HID help needed

On Nov 8, 2007, at 3:21 AM, Bill Kendrick wrote:

> On Tue, Nov 06, 2007 at 08:00:35PM -0500, Charles Lepple wrote:
>> Also, if you were just doing a simple read() on /dev/usb/hiddev0, it
>> was probably doing interrupt transfers, and hid_get_input_report()
>> uses control transfers.
>
> Ah, I see.  Obviously, I haven't had time to properly learn about USB,
> and was struggling from the top-down with libraries first. :)

The libusb and libhid documentation do not really cover the mechanics  
of USB or HID.

However, chapter 9 of the USB spec (the suggested API that libusb  
follows), and the USB HID Class specification, are handy reference  
guides, and are not completely unreadable. You can download them from:

http://www.usb.org/developers/docs/

http://www.usb.org/developers/devclass_docs/HID1_11.pdf

> Indeed.  I've decided to start using libusb directly, but currently  
> have
> two problems:
>
> (1) Reads fail :)

Which error code? (Once you detach the device, you should be able to  
do anything with libusb/libhid that you can do with the /dev/usb/ 
hiddev* interface, but it's a matter of finding out exactly what to do)
(Continue reading)

Bill Kendrick | 8 Nov 18:39 2007
Picon

Re: Digital Arts & Crafts Studio - HID help needed

On Thu, Nov 08, 2007 at 07:39:32AM -0500, Charles Lepple wrote:
> > Indeed.  I've decided to start using libusb directly, but currently  
> > have two problems:
> >
> > (1) Reads fail :)
> 
> Which error code? (Once you detach the device, you should be able to  
> do anything with libusb/libhid that you can do with the /dev/usb/ 
> hiddev* interface, but it's a matter of finding out exactly what to do)

I get timeouts.  I've updated the code to specifically examine the USB
device for it's wMaxPacketSize, to make sure I'm not trying to read too
much or too little at a time, but still get timeouts.  (Specifically,
error -110, which is negative ETIMEDOUT.)

> > (2) I have not successfully detatched the device from the kernel.
> >   libhid did this for me via the 'force' open call.
> >   For now, I need to use the 'libhid-detatch-device' (I think?)  
> > tool first. :(
> 
> All of the magic is contained in hid_os_force_claim() in linux.c. The  
> loop is a good idea for robustness, because sometimes the kernel does  
> not let go of the device immediately. Two or three retries should  
> suffice.

Got it.  I COULD detatch, I just forgot by the time I wrote that email. :^)
My issue was getting errors when I tried to detatch again.  So now I do like
libhid: try to open, if that fails, try (a few times) to detatch, and open
again.  Seems to work great. :)

(Continue reading)

Tino Keitel | 11 Nov 22:17 2007
Picon

example program kills hiddev device node

Hi folks,

I tried to use a tool called hidmon to control man TFT over USB. That
worked a few times, but now I noticed that the hiddev device node in
/dev/usb/ went away. I didn't kow why. I rebooted the computer, changed
from Linux 2.6.23.1 to 2.6.22, powercycled the TFT, without luck. As
soon as I use hidmon, the device node is gone.

Now I compiled the libhid test program test_libhid.c and got the same
effect. It seems like hid_force_open() kills the device, as udev
receives a remote udevent. Here is what I did:

$ ls -l /dev/usb
total 0
crw-rw---- 1 root root 180, 96 Nov 11 20:27 hiddev0
crw-rw---- 1 root root 180, 97 Nov 11 21:50 hiddev1
crw-rw---- 1 root lp   180,  0 Nov 11 21:30 lp0

$ sudo ./test_libhid
 NOTICE: hid_init(): libhid 0.2.15+20060325.0.0 is being initialized.
  TRACE: hid_init(): initialising USB subsystem...
  TRACE: hid_init(): scanning for USB busses...
  TRACE: hid_init(): scanning for USB devices...
 NOTICE: hid_init(): successfully initialised HID library.
  TRACE: hid_new_HIDInterface(): creating a new HIDInterface
instance...
  TRACE: hid_force_open(): forcefully opening a device interface
according to matching criteria...
  TRACE: hid_get_usb_handle(): acquiring handle for a USB device...
  TRACE: hid_find_usb_device(): enumerating USB busses...
(Continue reading)

Charles Lepple | 11 Nov 23:05 2007

Re: example program kills hiddev device node

[Please don't cross-post. Thanks.]

On Nov 11, 2007, at 4:17 PM, Tino Keitel wrote:

> I tried to use a tool called hidmon to control man TFT over USB. That
> worked a few times, but now I noticed that the hiddev device node in
> /dev/usb/ went away. I didn't kow why. I rebooted the computer,  
> changed
> from Linux 2.6.23.1 to 2.6.22, powercycled the TFT, without luck. As
> soon as I use hidmon, the device node is gone.
>
> Now I compiled the libhid test program test_libhid.c and got the same
> effect. It seems like hid_force_open() kills the device, as udev
> receives a remote udevent.

This is intentional. libhid is a cross-platform alternative to the  
Linux hiddev API, and as such, it detaches the kernel hiddev driver  
from the device (technically, from the HID interface, but USB devices  
often only have one interface). This is necessary for libhid or  
libusb to claim the device exclusively. Since the kernel hiddev  
driver no longer sees the device, udev removes the device node. (The  
usbdevfs node still remains, and that is what libusb and libhid use  
to communicate with the device.)

--

-- 
Charles Lepple
Peter Stuge | 11 Nov 23:13 2007

Re: example program kills hiddev device node

On Sun, Nov 11, 2007 at 10:17:03PM +0100, Tino Keitel wrote:
> It seems like hid_force_open() kills the device

Quite correct.

> Anyone knows what's going on here, and how to fix it?

The hiddev device nodes are provided by the kernel HID driver.

hid_force_open() detaches the kernel HID driver so that libhid can
communicate directly with the device through usbfs, which is
impossible if another kernel driver is attached to the device.

There's no simple fix if the app uses libhid.

Difficult fixes include:
1. changing the app to use the hiddev API when possible
2. changing libhid to use the hiddev API when possible

Myself and others have thought about 2 for some time, but haven't
found time to do it. I've also heard rumors that hiddev will be
replaced, which means it may be even less likely to happen sooner
rather than later.

//Peter

Gmane