PORTS Forum
Ports and Interfaces => USB => Topic started by: jeff648 on September 11, 2013, 01:59:23 pm
-
Hello,
I am a newbie and I have build a system with a microcontroller talking with a host in USB.
The device transmits a report of 20 bytes to the host each second on the USB port. The enumeration is OK. I use HID and all works fine when I use the
ReadFile code written in C# by Jan Axelson:
Marshal.StructureToPtr(HidOverlapped, unManagedOverlapped, false);
success = ReadFile(ReadHandleToUSBDevice, unManagedBuffer, inputReportBuffer.Length, ref numberOfBytesRead, unManagedOverlapped);
if (!success)
{
result = WaitForSingleObject(eventObject, 3000);
switch (result)
{
case WAIT_OBJECT_0:
success = true;
GetOverlappedResult(ReadHandleToUSBDevice, unManagedOverlapped, ref numberOfBytesRead, false);
break;
case WAIT_TIMEOUT:
CancelIo(ReadHandleToUSBDevice);
break;
default:
CancelIo(ReadHandleToUSBDevice);
break;
}
}
if (success)
{
Marshal.Copy(unManagedBuffer, inputReportBuffer, 0, numberOfBytesRead);
.........................
}
The problem is the other commands of the thread are not responsive, due to the 3000 ms blocking delay.
I don't understand why this delay is mandatory.
When I decrease the delay to 1 or 2 ms I sometimes loss reports.
I also loss reports if I modify the code to avoid the delay:
Marshal.StructureToPtr(HidOverlapped, unManagedOverlapped, false);
success = ReadFile(ReadHandleToUSBDevice, unManagedBuffer, inputReportBuffer.Length, ref numberOfBytesRead, unManagedOverlapped);
if (!success)
{
CancelIo(ReadHandleToUSBDevice);
}
if (success)
{
Marshal.Copy(unManagedBuffer, inputReportBuffer, 0, numberOfBytesRead);
.........................
}
My questions are why this delay, how can I avoid it and how prevent loss of reports.
Thank you for your help
jeff
-
The HID driver continuously requests reports from the interrupt IN endpoint and stores received reports in a buffer. If the buffer is full when a new report arrives, the driver drops the oldest report.
A blocking ReadFile will wait until a report is available or a timeout.
The latest versions of my HID code use events that trigger when data is received so the application doesn't have to wait for data:
http://www.lvr.com/hidpage.htm#MyExampleCode
You can increase the number of reports the HID driver's buffer can store with HidD_SetNumInputBuffers. See my example code.
ReadFile (and I think Filestream reads) can retrieve multiple reports at once if the function call's buffer is large enough to fit multiple reports and multiple reports are available.