当前位置:网站首页>[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

边栏推荐
- 贪心问题01_活动安排问题
- Varest blueprint settings JSON
- 2022 年中回顾|一文看懂预训练模型最新进展
- ArcMap cannot start the solution
- Chapter 4 linear equations
- RedisUtil
- 信号与槽机制==PYQT5
- Teach you how to configure S2E to UDP working mode through MCU
- Risks in software testing phase
- How to solve the problem that "w5500 chip cannot connect to the server immediately after power failure and restart in tcp_client mode"
猜你喜欢

小区蔬菜配送的小程序

什么是全局事件总线?

The most efficient note taking method in the world (change your old version of note taking method)

SQL injection less23 (filter comment)

ArcMap cannot start the solution

OneNET平台控制W5500开发板LED灯

Information management system for typical works of urban sculpture (picture sharing system SSM)

第4章线性方程组

SQL language (II)

Similarity matrix, diagonalization condition
随机推荐
Convert string to number
SQL language (4)
Review in the middle of 2022 | understand the latest progress of pre training model
Functions in JS
varest蓝图设置json
Flinksql client connection Kafka select * from table has no data error, how to solve it?
SQL language (II)
教你如何通过MCU配置S2E为TCP Client的工作模式
The first C language program (starting from Hello World)
Hardware peripherals =maixpy3
leetcode 剑指 Offer 27. 二叉树的镜像
LeetCode 50. Pow(x,n)
[electronic device notes 5] diode parameters and selection
[MySQL learning 08]
城市雕塑典型作品信息管理系统(图片分享系统SSM)
Management of software defects
小区蔬菜配送的小程序
基于Caffe ResNet-50网络实现图片分类(仅推理)的实验复现
Plot ==pyqt5
SQL injection less23 (filter comment)