This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Asymmetric sized USB HID IN and OUT reports

I trying to make the OUT report size 1 while the IN report size 2 or more.
Can this be done? Right now I have modified the descriptors and the client. The client sends the messages AFAIK. But device (Keil MCB2300) doesnt seem to receive any bytes.
Thanks for your help.

Parents
  • "I trying to make the OUT report size 1 while the IN report size 2 or more.
    Can this be done?"

    Yes, we can. :-)

    On USB, IN and OUT endpoints are independent each other, even if they share the same endpoint address. Just the default endpoint (EP0) joins them for the sake of control transfer protocol.

    On the device side, the report descriptor is defined as follows,

    #define INREPORT_SIZE    2
    #define OUTREPORT_SIZE   1
    
    BYTE InReport[  INREPORT_SIZE  ];             /* HID Input Report  */
    BYTE OutReport[ OUTREPORT_SIZE ];             /* HID Output Report */
    
    /* HID Report Descriptor */
    const BYTE HID_ReportDescriptor[] = {
      HID_UsagePageVendor( 0x00                                   ),
      HID_Usage(           0x01                                   ),
      HID_Collection(      HID_Application                        ),
                                                                      // common parameters
        HID_LogicalMin(    0                                      ),
        HID_LogicalMaxS(   0xFF                                   ),
        HID_ReportSize(    8                                      ),  //   bits
                                                                      // input report
        HID_ReportCount(   INREPORT_SIZE                          ),  //   bytes
        HID_Usage(         0x01                                   ),
        HID_Input(         HID_Data | HID_Variable | HID_Absolute ),
                                                                      // output report
        HID_ReportCount(   OUTREPORT_SIZE                         ),  //   bytes
        HID_Usage(         0x01                                   ),
        HID_Output(        HID_Data | HID_Variable | HID_Absolute ),
      HID_EndCollection,
    };
    

    On the host app, HidP_GetCaps() gives the read/write size, which is greater than each report size by one, for the default report ID.

                                             // determine read / write size
    PHIDP_PREPARSED_DATA    preparsedData;
    HIDP_CAPS               capabilities;
    HidD_GetPreparsedData( deviceHandle, &preparsedData );
    HidP_GetCaps( preparsedData, &capabilities );
    HidD_FreePreparsedData( preparsedData );
    ...
    ...
                                             // read
    input_report[0] = 0;                     //  default report ID
    DWORD nNumberOfBytesToRead = capabilities.InputReportByteLength;
    ReadFile(..., input_report, nNumberOfBytesToRead, ...);
    ...
                                             // write
    output_report[0] = 0;                    //  default report ID
    output_report[1] = ...
    DWORD nNumberOfBytesToWrite = capabilities.OutputReportByteLength;
    WriteFile(..., output_report, nNumberOfBytesToWrite,...);
    

    Tsuneo

Reply
  • "I trying to make the OUT report size 1 while the IN report size 2 or more.
    Can this be done?"

    Yes, we can. :-)

    On USB, IN and OUT endpoints are independent each other, even if they share the same endpoint address. Just the default endpoint (EP0) joins them for the sake of control transfer protocol.

    On the device side, the report descriptor is defined as follows,

    #define INREPORT_SIZE    2
    #define OUTREPORT_SIZE   1
    
    BYTE InReport[  INREPORT_SIZE  ];             /* HID Input Report  */
    BYTE OutReport[ OUTREPORT_SIZE ];             /* HID Output Report */
    
    /* HID Report Descriptor */
    const BYTE HID_ReportDescriptor[] = {
      HID_UsagePageVendor( 0x00                                   ),
      HID_Usage(           0x01                                   ),
      HID_Collection(      HID_Application                        ),
                                                                      // common parameters
        HID_LogicalMin(    0                                      ),
        HID_LogicalMaxS(   0xFF                                   ),
        HID_ReportSize(    8                                      ),  //   bits
                                                                      // input report
        HID_ReportCount(   INREPORT_SIZE                          ),  //   bytes
        HID_Usage(         0x01                                   ),
        HID_Input(         HID_Data | HID_Variable | HID_Absolute ),
                                                                      // output report
        HID_ReportCount(   OUTREPORT_SIZE                         ),  //   bytes
        HID_Usage(         0x01                                   ),
        HID_Output(        HID_Data | HID_Variable | HID_Absolute ),
      HID_EndCollection,
    };
    

    On the host app, HidP_GetCaps() gives the read/write size, which is greater than each report size by one, for the default report ID.

                                             // determine read / write size
    PHIDP_PREPARSED_DATA    preparsedData;
    HIDP_CAPS               capabilities;
    HidD_GetPreparsedData( deviceHandle, &preparsedData );
    HidP_GetCaps( preparsedData, &capabilities );
    HidD_FreePreparsedData( preparsedData );
    ...
    ...
                                             // read
    input_report[0] = 0;                     //  default report ID
    DWORD nNumberOfBytesToRead = capabilities.InputReportByteLength;
    ReadFile(..., input_report, nNumberOfBytesToRead, ...);
    ...
                                             // write
    output_report[0] = 0;                    //  default report ID
    output_report[1] = ...
    DWORD nNumberOfBytesToWrite = capabilities.OutputReportByteLength;
    WriteFile(..., output_report, nNumberOfBytesToWrite,...);
    

    Tsuneo

Children
No data