PORTS Forum

Ports and Interfaces => USB => Topic started by: len_white on June 24, 2013, 02:57:29 pm

Title: Beagleboard HID firmware for Win7 Host
Post by: len_white on June 24, 2013, 02:57:29 pm
Hello! I'm a huge fan of Jan's generous contributions to the USB community. Extremely useful. Thanks.

However, I'm running into a problem I can't get past.
I'm writing HID firmware on a Beagleboard-XM (Angstrom Linux) that allows it to function as a HID multi-touch device, primarily targeting Windows 7, for now.
By modifying hid.c I've created a custom kernel module g_hid.ko that works to create a single-touch HID device.
However, I thought going to multi-touch would be straightforward, but it's not. I can't get Windows 7 to recognized the Beagleboard's multiple touch events.
My suspicion from research is that Windows 7 is making a hid feature request for maximum number of touches that my Beagleboard is not responding to.
Problem is, this is where my understanding of the Linux HID kernel module stops. I can't figure out how to add that functionality.
Anyone know anything about Linux HID kernel module programming?
Any leads on where I can research to understand better are appreciated as well.
I'm really at sea on this one and am willing to hire a freelancer if I can find one to help finish the project.
Thanks and please contact me if you are interested.
-Len


Title: Re: Beagleboard HID firmware for Win7 Host
Post by: Jan Axelson on June 24, 2013, 10:46:45 pm
A protocol analyzer or other debugging techniques can tell you definitively what is happening on the bus.

http://lxr.free-electrons.com/source/drivers/hid/hid-multitouch.c

The BeagleBoard google group might have some advice.
Title: Re: Beagleboard HID firmware for Win7 Host
Post by: len_white on June 26, 2013, 01:50:00 am
Thanks, Jan.
Correct me if I'm wrong but that code you linked to is for a host-side driver, correct?
The Beagleboard-side firmware driver will have to use the gadget architecture, right?

-Len
Title: Re: Beagleboard HID firmware for Win7 Host
Post by: Jan Axelson on June 26, 2013, 09:53:21 am
Yes. Also see:

http://www.lvr.com/forum/index.php?topic=733.msg4271
Title: Re: Beagleboard HID firmware for Win7 Host
Post by: len_white on June 30, 2013, 04:21:29 pm
Thanks for the leads. I've pored overt those posts previously seeing if they hold the secret to my issue.
However, they still seems focused on the host-side of the equation.
I really need to understand better how linux is handling feature requests to provide the host with the appropriate multi-touch flags.
hid.c is the key, I think. That's the linux source that handles all the requests from the host for report descriptors and, I think, feature requests.
Those feature requests are going un-answered, as far as I can tell from studying the code.
But perhaps there's another file entirely that handles those requests?
As far as I can tell only one socket is being created via hid.c (/dev/hidg0) so that couldn't handle both types of requests, right?

-Len
Title: Re: Beagleboard HID firmware for Win7 Host
Post by: Jan Axelson on June 30, 2013, 05:32:13 pm
One way to do it is to attach a similar, working device and monitor the traffic.

Use whatever debugging tools you have to find out how your device is responding to the requests for Feature reports. Is the endpoint STALLing the request to indicate that the device doesn't support the request? Or ??
Title: Re: Beagleboard HID firmware for Win7 Host
Post by: len_white on June 30, 2013, 07:14:07 pm
Good ideas. Thanks.
Attaching a similar device is not easy for me since I don't have another multi-touch HID peripheral that works with Windows.
From what I can see of hid.c, a feature request response is not part of the linux hid gadget source.
At least not that I can tell.
It opens a socket at /dev/hidg0 and then basic reports (matching the top part of the report descriptor) can be sent through this and received by the Windows host.
However, this lets me send touch point data but, as far as I can tell, not feature request data.
So Windows never acknowledges more than one touch.
I could and will try to monitor the exact structure of the feature requests sent by the windows host (if they are indeed being sent at all).
It's only my guess at this point that a feature request is going un-responded-to. May be some other reason not more than one touch event is processed by the host.
But that won't change the sad fact that I'm a bit at a loss to understand how to respond to those feature requests in the linux kernel module source.
Linux is tough!  : )

-Len

Title: Re: Beagleboard HID firmware for Win7 Host
Post by: Tsuneo on June 30, 2013, 10:31:03 pm
Hi Len,

Quote
However, this lets me send touch point data but, as far as I can tell, not feature request data.

Multi-touch device should return one-byte "Contact Count Maximum" feature report, either in Parallel/Hybrid/Serial Reporting Mode.

In drivers/usb/gadget/f_hid.c, however, hidg_setup() returns empty report to Get_Report() request, either for input or for feature.

Code: [Select]
http://lxr.free-electrons.com/source/drivers/usb/gadget/f_hid.c#L372

372 static int hidg_setup(struct usb_function *f,
373                 const struct usb_ctrlrequest *ctrl)
374 {
    ...
387         switch ((ctrl->bRequestType << 8) | ctrl->bRequest) {
388         case ((USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE) << 8
389                   | HID_REQ_GET_REPORT):
390                 VDBG(cdev, "get_report\n");
391
392                 /* send an empty report */
393                 length = min_t(unsigned, length, hidg->report_length);
394                 memset(req->buf, 0x0, length);
395
396                 goto respond;
397                 break;

Modify it as follows, and try if any other problem would occur.
Code: [Select]
#define HID_REPORT_TYPE_INPUT    0x01
#define HID_REPORT_TYPE_OUTPUT   0x02
#define HID_REPORT_TYPE_FEATTURE 0x03

if ( ctrl->wValue == HID_REPORT_TYPE_FEATTURE << 8 ) {  // for Get_Report( FEATURE )
    length = 1;
    req->buf[0] = your_Contact_Count_Maximum;
    goto respond;
}

Tsuneo
Title: Re: Beagleboard HID firmware for Win7 Host
Post by: len_white on July 21, 2013, 01:00:57 pm
That is fantastic!
Thank you Tsuneo! I'm going to try your suggestions today and see how it goes.
(sorry for the late response - been crunched at my new job)

-Len
Title: Re: Beagleboard HID firmware for Win7 Host
Post by: len_white on July 28, 2013, 03:35:50 pm
I'm not getting the result I expected with this code update.
I insert the following just inside hidg_setup of f_hid.c but get no indication of the printk from dmesg, meaning that the condition is never being met.

if ( ctrl->wValue == HID_REPORT_TYPE_FEATURE << 8 ) {  // for Get_Report( FEATURE )
         memset(req->buf, 0x0f, 1);
         printk(KERN_ALERT, "Feature report requested and responded!");
         goto respond;
}

I can confirm that hidg_setup is being called correct from another printk just within.
Should the feature request be made every time a new hid connection is established or more often?

Thanks for the very useful help thus far.
-Len
Title: Re: Beagleboard HID firmware for Win7 Host
Post by: Jan Axelson on July 28, 2013, 09:54:38 pm
A host can request a HID Feature report whenever it wants.
Title: Re: Beagleboard HID firmware for Win7 Host
Post by: Tsuneo on July 29, 2013, 08:28:40 am
Quote
the condition is never being met.
Ah, I missed that report ID of the Contact Count Max should be coded.

Code: [Select]
#define HID_REPORT_ID_MAX_COUNT  0x02

if ( ctrl->wValue == ((HID_REPORT_TYPE_FEATTURE << 8) | HID_REPORT_ID_MAX_COUNT ) ) {

On your report descriptor, the report ID value may be different from above one. Tune it.

Tsuneo
Title: Re: Beagleboard HID firmware for Win7 Host
Post by: len_white on August 07, 2013, 10:27:59 am
I see. Interesting. Thank you. I'll try that.
MAX_COUNT can be a much larger number than 2, right?
Does anyone know what Windows allows?
Title: Re: Beagleboard HID firmware for Win7 Host
Post by: Tsuneo on August 08, 2013, 09:56:45 am
To pass Device.Digitizer Testing of Windows Hardware Certification Kit, at least five touches are required.

Windows Touch Five Point Minimum Test
http://msdn.microsoft.com/en-us/library/windows/hardware/jj125183.aspx

Tsuneo
Title: Re: Beagleboard HID firmware for Win7 Host
Post by: len_white on August 10, 2013, 01:09:38 pm
Unfortunately, that didn't help.
It's still not satisfying that conditional:
ctrl->wValue == ((HID_REPORT_TYPE_FEATTURE << 8) | HID_REPORT_ID_MAX_COUNT

I wonder...is there something in the feature descriptor that needs to match HID_REPORT_ID_MAX_COUNT?
I don't see it appearing anywhere.
Could a mismatch there cause a problem?

I've copied my report descriptor (from hid.c) for trying to get two simultaneous touches working next. Could you see if it looks ok? Thanks so much for the aid.

static struct hidg_func_descriptor my_hid_data_multitouch_2 = {
.subclass      = 0, /* No subclass */
   .protocol      = 0, /* 1=Keyboard 2=Mouse */
   .report_length      = 15,
   .report_desc_length   = 145,
   .report_desc      = {
    0x05, 0x0D,           // USAGE_PAGE (Digitizers)       
    0x09, 0x04,           // USAGE (Touch Screen)             
    0xA1, 0x01,           // COLLECTION (Application)         
    0x85, 0x01,           //   REPORT_ID (Touch)      DATA - byte #1           
    0x09, 0x22,           //   USAGE (Finger)                 
    0xA1, 0x02,           //     COLLECTION (Logical)    - first touch
    0x09, 0x42,           //       USAGE (Tip Switch)           
    0x15, 0x00,           //       LOGICAL_MINIMUM (0)         
    0x25, 0x01,           //       LOGICAL_MAXIMUM (1)         
    0x75, 0x01,           //       REPORT_SIZE (1)             
    0x95, 0x01,           //       REPORT_COUNT (1)             
    0x81, 0x02,           //       INPUT (Data,Var,Abs)    DATA   - 1 bit
    0x09, 0x32,           //       USAGE (In Range)             
    0x81, 0x02,           //       INPUT (Data,Var,Abs)    DATA  - 1 bit
    0x95, 0x06,           //       REPORT_COUNT (6) 
    0x81, 0x03,           //       INPUT (Cnst,Ary,Abs)    DATA  - byte #2 
    0x75, 0x08,           //       REPORT_SIZE (8)
    0x09, 0x51,           //       USAGE (Contact Identifier) 
    0x95, 0x01,           //       REPORT_COUNT (1)             
    0x81, 0x02,           //       INPUT (Data,Var,Abs)      DATA  - byte #3
    0x05, 0x01,           //       USAGE_PAGE (Generic Desk..
    0x26, 0xFF, 0x0F,     //       LOGICAL_MAXIMUM (4095)         
    0x75, 0x10,           //       REPORT_SIZE (16)             
    0x55, 0x00,           //       UNIT_EXPONENT (0)           
    0x65, 0x00,           //       UNIT (None)                 
    0x09, 0x30,           //       USAGE (X)                   
    0x35, 0x00,           //       PHYSICAL_MINIMUM (0)         
    0x46, 0x00, 0x00,     //       PHYSICAL_MAXIMUM (0)         
    0x81, 0x02,           //       INPUT (Data,Var,Abs)        DATA - byte #4,5
    0x26, 0xFF, 0x0B,     //       LOGICAL_MAXIMUM (3071)     
    0x09, 0x31,           //       USAGE (Y)                   
    0x81, 0x02,           //       INPUT (Data,Var,Abs)          DATA - byte #6,7    (67)
    0xC0,                 //    END_COLLECTION
    0xA1, 0x02,           //     COLLECTION (Logical)   - second touch
    0x09, 0x42,           //       USAGE (Tip Switch)           
    0x15, 0x00,           //       LOGICAL_MINIMUM (0)         
    0x25, 0x01,           //       LOGICAL_MAXIMUM (1)         
    0x75, 0x01,           //       REPORT_SIZE (1)             
    0x95, 0x01,           //       REPORT_COUNT (1)             
    0x81, 0x02,           //       INPUT (Data,Var,Abs)       
    0x09, 0x32,           //       USAGE (In Range)             
    0x81, 0x02,           //       INPUT (Data,Var,Abs)         
    0x95, 0x06,           //       REPORT_COUNT (6) 
    0x81, 0x03,           //       INPUT (Cnst,Ary,Abs)         
    0x75, 0x08,           //       REPORT_SIZE (8)
    0x09, 0x51,           //       USAGE (Contact Identifier) 
    0x95, 0x01,           //       REPORT_COUNT (1)             
    0x81, 0x02,           //       INPUT (Data,Var,Abs)       
    0x05, 0x01,           //       USAGE_PAGE (Generic Desk..
    0x26, 0xFF, 0x0F,     //       LOGICAL_MAXIMUM (4095)         
    0x75, 0x10,           //       REPORT_SIZE (16)             
    0x55, 0x00,           //       UNIT_EXPONENT (0)           
    0x65, 0x00,           //       UNIT (None)                 
    0x09, 0x30,           //       USAGE (X)                   
    0x35, 0x00,           //       PHYSICAL_MINIMUM (0)         
    0x46, 0x00, 0x00,     //       PHYSICAL_MAXIMUM (0)         
    0x81, 0x02,           //       INPUT (Data,Var,Abs)       
    0x26, 0xFF, 0x0B,     //       LOGICAL_MAXIMUM (3071)     
    0x09, 0x31,           //       USAGE (Y)                   
    0x81, 0x02,           //       INPUT (Data,Var,Abs)         
    0xC0,                 //    END_COLLECTION  (67 + 59)

    0x05, 0x0D,           //   USAGE_PAGE (Digitizers)   
    0x09, 0x54,           //   USAGE (Actual count)
    0x95, 0x01,           //   REPORT_COUNT (1)
    0x75, 0x08,           //   REPORT_SIZE (8) 
    0x15, 0x00,           //    LOGICAL_MINIMUM (0)
   0x25, 0x08,           //    LOGICAL_MAXIMUM (8)
    0x81, 0x02,           //   INPUT (Data,Var,Abs)     DATA - byte #8 or #14 (two touch)                 
    0x09, 0x55,           //   USAGE(Maximum Count)
    0xB1, 0x02,           //   FEATURE (Data,Var,Abs)    DATA - byte #15 -- ?
    0xC0                  // END_COLLECTION  (67 + 59 + 19)
}
Title: Re: Beagleboard HID firmware for Win7 Host
Post by: Jan Axelson on August 11, 2013, 08:58:55 pm
Your descriptor contains no report ID for the Feature report. Thus the report ID for the MAX_COUNT Feature report = 0.
Title: Re: Beagleboard HID firmware for Win7 Host
Post by: Tsuneo on August 12, 2013, 01:38:19 am
Quote
len_white:
I've copied my report descriptor (from hid.c) .. Could you see if it looks ok?

Your report descriptor is slightly modified one from the "Sample Report Descriptor (Parallel/Hybrid Mode)" on the MS document, DigitizerDrvs_touch.docx ( http://msdn.microsoft.com/en-us/windows/hardware/gg487437.aspx )
- Touch Valid Usage (bit) is deleted
- X,Y range is reduced from 0x7FFF to 0x0FFF

1) Missing USAGE_PAGE (Digitizers)
USAGE_PAGE (Digitizers) is required at the second touch collection, because the Usage Page is altered by the USAGE_PAGE (Generic DeskTop) of the first collection.
Code: [Select]
    0xA1, 0x02,           //     COLLECTION (Logical)   - second touch
    0x05, 0x0D,           //       USAGE_PAGE (Digitizers)    // <--------
    0x09, 0x42,           //       USAGE (Tip Switch)           

2) The size of the input report is 14 bytes
Code: [Select]
Byte offset
  0         Report ID (1)
            First touch
  1           Tip Switch / In Range / 6bits padding
  2           Contact Identifier
  3, 4        X
  5, 6        Y
            Second touch
  7           Tip Switch / In Range / 6bits padding
  8           Contact Identifier
  9, 10       X
  11, 12      Y

  13        Actual count

3) Feature report
The report ID of the feature report is 1, which is defined at the top of your report descriptor ( REPORT_ID (Touch) )
The size of Feature report is 2 bytes.
Code: [Select]
Byte offset
  0         Report ID (1)
  1         Maximum Count

Tsuneo
Title: Re: Beagleboard HID firmware for Win7 Host
Post by: Jan Axelson on August 12, 2013, 11:29:51 am
Yes, I missed the report ID near the top.
Title: Re: Beagleboard HID firmware for Win7 Host
Post by: pal on September 19, 2013, 03:06:04 am
Len,

I am implementing 10-touch using Linux HID gadget drivers and works perfectly on Windows 8.
Let me know if the below works for you ...

1.Revert all changes you have made to g_hid.c
2.Add a printk message in the "case" where an empty feature report is sent. This is to confirm you are receiving the "GET_REPORT" request from host.
3.For the HID descriptor posted by you, length=2; req->buf[0] = 0x01; req->buf[1] = 0x02;

With the above you should have your gadget detected as 2-touch device.
req->buf[1] is the one containing max contact count which you may modify based on your device's actual touch capabilities.

Let me know how it goes . Good luck !
Title: Re: Beagleboard HID firmware for Win7 Host
Post by: Calvin on September 23, 2013, 10:31:35 pm
Hi Len,

Did you solved the problem of multi-touch USB HID gadget?
Would you mind to share your experience since I also got stuck in the multi-touch USB HID gadget?
Title: Re: Beagleboard HID firmware for Win7 Host
Post by: len_white on April 04, 2014, 09:30:59 pm
It's been a while....but I'm still not done.
My beagleboard crashed (or more likely the SD card) then my Windows 7 USB drivers got corrupted.
And I'm trying to fit this all in with a full-time plus job and my confidence that I'll ever figure it out is dwindling rapidly.
I'm back to seeing if I can make this work and I have to admit that I just don't have enough experience to understand what's going wrong.
So....
Anyone of you, who has some confidence in making Beagleboard's act like HID devices, interested in making a little money on the side?
I am ready to pay someone to help me through this, provide me with the relevant files, or even take on the hardware and get it done.
Please message me (I assume that's possible) if you are at all interested and I'd love to talk to you further.
Thanks.
-Len
Title: Re: Beagleboard HID firmware for Win7 Host
Post by: Jan Axelson on April 05, 2014, 06:11:34 pm
If you don't get a response here, try the BeagleBoard email group.