当前位置:网站首页>[USB device design] - composite device, dual hid high-speed (64BYTE and 1024byte)
[USB device design] - composite device, dual hid high-speed (64BYTE and 1024byte)
2022-07-25 11:49:00 【L_ seventeen】
Preface
In the work project , Some projects have high requirements for data throughput ( Such as the need to 5M/s About the bandwidth ), So the author designed a high-speed HID, Endpoint size :1024Byte equipment , But the company's previous products used endpoint size :64Byte Full speed equipment , In order to ensure USB Device compatibility , So the author designed two interfaces HID equipment (Interface0:64Byte HID、Interface1:1024Byte HID). Okay , Next, let's introduce double HID How to develop composite equipment .
Preparation
1. belt USB 2.0 High speed function MCU ( The author's NXP RT1052)
2.libusb 1.x edition ( The development host computer can use this library )
3.VS2015 keil (IDE There are many environmental choices , Differ from man to man )
HID Descriptor basic structure

- Configuration descriptor : The number of interfaces mainly set is :2
- Interface descriptors : Interface 0, The endpoint descriptor is set to :64Byte; Interface 1, The endpoint descriptor is set to :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 iInterface
HID Descriptor:
------------------------------
0x09 bLength
0x21 bDescriptorType
0x0110 bcdHID
0x21 bCountryCode
0x01 bNumDescriptors
0x22 bDescriptorType (Report descriptor)
0x001B bDescriptorLength
Endpoint 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 iInterface
HID Descriptor:
------------------------------
0x09 bLength
0x21 bDescriptorType
0x0110 bcdHID
0x21 bCountryCode
0x01 bNumDescriptors
0x22 bDescriptorType (Report descriptor)
0x001B bDescriptorLength
Endpoint 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)
Interface 0,HID Report descriptor 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
};
Interface 1:HID Report descriptor 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
};
Realization USB Standard request
USB Standard request , does : Bus reset , Set interface , Get interface , Get device descriptor , Get configuration descriptor , Get string descriptor and so on . Anyway, the host requests nothing , What the equipment provides .
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 Report descriptor request function modification :
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;
}
Connect the device to the host to see the enumeration status

Enumeration process
adopt Bus Hound You can see the enumeration process by capturing packets , Here's the picture :
Design idea of upper computer
1. Traverse Windows All ports usb equipment , Get the number of devices
libusb_get_device_list
2. Traverse the descriptor information of all devices , adopt PID VID Wait for the information to find the equipment we specified
libusb_get_device_descriptor
3. Open the specified device
libusb_open
4. Query interface 0, Query interface 1
Get the interface endpoint IN OUT
5. Communication on endpoint (hid Is to interrupt transmission , So interrupt the transmission sdk)
libusb_interrupt_transfer
Refer to the author's previous articles :HID High speed equipment 1024byte------ Setup of upper and lower computers
Transceiver test

边栏推荐
- Database integrity -- six constraints learning
- Make a reliable delay queue with redis
- Various controls ==pyqt5
- SQL language (III)
- Menu bar + status bar + toolbar ==pyqt5
- 30套中国风PPT/创意PPT模板
- 教你如何通过MCU配置S2E为TCP Client的工作模式
- W5500多节点连接
- Eigenvalues and eigenvectors of matrices
- [IJCAI 2022] parameter efficient large model sparse training method, which greatly reduces the resources required for sparse training
猜你喜欢

Breadth first traversal (problems related to sequence traversal of graphs and binary trees)

Filter过滤器解决request请求参数乱码的原理解析

SQL injection less23 (filter comment)

SQL language (6)

Small and micro enterprise smart business card management applet

矩阵的特征值和特征向量

The principle analysis of filter to solve the request parameter garbled code

JS process control

Talking about Devops monitoring, how does the team choose monitoring tools?
Definition of information entropy
随机推荐
[MySQL learning 08]
Attendance system based on w5500
圆角大杀器,使用滤镜构建圆角及波浪效果!
Objects in JS
软件缺陷的管理
How does the whole network display IP ownership?
Talking about Devops monitoring, how does the team choose monitoring tools?
模型部署简述
Web APIs (get element event basic operation element)
Definition of information entropy
The first C language program (starting from Hello World)
基于Caffe ResNet-50网络实现图片分类(仅推理)的实验复现
JS中的对象
leetcode 剑指 Offer 28. 对称的二叉树
阿里云技术专家秦隆:可靠性保障必备——云上如何进行混沌工程
SQL language (II)
贪心问题01_活动安排代码分析
大话DevOps监控,团队如何选择监控工具?
JS中的函数
Hacker introductory tutorial (very detailed) from zero basic introduction to proficiency, it is enough to read this one.