6. 报告描述符及数据通信程序示例
报告描述符(由于是汇编代码,所以不必留意其语法,仅需注意表中的每个数据都占 1 个字节):
_ReportDescriptor: // 报告描述符
.dw 0x06, 0x00, 0xff // 用法页
.dw 0x09, 0x01 // 用法 ( 供应商用法 1)
.dw 0xa1, 0x01 // 集合开始
.dw 0x85, 0x01 // 报告 ID(1)
.dw 0x09, 0x01 // 用法 ( 供应商用法 1)
.dw 0x15, 0x00 // 逻辑最小值 (0)
.dw 0x26, 0xff, 0x0 // 逻辑最大值 (255)
.dw 0x75, 0x08 // 报告大小 (8)
.dw 0x95, 0x07 // 报告计数 (7)
.dw 0x81, 0x06 // 输入 (数据,变量,相对值)
.dw 0x09, 0x01 // 用法 ( 供应商用法 1)
.dw 0x85, 0x03 // 报告 ID ( 3 )
.dw 0xb1, 0x06 // 特征 (数据,变量,相对值)
.dw 0x09, 0x01 // 用法 ( 供应商用法 1)
.dw 0x85, 0x02 // 报告 ID ( 2 )
.dw 0xb1, 0x06 // 特征 (数据,变量,相对值)
.dw 0x09, 0x01 // 用法 ( 供应商用法 1)
.dw 0x85, 0x04 // 报告 ID ( 4 )
.dw 0x91, 0x06 // 输出 (数据,变量,相对值)
.dw 0xc0 // 结合结束
_ReportDescriptor_End:
这个报告描述符,定义了 4 个不同的报告:输入报告 1 ,特征报告 2 ,特征报告 3 ,输出报告 4 (数字代表其报告 ID )。为了简化,每个报告都是 7 个字节(加上报告 ID 就是 8 个字节)。下面用一个简单的示例来描述 PC 端与 USB HID 设备进行通信的一般方法。
- #define USB_VID 0xFC0
- #define USB_PID 0x420
- HANDLE OpenMyHIDDevice(int overlapped);
- void HIDSampleFunc()
- {
- HANDLE hDev;
- BYTE recvDataBuf[8];
- BYTE reportBuf[8];
- DWORD bytes;
- hDev = OpenMyHIDDevice(0);
- if (hDev == INVALID_HANDLE_VALUE)
- return;
- reportBuf[0] = 4;
- memset(reportBuf, 0, 8);
- reportBuf[1] = 1;
- if (!WriteFile(hDev, reportBuf, 8, &bytes, NULL))
- return;
- ReadFile(hDev, recvDatatBuf, 8, &bytes, NULL);
- }
-
- HANDLE OpenMyHIDDevice(int overlapped)
- {
- HANDLE hidHandle;
- GUID hidGuid;
- HidD_GetHidGuid(&hidGuid);
- HDEVINFO hDevInfo = SetupDiGetClassDevs(&hidGuid,
- NULL,
- NULL,
- (DIGCF_PRESENT | DIGCF_DEVICEINTERFACE));
- if (hDevInfo == INVALID_HANDLE_VALUE)
- {
- return INVALID_HANDLE_VALUE;
- }
- SP_DEVICE_INTERFACE_DATA devInfoData;
- devInfoData.cbSize = sizeof (SP_DEVICE_INTERFACE_DATA);
- int deviceNo = 0;
- SetLastError(NO_ERROR);
- while (GetLastError() != ERROR_NO_MORE_ITEMS)
- {
- if (SetupDiEnumInterfaceDevice (hDevInfo,
- 0,
- &hidGuid,
- deviceNo,
- &devInfoData))
- {
- ULONG requiredLength = 0;
- SetupDiGetInterfaceDeviceDetail(hDevInfo,
- &devInfoData,
- NULL,
- 0,
- &requiredLength,
- NULL);
- PSP_INTERFACE_DEVICE_DETAIL_DATA devDetail = (SP_INTERFACE_DEVICE_DETAIL_DATA*) malloc (requiredLength);
- devDetail->cbSize = sizeof(SP_INTERFACE_DEVICE_DETAIL_DATA);
- if(!SetupDiGetInterfaceDeviceDetail(hDevInfo,
- &devInfoData,
- devDetail,
- requiredLength,
- NULL,
- NULL))
- {
- free(devDetail);
- SetupDiDestroyDeviceInfoList(hDevInfo);
- return INVALID_HANDLE_VALUE;
- }
- if (overlapped)
- {
- hidHandle = CreateFile(devDetail->DevicePath,
- GENERIC_READ | GENERIC_WRITE,
- FILE_SHARE_READ | FILE_SHARE_WRITE,
- NULL,
- OPEN_EXISTING,
- FILE_FLAG_OVERLAPPED,
- NULL);
- }
- else
- {
- hidHandle = CreateFile(devDetail->DevicePath,
- GENERIC_READ | GENERIC_WRITE,
- FILE_SHARE_READ | FILE_SHARE_WRITE,
- NULL,
- OPEN_EXISTING,
- 0,
- NULL);
- }
- free(devDetail);
- if (hidHandle==INVALID_HANDLE_VALUE)
- {
- SetupDiDestroyDeviceInfoList(hDevInfo);
- free(devDetail);
- return INVALID_HANDLE_VALUE;
- }
- _HIDD_ATTRIBUTES hidAttributes;
- if(!HidD_GetAttributes(hidHandle, &hidAttributes))
- {
- CloseHandle(hidHandle);
- SetupDiDestroyDeviceInfoList(hDevInfo);
- return INVALID_HANDLE_VALUE;
- }
- if (USB_VID == hidAttributes.VendorID
- && USB_PID == hidAttributes.ProductID)
- {
- break;
- }
- else
- {
- CloseHandle(hidHandle);
- ++deviceNo;
- }
- }
- }
- SetupDiDestroyDeviceInfoList(hDevInfo);
- return hidHandle;
- }