PORTS Forum
Ports and Interfaces => Other Interfaces => Topic started by: jeffcarl1 on May 14, 2015, 11:18:31 am
-
I remember seeing on a janaxelson related website about using multiple mouse in programs. Well, I am trying to get a report descriptor right but I believe I might have done something wrong. Anyone willing to take a look?
Its a really a simple report descriptor in which an intermediate device passes input down the chain to a mouse device its connected to. I have an error somewhere in the code descriptor or driver code but I believe its in the descriptor. I can post what it returns for the usage too if anyone needs it.
Here's the report descriptor:
HID_REPORT_DESCRIPTOR G_DefaultReportDescriptor[] = {
0x06, 0x00,0xFF, // (GLOBAL) USAGE_PAGE 0xFF00 Vendor-defined
0x09, 0x01, // (LOCAL) USAGE 0xFF000001
0xA1, 0x01, //(MAIN) COLLECTION 0x01 Application (Usage=0xFF000001: Page=Vendor-defined, Usage=, Type=)
0x85, 0x0F, // (GLOBAL) REPORT_ID 0x0F (15)
0x09, 0x01, // (LOCAL) USAGE 0xFF000001
0x15, 0x00, // (GLOBAL) LOGICAL_MINIMUM 0x00 (0) <-- Redundant: LOGICAL_MINIMUM is already 0
0x26, 0xFF,0x00, // (GLOBAL) LOGICAL_MAXIMUM 0x00FF (255)
0x75, 0x08, //(GLOBAL) REPORT_SIZE 0x08 (8) Number of bits per field
0x95, 0x09, // go back to (GLOBAL) REPORT_COUNT 0x0009 (9) Number of fields
0xB1, 0x00, // (MAIN) FEATURE 0x00000000 (9 fields x 8 bits) 0=Data 0=Array 0=Absolute 0=NoWrap 0=Linear 0=PrefState 0=NoNull 0=NonVolatile 0=Bitmap
0x09, 0x01, // (LOCAL) USAGE 0xFF000001
0x95, 0x01, // go back to (GLOBAL) REPORT_COUNT 0x0001 (1) Number of fields
0x81, 0x00, // (MAIN) INPUT 0x00000000 (1 field x 8 bits) 0=Data 0=Array 0=Absolute 0=Ignored 0=Ignored 0=PrefState 0=NoNull
0x09, 0x01, //(LOCAL) USAGE 0xFF000001
0x95, 0x07, // (GLOBAL) REPORT_COUNT 0x0007 (7) Number of fields
0x91, 0x00, //(MAIN) OUTPUT 0x00000000 (7 fields x 8 bits) 0=Data 0=Array 0=Absolute 0=NoWrap 0=Linear 0=PrefState 0=NoNull 0=NonVolatile 0=Bitmap
0xC0, //(MAIN) END_COLLECTION Application
0x05, 0x01, // (GLOBAL) USAGE_PAGE 0x0001 Generic Desktop Page
0x09, 0x02, // (LOCAL) USAGE 0x00010002 Mouse (CA=Application Collection)
0xA1, 0x01, // (MAIN) COLLECTION 0x01 Application (Usage=0x00010002: Page=Generic Desktop Page, Usage=Mouse, Type=CA)
0x09, 0x01, // (LOCAL) USAGE 0x00010001 Pointer (CP=Physical Collection)
0xA1, 0x02, // (MAIN) COLLECTION 0x02 Logical (Usage=0x00010001: Page=Generic Desktop Page, Usage=Pointer, Type=CP) <-- Warning: USAGE type should be CL (Logical)
0x05, 0x0A, // (GLOBAL) USAGE_PAGE 0x000A Ordinal Page
0x09, 0x01, // (LOCAL) USAGE 0x000A0001 Instance 1 (UM=Usage Modifier)
0x85, 0x01, // (GLOBAL) REPORT_ID 0x01 (1)
0xA1, 0x00, // (MAIN) COLLECTION 0x00 Physical (Usage=0x000A0001: Page=Ordinal Page, Usage=Instance 1, Type=UM) <-- Warning: USAGE type should be CP (Physical)
0x05, 0x09, // (GLOBAL) USAGE_PAGE 0x0009 Button Page
0x19, 0x01, // (LOCAL) USAGE_MINIMUM 0x00090001 Button 1 Primary/trigger (MULTI=Selector, On/Off, Momentary, or One Shot)
0x29, 0x03, // (LOCAL) USAGE_MAXIMUM 0x00090003 Button 3 Tertiary (MULTI=Selector, On/Off, Momentary, or One Shot)
0x15, 0x00, // (GLOBAL) LOGICAL_MINIMUM 0x00 (0) <-- Redundant: LOGICAL_MINIMUM is already 0
0x25, 0x01, // (GLOBAL) LOGICAL_MAXIMUM 0x01 (1)
0x75, 0x01, // (GLOBAL) REPORT_SIZE 0x01 (1) Number of bits per field
0x95, 0x03, // (GLOBAL) REPORT_COUNT 0x03 (3) Number of fields
0x81, 0x02, // (MAIN) INPUT 0x00000002 (3 fields x 1 bit) 0=Data 1=Variable 0=Absolute 0=NoWrap 0=Linear 0=PrefState 0=NoNull 0=NonVolatile 0=Bitmap
0x95, 0x05, // (GLOBAL)REPORT_COUNT 0x05 (5) Number of fields
0x81, 0x03, // (MAIN)INPUT 0x00000003 (5 fields x 1 bit) 1 = Constant 1 = Variable 0 = Absolute 0 = NoWrap 0 = Linear 0 = PrefState 0 = NoNull 0 = NonVolatile 0 = Bitmap
0x05, 0x01, // (GLOBAL)USAGE_PAGE 0x0001 Generic Desktop Page
0x09, 0x30, // (LOCAL)USAGE 0x00010030 X(DV = Dynamic Value)
0x09, 0x31, // (LOCAL)USAGE 0x00010031 Y(DV = Dynamic Value)
0x15, 0x81, // (GLOBAL)LOGICAL_MINIMUM 0x81 (-127)
0x25, 0x7F, // (GLOBAL)LOGICAL_MAXIMUM 0x7F (127)
0x75, 0x08, // (GLOBAL)REPORT_SIZE 0x08 (8) Number of bits per field
0x95, 0x02, // (GLOBAL)REPORT_COUNT 0x02 (2) Number of fields
0x81, 0x06, // (MAIN)INPUT 0x00000006 (2 fields x 8 bits) 0 = Data 1 = Variable 1 = Relative 0 = NoWrap 0 = Linear 0 = PrefState 0 = NoNull 0 = NonVolatile 0 = Bitmap
0xC0, // END_COLLECTION Physical
0x05, 0x0A, // (GLOBAL)USAGE_PAGE 0x000A Ordinal Page
0x09, 0x02, // (LOCAL)USAGE 0x000A0002 Instance 2 (UM = Usage Modifier)
0x85, 0x02, // (GLOBAL)REPORT_ID 0x02 (2)
0xA1, 0x00, // (MAIN)COLLECTION 0x00 Physical(Usage = 0x000A0002: Page = Ordinal Page, Usage = Instance 2, Type = UM) < --Warning: USAGE type should be CP(Physical)
0x05, 0x09, // (GLOBAL)USAGE_PAGE 0x0009 Button Page
0x19, 0x01, // (LOCAL)USAGE_MINIMUM 0x00090001 Button 1 Primary / trigger(MULTI = Selector, On / Off, Momentary, or One Shot)
0x29, 0x03, // (LOCAL)USAGE_MAXIMUM 0x00090003 Button 3 Tertiary(MULTI = Selector, On / Off, Momentary, or One Shot)
0x15, 0x00, // (GLOBAL)LOGICAL_MINIMUM 0x00 (0)
0x25, 0x01, // (GLOBAL)LOGICAL_MAXIMUM 0x01 (1)
0x75, 0x01, // (GLOBAL)REPORT_SIZE 0x01 (1) Number of bits per field
0x95, 0x03, // (GLOBAL)REPORT_COUNT 0x03 (3) Number of fields
0x81, 0x02, // (MAIN)INPUT 0x00000002 (3 fields x 1 bit) 0 = Data 1 = Variable 0 = Absolute 0 = NoWrap 0 = Linear 0 = PrefState 0 = NoNull 0 = NonVolatile 0 = Bitmap
0x95, 0x05, // (GLOBAL)REPORT_COUNT 0x05 (5) Number of fields
0x81, 0x03, // (MAIN)INPUT 0x00000003 (5 fields x 1 bit) 1 = Constant 1 = Variable 0 = Absolute 0 = NoWrap 0 = Linear 0 = PrefState 0 = NoNull 0 = NonVolatile 0 = Bitmap
0x05, 0x01, // (GLOBAL)USAGE_PAGE 0x0001 Generic Desktop Page
0x09, 0x30, // (LOCAL)USAGE 0x00010030 X(DV = Dynamic Value)
0x09, 0x31, // (LOCAL)USAGE 0x00010031 Y(DV = Dynamic Value)
0x15, 0x81, // (GLOBAL)LOGICAL_MINIMUM 0x81 (-127)
0x25, 0x7F, // (GLOBAL)LOGICAL_MAXIMUM 0x7F (127)
0x75, 0x08, // (GLOBAL)REPORT_SIZE 0x08 (8) Number of bits per field
0x95, 0x02, // (GLOBAL)REPORT_COUNT 0x02 (2) Number of fields
0x81, 0x06, // (MAIN)INPUT 0x00000006 (2 fields x 8 bits) 0 = Data 1 = Variable 1 = Relative 0 = NoWrap 0 = Linear 0 = PrefState 0 = NoNull 0 = NonVolatile 0 = Bitmap
0xC0, // END_COLLECTION Physical
0x05, 0x0A, // (GLOBAL)USAGE_PAGE 0x000A Ordinal Page
0x09, 0x03, // (LOCAL)USAGE 0x000A0003 Instance 3 (UM = Usage Modifier)
0x85, 0x03, // (GLOBAL)REPORT_ID 0x03 (3)
0xA1, 0x00, // (MAIN)COLLECTION 0x00 Physical(Usage = 0x000A0003: Page = Ordinal Page, Usage = Instance 3, Type = UM) < --Warning: USAGE type should be CP(Physical)
0x05, 0x09, // (GLOBAL)USAGE_PAGE 0x0009 Button Page
0x19, 0x01, // (LOCAL)USAGE_MINIMUM 0x00090001 Button 1 Primary / trigger(MULTI = Selector, On / Off, Momentary, or One Shot)
0x29, 0x03, // (LOCAL)USAGE_MAXIMUM 0x00090003 Button 3 Tertiary(MULTI = Selector, On / Off, Momentary, or One Shot)
0x15, 0x00, // (GLOBAL)LOGICAL_MINIMUM 0x00 (0)
0x25, 0x01, // (GLOBAL)LOGICAL_MAXIMUM 0x01 (1)
0x75, 0x01, // (GLOBAL)REPORT_SIZE 0x01 (1) Number of bits per field
0x95, 0x03, // (GLOBAL)REPORT_COUNT 0x03 (3) Number of fields
0x81, 0x02, // (MAIN)INPUT 0x00000002 (3 fields x 1 bit) 0 = Data 1 = Variable 0 = Absolute 0 = NoWrap 0 = Linear 0 = PrefState 0 = NoNull 0 = NonVolatile 0 = Bitmap
0x95, 0x05, // (GLOBAL)REPORT_COUNT 0x05 (5) Number of fields
0x81, 0x03, // (MAIN)INPUT 0x00000003 (5 fields x 1 bit) 1 = Constant 1 = Variable 0 = Absolute 0 = NoWrap 0 = Linear 0 = PrefState 0 = NoNull 0 = NonVolatile 0 = Bitmap
0x05, 0x01, // (GLOBAL)USAGE_PAGE 0x0001 Generic Desktop Page
0x09, 0x30, // (LOCAL)USAGE 0x00010030 X(DV = Dynamic Value)
0x09, 0x31, // (LOCAL)USAGE 0x00010031 Y(DV = Dynamic Value)
0x15, 0x81, // (GLOBAL)LOGICAL_MINIMUM 0x81 (-127)
0x25, 0x7F, // (GLOBAL)LOGICAL_MAXIMUM 0x7F (127)
0x75, 0x08, // (GLOBAL)REPORT_SIZE 0x08 (8) Number of bits per field
0x95, 0x02, // (GLOBAL)REPORT_COUNT 0x02 (2) Number of fields
0x81, 0x06, // (MAIN)INPUT 0x00000006 (2 fields x 8 bits) 0 = Data 1 = Variable 1 = Relative 0 = NoWrap 0 = Linear 0 = PrefState 0 = NoNull 0 = NonVolatile 0 = Bitmap
0xC0, // END_COLLECTION Physical
0x05, 0x0A, // (GLOBAL)USAGE_PAGE 0x000A Ordinal Page
0x09, 0x04, // (LOCAL)USAGE 0x000A0004 Instance 4 (UM = Usage Modifier)
0x85, 0x04, // (GLOBAL)REPORT_ID 0x04 (4)
0xA1, 0x00, // (MAIN)COLLECTION 0x00 Physical(Usage = 0x000A0004: Page = Ordinal Page, Usage = Instance 4, Type = UM) < --Warning: USAGE type should be CP(Physical)
0x05, 0x09, // (GLOBAL)USAGE_PAGE 0x0009 Button Page
0x19, 0x01, // (LOCAL)USAGE_MINIMUM 0x00090001 Button 1 Primary / trigger(MULTI = Selector, On / Off, Momentary, or One Shot)
0x29, 0x03, // (LOCAL)USAGE_MAXIMUM 0x00090003 Button 3 Tertiary(MULTI = Selector, On / Off, Momentary, or One Shot)
0x15, 0x00, // (GLOBAL)LOGICAL_MINIMUM 0x00 (0)
0x25, 0x01, // (GLOBAL)LOGICAL_MAXIMUM 0x01 (1)
0x75, 0x01, // (GLOBAL)REPORT_SIZE 0x01 (1) Number of bits per field
0x95, 0x03, // (GLOBAL)REPORT_COUNT 0x03 (3) Number of fields
0x81, 0x02, // (MAIN)INPUT 0x00000002 (3 fields x 1 bit) 0 = Data 1 = Variable 0 = Absolute 0 = NoWrap 0 = Linear 0 = PrefState 0 = NoNull 0 = NonVolatile 0 = Bitmap
0x95, 0x05, // (GLOBAL)REPORT_COUNT 0x05 (5) Number of fields
0x81, 0x03, // (MAIN)INPUT 0x00000003 (5 fields x 1 bit) 1 = Constant 1 = Variable 0 = Absolute 0 = NoWrap 0 = Linear 0 = PrefState 0 = NoNull 0 = NonVolatile 0 = Bitmap
0x05, 0x01, // (GLOBAL)USAGE_PAGE 0x0001 Generic Desktop Page
0x09, 0x30, // (LOCAL)USAGE 0x00010030 X(DV = Dynamic Value)
0x09, 0x31, // (LOCAL)USAGE 0x00010031 Y(DV = Dynamic Value)
0x15, 0x81, // (GLOBAL)LOGICAL_MINIMUM 0x81 (-127)
0x25, 0x7F, // (GLOBAL)LOGICAL_MAXIMUM 0x7F (127)
0x75, 0x08, // (GLOBAL)REPORT_SIZE 0x08 (8) Number of bits per field
0x95, 0x02, // (GLOBAL)REPORT_COUNT 0x02 (2) Number of fields
0x81, 0x06, // (MAIN)INPUT 0x00000006 (2 fields x 8 bits) 0 = Data 1 = Variable 1 = Relative 0 = NoWrap 0 = Linear 0 = PrefState 0 = NoNull 0 = NonVolatile 0 = Bitmap
0xC0, // END_COLLECTION Physical
0xC0, // END_COLLECTION Logical
0xC0, // END_COLLECTION Application
};
Here's the code in the original program which uses the default usage for a generic vendor device (really needs to be changed to a mouse device):
BOOLEAN
CheckIfOurDevice(
HANDLE file)
{
PHIDP_PREPARSED_DATA Ppd; // The opaque parser info describing this device
HIDP_CAPS Caps; // The Capabilities of this hid device.
USAGE MyUsagePage = 0xff00;
USAGE MyUsage = 0x0001;
HIDD_ATTRIBUTES attr; // Device attributes
if (!HidD_GetAttributes(file, &attr))
{
printf("Error: HidD_GetAttributes failed \n");
return FALSE;
}
printf("Device Attributes - PID: 0x%x, VID: 0x%x \n", attr.ProductID, attr.VendorID);
if ((attr.VendorID != HIDMINI_DEFAULT_VID) || (attr.ProductID != HIDMINI_DEFAULT_PID))
{
printf("Device attributes doesn't match the sample \n");
return FALSE;
}
if (!HidD_GetPreparsedData (file, &Ppd))
{
printf("Error: HidD_GetPreparsedData failed \n");
return FALSE;
}
if (!HidP_GetCaps (Ppd, &Caps))
{
printf("Error: HidP_GetCaps failed \n");
HidD_FreePreparsedData (Ppd);
return FALSE;
}
if ((Caps.UsagePage == MyUsagePage) && (Caps.Usage == MyUsage)){
printf("Success: Found my device.. \n");
return TRUE;
}
return FALSE;
}
-
Answering these questions will help to isolate the problem:
What happens when you attach the device?
Does it complete enumeration?
If no, where does the enumeration fail?
If yes, does it appear in Device Manager without errors?
If yes, what happens when you try to use data from the device?
Also, if you have changed the descriptors and kept the same Product ID and Vendor ID, see:
http://janaxelson.com/forum/index.php?topic=1367.msg6187#msg6187