CoiSiNi7 2023-10-06 16:32 采纳率: 0%
浏览 29
已结题

hid触摸板调试问题调试

最近在调试一个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)  // 逻辑最小值(00x25, 0x01,         // LOGICAL_MAXIMUM (1)  // 逻辑最大值(10x75, 0x01,         // REPORT_SIZE (1)  // 报告大小(10x95, 0x01,         // REPORT_COUNT (1)  // 报告数量(10x81, 0x02,         // INPUT (Cnst,Ary,Abs)  // 输入(常数,数组,绝对)

        0x95, 0x07,         // REPORT_COUNT (7)  // 报告数量(70x81, 0x03,         // INPUT (Cnst,Ary,Abs)  // 输入(常数,数组,绝对)

    0x09, 0x51,         // USAGE (Contact Identifier)  // 使用(触点标识符)
    0x25, 0xFF,         // LOGICAL_MAXIMUM (255)  // 逻辑最大值(2550x75, 0x08,         // REPORT_SIZE (8)  // 报告大小(80x95, 0x01,         // REPORT_COUNT (1)  // 报告数量(10x81, 0x02,         // INPUT (Data,Var,Abs)  // 输入(数据,可变,绝对)

    0x05, 0x01,         // USAGE_PAGE (Digitizers)  // 使用页面(数字设备)
    0x26, 0xFF, 0x0F,   // LOGICAL_MAXIMUM (4096)  // 逻辑最大值(40950x75, 0x10,         // REPORT_SIZE (16)  // 报告大小(160x55, 0x00,         // UNIT_EXPONENT (0)  // 单位指数(00x65, 0x00,         // UNIT (None)  // 单位(无)

    0x09, 0x30,         // USAGE (X)  // 使用(X轴)
    0x35, 0x00,         // PHYSICAL_MINIMUM (0)  // 物理最小值(00x46, 0xFF, 0x04,   // PHYSICAL_MAXIMUM (1279)  // 物理最大值(12790x81, 0x02,         // INPUT (Data,Var,Abs)  // 输入(数据,可变,绝对)
    0x09, 0x31,         // USAGE (Y)  // 使用(Y轴)
    0x46, 0x1F, 0x03,   // PHYSICAL_MAXIMUM (799)  // 物理最大值(7990x81, 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;
    }
}

调试结果
电脑识别的设备

img

img

串口打印的10点数据

img

hid发送的10点数据

img

  • 写回答

12条回答 默认 最新

  • Programming_Konjac 2023-10-06 16:35
    关注

    根据描述符配置和数据传输过程的代码,应该没有问题。可能是电脑对多点触控的支持不够好,或者驱动需要更新。建议尝试在其他支持多点触控的设备上测试,或者查看触控板的官方文档和驱动更新情况。

    评论

报告相同问题?

问题事件

  • 已结题 (查看结题原因) 10月11日
  • 修改了问题 10月9日
  • 修改了问题 10月9日
  • 创建了问题 10月6日