PORTS Forum
Ports and Interfaces => USB => Topic started by: samchen on July 18, 2018, 05:27:05 am
-
Hi
Below is my usb hid descriptor, and I want to use HidD_SetOutputReport to send data via control transfer.
But it returns fail with error code 1 (ERROR_INVALID_FUNCTION). (OS: Windows 110)
Does anyone have idea how to using control transfer in windows ?
Thanks.
Device Descriptor:
bcdUSB: 0x0200
bDeviceClass: 0x00
bDeviceSubClass: 0x00
bDeviceProtocol: 0x00
bMaxPacketSize0: 0x40 (64)
ConnectionStatus: DeviceConnected
Current Config Value: 0x01
Device Bus Speed: High
Device Address: 0x37
Open Pipes: 1
Endpoint Descriptor:
bEndpointAddress: 0x81 IN
Transfer Type: Interrupt
wMaxPacketSize: 0x0040 (64)
bInterval: 0x01
Configuration Descriptor:
wTotalLength: 0x0022
bNumInterfaces: 0x01
bConfigurationValue: 0x01
iConfiguration: 0x00
bmAttributes: 0x80 (Bus Powered )
MaxPower: 0xFA (500 Ma)
Interface Descriptor:
bInterfaceNumber: 0x00
bAlternateSetting: 0x00
bNumEndpoints: 0x01
bInterfaceClass: 0x03 (HID)
bInterfaceSubClass: 0x00
bInterfaceProtocol: 0x00
iInterface: 0x00
HID Descriptor:
bcdHID: 0x0100
bCountryCode: 0x00
bNumDescriptors: 0x01
bDescriptorType: 0x22
wDescriptorLength: 0x003E
Endpoint Descriptor:
bEndpointAddress: 0x81 IN
Transfer Type: Interrupt
wMaxPacketSize: 0x0040 (64)
bInterval: 0x01
-
I saw the source code in Generic_Hid_cs_v62 project.
It looks like we can't use HidD_SetOutputReport when there is no output endpoint.
How to set report without out endpoint?
Thanks you
// Don't attempt to send an Output report if the HID has no Output report.
if (_myHid.Capabilities.OutputReportByteLength > 0)
{
// Set the size of the Output report buffer.
var outputReportBuffer = new Byte[_myHid.Capabilities.OutputReportByteLength];
// Store the report ID in the first byte of the buffer:
outputReportBuffer[0] = 0x00;
// Store the report data following the report ID.
// Use the data in the combo boxes on the form.
outputReportBuffer[1] = Convert.ToByte(CboByte0.SelectedIndex);
if (outputReportBuffer.GetUpperBound(0) > 1)
{
outputReportBuffer[2] = Convert.ToByte(CboByte1.SelectedIndex);
}
// Write a report.
Boolean success;
if (_transferType.Equals(TransferTypes.Control))
{
{
_transferInProgress = true;
// Use a control transfer to send the report,
// even if the HID has an interrupt OUT endpoint.
Debug.Print("control transfer");
success = _myHid.SendOutputReportViaControlTransfer(_hidHandle, outputReportBuffer);
_transferInProgress = false;
cmdSendOutputReportControl.Enabled = true;
}
}
-
HidD_SetOutputReport always uses a control transfer.
Compare your code to my Generic_Hid_cs example. Examine the parameters passed to the function.
-
There are two mistake I made for this issue.
1. USB hid descriptor misses report id for output report.
I have two report id (1 & 2) for input report, but lack of report id for output, so I add report id (3) for output.
When I call HidD_SetOutputReport, the first byte of buffer is 0x03.
2. Buffer size (65) for output exceeds maximum packet size (64).
I defines the maximum packet size to 64, and output size to 64, but we need one more byte for report id (That means the buffer size is 64 + 1).
After fixing these two problem, my program can use HidD_SetOutputReport successfully.
Thanks for your help.
Sam
-
Glad you got it working. Thanks for reporting what you found!