USB HID Report ID

Hello,

I am useing an SAM7S256 controller. I want to implement a USB HID communication. I have already succeded to some degree with the Keil sample code for HID.

My problem is the Report descriptor.
I want to be able to transmit 1 to 1024 bytes from HOST to DEVICE and DEVICE to HOST. I could define a report descriptor for 1026 bytes and use 2 bytes for the length of the actual data. However I don't want to waste so much bandwidth if there is only a few bytes actual information to send.
I came up with the idea to use report IDs and to define say 17 report IDs with sizes from 64-bytes to 1026 bytes.
My problem is I don't know how to specify this so it works correctly.
Are you aware of a tool to test the descriptors in depth. The Tools I have found on the usb.org page only tell me how many errors there are in my report descriptor but not what exactly the problem is?

My descriptor so far ...

/* HID Report Descriptor */
const BYTE HID_ReportDescriptor[] = {
  HID_UsagePageVendor(0x00),
  HID_Usage(          0x01),
  HID_Collection(     HID_Application),

    // INPUT (DEVICE -> HOST)
  HID_Collection(     HID_Logical),
        HID_ReportID(     1),
        HID_Usage(        0x01),
    HID_LogicalMin(   0),
    HID_LogicalMax(   255),
    HID_ReportCount(  64),
    HID_ReportSize(   8),
    HID_Input(        HID_Data | HID_Variable | HID_Absolute),
  HID_EndCollection,


  HID_Collection(     HID_Logical),
        HID_ReportID(     2),
        HID_Usage(        0x01),
    HID_LogicalMin(   0),
    HID_LogicalMax(   255),
    HID_ReportCount(  128),
    HID_ReportSize(   8),
    HID_Input(        HID_Data | HID_Variable | HID_Absolute),
  HID_EndCollection,

        // INPUT (HOST -> DEVICE)
  HID_Collection(     HID_Logical),
        HID_ReportID(     1),
        HID_UsagePage(HID_USAGE_PAGE_GENERIC),
    HID_Usage(HID_USAGE_GENERIC_COUNTED_BUFFER),
    HID_LogicalMin(0),
    HID_LogicalMax(255),
    HID_ReportCount(64),
    HID_ReportSize(8),
    HID_Output(HID_Data | HID_Variable | HID_Absolute),
  HID_EndCollection,

 HID_Collection(     HID_Logical),
        HID_ReportID(     2),
        HID_UsagePage(HID_USAGE_PAGE_GENERIC),
    HID_Usage(HID_USAGE_GENERIC_COUNTED_BUFFER),
    HID_LogicalMin(0),
    HID_LogicalMax(255),
    HID_ReportCount(128),
    HID_ReportSize(8),
    HID_Output(HID_Data | HID_Variable | HID_Absolute),
  HID_EndCollection,

 HID_Collection(     HID_Logical),
        HID_ReportID(     3),
        HID_UsagePage(HID_USAGE_PAGE_GENERIC),
    HID_Usage(HID_USAGE_GENERIC_COUNTED_BUFFER),
    HID_LogicalMin(0),
    HID_LogicalMax(255),
    HID_ReportCount(192),
    HID_ReportSize(8),
    HID_Output(HID_Data | HID_Variable | HID_Absolute),
  HID_EndCollection,

  HID_EndCollection,
};

Parents Reply
  • 1) HID Descriptor Tool
    Make up your report descriptor on HID Descriptor Tool, and check it.

    "HID Descriptor Tool" on USB.org
    www.usb.org/.../dt2_4.zip

    The GUI of this tool is troublesome to make up a huge report on it.
    Make up this minimum descriptor on the GUI first.

    /* HID Report Descriptor */
    const BYTE HID_ReportDescriptor[] = {
        0x06, 0x00, 0xff,              // USAGE_PAGE (Vendor Defined Page 1)
        0xa1, 0x01,                    // COLLECTION (Application)
        0x15, 0x00,                    //   LOGICAL_MINIMUM (0)
        0x26, 0xff, 0x00,              //   LOGICAL_MAXIMUM (255)
        0x75, 0x08,                    //   REPORT_SIZE (8)
    
        0x85, 0x01,                    //   REPORT_ID (1)
        0x95, 0x40,                    //   REPORT_COUNT (64)
        0x09, 0x01,                    //   USAGE (Vendor Usage 1)
        0x81, 0x02,                    //   INPUT (Data,Var,Abs)
        0x09, 0x01,                    //   USAGE (Vendor Usage 1)
        0x91, 0x02,                    //   OUTPUT (Data,Var,Abs)
    
        0xc0                           // END_COLLECTION
    };
    

    The next block is copy-pasted as follows,
    - Click on REPORT_ID(1) line, and click on OUTPUT(Data,Var,Abs) line with shift key -- above REPORT_ID (1) block is selected
    - Copy these lines (CTRL-C)
    - Click on END_COLLECTION line
    - Paste it (CTRL-V)

    To modify the new block,
    - Double click on REPORT_ID (1) and enter new report ID
    - Double click on REPORT_COUNT (64) and enter new report count

    Repeat this paste and modify process for more blocks
    - block is already copied, then just paste it.

    In this way, you can make up the huge report descriptor in a few minute.
    When you finish the descriptor, check it using "Parse Descriptor"

    As you can see, no HID_Usage(0x01) before the HID_Collection(HID_Application) line is required.

    When the descriptor passes the check, save it with "Save As".
    - File type -- Header File
    Then, you'll get a text file like above. Copy the contents to your code.



    2) Descriptor definitions

    "Do I have to change something else in a different descriptor?"

    The size of the report descriptor is altered.
    - wDescriptorLength on the HID class descriptor
    - Get_Descriptor( HID Report ) handling

    Using sizeof() as follows, compiler automatically takes care of it.

    #if defined BIG_ENDIAN
      #define LE(x)   ((((x)&0x00FF)<<8)|(((x)&0xFF00)>>8))  // convert to little endian
    #else
      #define LE(x) (x)                                      // no conversion
    #endif
    
    /* HID Report Descriptor */
    const BYTE HID_ReportDescriptor[] = {
        //
        // your descriptor comes here
        //
    };
    
    const unsigned int HID_ReportDescriptor_size = sizeof( HID_ReportDescriptor );
                                    // export the size of report descriptor for Get_Descriptor
    /* Device Descriptor */
    ...
    /* Configuration Descriptor set */
    const BYTE USB_ConfigDescriptor[] = {
       ...
       {
          // HID class descriptor
          sizeof(THID_class_descriptor),        // bLength
          DSC_SUBTYPE_CS_HID_CLASS,             // bDescriptorType
          LE( 0x0111 ),                         // bcdHID (ver1.11)
          0x00,                                 // bCountryCode
          0x01,                                 // bNumDescriptors
          HID_REPORT_DESCRIPTOR,                // bDescriptorType
          LE( sizeof( HID_ReportDescriptor ) ), // wDescriptorLength
       },
       ...
    };
    

    Tsuneo

Children
More questions in this forum