Ports and Interfaces > USB

HID - Sending OUT Report while IN Report is Waiting

(1/4) > >>

Victor M:
I'm trying to learn how to use USB for general two way communications with a generic HID device.

For the device I have selected the Atmel ATxmega256A3BU on a demo board which includes an LCD, buttons, and LEDs.

For the host application I'm using Jan's 'generic_hid_cs_60' (Visual C#).
I have modified the code for PC and device to support two basic features --

⦁   When a button on the windows form is clicked, an OUT report is sent to endpoint 2 with 64 bytes of character data (obtained from a new text box on the form). When received, the text is displayed on the device's LCD.

⦁   When a button on the device is pressed, a different text string is written to the device endpoint 1 buffer. Then when the 'Get Input Report' (by interrupt) button on the form is clicked, the received text string is written to a listbox (new listbox, not LstResults) on the form.

Both of these features are working, but I don't want to have to click a button on the form in order to get the message to display in the listbox.

In an attempt to fix this, I made changes to the application code - 1) changed the readTimeout value from 5000 to -1 (no timeout). 2) After receiving the IN report, I call the method to initiate another IN report. This way the host is always sending IN tokens, and when the device writes to the IN buffer, the data is transferred immediately. This makes the second feature work as intended.

Of course this creates a different problem, the OUT report (first feature) can never occur because it is blocked by the _transferInProgress flag.

Question: is there a way to make both these features work as intended? For instance, can the Get IN Report be canceled so the Get OUT Report can be sent?

I did see the following on the HID FAQ page, and it might relate to my problem, but I don't really understand the answer. Could someone clarify? Is there example code?

" How can I find out if a report is available without hanging my application?
Use overlapped ReadFile with a short timeout or use ReadFileEx to signal when a report is available. In .NET, you can do asynchronous ReadFile calls with a delegate and BeginInvoke and EndInvoke methods. "

Any help will be greatly appreciated.

Jan Axelson:
The host driver continuously requests data from the interrupt IN endpoint regardless of whether applications use it. You are just requesting the data from the buffer more frequently.

If the IN data isn't a response to OUT data,  you don't need to wait for an OUT transfer to complete before requesting IN data.

Before initiating another read, check for a write request. Or use delegates, etc. See my more recent example code.

Let me know if you still have questions. I don't have the code in front of me right now.

Victor M:
Hi Jan, thanks for the reply.
So even before the application calls RequestToGetInputReport(), the host USB software stack has retrieved the report from the HID? That's very interesting.

To state the problem more clearly, the only way I know of to read the IN report (in a timely manner) is to call RequestToGetInputReport() every time it returns data. But in the meantime if I need to send an OUT report, it gets blocked or the software hangs.

You mentioned "more recent example code" but I don't see any. I thought I was using the most recent. It is V6.2 dated 11/12/13. If there is other code, could you give me the link?
I have used delegates in other c# windows form code, but I don't understand exactly how it can help in this case. Could you be more explicit?

I see the FileStream object _deviceData being created in the FindTheHid() method. Does this FileStream support concurrent read and write? In other words, when the read method is called (asynchronously) should I then be able to call the write method before read completes? It doesn't seem to work. I noticed there is a flag, _transferInProgress to prevent this. It must be there for a reason. If I ignore the flag and call RequestToSendOutputReport() it causes the program to hang.

As I study this more I will definitely have more questions.
Thanks,
Victor

Jan Axelson:
>So even before the application calls RequestToGetInputReport(), the host USB software stack has retrieved the report from the HID?

yes, if the endpoint has sent one. The driver uses a ring buffer.

V6.2 is the latest.

These might help

https://docs.microsoft.com/en-us/dotnet/standard/io/asynchronous-file-i-o

https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/async/using-async-for-file-access

Victor M:

--- Quote ---yes, if the endpoint has sent one.
--- End quote ---

Okay, but to test my understanding, the device cannot initiate a transaction, it can only respond to an 'IN token' from the host, right? If the device has no data in it's buffer it replies with NAK. So there must be a periodic polling by the host.

Thanks for the references. I will study those.

Navigation

[0] Message Index

[#] Next page

Go to full version