最近在调试一个HID触摸板的项目,目前已经成功枚举到设备,硬件是支持10点触摸的,我也已经正确发送了10点触摸数据,可是电脑只显示单一触控支持,触摸板也只有单点触摸有效;当我按下超过一个手指后触摸就失效了,但是触摸数据还是正常在传输。请教下这个情况哪里出的问题呢??
这是描述符配置
uint8_t HIDpad_ReportDescriptor[] =
{
0x05, 0x0D, // USAGE_PAGE (Digitizers) // 使用页面(数字设备)
0x09, 0x04, // USAGE (Touch Screen) // 使用(触摸屏)
0xA1, 0x01, // COLLECTION (Application) // 集合(应用程序)
0x85, 0x01, // REPORT_ID (Touch) // 报告ID(触摸)
0x09, 0x22, // USAGE (Finger) // 使用(手指)
//第一个手指
0xA1, 0x02, // COLLECTION (Logical) // 集合(逻辑)
0x09, 0x42, // USAGE (Tip Switch) // 使用(尖端开关)
0x15, 0x00, // LOGICAL_MINIMUM (0) // 逻辑最小值(0)
0x25, 0x01, // LOGICAL_MAXIMUM (1) // 逻辑最大值(1)
0x75, 0x01, // REPORT_SIZE (1) // 报告大小(1)
0x95, 0x01, // REPORT_COUNT (1) // 报告数量(1)
0x81, 0x02, // INPUT (Cnst,Ary,Abs) // 输入(常数,数组,绝对)
0x95, 0x07, // REPORT_COUNT (7) // 报告数量(7)
0x81, 0x03, // INPUT (Cnst,Ary,Abs) // 输入(常数,数组,绝对)
0x09, 0x51, // USAGE (Contact Identifier) // 使用(触点标识符)
0x25, 0xFF, // LOGICAL_MAXIMUM (255) // 逻辑最大值(255)
0x75, 0x08, // REPORT_SIZE (8) // 报告大小(8)
0x95, 0x01, // REPORT_COUNT (1) // 报告数量(1)
0x81, 0x02, // INPUT (Data,Var,Abs) // 输入(数据,可变,绝对)
0x05, 0x01, // USAGE_PAGE (Digitizers) // 使用页面(数字设备)
0x26, 0xFF, 0x0F, // LOGICAL_MAXIMUM (4096) // 逻辑最大值(4095)
0x75, 0x10, // REPORT_SIZE (16) // 报告大小(16)
0x55, 0x00, // UNIT_EXPONENT (0) // 单位指数(0)
0x65, 0x00, // UNIT (None) // 单位(无)
0x09, 0x30, // USAGE (X) // 使用(X轴)
0x35, 0x00, // PHYSICAL_MINIMUM (0) // 物理最小值(0)
0x46, 0xFF, 0x04, // PHYSICAL_MAXIMUM (1279) // 物理最大值(1279)
0x81, 0x02, // INPUT (Data,Var,Abs) // 输入(数据,可变,绝对)
0x09, 0x31, // USAGE (Y) // 使用(Y轴)
0x46, 0x1F, 0x03, // PHYSICAL_MAXIMUM (799) // 物理最大值(799)
0x81, 0x02, // INPUT (Data,Var,Abs) // 输入(数据,可变,绝对)
0xC0, // END_COLLECTION // 结束集合
//以上重复9次实现10点触摸
//触点计数
0x05, 0x0D, // USAGE_PAGE (Digitizers) // 使用页面(数字设备)
0x09, 0x54, // USAGE (Contact count) // 使用 (触点计数)
0x95, 0x01, // REPORT_COUNT (1) // 报告数量 (1)
0x75, 0x08, // REPORT_SIZE (8) // 报告大小 (8)
0x15, 0x00, // LOGICAL_MAXIMUM (0) // 逻辑最小值 (0)
0x25, 0x7f, // LOGICAL_MAXIMUM (127) // 逻辑最大值 (127)
0x81, 0x02, // INPUT (Data,Var,Abs) // 输入 (数据,可变,绝对)
0xC0 // END // 结束
下面是hid传输过程
void gsl_report_point(struct gsl_touch_info *report) {
// 初始化一个标志,表示是否有手指触摸屏幕,默认为没有触摸
int hasTouch = 0;
// 定义一个数组,用于存储每个手指的触摸状态
uint8_t touchFlags[TP_MAX_POINTS] = {0};
uint8_t vendorID1 = 0x01; // 设备报告ID
// 循环处理每个手指
for (int fingerIndex = 0; fingerIndex < TP_MAX_POINTS; fingerIndex++) {
if (fingerIndex < report->finger_num) {
int mapped_x, mapped_y;
mapCoordinates(report->x[fingerIndex], report->y[fingerIndex], &mapped_x, &mapped_y);
// 计算手指数据存储的起始索引
int startIndex = fingerIndex * 6 + 1;
// 存储手指数据
uint8_t hasTouchFlag = 1; // 有触摸标志
uint8_t fingerID = report->id[fingerIndex]; // 手指 ID
uint8_t xLowByte = mapped_x & 0xFF; // x 坐标低字节
uint8_t xHighByte = mapped_x >> 8; // x 坐标高字节
uint8_t yLowByte = mapped_y & 0xFF; // y 坐标低字节
uint8_t yHighByte = mapped_y >> 8; // y 坐标高字节
// 存储手指数据到数组
touchReport[startIndex] = hasTouchFlag;
touchReport[startIndex + 1] = fingerID;
touchReport[startIndex + 2] = xLowByte;
touchReport[startIndex + 3] = xHighByte;
touchReport[startIndex + 4] = yLowByte;
touchReport[startIndex + 5] = yHighByte;
// 将该手指的触摸状态设为 1
touchFlags[fingerIndex] = hasTouchFlag;
// 手指的数量,X、Y坐标,手指ID
printf("Finger %d: X=%d, Y=%d, ID=%d\n", fingerIndex, mapped_x, mapped_y, fingerID);
// 设置触摸标志
hasTouch = 1;
} else {
// 触摸点已松开,清除触摸数据
int startIndex = fingerIndex * 6 + 1;
clearTouchData(startIndex);
}
}
// 在处理完所有手指的触摸数据后,报告id和手指数量
touchReport[0] = vendorID1;
touchReport[61] = report->finger_num;
// 通过 USBD_TxWrite 函数将 touchReport 数组的内容传输给 PC
USBD_TxWrite(EP_INT_IN_1, touchReport, sizeof(touchReport));
// 检查抬手标志
if (hasTouch == 0 && gsl_up_flag == 1) {
// 手指已经离开屏幕,重置抬手标志
gsl_up_flag = 0;
}
}
调试结果
电脑识别的设备


串口打印的10点数据

hid发送的10点数据
