目录

应用程序改自沁恒官网的CH583EVT包中的CompoundDev工程,配合下方的描述符能够实现①直接接电脑,在设备管理器中能够查到被电脑识别为HID- compliant game contorller;②在CH582m单片机中自定义了回包内容,通过USB抓包工具可以抓到单片机模拟的JoyStick与电脑主机正常通信。笔者将把主要函数贴在另一篇随笔中。

设备、接口、类、端点描述符都是照猫画虎改的,每行的注释摘自《USB设计及应用设计》一书。HID报表描述符是根据HID1.12规范写的,JoyStick的报表描述符搬用了HID1.12手册的例子,报表格式如下。

在电脑设备管理器中识别的类型↓

USB抓包↓(数值是随便写的,一般按键松开后,需要把对应位置改成0x00再上传一包)

JoyStick设备长这样↓

/*前缀:b:8位字节
* w:16位字
* bm:按位寻址
* i:索引
* id:标识码
* bcd:采用BCD码编码*/ const uint8_t MyDevDescr[] = {
  // 设备描述符↓
    0x12, //bLength 描述符的字节数长度 标准为0x12
    0x01, //bDescriptorType 描述符的类型 0x01为设备描述符
    0x10, 0x01, //bcdUSB 设备支持的协议版本号,0x0110表示为1.1
    0x00, //bDeviceClass 设备类代码 0:每个接口指出它自己的类且各自独立工作 FF:设备类由厂商定义
        //其他值表示设备在不同的接口上支持不同的类,接口之间可能不能独立工作
    0x00, //bDeviceSubClass 设备子类代码 根据手册以及bDeviceClass的值而定,bDeviceClass为0,此值也要为0;若bDeviceClass为0xFF,此值保留
    0x00, //bDevicePortocol 协议码 根据手册以及bDeviceClass和bDeviceSubClass的值而定,上两者为0,该值也要为0
    0x08, //bMaxPacketSize0 端点0的数据包的最大净长度
    0x00, 0x00, //idVendor 厂商ID
    0x00, 0x00, //idProduct 产品ID
    0x00, 0x00, //bcdDevice BCD设备发行号
    0x00, //iManufacturer 厂商信息字符串的索引
    0x00, //iProduct 产品信息字符串的索引
    0x00, //iSerialNumber 设备序列号字符串的索引
    0x01 //bNumConfigurations 可能的配置描述符数目 只有一种配置时此值为1
}; const uint8_t MyCfgDescr[] = {  
  // 配置描述符↓
    0x09, //bLength 描述符的字节数长度 标准为0x09
    0x02, //bDescriptorType 描述符的类型 0x02为配置描述符
    0x22, 0x00, //wTotalLength 配置信息的总长(包括配置、接口、端点、类和厂商描述符)
    0x01, //bNumInterfaces 该配置所支持的接口数目
    0x01, //bConfigurationValue 被SET_CONFIGURATION请求用作参数来选定
    0x00, //iConfiguration 该配置的字符串描述符索引值,在SET_CONFIGURATION中用作选定配置的参数
    0xA0, //bmAttributes D6:自供电 D5:远程唤醒 其他位保留。
        //若一个设备既能自供电又能使用总线供电,D6也要置1并在MaxPower指出需要从总线获取的电量
    0x32, //MaxPower 该配置下的总线电源耗费量,为两倍此值(如0x32*2 = 100)mA
  //接口描述符↓
    0x09, //bLength 描述符的字节数长度 标准为0x09
    0x04, //bDescriptorType 描述符的类型 0x04为接口描述符
    0x00, //bInterfaceNumber 接口号,当前配置支持的接口数组索引(从0开始)。
        //若该配置有俩接口,接下来的接口描述符此值就为1
    0x00, //bAlternateSetting 可选设置的索引值。一个接口可以有多个接口描述符,靠此字段区分
    0x01, //bNumEndpoints 除了USB设备必须支持的端点0外,此接口所包括的端点的个数。此值为0表示该接口只使用端点0。
    0x03, //bInterfaceClass 接口所属的类值。为0表示为将来的标准保留。为FF表示此接口类由厂商说明。其他值查手册。0x03为HID类
    0x00, //bInterfaceSublass 接口所属子类的值。根据手册以及bInterfaceClass的值来定,若上面的值为0,此值也要为0。
    0x00, //bInterfaceProtocol 协议码,视手册以及上两者而定。上两者为0,此值也要为0。
    0x00, //iInterface 此接口的字符串描述符的索引值。
  //HID类描述符↓
    0x09, //bLength 描述符的字节数长度 标准为0x09
    0x21, //bDescriptorType 描述符的类型 0x21为人机接口类描述符
    0x12, 0x01, //bcdHID HID规范版本号的BCD码,此描述符所用版本为1.12
    0x00, //bCountryCode 硬件目的国家的识别号码。不启用此功能则为0
    0x01, //bNumDescriptors 支持的附属描述符数目。最小值为1:HID类至少有个报表描述符
    0x22, //bDescriptorType 类别描述符的类型。只有报表描述符为0x22;还有个实体描述符则为0x23
    0x4e, 0x00, //wDescriptorLength 报表描述符总长度
  //端点描述符↓
    0x07, //bLength 描述符的字节数长度 标准为0x07
    0x05, //bDescriptorType 描述符的类型 0x05为端点描述符
    0x81, //bmEndpointAddress 低四位为端点号,最高位为0:OUT方向,为1:IN方向。其他位保留。
    0x03, //bmAttributes 低两位为 00:控制传输;01:实时传输;10:批量传输;11:中断传输。其他位保留
    0x08, 0x00, //bMaxPacketSize 端点收发的数据包最大净长度
    0x0a, //bInterval 周期数据传输端点的时间间隙。对于批量和控制传输来说无意义
      //若该端点配置实时传输,此值必须为1(ms);若该端点配置中断传输,此值为1~255(ms)
}; //JoyStick报表描述符↓,大多数是查手册得到的数值。每行为一个short item。每个item的第一个字节的低两位表示这个字节后面还有多少字节的数据 const uint8_t JoyStickRepDesc[] = {    //模拟操纵飞机的一种摇杆手柄
    0x05, 0x01, //Usage Page (Generic Desktop) UsagePage定义数据的用法或功能
    0x09, 0x04, //Usage (Joystick) Usage描述项目或collection的使用的索引
    0xA1, 0x01, //Collection (Application) 包含有共同用途或者执行单一功能的项目。该项目可能指代节流阀、X方向和Y方向的指针,一起用来控制飞机的移动
      0x05, 0x02, //Usage Page (Simulation Controls)  模拟输出的控制器
      0x09, 0xBB, //Usage (Throttle)  节流阀,类似于飞机的油门
      0x15, 0x81, //Logical Minimum (-127) 报表项目的最小数值
      0x25, 0x7F, //Logical Maximum (127) 报表项目的最大数值
      0x75, 0x08, //Report Size (8) 项目数据段的大小  每个数据段为8位
      0x95, 0x01, //Report Count (1) 项目的数据段的数目  1个数据段
      0x81, 0x02, //Input (Data, Variable, Absolute)  0x02的各位含义详见卷标       0x05, 0x01, //Usage Page (Generic Desktop)  通用桌面设备
      0x09, 0x01, //Usage (Pointer)  指针,控制飞机的上下左右方向(鼠标也是一种Pointer)
      0xA1, 0x00, //Collection (Physical) 包含代表数据在一个单一几何上的项目
        0x09, 0x30, //Usage (X)  X方向
        0x09, 0x31, //Usage (Y)  Y方向
        0x95, 0x02, //Report Count (2)  (X和Y方向)回传2个数据。协议手册的例子中并没有列ReportSize,该值沿用上一个ReportSize的值即8位
        0x81, 0x02, //Input (Data, Variable, Absolute)  0x02的各位含义详见卷标
      0xC0, //End Collection 关闭集合       0x09, 0x39, //Usage (Hat switch)  苦力帽,在游戏中用于控制飞机的视野。根据下面的数值,可能这是个4向苦力帽。
      0x15, 0x00, //Logical Minimum (0) 报表项目的最小数值
      0x25, 0x03, //Logical Maximum (3) 报表项目的最大数值
      0x35, 0x00, //Physical Minimum (0) 以实际单位表示的逻辑小数值
      0x46, 0x0E, 0x01, //Physical Maximum (270) 以实际单位表示的逻辑大数值
        //将0~270这些数值分到0~3这些数据中,相当于每一个报表数值代表了67.75个实际单位
      0x65, 0x04, //Unit (English Rotation: Angular Position) 表示单位。详见表格,本设备单位为英制、角度
        //本设备只用到第0个半字节,故只需要1字节数据即可表示单位。0x65后面最多可达4个字节的数据,即8个半字节来表示单位
      0x55, 0x00, //Unit Exponent (0) 10的(0)次幂。详见数值表,00h~到07h符号为正,08h~0Fh符号为负
      0x75, 0x04, //Report Size (4)  每个数据段占4位
      0x95, 0x01, //Report Count (1)  1个数据段
      0x81, 0x42, //Input (Data, Variable, Absolute, Null State)  0x42的各位含义详见卷标       0x05, 0x09, //Usage Page (Buttons)  按键
      0x19, 0x01, //Usage Minimum 定义1~4号四个按键
      0x29, 0x04, //Usage Maximum
      0x15, 0x00, //Logical Minimum (0) 报表项目的最小数值
      0x25, 0x01, //Logical Maximum (1) 报表项目的最大数值
      0x35, 0x00, //Physical Minimum (0) 以实际单位表示的逻辑小数值
      0x45, 0x01, //Physical Maximum (1) 以实际单位表示的逻辑大数值
      0x95, 0x04, //Report Count (4)  4个数据段
      0x75, 0x01, //Report Size (1)  每个数据段占1位
      0x64, //Unit (None)  无单位
      0x81, 0x02, //Input (Data, Variable, Absolute)
    0xC0 //End Collection
};

HID类的JoyStick描述符的更多相关文章

  1. usb的hid鼠标键盘报告描述符(五)

    title: usb的hid鼠标键盘报告描述符 tags: linux date: 2018/12/20/ 18:05:08 toc: true --- usb的hid鼠标键盘报告描述符 https: ...

  2. USB HID报告及报告描述符简介

    在USB中,USB HOST是通过各种描述符来识别设备的,有设备描述符,配置描述符,接口描述符,端点描述符,字符串描述符,报告描述符等等.USB报告描述符(Report Descriptor)是HID ...

  3. USB HID Report Descriptor 报告描述符详解

    Report descriptors are composed of pieces of information. Each piece of information is called an Ite ...

  4. USB学习小记-HID类键盘的报告描述符的理解

    前言 断断续续的学习了将近三个月,才把USB的HID类搞明白,速度真是够慢的.利用晚上+周末的时间学习自己的东西确实是必要的,不过效率是有点低,以后要更专注一些才行,希望自己能做到吧. 在学习过程中, ...

  5. USB HID描述符【转】

    本文转载自: USB是个通用的总线,端口都是统一的.但是USB设备却各种各样,例如USB鼠标,USB键盘,U盘等等,那么USB主机是如何识别出不同的设备的呢?这就要依赖于描述符了.USB的描述符主要有 ...

  6. python描述符(descriptor)、属性(property)、函数(类)装饰器(decorator )原理实例详解

     1.前言 Python的描述符是接触到Python核心编程中一个比较难以理解的内容,自己在学习的过程中也遇到过很多的疑惑,通过google和阅读源码,现将自己的理解和心得记录下来,也为正在为了该问题 ...

  7. 11.python描述符---类的装饰器---@property

    描述符1.描述符是什么:描述符本质就是一个新式类,在这个新式类中,至少实现了__get__(),__set__(),__delete__()这三个内置方法中的一个,描述符也被称为描述符协议(1):__ ...

  8. python小知识-__call__和类装饰器的结合使用,数据描述符__get__\__set__\__delete__(描述符类是Python中一种用于储存类属性值的对象)

    class Decorator(): def __init__(self, f): print('run in init......') self.f = f def __call__(self, a ...

  9. USB描述符解析-->枚举.

    枚举可以理解为主机按不定的顺序向USB设备讨要设备信息,好给它分配资源,若枚举不成功,就放弃分配资源,免得浪费资源.一般都是使用中断传输方式通信. 常用的描述符有以下几种:01H.设备描述符  02H ...

  10. USB描述符(转)

    //============================================================================// 文件名: USBDESC.C// 用 ...

随机推荐

  1. MySQL 嵌套子查询 with子句 from子查询 in子查询 join组合

    一.适用场景和方法 (1)适用场景 考虑查询过程中是否存在以下情况: 查询某些数据时需要分组才能得到,某些数据不需要分组就能得到或者分组条件不同: 查询某些数据时需要where条件,某些列不需要whe ...

  2. 从0到1手把手实现vite

    什么是Vite? 法语:轻量化,快速 基于VUE3 非 打包开发服务器,请注意,它是个开发服务器哇!! 快速开发,按需编译,不再等待整个应用编译完成 基于原生模块系统ESModule实现 说白了,就是 ...

  3. Kubernetes(k8s)控制器(三):ReplicationController

    目录 一.系统环境 二.前言 三.ReplicationController概览 四.ReplicationController工作机制 五.创建ReplicationController 六.扩展r ...

  4. Selenium4.6版本浏览器自动退出问题

    Selenium4.6版本浏览器自动退出问题 代码 from selenium import webdriver driver = webdriver.Chrome() driver.get('htt ...

  5. mysql 错误解决大法 Specified key was too long; max key length is 767 bytes

    高版本mysql向低版本(5.7以下)导入sql时可能会发生此问题 开启索引最大长度 SET GLOBAL INNODB_LARGE_PREFIX = ON; 将表改为动态表SET GLOBAL in ...

  6. Linux 安装 WIFI驱动 rtl8188gu

    https://www.wyr.me/post/623 https://www.leonlu.cc/hobby/note006-rtl8188gu-linux/ 亲测:debian11,manjaro ...

  7. 工控领域上云实践-Zstack和软赢

    工业以太网常见五大协议对比 大规模电机控制的方案选择-电机和驱动器篇 大规模电机控制的方案选择-控制器篇 工控领域有各种各样的总线来通讯以控制设备,很小众的接口规范慢慢的更小众了,最常见的接口规范就是 ...

  8. 基于minikube快速搭建kubernetes单节点环境

    一.说明 本文主要介绍在 Centos7 环境下基于 Minikube 来快速部署 Kubernetes 单节点集群环境,并在浏览器上访问部署在 k8s 上的 dashboard 服务. 二.Mini ...

  9. setInterval()的使用

    setInterval() 作用  这个函数可以将一个函数每隔一段时间执行一次 参数  1.回调函数,该函数会每隔一段时间被调用一次  2.每次调用间隔的时间,单位是毫秒 返回值  返回一个Numbe ...

  10. ctf 菜鸟杯

    web签到 首先最里面的是ctfshow-QQ群:,而他需要进行cookie传参,因此我们需要在cookie传入CTFshow-QQ群=a,然后就要以POST方式传入a的值,我们传入a=b,而b是以G ...