前言

​ 工作项目中,某些项目对数据吞吐量有很高要求(比如需要5M/s左右的带宽),于是笔者设计了高速HID,端点大小:1024Byte设备,但是公司之前产品使用的是端点大小:64Byte的全速设备,为了保证USB设备的兼容性,于是笔者设计成两个接口的HID设备(Interface0:64Byte HID、Interface1:1024Byte HID)。好了,接下来介绍双HID复合设备是如何开发的。

前期准备

1.带USB 2.0高速功能的MCU (笔者使用的NXP RT1052)

2.libusb 1.x 版本(开发上位机可使用该库)

3.VS2015 keil (IDE环境选择很多,因人而异)

HID描述符基本结构

  • 配置描述符:主要设置接口数量为:2
  • 接口描述符:接口0,端点描述符设置为:64Byte;接口1,端点描述符设置为:1024Byte
-------------------------
Configuration Descriptor:
-------------------------
0x09    bLength
0x02    bDescriptorType
0x0049  wTotalLength   (73 bytes)
0x02    bNumInterfaces
0x01    bConfigurationValue
0x00    iConfiguration
0xC0    bmAttributes   (Self-powered Device)
0x32    bMaxPower      (100 mA)Interface Descriptor:
------------------------------
0x09    bLength
0x04    bDescriptorType
0x00    bInterfaceNumber
0x00    bAlternateSetting
0x02    bNumEndPoints
0x03    bInterfaceClass      (Human Interface Device Class)
0x00    bInterfaceSubClass
0x00    bInterfaceProtocol
0x00    iInterfaceHID Descriptor:
------------------------------
0x09    bLength
0x21    bDescriptorType
0x0110  bcdHID
0x21    bCountryCode
0x01    bNumDescriptors
0x22    bDescriptorType   (Report descriptor)
0x001B  bDescriptorLengthEndpoint Descriptor:
------------------------------
0x07    bLength
0x05    bDescriptorType
0x81    bEndpointAddress  (IN endpoint 1)
0x03    bmAttributes      (Transfer: Interrupt / Synch: None / Usage: Data)
0x0040  wMaxPacketSize    (1 x 64 bytes)
0x01    bInterval         (1 microframes)Endpoint Descriptor:
------------------------------
0x07    bLength
0x05    bDescriptorType
0x02    bEndpointAddress  (OUT endpoint 2)
0x03    bmAttributes      (Transfer: Interrupt / Synch: None / Usage: Data)
0x0040  wMaxPacketSize    (1 x 64 bytes)
0x01    bInterval         (1 microframes)Interface Descriptor:
------------------------------
0x09    bLength
0x04    bDescriptorType
0x01    bInterfaceNumber
0x00    bAlternateSetting
0x02    bNumEndPoints
0x03    bInterfaceClass      (Human Interface Device Class)
0x00    bInterfaceSubClass
0x00    bInterfaceProtocol
0x00    iInterfaceHID Descriptor:
------------------------------
0x09    bLength
0x21    bDescriptorType
0x0110  bcdHID
0x21    bCountryCode
0x01    bNumDescriptors
0x22    bDescriptorType   (Report descriptor)
0x001B  bDescriptorLengthEndpoint Descriptor:
------------------------------
0x07    bLength
0x05    bDescriptorType
0x83    bEndpointAddress  (IN endpoint 3)
0x03    bmAttributes      (Transfer: Interrupt / Synch: None / Usage: Data)
0x0400  wMaxPacketSize    (1 x 1024 bytes)
0x01    bInterval         (1 microframes)Endpoint Descriptor:
------------------------------
0x07    bLength
0x05    bDescriptorType
0x03    bEndpointAddress  (OUT endpoint 3)
0x03    bmAttributes      (Transfer: Interrupt / Synch: None / Usage: Data)
0x0400  wMaxPacketSize    (1 x 1024 bytes)
0x01    bInterval         (1 microframes)

接口0,HID报告描述符 64byte

uint8_t g_UsbDeviceHid64ByteReportDescriptor[] =
{0x05, 0x01,0x09, 0x00,0xa1, 0x01,0x15, 0x00,0x25, 0xff,0x19, 0x01,0x29, 0x08,0x95, 0x40,0x75, 0x08,0x81, 0x02,0x19, 0x01,0x29, 0x08,0x91, 0x02,0xc0
};

接口1:HID报告描述符 1024byte

uint8_t g_UsbDeviceHid1024ByteReportDescriptor[] =
{0x05, 0x01,0x09, 0x00,0xa1, 0x01,0x15, 0x00,0x25, 0xff,0x19, 0x01,0x29, 0x08,0x95, 0x80,0x75, 0x40,0x81, 0x02,0x19, 0x01,0x29, 0x08,0x91, 0x02,0xc0
};

实现USB标准请求

USB标准请求,无非就是:总线复位,设置接口,获取接口,获取设备描述符,获取配置描述符,获取字符串描述符等等。反正主机请求啥,设备提供啥就行。

usb_status_t USB_DeviceCallback(usb_device_handle handle, uint32_t event, void *param)
{usb_status_t error = kStatus_USB_Success;uint8_t *temp8 = (uint8_t *)param;uint16_t *temp16 = (uint16_t *)param;switch (event){case kUSB_DeviceEventBusReset:{/* USB bus reset signal detected */g_UsbDeviceHidGeneric.attach = 0U;if (kStatus_USB_Success == USB_DeviceClassGetSpeed(CONTROLLER_ID, &g_UsbDeviceHidGeneric.speed)){USB_DeviceSetSpeed(handle, g_UsbDeviceHidGeneric.speed);}        }break;case kUSB_DeviceEventSetConfiguration:if(param){/* Set device configuration request */g_UsbDeviceHidGeneric.attach = 1U;g_UsbDeviceHidGeneric.currentConfiguration = *temp8;if (USB_HID_GENERIC_CONFIGURE_INDEX == (*temp8)){error = USB_DeviceHidRecv(g_UsbDeviceHidGeneric.hidHandle, USB_HID_GENERIC_ENDPOINT_OUT,(uint8_t *)g_UsbDeviceHidGeneric.buffer,  USB_HID_GENERIC_OUT_BUFFER_LENGTH);error = USB_DeviceHidRecv(g_UsbDeviceHidGeneric.hid1024ByteHandle, USB_HID_1024BYTE_ENDPOINT_OUT,(uint8_t *)g_UsbDeviceHidGeneric.buffer1024byte,   USB_HID_1024BYTE_OUT_BUFFER_LENGTH);                     }           }break;case kUSB_DeviceEventSetInterface:if (g_UsbDeviceHidGeneric.attach){/* Set device interface request */uint8_t interface = (uint8_t)((*temp16 & 0xFF00U) >> 0x08U);uint8_t alternateSetting = (uint8_t)(*temp16 & 0x00FFU);if (interface == USB_HID_64BYTE_INTERFACE_INDEX)  {g_UsbDeviceHidGeneric.currentInterfaceAlternateSetting[interface] = alternateSetting;if (alternateSetting == 0U){error = USB_DeviceHidRecv(g_UsbDeviceHidGeneric.hidHandle, USB_HID_GENERIC_ENDPOINT_OUT,(uint8_t *)g_UsbDeviceHidGeneric.buffer,USB_HID_GENERIC_OUT_BUFFER_LENGTH);}}else if (interface == USB_HID_1024BYTE_INTERFACE_INDEX){g_UsbDeviceHidGeneric.currentInterfaceAlternateSetting[interface] = alternateSetting;if (alternateSetting == 0U){error = USB_DeviceHidRecv(g_UsbDeviceHidGeneric.hid1024ByteHandle, USB_HID_1024BYTE_ENDPOINT_OUT,(uint8_t *)g_UsbDeviceHidGeneric.buffer1024byte,   USB_HID_1024BYTE_OUT_BUFFER_LENGTH);   }}}break;case kUSB_DeviceEventGetConfiguration:if (param){/* Get current configuration request */*temp8 = g_UsbDeviceHidGeneric.currentConfiguration;error = kStatus_USB_Success;}break;case kUSB_DeviceEventGetInterface:if (param){/* Get current alternate setting of the interface request */uint8_t interface = (uint8_t)((*temp16 & 0xFF00U) >> 0x08U);if (interface < USB_DEVICE_INTERFACE_COUNT){*temp16 = (*temp16 & 0xFF00U) | g_UsbDeviceHidGeneric.currentInterfaceAlternateSetting[interface];error = kStatus_USB_Success;}else{error = kStatus_USB_InvalidRequest;}}break;case kUSB_DeviceEventGetDeviceDescriptor:if (param){/* Get device descriptor request */error = USB_DeviceGetDeviceDescriptor(handle, (usb_device_get_device_descriptor_struct_t *)param);}break;case kUSB_DeviceEventGetConfigurationDescriptor:if (param){/* Get device configuration descriptor request */error = USB_DeviceGetConfigurationDescriptor(handle,(usb_device_get_configuration_descriptor_struct_t *)param);}break;case kUSB_DeviceEventGetStringDescriptor:if (param){/* Get device string descriptor request */error = USB_DeviceGetStringDescriptor(handle, (usb_device_get_string_descriptor_struct_t *)param);}break;case kUSB_DeviceEventGetHidDescriptor:if (param){/* Get hid descriptor request */error = USB_DeviceGetHidDescriptor(handle, (usb_device_get_hid_descriptor_struct_t *)param);}break;case kUSB_DeviceEventGetHidReportDescriptor:if (param){/* Get hid report descriptor request */error =USB_DeviceGetHidReportDescriptor(handle, (usb_device_get_hid_report_descriptor_struct_t *)param);}break;case kUSB_DeviceEventGetHidPhysicalDescriptor:if (param){/* Get hid physical descriptor request */error = USB_DeviceGetHidPhysicalDescriptor(handle,(usb_device_get_hid_physical_descriptor_struct_t *)param);}break;default:break;}return error;
}

HID报告描述符请求函数修改:

usb_status_t USB_DeviceGetHidReportDescriptor(usb_device_handle handle,usb_device_get_hid_report_descriptor_struct_t *hidReportDescriptor)
{if (USB_HID_64BYTE_INTERFACE_INDEX== hidReportDescriptor->interfaceNumber){hidReportDescriptor->buffer = g_UsbDeviceHidGenericReportDescriptor;hidReportDescriptor->length = USB_DESCRIPTOR_LENGTH_HID_GENERIC_REPORT;}else if(USB_HID_1024BYTE_INTERFACE_INDEX == hidReportDescriptor->interfaceNumber){hidReportDescriptor->buffer = g_UsbDeviceHid1024ByteReportDescriptor;hidReportDescriptor->length = USB_DESCRIPTOR_LENGTH_HID_GENERIC_REPORT;}else{return kStatus_USB_InvalidRequest;}return kStatus_USB_Success;
}

将设备接上主机看枚举状况

枚举过程

通过Bus Hound可以抓包看到枚举过程,如下图:

上位机设计思路

1.遍历Windows端口所有usb设备,获取设备数量
libusb_get_device_list2.遍历所有设备的描述符信息,通过PID VID等信息找到我们指定的设备
libusb_get_device_descriptor3.打开指定设备
libusb_open4.查询接口0,查询接口1
获取该接口端点IN OUT5.端点上通信(hid 是中断传输,所以调用中断传输sdk)
libusb_interrupt_transfer

实例化成功USB HID设备后,如下识别2个Interface和对应的四个端点地址

可参考笔者之前的文章:HID高速设备1024byte------上下位机搭建

收发测试

端点1024Byte占用窗口比较大,这里就部分展示下

【USB设备设计】--复合设备,双HID高速(64Byte 和 1024Byte)相关推荐

  1. STM32CubeMX学习笔记(44)——USB接口使用(HID按键)

    一.USB简介 USB(Universal Serial BUS)通用串行总线,是一个外部总线标准,用于规范电脑与外部设备的连接和通讯.是应用在 PC 领域的接口技术.USB 接口支持设备的即插即用和 ...

  2. USB 协议分析之 HID 设备(转)

    USB 协议分析之 HID 设备 转载于:https://www.cnblogs.com/LittleTiger/p/10764891.html

  3. Android usb otg通讯总结 HiD通讯直接来取吧

    最近在搞一个Android的通过otg与设备进行usb通讯的功能HID. 过程中遇到了一个大坑,就是usb发数据的时候,第一次显示发送成功(返回值大于1),但是设备并没有收到实际的数据,把usb重新拔 ...

  4. 双路高速 AD 实验

    目录 双路高速 AD 实验 1.简介 3PA1030 芯片 2.实验任务 3.程序设计 3.1.hs_dual_ad 模块代码 clk_wiz IP 核 的添加方法 ILA IP 核(集成逻辑分析器: ...

  5. 【正点原子FPGA连载】 第二十八章 双路高速DA实验-摘自【正点原子】领航者ZYNQ之FPGA开发指南_V2.0

    1)实验平台:正点原子领航者ZYNQ开发板 2)平台购买地址:https://item.taobao.com/item.htm?&id=606160108761 3)全套实验源码+手册+视频下 ...

  6. Usb Composite Device (audio+hid) Descriptor

    近期开发USB Composite Device 撰写的USB 描述符 ,支持 USB speaker + USB Mic,同时支持USB HID 自定义设备.可以作为 开发设备的参考.(此描述符已经 ...

  7. usb中cdc dfu hid msc的区别

    cdc : communication device class,CDC是通信设备级方案,是USB 转其他的接口的一类设备,比如USB转RS232,USB转Ethernet等 dfu : Device ...

  8. USB 协议分析之 HID 设备

    1. 简述 USB HID类是USB设备的一个标准设备类,包括的设备非常多.HID类设备定义它属于人机交互操作的设备,用于控制计算机操作的一些方面,如USB鼠标.USB键盘.USB游戏操纵杆等.但HI ...

  9. usb的device模式hid配置错误点

    将usb做从机,hid通信操作(模拟串口,模拟u盘,hid通信...) 内核设定 1-模拟u盘 2.模拟串口 3.hid通信 1.报错: # insmod libcomposite.ko [   88 ...

  10. QCC3040 USB Composite Device: Audio+HID+CDC/虚拟串口

    笔记一下USB IAD的用途, 真实体验到了什么叫概念不清,误入歧途. 首先声明一下,笔者没有系统性了解过USB协议,只是按照实际情况,提出需求,发现问题,解决问题. 笔者记录一下在高通QCC3040 ...

最新文章

  1. 技术一般,却被破格提拔!肯定有黑幕......
  2. python中的ideavim有什么作用_Pycharm和Idea支持的vim插件的方法
  3. 《机器学习导论》和《统计机器学习》学习资料:张志华教授
  4. python enumeration_python模块之enum_上
  5. 泰勒及洛朗展开学习笔记
  6. Vue3 高级语法(一)—— h函数、jsx
  7. LeetCode 1291. 顺次数(模拟)
  8. java 多个数字_java 输入多个数字
  9. python爬虫入库到帝国cms_帝国小说连载系统合理利用第三方云爬虫缓存章节内容...
  10. Java从零开始(4)——入门项目
  11. 强化学习读书笔记 - 03 - 有限马尔科夫决策过程
  12. vmware虚拟机安装jdk
  13. 《 郝斌 java自学视频 完结 》_郝斌Java自学视频 全107讲视频教程下载 完整版
  14. 串口转usb驱动c语言程序,usb serial驱动下载-usb serial converter驱动下载 官方版usb转串口驱动程序-win7/8/10/xp32/64位-IT猫扑网...
  15. 软件设计的七大原则——超详细
  16. 01 官网下载各种CentOS教程(超详细版)
  17. 【源码分析】Spring Boot中Relaxed Binding机制的不同实现
  18. [差分 上下界最大流] SRM 694 div1 SRMDiv0Easy
  19. DOS之bat启动Exe脚本
  20. 企业BI工具实现库存周转率分析

热门文章

  1. 随机地图生成工具 fastMapper
  2. 流程图中的实线_教你如何正确看懂工艺流程图
  3. 网络安全应急响应实施过程
  4. java实现一码多扫支付_详解JAVA后端实现统一扫码支付:微信篇
  5. 微信小程序授权登录源码
  6. radon变换(c++、OpenCV实现)
  7. 小朋友Stem课程制作3D打印无人机
  8. Java proxy 代理
  9. 2021年起重机司机(限桥式起重机)考试题及起重机司机(限桥式起重机)免费试题
  10. macbook pro配置maven环境变量