使用USB HID进行数据交互

最近看到一款与我们同类型的USB Audio  Chip的SPEC: CM108AH(http://www.hardwaresecrets.com/datasheets/CM108AH.pdf), 其中通过HID协议对芯片内部寄存器进行读写操作的feature觉得很有意思。 考虑到客户应用场景下通过USB进行寄存器调整的简便性,觉得增加这个功能还是很有必要。

由于之前已经使用USB HID来进行音量的控制,所以相对修改就小的多,基本上只需要进行描述符的改动即可。

HID接口描述符

  0x09,         /* bLength: Interface Descriptor size */
  0x04,         /* bDescriptorType: Interface descriptor type */
  0x03,         /* bInterfaceNumber: Number of Interface */
  0x00,         /* bAlternateSetting: Alternate setting */
  0x02,         /* bNumEndpoints */
  0x03,         /* bInterfaceClass: HID */
  0x00,         /* bInterfaceSubClass : 1=BOOT, 0=no boot */
  0x00,         /* nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse */
  0x00,         /* iInterface: Index of string descriptor */

端点描述符


  0x07,          /* bLength: Endpoint Descriptor size */
  0x05,          /* bDescriptorType: */
  0x81,          /* bEndpointAddress: Endpoint Address (IN) */
  0x03,          /* bmAttributes: Interrupt endpoint */
  0x08, 0x00,    /* wMaxPacketSize: 8 Bytes max */
  0x20,          /* bInterval: Polling Interval (32 ms) */

  0x07,          /* bLength: Endpoint Descriptor size */
  0x05,          /* bDescriptorType: */
  0x09,          /* bEndpointAddress: Endpoint Address (OUT) */
  0x03,          /* bmAttributes: Interrupt endpoint */
  0x08, 0x00,    /* wMaxPacketSize: 8 Bytes max */
  0x20,          /* bInterval: Polling Interval (32 ms) */
 

这里使用了2个端点,IN端点1作为媒体控制信息和私有数据的输入端点,OUT端点作为私有数据的输出端点。

由于IN端点1里面承载的2种不同用途的payload,就必须要用report id区分下。

HID 描述符

    0x05, 0x0c,                    // USAGE_PAGE (Consumer Devices)
    0x09, 0x01,                    // USAGE (Consumer Control)
    0xa1, 0x01,                    // COLLECTION (Application)
    
    0x85, 0x01,                    //   Report ID1
    0x15, 0x00,                    //   LOGICAL_MINIMUM (0)
    0x25, 0x01,                    //   LOGICAL_MAXIMUM (1)
    0x09, 0xe9,                    //   USAGE (Volume Up)
    0x09, 0xea,                    //   USAGE (Volume Down)
    0x09, 0xe2,                    //   USAGE (Mute)
    0x09, 0xCD,                    //   USAGE (Play/Pause)
    0x09, 0xb5,                    //   USAGE (Scan Next Track)
    0x09, 0xb6,                    //   USAGE (Scan Previous Track)
    0x09, 0xb3,                    //   USAGE (Fast Forward)
    0x09, 0xb7,                    //   USAGE (Stop)
    0x75, 0x01,                    //   REPORT_SIZE (1)
    0x95, 0x08,                    //   REPORT_COUNT (8)
    0x81, 0x42,                    //   INPUT (Data,Var,Abs,Null)

    0x85, 0x02,                    //   Report ID2 Data Input(2 bytes)
    0x26, 0xFF, 0x00,
    0x09, 0x00,
    0x75, 0x08,
    0x95, 0x02,
    0x81, 0x02,
    
    0x85, 0x03,                    //   Report ID3 Data Output (2 bytes)
    0x26, 0xFF, 0x00,
    0x09, 0x00,
    0x75, 0x08,
    0x95, 0x02,
    0x91, 0x02,
    
    0xc0,                           // END_COLLECTION

注意在进行数据传输时,需要先发送report id,然后再加上playload。

按上面的描述信息,report ID1的payload是1个字节,所以传输数据格式应该为: 0x01,,0x**,其他对应的格式如下:

133417_xDCf_2007478.png

我是通过Linux下对/dev/hidrawX这个设备节点进行read、write操作来进行功能的验证。

USB分析仪抓包数据如下:

133748_tD9Q_2007478.png

可以看到帧号45096是report1的输入数据,帧号45105是report3的输出数据。

BTW:

  1. 大家可以观察下,HID采用USB中断传输类型,其本质也是轮询方式,如果过多使用的话也会很占用USB带宽(从超多的NAK就可以看出来)。
  2. 我本人是在vmware虚拟机里装ubuntu进行对hidrawX节点的操作,结果问题很多hidapi(http://www.signal11.us/oss/hidapi/)也用不起来。如果只能在虚拟机下测试,最好每次测试完后拔插下USB设备。
  3. 关于OUT端点9可以不用,这样的话HID默认采用端点0进行传输。

 

转载于:https://my.oschina.net/u/2007478/blog/1036573

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值