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);
 

Reply via email to