2013-02-06 01:41 AM
2014-09-08 12:24 AM
Hi, chang
have you by any chance found a solution for this problem? I implemented ur code and have the same problem, i even change the descriptor entirely for 10 touch points, but still windows only react to the first touch point, i know this post is too old, but i hopelessly hope somebody answer me thanks in advance2014-09-08 09:43 PM
> My problem is that even though my device reports two touches, PC recognizes only one touch
It sounds like you are very near to your goal. Maybe, you dont respond to the ''Contact Count Maximum'' query over Get_Report( Feature ) Request. This Feature report is defined on your report descriptor (just relevant lines)const uint8_t CustomHID_ReportDescriptor[CUSTOMHID_SIZ_REPORT_DESC] =
{
...
0x85, REPORTID_PEN, // REPORT_ID (Touch)
...
0x95, 0x01, // REPORT_COUNT (1)
0x75, 0x08, // REPORT_SIZE (8)
0x15, 0x00, // LOGICAL_MINIMUM (0)
0x25, 0x02, // LOGICAL_MAXIMUM (2) (Origianlly 8)
...
0x09, 0x55, // USAGE(Contact Count Maximum)
0xb1, 0x02, // FEATURE (Data,Var,Abs) (Originally 8)
0xc0 // END_COLLECTION
};
Your device has to return this two-byte Feature report to this Request, to make host know that your device returns two distinct touches, at most.
offset
0 0x01 : report ID
1 0x02 : Contact Count Maximum, two touches
To handle this Get_Report( Feature ),
1) STM32_USB-FS-Device_Lib_V4.0.0
\STM32_USB-FS-Device_Lib_V4.0.0\Projects\Custom_HID\src\usb_prop.c
uint8_t * CustomHID_GetReportFeatureValue(uint16_t Length); // <----- add this line
RESULT CustomHID_Data_Setup(uint8_t RequestNo)
{
...
/*** GET_PROTOCOL, GET_REPORT, SET_REPORT ***/
else if ( (Type_Recipient == (CLASS_REQUEST | INTERFACE_RECIPIENT)) )
{
switch( RequestNo )
{
case GET_PROTOCOL:
CopyRoutine = CustomHID_GetProtocolValue;
break;
case SET_REPORT:
CopyRoutine = CustomHID_SetReport_Feature;
Request = SET_REPORT;
break;
// ------------------ add, from here ------------------
#define HID_INPUT 1
#define HID_OUTPUT 2
#define HID_FEATURE 3
case GET_REPORT:
if ( USBwValue == ((HID_FEATURE <<
8
) | REPORTID_PEN) ) {
CopyRoutine
=
CustomHID_GetReportFeatureValue
;
}
break;
// ------------------ add, to here ------------------
default:
break;
}
}
...
}
// ------------------ add, from here ------------------
#define CONTACT_COUNT_MAX 2
static const uint8_t hid_Feature_Report[] = { REPORTID_PEN, CONTACT_COUNT_MAX };
uint8_t * CustomHID_GetReportFeatureValue(uint16_t Length)
{
if (Length == 0)
{
pInformation->Ctrl_Info.Usb_wLength = sizeof( hid_Feature_Report );
return NULL;
}
else
{
return (uint8_t *)hid_Feature_Report;
}
}
// ------------------ add, to here ------------------
2) STM32_USB-Host-Device_Lib_V2.1.0
\STM32_USB-Host-Device_Lib_V2.1.0\Libraries\STM32_USB_Device_Library\Class\hid\src\usbd_hid_core.c
// ------------------ add, from here ------------------
#define CONTACT_COUNT_MAX 2
static const uint8_t hid_Feature_Report[] = { REPORTID_PEN, CONTACT_COUNT_MAX };
#define HID_INPUT 1
#define HID_OUTPUT 2
#define HID_FEATURE 3
// ------------------ add, to here ------------------
static uint8_t USBD_HID_Setup (void *pdev,
USB_SETUP_REQ *req)
{
uint16_t len = 0;
uint8_t *pbuf = NULL;
switch (req->bmRequest & USB_REQ_TYPE_MASK)
{
case USB_REQ_TYPE_CLASS :
switch (req->bRequest)
{
...
...
case HID_REQ_GET_IDLE:
USBD_CtlSendData (pdev,
(uint8_t *)&USBD_HID_IdleState,
1);
break;
// ------------------ add, from here ------------------
case HID_REQ_GET_REPORT:
if ( req->wValue == ((HID_FEATURE << 8) | REPORTID_PEN) ) {
USBD_CtlSendData (pdev,
(uint8_t *)hid_Feature_Report,
sizeof(hid_Feature_Report));
} else {
USBD_CtlError (pdev, req);
return USBD_FAIL;
}
break;
// ------------------ add, to here ------------------
default:
USBD_CtlError (pdev, req);
return USBD_FAIL;
}
break;
3) STM32Cube_FW_F4_V1.3.0
Apply the same modification as above 2), to
\STM32Cube_FW_F4_V1.3.0\Middlewares\ST\STM32_USB_Device_Library\Class\HID\Src\usbd_hid.c
USBD_HID_Setup ()
Tsuneo