应用程序与键盘通信

时间:2014-05-07 11:41:34

标签: c# keyboard usb hid

我创建了自己的可配置键盘设备(我可以更改任何键的代码)。 现在我正在尝试编写将与此设备通信的C#应用​​程序,但我对此有疑问。

键盘设备报告描述符:

//Keyboard
0x05, 0x01,   // USAGE_PAGE (Generic Desktop)
    0x09, 0x06,   // USAGE (Keyboard)
    0xa1, 0x01,   // COLLECTION (Application)
    0x85, 0x01,   //   REPORT_ID (1)
    0x05, 0x07,   //   USAGE_PAGE (Keyboard)
    0x19, 0xe0,   //   USAGE_MINIMUM (Keyboard LeftControl)
    0x29, 0xe7,   //   USAGE_MAXIMUM (Keyboard Right GUI)
    0x15, 0x00,   //   LOGICAL_MINIMUM (0)
    0x25, 0x01,   //   LOGICAL_MAXIMUM (1)
    0x75, 0x01,   //   REPORT_SIZE (1)
    0x95, 0x08,   //   REPORT_COUNT (8)
    0x81, 0x02,   //   INPUT (Data,Var,Abs)
    0x95, 0x01,   //   REPORT_COUNT (1)
    0x75, 0x08,   //   REPORT_SIZE (8)
    0x81, 0x03,   //   INPUT (Cnst,Var,Abs)
    0x95, 0x05,   //   REPORT_COUNT (5)
    0x75, 0x01,   //   REPORT_SIZE (1)
    0x05, 0x08,   //   USAGE_PAGE (LEDs)
    0x19, 0x01,   //   USAGE_MINIMUM (Num Lock)
    0x29, 0x05,   //   USAGE_MAXIMUM (Kana)
    0x91, 0x02,   //   OUTPUT (Data,Var,Abs)
    0x95, 0x01,   //   REPORT_COUNT (1)
    0x75, 0x03,   //   REPORT_SIZE (3)
    0x91, 0x03,   //   OUTPUT (Cnst,Var,Abs)
    0x95, 0x06,   //   REPORT_COUNT (6)
    0x75, 0x08,   //   REPORT_SIZE (8)
    0x15, 0x00,   //   LOGICAL_MINIMUM (0)
    0x25, 0xFF,   //   LOGICAL_MAXIMUM (255) //0x25, 0x65,   //   LOGICAL_MAXIMUM (101)
    0x05, 0x07,   //   USAGE_PAGE (Keyboard)
    0x19, 0x00,   //   USAGE_MINIMUM (Reserved (no event indicated))
    0x29, 0x65,   //   USAGE_MAXIMUM (Keyboard Application)
    0x81, 0x00,   //   INPUT (Data,Ary,Abs)
0xc0,         // END_COLLECTION
/*65*/

//Device Configuration
0x06, 0xFF, 0xA0,  // USAGE_PAGE (Vendor-Defined)
    0x09, 0x01,    // USAGE (Vendor-Defined)
    0xA1, 0x01,    // COLLECTION (Application)
    0x85, 0x02,    // REPORT_ID (2)

    0x09, 0x03,    // USAGE (Vendor-Defined)
    0x15, 0x00,    // LOGICAL_MINIMUM (0)
    0x26, 0x00, 0xFF, // LOGICAL_MAXIMUM (255)
    0x95, 0x2D,    // REPORT_COUNT (45)
    0x75, 0x08,    // REPORT_SIZE (8)
    0x81, 0x02,    // Input (Data, Variable, Absolute)

    0x09, 0x04,    // USAGE (Vendor-Defined)
    0x15, 0x00,    // LOGICAL_MINIMUM (0)
    0x26, 0x00, 0xFF, // LOGICAL_MAXIMUM (255)
    0x95, 0x2D,    // REPORT_COUNT (45)
    0x75, 0x08,    // REPORT_SIZE (8)
    0x91, 0x02,    // Output (Data, Variable, Absolute)

    0x09, 0x05,    // USAGE (Vendor-Defined)
    0x15, 0x00,    // LOGICAL_MINIMUM (0)
    0x26, 0x00, 0xFF, // LOGICAL_MAXIMUM (255)
    0x95, 0x2D,    // REPORT_COUNT (45)
    0x75, 0x08,    // REPORT_SIZE (8)
    0xB1, 0x02,    // Feature (Data, Variable, Absolute)
0xc0,          //   END_COLLECTION

C#代码的一部分(我使用HIDLibrary):

    Device = HidDevices.Enumerate(VendorID, ProductID).FirstOrDefault();

    if (Device == null)
    {
        return;
    }
    //Open Device
    Device.OpenDevice();
    //if( Device.IsOpen == false )
    //  return;
    Device.Inserted += DeviceAttachedHandler;
    Device.Removed += DeviceRemovedHandler;
    Device.MonitorDeviceEvents = true;


    //Handle Reports
    KeyMapRequest(); //Fill Buffer with KeyMapRequest
    HidReport report = Device.CreateReport();
    report.ReportId = 2;
    report.Data = USBBuffer;

    succeed = Device.WriteReport(report, 10);
    Device.ReadReport(OnReport);
    LastDataEventDate = DateTime.Now;
    while ((DateTime.Now - LastDataEventDate).TotalMilliseconds < 100)
    {
    }

键盘工作正常,但应用程序无法与设备通信。 &#34; Device.IsOpen&#34;总是&#34;假&#34;。 但是当我从报告描述符部分删除&#34; Report_ID(1)&#34; (键盘部分),&#34; Device.IsOpen&#34;是&#34;是&#34;,沟通正常。

Windows是否负责阻止通信?我该怎么处理? 或许我在描述符中有一些错误?

1 个答案:

答案 0 :(得分:0)

我认为这种行为可能是LOGICAL_MAXIMUM规范不正确的副作用。您不小心编码了-256而不是255.当我使用hidrdd解码您的声明时,它会输出:

/*
06 FFA0      (GLOBAL) USAGE_PAGE         0xA0FF Reserved 
09 01        (LOCAL)  USAGE              0xA0FF0001  
A1 01        (MAIN)   COLLECTION         0x01 Application (Usage=0xA0FF0001: Page=Reserved, Usage=, Type=) <-- Warning: USAGE type should be CA (Application)
85 02          (GLOBAL) REPORT_ID          0x02 (2) 
09 03          (LOCAL)  USAGE              0xA0FF0003  
15 00          (GLOBAL) LOGICAL_MINIMUM    0x00 (0) <-- Redundant: LOGICAL_MINIMUM is already 0
26 00FF        (GLOBAL) LOGICAL_MAXIMUM    0xFF00 (-256) 
95 2D          (GLOBAL) REPORT_COUNT       0x2D (45) Number of fields 
75 08          (GLOBAL) REPORT_SIZE        0x08 (8) Number of bits per field <-- Redundant: REPORT_SIZE is already 8
81 02          (MAIN)   INPUT              0x00000002 (45 fields x 8 bits) 0=Data 1=Variable 0=Absolute 0=NoWrap 0=Linear 0=PrefState 0=NoNull 0=NonVolatile 0=Bitmap  <-- Error: REPORT_SIZE (8) is too small for LOGICAL_MAXIMUM (-256) which needs 9 bits. <-- Error: LOGICAL_MAXIMUM (-256) is less than LOGICAL_MINIMUM (0)
09 04          (LOCAL)  USAGE              0xA0FF0004  
15 00          (GLOBAL) LOGICAL_MINIMUM    0x00 (0) <-- Redundant: LOGICAL_MINIMUM is already 0
26 00FF        (GLOBAL) LOGICAL_MAXIMUM    0xFF00 (-256) <-- Redundant: LOGICAL_MAXIMUM is already -256
95 2D          (GLOBAL) REPORT_COUNT       0x2D (45) Number of fields <-- Redundant: REPORT_COUNT is already 45
75 08          (GLOBAL) REPORT_SIZE        0x08 (8) Number of bits per field <-- Redundant: REPORT_SIZE is already 8
91 02          (MAIN)   OUTPUT             0x00000002 (45 fields x 8 bits) 0=Data 1=Variable 0=Absolute 0=NoWrap 0=Linear 0=PrefState 0=NoNull 0=NonVolatile 0=Bitmap  <-- Error: REPORT_SIZE (8) is too small for LOGICAL_MAXIMUM (-256) which needs 9 bits. <-- Error: LOGICAL_MAXIMUM (-256) is less than LOGICAL_MINIMUM (0)
09 05          (LOCAL)  USAGE              0xA0FF0005  
15 00          (GLOBAL) LOGICAL_MINIMUM    0x00 (0) <-- Redundant: LOGICAL_MINIMUM is already 0
26 00FF        (GLOBAL) LOGICAL_MAXIMUM    0xFF00 (-256) <-- Redundant: LOGICAL_MAXIMUM is already -256
95 2D          (GLOBAL) REPORT_COUNT       0x2D (45) Number of fields <-- Redundant: REPORT_COUNT is already 45
75 08          (GLOBAL) REPORT_SIZE        0x08 (8) Number of bits per field <-- Redundant: REPORT_SIZE is already 8
B1 02          (MAIN)   FEATURE            0x00000002 (45 fields x 8 bits) 0=Data 1=Variable 0=Absolute 0=NoWrap 0=Linear 0=PrefState 0=NoNull 0=NonVolatile 0=Bitmap  <-- Error: REPORT_SIZE (8) is too small for LOGICAL_MAXIMUM (-256) which needs 9 bits. <-- Error: LOGICAL_MAXIMUM (-256) is less than LOGICAL_MINIMUM (0)
C0           (MAIN)   END_COLLECTION     Application
*/

在HID报告描述符中,您需要以Little-Endian顺序编码值。这也适用于USAGE_PAGE(我已经更正了下面的例子)。

顺便说一下,您不需要重复LOGICAL_MINIMUM,LOGICAL_MAXIMUM,REPORT_COUNT或REPORT_SIZE值,因为它们都是GLOBAL项 - 因此只有在值改变时(因为解析器扫描它们)才需要指定它们。尝试指定:

/*
06 A0FF      (GLOBAL) USAGE_PAGE         0xFFA0 Vendor-defined 
09 01        (LOCAL)  USAGE              0xFFA00001  
A1 01        (MAIN)   COLLECTION         0x01 Application (Usage=0xFFA00001: Page=Vendor-defined, Usage=, Type=)
85 02          (GLOBAL) REPORT_ID          0x02 (2) 
09 03          (LOCAL)  USAGE              0xFFA00003  
15 00          (GLOBAL) LOGICAL_MINIMUM    0x00 (0) <-- Redundant: LOGICAL_MINIMUM is already 0
26 FF00        (GLOBAL) LOGICAL_MAXIMUM    0x00FF (255) 
95 2D          (GLOBAL) REPORT_COUNT       0x2D (45) Number of fields 
75 08          (GLOBAL) REPORT_SIZE        0x08 (8) Number of bits per field <-- Redundant: REPORT_SIZE is already 8
81 02          (MAIN)   INPUT              0x00000002 (45 fields x 8 bits) 0=Data 1=Variable 0=Absolute 0=NoWrap 0=Linear 0=PrefState 0=NoNull 0=NonVolatile 0=Bitmap 
09 04          (LOCAL)  USAGE              0xFFA00004  
91 02          (MAIN)   OUTPUT             0x00000002 (45 fields x 8 bits) 0=Data 1=Variable 0=Absolute 0=NoWrap 0=Linear 0=PrefState 0=NoNull 0=NonVolatile 0=Bitmap 
09 05          (LOCAL)  USAGE              0xFFA00005  
B1 02          (MAIN)   FEATURE            0x00000002 (45 fields x 8 bits) 0=Data 1=Variable 0=Absolute 0=NoWrap 0=Linear 0=PrefState 0=NoNull 0=NonVolatile 0=Bitmap 
C0           (MAIN)   END_COLLECTION     Application
*/