I have a question about how WinUsb handles short, irregular reads and
timeouts.
I’ve been looking through the documentation and examples but I don’t
quite find the options that will do what I want. I am relatively new to
windows and usb development so I apologize if what I ask is basic and I
just don’t know how to look for the answer. I have found very little
information or examples about WinUSB compared to other USB development.
I have several devices from different manufacturers, each of them with
similar, but not quite the same, communication protocols. Each
apparently was originally designed for serial interface, but now every
one of them offers USB as a connection option.
I have code to talk to these devices when connected via serial cable
that basically does the following:
open serial port for non overlapped IO using a tiemout
loop (a long time) {
check if device has any data to read using ReadFile
read until read buffer is empty
/* This times out if there is nothing, or returns whatever
is in the read buffer at the time of the read call */
When user is ready, send a command to the device using WriteFile
checks for ACK/NAK
}
The read data is variable in length, including 0 bytes if there is no
data to read, and can vary from 1 byte (ACK/NAK) to hundreds of bytes. I
do not know the length ahead of time.
I want to mimic this behavior using WinUSB, but I can’t quite get it to
do what I want. I believe I need to set the ReadPipe options to RAW_IO,
but when I combine this with timeouts the code breaks in mysterious ways.
I am using non-overlapped reads/writes.
I have code similar to:
timeout=400;
retval = WinUsb_SetPipePolicy(handle, epin,
PIPE_TRANSFER_TIMEOUT, sizeof(timeout),
&timeout);
/* check for errors */
t = FALSE:
retval = WinUsb_SetPipePolicy(handle, epin, ALLOW_PARTIAL_READS,
sizeof(t), &t); /* check for errors */
raw=0;
retval = WinUsb_SetPipePolicy(handle, epin, RAW_IO, sizeof(raw), &raw);
/* check for errors */
later on, I have a loop where I send commands to the device and expect a
response from it. Similar to:
loop () {
retval = WinUsb_ReadPipe (handle, epin, buf, 64, &readbytes, NULL);
/* check for errors or timeout */
/* handle read data */
if (I need to send a command) {
retval = WinUsb_WritePipe(handle, epout, some_command,
command_len, &sentbytes, NULL);
/* check for errors */
}
}
I have no problems with my writes, but the reads are timing out without
returning any data when I know the device is ready to send small amounts
of data (for example, with ACKs). Also, for long reads I am missing part
of the read buffer - my guess is that at timeout the read request is
canceled and with it whatever data the device was getting ready to send
to me.
I created a sample script that is successful in communicating with the
device if I use raw IO without timeouts. Unfortunately I can’t use this
since I do not know exactly when I will have data nor the size of the
data received.
I need behavior similar to ReadFile where it will return right away with
whatever is in the buffer at the time I call it, and if it times out
with an empty buffer, it returns 0 bytes, but it doesn’t drop any data
if I cancel the timeout.
Any help or pointers to examples I could read would be very much
appreciated.
I also tried without RAW_IO, but I noticed then that ACKs would not be
received until the device had additional (64 bytes total) data to send.
–
Miguel Sosa