The behaviour of the ftdi_read_data function is not so well defined
(IMO, no offense intended). It loops calling usb_bulk_read(), collects
all the data, until the requested number of bytes have been transfered;
but it also returns when the usb_bulk_read() call didn't return any
data.
For my application, I would prefer the behaviour of the original FTDI
d2xx dll: the read() call returns when either the requested number of
bytes have been transferred or when the read-timeout has expired.
Here is a patch which implements a ftdi_read_data_timeout() function
that also has this behaviour. The patch only works on Windows since
it GetTickCount() api call.
Is it worth to consider this extension for the official repository?
Thanks,
Thomas
--
libftdi - see http://www.intra2net.com/en/developer/libftdi for details.
To unsubscribe send a mail to [email protected]
Index: ftdi.c
===================================================================
--- ftdi.c (revision 50283)
+++ ftdi.c (working copy)
@@ -1537,8 +1537,31 @@
*/
int ftdi_read_data(struct ftdi_context *ftdi, unsigned char *buf, int size)
{
+ return ftdi_read_data_timeout(ftdi, buf, size, 0);
+}
+
+/**
+ Reads data in chunks (see ftdi_read_data_set_chunksize()) from the chip.
+
+ Returns when the supplied buffer is full or when the timeout has expired.
+ Automatically strips the two modem status bytes transfered during every
read.
+
+ \param ftdi pointer to ftdi_context
+ \param buf Buffer to store data in
+ \param size Size of the buffer
+ \param timeout Timeout value in milliseconds
+
+ \retval -666: USB device unavailable
+ \retval <0: error code from usb_bulk_read()
+ \retval 0: no data was available
+ \retval >0: number of bytes read
+
+*/
+int ftdi_read_data_timeout(struct ftdi_context *ftdi, unsigned char *buf, int
size, int timeout)
+{
int offset = 0, ret = 1, i, num_of_chunks, chunk_remains;
int packet_size;
+ DWORD started = GetTickCount();
if (ftdi == NULL || ftdi->usb_dev == NULL)
ftdi_error_return(-666, "USB device unavailable");
@@ -1572,6 +1595,8 @@
// do the actual USB read
while (offset < size && ret > 0)
{
+ if ((timeout > 0) && (GetTickCount() - started > timeout))
+ return offset;
ftdi->readbuffer_remaining = 0;
ftdi->readbuffer_offset = 0;
/* returns how much received */
@@ -1610,7 +1635,9 @@
else if (ret <= 2)
{
// no more data to read?
- return offset;
+ if (timeout > 0)
+ continue;
+ return offset;
}
if (ret > 0)
{
Index: ftdi.h
===================================================================
--- ftdi.h (revision 50283)
+++ ftdi.h (working copy)
@@ -400,6 +400,7 @@
enum ftdi_break_type break_type);
int ftdi_read_data(struct ftdi_context *ftdi, unsigned char *buf, int
size);
+ int ftdi_read_data_timeout(struct ftdi_context *ftdi, unsigned char *buf,
int size, int timeout);
int ftdi_read_data_set_chunksize(struct ftdi_context *ftdi, unsigned int
chunksize);
int ftdi_read_data_get_chunksize(struct ftdi_context *ftdi, unsigned int
*chunksize);