HID类的触摸屏TouchScreen描述符
本文主要分析触摸屏的报表描述符,设备、配置描述符和其他描述符就不赘述了,可以参考HID类的JoyStick描述符 - JayWell - 博客园 (cnblogs.com)。
// 设备描述符 const uint8_t MyDevDescr[] = {0x12, 0x01, 0x10, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, //厂商ID 0x00, 0x00, //产品ID 0x00, 0x00, 0x01, 0x02, 0x00, 0x01}; // 配置描述符 const uint8_t MyCfgDescr[] = { 0x09, 0x02, 0x22, 0x00, 0x01, 0x01, 0x00, 0xA0, 0x20, //配置描述符 0x09, 0x04, 0x00, 0x00, 0x01, 0x03, 0x00, 0x00, 0x00, //接口描述符 0x09, 0x21, 0x00, 0x01, 0x00, 0x01, 0x22, 0x86, 0x01, //HID类描述符 0x07, 0x05, 0x81, 0x03, 0x40, 0x00, 0x01, //端点描述符 };
触摸屏报表可以实现最多5指触控。
#define TOUCHPAD_RESOLUTION_X 800 #define TOUCHPAD_RESOLUTION_Y 480 /*HID类报表描述符*/ const uint8_t TouchDesc[] = { //XXX JW 0x05, 0x0d, //digitizers 0x09, 0x04, //touch screen 0xa1, 0x01, 0x85, 0x01, //report id 01 0x09, 0x22, //useage finger 手指1 0xa1, 0x02, 0x09, 0x42, //tip switch 0x15, 0x00, 0x25, 0x01, 0x75, 0x01, //1位/段 0x95, 0x01, //1段 0x81, 0x02, 0x95, 0x07, //填充7段 0x81, 0x01, // 1字节 手指是否按下 0x75, 0x08, //8位/段 0x09, 0x51, //contact identifier 0x95, 0x01, //1段 0x81, 0x02, // 2字节 手指编号 0x05, 0x01, 0x26, (uint8_t)TOUCHPAD_RESOLUTION_X, (uint8_t)(TOUCHPAD_RESOLUTION_X >> 8), //上传报表的X轴分辨率 0x75, 0x10, //16位/段*1 0x55, 0x0e, 0x65, 0x11, 0x09, 0x30, //X轴坐标 0x35, 0x00, 0x46, (uint8_t)TOUCHPAD_RESOLUTION_X, (uint8_t)(TOUCHPAD_RESOLUTION_X >> 8), //这里改动影响不大,可以与上传报表的X轴分辨率一致,猜测是电脑驱动接管了缩放 0x81, 0x02, // 4字节 0x26, (uint8_t)TOUCHPAD_RESOLUTION_Y, (uint8_t)(TOUCHPAD_RESOLUTION_Y >> 8), //上传报表的Y轴分辨率 0x46, (uint8_t)TOUCHPAD_RESOLUTION_Y, (uint8_t)(TOUCHPAD_RESOLUTION_Y >> 8), //这里改动影响不大,可以与上传报表的Y轴分辨率一致,猜测是电脑驱动接管了缩放 0x09, 0x31, //Y轴坐标 0x81, 0x02, // 6字节 0x05, 0x0d, 0x09, 0x48, 0x81, 0x02, 0xc0, 0x09, 0x22, //手指2 0xa1, 0x02, 0x09, 0x42, 0x15, 0x00, 0x25, 0x01, 0x75, 0x01, 0x95, 0x01, 0x81, 0x02, 0x95, 0x07, 0x81, 0x01, 0x75, 0x08, 0x09, 0x51, 0x95, 0x01, 0x81, 0x02, 0x05, 0x01, 0x26, (uint8_t)TOUCHPAD_RESOLUTION_X, (uint8_t)(TOUCHPAD_RESOLUTION_X >> 8), 0x75, 0x10, 0x55, 0x0e, 0x65, 0x11, 0x09, 0x30, 0x35, 0x00, 0x46, (uint8_t)TOUCHPAD_RESOLUTION_X, (uint8_t)(TOUCHPAD_RESOLUTION_X >> 8), 0x81, 0x02, 0x26, (uint8_t)TOUCHPAD_RESOLUTION_Y, (uint8_t)(TOUCHPAD_RESOLUTION_Y >> 8), 0x46, (uint8_t)TOUCHPAD_RESOLUTION_Y, (uint8_t)(TOUCHPAD_RESOLUTION_Y >> 8), 0x09, 0x31, 0x81, 0x02, 0x05, 0x0d, 0x09, 0x48, 0x81, 0x02, 0xc0, 0x09, 0x22, //手指3 0xa1, 0x02, 0x09, 0x42, 0x15, 0x00, 0x25, 0x01, 0x75, 0x01, 0x95, 0x01, 0x81, 0x02, 0x95, 0x07, 0x81, 0x01, 0x75, 0x08, 0x09, 0x51, 0x95, 0x01, 0x81, 0x02, 0x05, 0x01, 0x26, (uint8_t)TOUCHPAD_RESOLUTION_X, (uint8_t)(TOUCHPAD_RESOLUTION_X >> 8), 0x75, 0x10, 0x55, 0x0e, 0x65, 0x11, 0x09, 0x30, 0x35, 0x00, 0x46, (uint8_t)TOUCHPAD_RESOLUTION_X, (uint8_t)(TOUCHPAD_RESOLUTION_X >> 8), 0x81, 0x02, 0x26, (uint8_t)TOUCHPAD_RESOLUTION_Y, (uint8_t)(TOUCHPAD_RESOLUTION_Y >> 8), 0x46, (uint8_t)TOUCHPAD_RESOLUTION_Y, (uint8_t)(TOUCHPAD_RESOLUTION_Y >> 8), 0x09, 0x31, 0x81, 0x02, 0x05, 0x0d, 0x09, 0x48, 0x81, 0x02, 0xc0, 0x09, 0x22, //手指4 0xa1, 0x02, 0x09, 0x42, 0x15, 0x00, 0x25, 0x01, 0x75, 0x01, 0x95, 0x01, 0x81, 0x02, 0x95, 0x07, 0x81, 0x01, 0x75, 0x08, 0x09, 0x51, 0x95, 0x01, 0x81, 0x02, 0x05, 0x01, 0x26, (uint8_t)TOUCHPAD_RESOLUTION_X, (uint8_t)(TOUCHPAD_RESOLUTION_X >> 8), 0x75, 0x10, 0x55, 0x0e, 0x65, 0x11, 0x09, 0x30, 0x35, 0x00, 0x46, (uint8_t)TOUCHPAD_RESOLUTION_X, (uint8_t)(TOUCHPAD_RESOLUTION_X >> 8), 0x81, 0x02, 0x26, (uint8_t)TOUCHPAD_RESOLUTION_Y, (uint8_t)(TOUCHPAD_RESOLUTION_Y >> 8), 0x46, (uint8_t)TOUCHPAD_RESOLUTION_Y, (uint8_t)(TOUCHPAD_RESOLUTION_Y >> 8), 0x09, 0x31, 0x81, 0x02, 0x05, 0x0d, 0x09, 0x48, 0x81, 0x02, 0xc0, 0x09, 0x22, //手指5 0xa1, 0x02, 0x09, 0x42, 0x15, 0x00, 0x25, 0x01, 0x75, 0x01, 0x95, 0x01, 0x81, 0x02, 0x95, 0x07, 0x81, 0x01, 0x75, 0x08, 0x09, 0x51, 0x95, 0x01, 0x81, 0x02, 0x05, 0x01, 0x26, (uint8_t)TOUCHPAD_RESOLUTION_X, (uint8_t)(TOUCHPAD_RESOLUTION_X >> 8), 0x75, 0x10, 0x55, 0x0e, 0x65, 0x11, 0x09, 0x30, 0x35, 0x00, 0x46, (uint8_t)TOUCHPAD_RESOLUTION_X, (uint8_t)(TOUCHPAD_RESOLUTION_X >> 8), 0x81, 0x02, 0x26, (uint8_t)TOUCHPAD_RESOLUTION_Y, (uint8_t)(TOUCHPAD_RESOLUTION_Y >> 8), 0x46, (uint8_t)TOUCHPAD_RESOLUTION_Y, (uint8_t)(TOUCHPAD_RESOLUTION_Y >> 8), 0x09, 0x31, 0x81, 0x02, 0x05, 0x0d, 0x09, 0x48, 0x81, 0x02, 0xc0, 0x05, 0x0d, 0x27, 0xff, 0xff, 0x00, 0x00, 0x75, 0x10, //16位/段 0x95, 0x01, //1段 0x09, 0x56, //Scan Time 0x81, 0x02, 0x09, 0x54, //Contact count 0x15, 0x00, 0x25, 0x7f, 0x95, 0x01, //1段 0x75, 0x08, //8位/段 0x81, 0x02, 0x85, 0x02, //report id 02 0x09, 0x55, //contact count maximum 0x95, 0x01, //1段 0x25, 0x0a, 0xb1, 0x02, 0x85, 0x03, //report id 03 0x06, 0x00, 0xff, //vendor usage page 0x09, 0xc5, //vendor usage 0x15, 0x00, 0x26, 0xff, 0x00, 0x75, 0x08, //8位/段 0x96, 0x00, 0x01, //1段 0xb1, 0x02, 0xc0, };
根据报表描述符,可以推测出触摸屏检测到手指按下时上传的报表格式。以下测试代码可以实现在WIN11电脑上显示点击屏幕的光圈,屏幕左上角有两指点击效果。
int main() { SetSysClock(CLK_SOURCE_PLL_60MHz); DebugInit(); PRINT("start\n"); pEP0_RAM_Addr = EP0_Databuf; pEP1_RAM_Addr = EP1_Databuf; pEP2_RAM_Addr = EP2_Databuf; pEP3_RAM_Addr = EP3_Databuf; USB_DeviceInit(); PFIC_EnableIRQ(USB_IRQn); mDelaymS(3000); while(1) { char report_array[44] = {0x01, //report id 0x01, //是否按下 0x00, //手指编号,从0开始 0x64, 0x00, //X轴坐标 0x64, 0x00, //Y轴坐标 0x30, 0x00, //宽度(单位同X轴) //手指1 0x01, 0x01, 0x00, 0x01, 0x00, 0x01, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,//手指5 0x01, 0x01, 0x02, //扫描时间、手指按下个数 }; mDelaymS(100); TouchReport(report_array, sizeof report_array); memset(report_array+1, 0, 43); mDelaymS(300); TouchReport(report_array, sizeof report_array); //模拟手指离开屏幕 } }