PORTS Forum

Ports and Interfaces => USB => Topic started by: ftariq68 on February 10, 2012, 05:26:53 pm

Title: Compressing the Report Descriptor for Multi Touch HID
Post by: ftariq68 on February 10, 2012, 05:26:53 pm
Hello All:

The Report Descriptor for Multi-Touch HID can become quite large.  For one touch it is quite big and for multiple touches it grows, essentially it is a copy of the early one with a few changes.  In the end for 10 touch it looks rather massive.  Is there a way to compress the Report Descriptor in size, so that we don't send the big behmoth?  Please see the Report Desciptor for 4 touch below.  As you can see all the Report Descriptor is getting repeated for each finger.  Can't we combine them somehow?

Windows HID Report Descriptor for Multi-Touch:

    0x05, 0x0D,     // USAGE_PAGE (Digitizers)         
    0x09, 0x04,     // USAGE (Touch Screen)             
    0xA1, 0x01,           // COLLECTION (Application)         
    0x85, 0x02,           //   REPORT_ID (Touch)                 
    0x09, 0x22,           //   USAGE (Finger)   

// 1st Touch           
    0xA1, 0x02,           //     COLLECTION (Logical) 
    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)   
    0x09, 0x47,   //     USAGE (Touch Valid)
    0x81, 0x02,   //     INPUT (Data,Var,Abs)
    0x95, 0x05,           //       REPORT_COUNT (5) 
    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, 0xF4, 0x08,     // LOGICAL_MAXIMUM (2292), BASED ON MAXIM EV-KIT
    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, 0xBE, 0x05,      //     LOGICAL_MAXIMUM (1470), BASED ON MAXIM EV-KIT
    0x09, 0x31,           //       USAGE (Y)                   
    0x81, 0x02,           //       INPUT (Data,Var,Abs)         
    0xC0,                 //    END_COLLECTION

//2nd Touch
    0xA1, 0x02,           //    COLLECTION (Logical) 
    0x05, 0x0D,    //       USAGE_PAGE (Digitizers) 
    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)         
    0x09, 0x47,           //     USAGE (Touch Valid)
    0x81, 0x02,   //     INPUT (Data,Var,Abs)       
    0x95, 0x05,           //       REPORT_COUNT (5) 
    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, 0xF4, 0x08,               // LOGICAL_MAXIMUM (2292), BASED ON MAXIM EV-KIT
    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, 0xBE, 0x05,           //     LOGICAL_MAXIMUM (1470), BASED ON MAXIM EV-KIT
    0x09, 0x31,           //       USAGE (Y)                   
    0x81, 0x02,           //       INPUT (Data,Var,Abs)   
    0xC0,                 //   END_COLLECTION

// 3rd touch
    0xA1, 0x02,           //    COLLECTION (Logical) 
    0x05, 0x0D,             //       USAGE_PAGE (Digitizers) 
    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)         
    0x09, 0x47,   //     USAGE (Touch Valid)
    0x81, 0x02,   //     INPUT (Data,Var,Abs)       
    0x95, 0x05,           //       REPORT_COUNT (5) 
    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, 0xF4, 0x08,               // LOGICAL_MAXIMUM (2292), BASED ON MAXIM EV-KIT
    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, 0xBE, 0x05,           //     LOGICAL_MAXIMUM (1470), BASED ON MAXIM EV-KIT
    0x09, 0x31,           //       USAGE (Y)                   
    0x81, 0x02,           //       INPUT (Data,Var,Abs)         
    0xC0,                 //   END_COLLECTION

// 4th touch
    0xA1, 0x02,           //    COLLECTION (Logical) 
    0x05, 0x0D,             //       USAGE_PAGE (Digitizers) 
    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)           
    0x09, 0x47,     //     USAGE (Touch Valid)
    0x81, 0x02,     //     INPUT (Data,Var,Abs)       
    0x95, 0x05,            //       REPORT_COUNT (5) 
    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, 0xF4, 0x08,               // LOGICAL_MAXIMUM (2292), BASED ON MAXIM EV-KIT
    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, 0xBE, 0x05,  //     LOGICAL_MAXIMUM (1470), BASED ON MAXIM EV-KIT
    0x09, 0x31,            //       USAGE (Y)                   
    0x81, 0x02,            //       INPUT (Data,Var,Abs)         
    0xC0,                    //   END_COLLECTION



    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)           
    0x85, 0x03,           //*   REPORT_ID (Feature)            
    0x09, 0x55,           //   USAGE(Maximum Count)
    0x25, 0x02,           //   LOGICAL_MAXIMUM (8)
    0xB1, 0x02,           //   FEATURE (Data,Var,Abs)          
    0xC0                  // END_COLLECTION
   
 
Title: Re: Compressing the Report Descriptor for Multi Touch HID
Post by: Jan Axelson on February 10, 2012, 09:24:16 pm
You might be able to eliminate a few lines with these:

Global item tags apply to all subsequently defined items unless overridden by another Global item.

A Local item’s value applies to all items that follow within a Main item until the descriptor assigns a new value. Local items don’t carry over to the next Main item.

See 6.2.2.4 - 6.2.2.8 in the HID spec.

Jan
Title: Re: Compressing the Report Descriptor for Multi Touch HID
Post by: Tsuneo on February 11, 2012, 08:19:41 am
Hi ftariq68,

I believe you refer to "Sample Report Descriptor (Parallel/Hybrid Mode)" on this Microsoft document (DigitizerDrvs_touch.docx), distributed on this MS page,
http://msdn.microsoft.com/en-us/windows/hardware/gg487437.aspx

In this example, and in yours too, there are a couple of redundant lines.
You may delete these lines.

- UNIT_EXPONENT (0)
- UNIT (None)
- PHYSICAL_MINIMUM (0)
- PHYSICAL_MAXIMUM (0)

The value of these items is the default one, and anywhere on the descriptor, it doesn't change.

Code: [Select]
Sample Report Descriptor (Parallel/Hybrid Mode)
    0x05, 0x0d,                         // USAGE_PAGE (Digitizers)
    0x09, 0x04,                         // USAGE (Touch Screen)
    0xa1, 0x01,                         // COLLECTION (Application)
    0x85, REPORTID_MTOUCH,              //   REPORT_ID (Touch)

                                        // --------- 1st finger ----------
    0x09, 0x22,                         //   USAGE (Finger)
    0xa1, 0x02,                         //   COLLECTION (Logical)
    ...
    ...
    0x05, 0x01,                         //       USAGE_PAGE (Generic Desk..
    0x26, 0xff, 0x7f,                   //       LOGICAL_MAXIMUM (32767)
    0x75, 0x10,                         //       REPORT_SIZE (16)
//    0x55, 0x00,                         //       UNIT_EXPONENT (0)     // <--- delete this line
//    0x65, 0x00,                         //       UNIT (None)           // <--- delete this line
    0x09, 0x30,                         //       USAGE (X)
//    0x35, 0x00,                         //       PHYSICAL_MINIMUM (0)  // <--- delete this line
//    0x46, 0x00, 0x00,                   //       PHYSICAL_MAXIMUM (0)  // <--- delete this line
    0x81, 0x02,                         //       INPUT (Data,Var,Abs)
    0x09, 0x31,                         //       USAGE (Y)
//    0x46, 0x00, 0x00,                   //       PHYSICAL_MAXIMUM (0)  // <--- delete this line
    0x81, 0x02,                         //       INPUT (Data,Var,Abs)
    0xc0,                               //    END_COLLECTION

                                        // --------- 2nd finger ----------
    0x05, 0x0d,                         //    USAGE_PAGE (Digitizers)    // <--- move to here
    0x09, 0x22,                         //    USAGE (Finger)             // <--- add this line
    0xa1, 0x02,                         //    COLLECTION (Logical)
//    0x05, 0x0d,                         //    USAGE_PAGE (Digitizers)  // <--- move to above line
    0x09, 0x42,                         //       USAGE (Tip Switch)
    ...
    ...

The second COLLECTION(Logical) requires USAGE(Finger), like above modification.

Quote
For one touch it is quite big and for multiple touches it grows, essentially it is a copy of the early one with a few changes.

Unfortunately, report descriptor 'grammar' doesn't have any macro, which represents a sequence of definitions. We have to repeat the 'finger' collections as many.

Tsuneo
Title: Re: Compressing the Report Descriptor for Multi Touch HID
Post by: Bret on February 11, 2012, 11:09:04 am
Just as a thought: Another possibility would be to not send all 10 touches in the same report -- just send them one or two at a time.  I'm not familiar with the application, so that could cause timing or latency issues in the software, especially if all 10 were pressed at the same time.  You could even set a flag in the reports to indicate that "the following report is linked to this one, and the data indicated in the next report actually happened at the same time as this one", which would cause some "binding" in the software.

Again, just a thought.
Title: Re: Compressing the Report Descriptor for Multi Touch HID
Post by: Tsuneo on February 11, 2012, 10:01:32 pm
Quote
just send them one or two at a time.

You are right.
It's described as Serial Mode on above MS document, too.

Tsuneo
Title: Re: Compressing the Report Descriptor for Multi Touch HID
Post by: ftariq68 on February 13, 2012, 11:05:32 am
Thanks everyone, for your reply and the tips on shrinking what I currently have.  I am also looking at the Serial Reporting Mode found at the Microsoft Windows website.  I have a feeling it may just do the job.  If speed does become an issue, a hybrid may just work.

Thanks

Title: Re: Compressing the Report Descriptor for Multi Touch HID
Post by: ftariq68 on February 14, 2012, 12:47:14 pm
Hi All:

The Serial Reporting mode at the MS website did not make too much sense.  But I believe the jist of all of this is that I can create a report exactly as I have for the 4 touch as above, except that it is now for single touch (at a time0 and the only thing that will change is the contact Identifier, based on the touch, i.e. if 4 fingers are touching then the data for the 1st touch will be sent with the contact ID=1, followed by 2nd touch data with the contact ID=2 and so on... (and offcourse the Feature Report will need to have the maximum touch allowed by the system to be sent as well) it will be a little slow but it will do the job.  Did I get it ?  (I know I still have to remove some of the redundant stuff).

Please see my new "Serial" Report Descriptor below.

unsigned char reportItemMultiTouch[] = {
    0x05, 0x0D,             // USAGE_PAGE (Digitizers)          
    0x09, 0x04,             // USAGE (Touch Screen)            
    0xA1, 0x01,           // COLLECTION (Application)        
    0x85, 0x01,             //   REPORT_ID (Touch)                 
    0x09, 0x22,           //   USAGE (Finger)                
    0xA1, 0x02,           //     COLLECTION (Logical)  
    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
    0x05, 0x0D,             //   USAGE_PAGE (Digitizers)    
    0x09, 0x54,             //   USAGE (Actual count)
    0x95, 0x01,           //   REPORT_COUNT (1)
    0x75, 0x08,           //   REPORT_SIZE (8)    
    0x81, 0x02,           //   INPUT (Data,Var,Abs)            
    0x85, 0x02,           //   REPORT_ID (Feature)                  
    0x09, 0x55,           //   USAGE(Maximum Count)
    0x25, 0x02,           //   LOGICAL_MAXIMUM (2)
    0xB1, 0x02,           //   FEATURE (Data,Var,Abs)    
    0xC0                  // END_COLLECTION
   }
};

Title: Re: Compressing the Report Descriptor for Multi Touch HID
Post by: Tsuneo on February 15, 2012, 07:23:02 am
I believe you get the points of the MS document well.
As of your report descriptor,

1) Report IDs are not required.
This report descriptor defines single input and single feature report.
You may delete report ID lines.
Code: [Select]
    0x85, 0x01,             //   REPORT_ID (Touch)
    0x85, 0x02,             //   REPORT_ID (Feature)

2) You may bind two or more USAGEs into single INPUT, like
Code: [Select]
    0x75, 0x01,           //       REPORT_SIZE (1)             
    0x95, 0x02,           //       REPORT_COUNT (2)   // <----
    0x09, 0x42,           //       USAGE (Tip Switch)         
    0x09, 0x32,           //       USAGE (In Range)           
    0x81, 0x02,           //       INPUT (Data,Var,Abs)
The USAGEs are assigned to LSB first.

3) You may delete these default values
Code: [Select]
    0x55, 0x00,           //       UNIT_EXPONENT (0) 
    0x65, 0x00,           //       UNIT (None) 
    0x35, 0x00,           //       PHYSICAL_MINIMUM (0) 
    0x46, 0x00, 0x00,     //       PHYSICAL_MAXIMUM (0)

Tsuneo
Title: Re: Compressing the Report Descriptor for Multi Touch HID
Post by: ftariq68 on February 15, 2012, 10:59:51 am
Hello Tsuneo:

Thanks a lot for your feedback and assistance, in this matter.  I checked the code and it is working very well under windows 7.  So the serial Report Descriptor works very well.

Thanks
Title: Re: Compressing the Report Descriptor for Multi Touch HID
Post by: Krcevina on December 25, 2012, 02:31:25 am
Hello,
I'm posting on this subject in hope that I will somehow caught Tsuneo's attention. During past few days I have been researching on this subject a lot, and I noticed that you know a great amount of stuff on this subject.

My project looks like this:
I have a remote device with four buttons and multi-touch. It is all under the control of a local c8051 uC. At the other side I have android phone in which I need to play with the information I am going to get (via Bluetooth) from the remote device. As you can assume, I need to write the HID descriptor for this device (Digitizer?).

But I have a few concerns.
This whole HID descriptor is something I need to write on the side of the android phone, so that he can parse the information which he is going to get from remote device (okay there is already that written, I need just to use it...). And on the side of the remote device i.e. in the firmware of the c9051, I need to pack the information in such a way that they match the expected form for the HID descriptor. Am i right?

And since my touch pad can detect up to to two touches, it wouldn't be such a burden to always send report for both of them (although one or both of them can be equal to zero)?

If I succeed in getting your attention, then I can perhaps send you my HID descriptor for quick analyze?

It would make such a good end of the year :)

Thanks in advance,
Krcevina
Title: Re: Compressing the Report Descriptor for Multi Touch HID
Post by: Tsuneo on December 27, 2012, 08:59:53 pm
Hi Krcevina,

Android supports Bluetooth HID profile and multi-touch on ICS (Android 4.0) and later as the default - 1),2)

The mapping of HID Usage for multi-touch is processed by mt_input_mapping() - Linux/drivers/hid/hid-multitouch.c
http://lxr.free-electrons.com/source/drivers/hid/hid-multitouch.c#L313

These HID Usages are mapped.
Code: [Select]
HID_UP_GENDESK          0x00010000    Generic Desktop page
    HID_GD_X            0x00010030      X
    HID_GD_Y 0x00010031      Y

HID_UP_DIGITIZER        0x000d0000    Digitizers page
    HID_DG_TIPPRESSURE  0x000d0030      Tip Pressure
    HID_DG_INRANGE      0x000d0032      In Range
    HID_DG_TOUCH        0x000d0033      Touch
    HID_DG_TIPSWITCH    0x000d0042      Tip Switch

    HID_DG_CONFIDENCE   0x000d0047      Touch Valid
    HID_DG_WIDTH        0x000d0048      Width
    HID_DG_HEIGHT       0x000d0049      Height
    HID_DG_CONTACTID    0x000d0051      Contact identifier
    HID_DG_CONTACTCOUNT 0x000d0054      Contact count
    HID_DG_CONTACTMAX   0x000d0055      Contact count maximum

HID_UP_BUTTON           0x00090000    Buttons page

It covers most of Usages on above MS document, except for Configuration (0x0E), Device mode (0x52), Device settings (0x23) and Device identifier (0x53)

Therefore, the examples on above MS document should work on Android ICS, too.

Quote
This whole HID descriptor is something I need to write on the side of the android phone, so that he can parse the information which he is going to get from remote device
The HID report descriptor is provided by the multi-touch device at the response to SDP(Service Discovery Protocol), not by the Android phone.

[References]
1) HID profile is implemented in this source.
android/frameworks/base/core/java/android/bluetooth/BluetoothInputDevice.java

2) Migration Guide
http://source.android.com/tech/input/migration-guide.html
Migrating to Android Ice Cream Sandwich 4.0
In Ice Cream Sandwich 4.0, we changed the device driver requirements for touch screens to follow the standard Linux multitouch input protocol and added support for protocol "B". We also support digitizer tablets and stylus-based touch devices.


Tsuneo