PORTS Forum
Ports and Interfaces => USB => Topic started 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
-
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
-
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.
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.
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
-
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.
-
just send them one or two at a time.
You are right.
It's described as Serial Mode on above MS document, too.
Tsuneo
-
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
-
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
}
};
-
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.
0x85, 0x01, // REPORT_ID (Touch)
0x85, 0x02, // REPORT_ID (Feature)
2) You may bind two or more USAGEs into single INPUT, like
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
0x55, 0x00, // UNIT_EXPONENT (0)
0x65, 0x00, // UNIT (None)
0x35, 0x00, // PHYSICAL_MINIMUM (0)
0x46, 0x00, 0x00, // PHYSICAL_MAXIMUM (0)
Tsuneo
-
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
-
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
-
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.
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.
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