论坛首页 物联网安全区 阅读主题

[原创] 实战解析I2C HID协议----以I2C Touch Pad为例

77 浏览 5 回复
#1 楼主 2026-06-01 21:09:04
本文是<实战解析 USB HID 协议>和<实战解析 USB HID 协议 2>的扩展篇. 不过这次将目光转移到应用了I2C HID协议的设备.1. 硬件部分在单片机/嵌入式应用场景中, 设备间通信只需SCL/SDA 2根信号线; 而HID over I2C协议还额外需要一根INT中断信号. 当I2C Slaver有数据时, 如触摸Pad, 会触发INT信号 (Assert INT#). Host收到中断后才会发起I2C事务(直至此时Host才使能SCL信号, 再通过SDA信号读取数据).  由于这个特性, HID over I2C信号在逻辑分析仪中的输出会呈现一定的规律性: SCL/SDA仅在INT# Assert期间变化; 在INT# De-Assert期间无变化, 这种特性使得波形比较清澈(这样设计可能也是为了省电):
由Acute解析的HID Over I2C波形
常见的I2C HID设备有I2C Touch Pad和I2C Touch Panel, 正好我手边有台带FocalTech I2C Touch Pad的二手笔记本且Touch Pad PCB上有INT/SCL/SDA这些信号的丝印, 方便接转接板. 本文的内容将基于此笔记本展开.
FocalTech I2C Pad PCB
2.固件部分硬件部分的准备完成, 再看看固件/OS部分. HID over I2C协议获取HID Report Descriptor的过程有点绕. OS需要从ACPI中获得HID Descriptor Register. OS通过HID Descriptor Register去Touch Pad中读取HID Descriptor. 注意, 目前读到的是HID Descriptor, 其结构如下:typedef struct _HIDDescriptor
uint16 wHIDDescLength;       
uint16 bcdVersion;              
uint16 wReportDescriptorLength;   
uint16 wReportDescriptorRegister; 
uint16 wInputRegister; 
uint16 wMaxInputLength;
uint16 wOutputRegister;
uint16 wMaxOutputLength; 
uint16 wCommandRegister; 
uint16 wDataRegister; 
uint16 wVendorID;
uint16 wProductID;
uint16 wVersionID;
uint32 Reserved;
}HIDDescriptor;OS再从HIDDescriptor->wReportDescriptorRegister获得Report Descriptor Register地址, 最终通过该地址获得HID Report Descriptor. 该过程的示意图如下:
另外OS从HIDDescriptor->wCommandRegister获得Command Register, 该寄存器用于Host向Slave发出如SetPower/RESET请求. 2.1. SetPower/RESETOS在读取HID Descriptor后, 在进一步读取HID Report Descriptor前, 还需要对HID Over I2C设备依次执行2个动作SetPower和RESET
这2个命令都是OS通过向HIDDescriptor->wCommandRegister(在本文中是0x22)指定的寄存器写入2 BYTE的Command实现.
命令
           HOST向wCommandRegister写入的2 BYTE数值
           备注

           SET_POWER
           BYTE0=0x08, BYTE1=0x00
           SET_POWER=On, 让设备开始工作
           RESET
           BYTE0=0x01, BYTE1=0x00
           1.Slave重置自身;
               2.重置完成后Assert INT#
               3.Host发现INT# Assert后发起I2CRead事务
               4.Slave持续向Host返回0x00 0x00作为重置成功的标志
               5.Host读取完毕后, Slave将De-Assert INT#
           附注, 如果RESET流程执行失败,  Windows设备管理器中的I2C 设备会出现黄色感叹号.
2.2. 获取I2C Slave Address和HID Descriptor Register Address HID over I2C协议本质上依然是I2C协议和HID协议.  对于I2C协议, 固件需要向主机提供I2C Slave Address; 而对于HID协议, 固件需要向Host提供HID Descriptor Register. Host获得Descriptor Register后, 再通过I2C 协议(Repeat Start事务)从Pad固件中获得  HID Descriptor. 这种关系就像C语言里的指针: HID Descriptor Register就像HID Descriptor类型的指针,  通过该指针获取HID Descriptor结构体变量.

获取方式
           备注
           I2C Slaver Address
           OS enable ACPI以后, 由Method(_INI)设定, OS通过Method(_CRS)获取
           字面意思, 就是Slave设备地址, 在本文中就是I2C Touch Pad Slave地址. 
           HID Descriptor Register
           OS enable ACPI以后, 由Method(_INI)设定, OS通过Method(_DSW)获取
           HID over I2C协议中最重要的部分. 由厂商提供, 固件设定的16bit地址.  Method(_DSW)中获得HID Descriptor Register,  再从Register中获得HID Descriptor.

作为Pad厂商和主机厂商以外的读者, 可以通过RW dump整个ACPI Table获得这2个信息(本文使用的ACPI Dump文件参见附录):a.       首先查看设备管理器, 定位I2C Touch Pad的Bios Device Name:
b.       根据Bios Devic

...(已截断)

---
来源: 看雪论坛
原文链接: https://bbs.kanxue.com/thread-289800.htm
#2 2026-06-01 21:09:04
很棒的分享!不过有几处_DSM写成DSW了吧
#3 2026-06-01 21:09:04
AmnesiaSoly


很棒的分享!不过有几处_DSM写成DSW了吧

确实,感谢指出
#4 2026-06-01 21:09:04
确实,还是你眼尖发现了,谢谢
#5 2026-06-01 21:09:04
帖主你好,不知道为什么没有权限私信,我想问下我用STM32模拟触摸板通信主机已经识别到touchpad成功了,但是为什么发送移动数据报告成功了 鼠标却没有反应呢?
#6 2026-06-01 21:09:04
mb_vhtnulms

帖主你好,不知道为什么没有权限私信,我想问下我用STM32模拟触摸板通信主机已经识别到touchpad成功了,但是为什么发送移动数据报告成功了 鼠标却没有反应呢?
你用逻辑分析仪的hid over iic看下通信过程,正常吗

请登录后参与讨论

立即登录 注册账号