libftdi Archives

Subject: Wrong version of readstream patch sent: patch against HEAD

From: Uwe Bonnes <bon@xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx>
To: libftdi@xxxxxxxxxxxxxxxxxxxxxxx
Date: Thu, 10 Jun 2010 15:54:06 +0200
-- 
Uwe Bonnes                bon@xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

Institut fuer Kernphysik  Schlossgartenstrasse 9  64289 Darmstadt
--------- Tel. 06151 162516 -------- Fax. 06151 164321 ----------
>From 93e8ce69a40b62661cfebaaceec68c461f4e65e2 Mon Sep 17 00:00:00 2001
From: Uwe Bonnes <bon@xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx>
Date: Thu, 10 Jun 2010 15:50:35 +0200
Subject: Correct version of ftdi_readstream agains GIT Head

---
 examples/stream_test.c |   25 ++++----
 src/ftdi_stream.c      |  147 +++++++++++++++++++++++-------------------------
 2 files changed, 82 insertions(+), 90 deletions(-)

diff --git a/examples/stream_test.c b/examples/stream_test.c
index 8d90fc2..2c552e6 100644
--- a/examples/stream_test.c
+++ b/examples/stream_test.c
@@ -65,7 +65,7 @@ usage(const char *argv0)
 
 static uint32_t start = 0;
 static uint32_t offset = 0;
-static uint32_t blocks = 0;
+static uint64_t blocks = 0;
 static uint32_t skips = 0;
 static uint32_t n_err = 0;
 static int
@@ -83,7 +83,7 @@ readCallback(uint8_t *buffer, int length, FTDIProgressInfo 
*progress, void *user
                if (start && (num != start +0x4000))
                {
                    uint32_t delta = ((num-start)/0x4000)-1;
-                   fprintf(stderr, "Skip %7d blocks from 0x%08x to 0x%08x at 
blocks %10d \n",
+                   fprintf(stderr, "Skip %7d blocks from 0x%08x to 0x%08x at 
blocks %10ld \n",
                            delta, start -0x4000, num, blocks);
                    n_err++;
                    skips += delta;
@@ -98,7 +98,7 @@ readCallback(uint8_t *buffer, int length, FTDIProgressInfo 
*progress, void *user
                if (start && (num != start +0x4000))
                {
                    uint32_t delta = ((num-start)/0x4000)-1;
-                   fprintf(stderr, "Skip %7d blocks from 0x%08x to 0x%08x at 
blocks %10d \n",
+                   fprintf(stderr, "Skip %7d blocks from 0x%08x to 0x%08x at 
blocks %10ld \n",
                            delta, start -0x4000, num, blocks);
                    n_err++;
                    skips += delta;
@@ -124,11 +124,12 @@ readCallback(uint8_t *buffer, int length, 
FTDIProgressInfo *progress, void *user
    }
    if (progress)
    {
-       fprintf(stderr, "%10.02fs total time %9.3f MiB captured %7.1f kB/s curr 
rate %7.1f kB/s totalrate \n",
+       fprintf(stderr, "%10.02fs total time %9.3f MiB captured %7.1f kB/s curr 
rate %7.1f kB/s totalrate %d dropouts\n",
                progress->totalTime,
                progress->current.totalBytes / (1024.0 * 1024.0),
                progress->currentRate / 1024.0,
-               progress->totalRate / 1024.0);
+               progress->totalRate / 1024.0,
+               n_err);
    }
    return exitRequested ? 1 : 0;
 }
@@ -192,7 +193,7 @@ int main(int argc, char **argv)
    /* A timeout value of 1 results in may skipped blocks */
    if(ftdi_set_latency_timer(&ftdic, 2))
    {
-       fprintf(stderr,"Can't set latency\n",ftdi_get_error_string(&ftdic));
+       fprintf(stderr,"Can't set latency, Error 
%s\n",ftdi_get_error_string(&ftdic));
        return EXIT_FAILURE;
    }
    
@@ -221,7 +222,7 @@ int main(int argc, char **argv)
    
    if (ftdi_set_bitmode(&ftdic,  0xff, BITMODE_RESET) < 0)
    {
-       fprintf(stderr,"Can't set synchronous fifo 
mode\n",ftdi_get_error_string(&ftdic));
+       fprintf(stderr,"Can't set synchronous fifo mode, Error 
%s\n",ftdi_get_error_string(&ftdic));
        return EXIT_FAILURE;
    }
    ftdi_usb_close(&ftdic);
@@ -238,7 +239,7 @@ int main(int argc, char **argv)
        fclose(outputFile);
    }
    else if (check)
-       fprintf(stderr,"%d errors of %d blocks (%Le), %d (%Le) blocks 
skipped\n",
+       fprintf(stderr,"%d errors of %ld blocks (%Le), %d (%Le) blocks 
skipped\n",
                n_err, blocks, (long double)n_err/(long double) blocks,
                skips, (long double)skips/(long double) blocks);
    exit (0);
@@ -256,7 +257,6 @@ void check_outfile(char *descstring)
        int err_count = 0;
        unsigned int num_start, num_end;
 
-       unsigned int block[4];
        pa = buf0;
        pb = buf1;
        pc = buf0;
@@ -313,7 +313,6 @@ void check_outfile(char *descstring)
         uint32_t *pc = block0;
         uint32_t start= 0;
         uint32_t nread = 0;
-        int expect = 1;
         int n_shown = 0;
         int n_errors = 0;
         if (fread(pa, sizeof(uint32_t), 4,outputFile) < 4)
@@ -329,7 +328,7 @@ void check_outfile(char *descstring)
             {
                 if(n_shown < 30)
                 {
-                    fprintf(stderr, "Skip %7d blocks from 0x%08x to 0x%08x at 
blocks %10d \n",
+                    fprintf(stderr, "Skip %7d blocks from 0x%08x to 0x%08x at 
blocks %10ld \n",
                             (nread-start)/0x4000, start -0x4000, nread, 
blocks);
                     n_shown ++;
                 }
@@ -343,9 +342,9 @@ void check_outfile(char *descstring)
             pc = pa;
         }
         if(n_errors)
-            fprintf(stderr, "%d blocks wrong from %d blocks read\n",
+            fprintf(stderr, "%d blocks wrong from %ld blocks read\n",
                     n_errors, blocks);
         else
-            fprintf(stderr, "%d blocks all fine\n",blocks);
+            fprintf(stderr, "%ld blocks all fine\n",blocks);
     }
 }
diff --git a/src/ftdi_stream.c b/src/ftdi_stream.c
index 3f12ebc..4575f72 100644
--- a/src/ftdi_stream.c
+++ b/src/ftdi_stream.c
@@ -49,66 +49,64 @@ typedef struct
     FTDIStreamCallback *callback;
     void *userdata;
     int packetsize;
+    int activity;
     int result;
     FTDIProgressInfo progress;
 } FTDIStreamState;
 
+/* Handle callbacks
+ * 
+ * With Exit request, free memory and release the transfer
+ *
+ * state->result is only set when some error happens 
+ */
 static void
 ftdi_readstream_cb(struct libusb_transfer *transfer)
 {
    FTDIStreamState *state = transfer->user_data;
    int packet_size = state->packetsize;
 
-   if(transfer->status & LIBUSB_TRANSFER_CANCELLED)
+   state->activity++;
+   if (transfer->status == LIBUSB_TRANSFER_COMPLETED)
    {
-       free(transfer->buffer);
-       libusb_free_transfer(transfer);
-       return;
-   }
-   if (state->result == 0)
-   {
-       if (transfer->status == LIBUSB_TRANSFER_COMPLETED)
+       int i;
+       uint8_t *ptr = transfer->buffer;
+       int length = transfer->actual_length;
+       int numPackets = (length + packet_size - 1) / packet_size;
+       int res;
+       
+       for (i = 0; i < numPackets; i++)
        {
-           int i;
-           uint8_t *ptr = transfer->buffer;
-           int length = transfer->actual_length;
-           int numPackets = (length + packet_size - 1) / packet_size;
-
-           for (i = 0; i < numPackets; i++)
-           {
-               int payloadLen;
-               int packetLen = length;
-
-               if (packetLen > packet_size)
-                   packetLen = packet_size;
-
-               payloadLen = packetLen - 2;
-               state->progress.current.totalBytes += payloadLen;
-
-               state->result = state->callback(ptr + 2, payloadLen,
-                                               NULL, state->userdata);
-               if (state->result)
-                   break;
-
-               ptr += packetLen;
-               length -= packetLen;
-           }
-
-
+           int payloadLen;
+           int packetLen = length;
+           
+           if (packetLen > packet_size)
+               packetLen = packet_size;
+           
+           payloadLen = packetLen - 2;
+           state->progress.current.totalBytes += payloadLen;
+           
+           res = state->callback(ptr + 2, payloadLen,
+                                 NULL, state->userdata);
+
+           ptr += packetLen;
+           length -= packetLen;
+       }
+       if (res)
+       {
+           free(transfer->buffer);
+           libusb_free_transfer(transfer);           
        }
        else
        {
-           fprintf(stderr, "unknown status %d\n",transfer->status); 
-           state->result = LIBUSB_ERROR_IO;
+           transfer->status = -1;
+           state->result = libusb_submit_transfer(transfer);
        }
    }
    else
-       fprintf(stderr,"state->result %d\n", state->result);
-
-   if (state->result == 0)
    {
-       transfer->status = -1;
-       state->result = libusb_submit_transfer(transfer);
+       fprintf(stderr, "unknown status %d\n",transfer->status); 
+       state->result = LIBUSB_ERROR_IO;
    }
 }
 
@@ -126,7 +124,7 @@ TimevalDiff(const struct timeval *a, const struct timeval 
*b)
 
 /**
     Streaming reading of data from the device
-
+    
     Use asynchronous transfers in libusb-1.0 for high-performance
     streaming of data from a device interface back to the PC. This
     function continuously transfers data until either an error occurs
@@ -150,43 +148,43 @@ ftdi_readstream(struct ftdi_context *ftdi,
                       int packetsPerTransfer, int numTransfers)
 {
     struct libusb_transfer **transfers;
-    FTDIStreamState state = { callback, userdata, ftdi->max_packet_size };
+    FTDIStreamState state = { callback, userdata, ftdi->max_packet_size, 1 };
     int bufferSize = packetsPerTransfer * ftdi->max_packet_size;
     int xferIndex;
     int err = 0;
-
+    
     fprintf(stderr, "ftdi_readstream\n");
     /*
      * Set up all transfers
      */
-
+    
     transfers = calloc(numTransfers, sizeof *transfers);
     if (!transfers) {
         err = LIBUSB_ERROR_NO_MEM;
         goto cleanup;
     }
-
+    
     for (xferIndex = 0; xferIndex < numTransfers; xferIndex++)
     {
         struct libusb_transfer *transfer;
-
+        
         transfer = libusb_alloc_transfer(0);
         transfers[xferIndex] = transfer;
         if (!transfer) {
             err = LIBUSB_ERROR_NO_MEM;
             goto cleanup;
         }
-
+        
         libusb_fill_bulk_transfer(transfer, ftdi->usb_dev, ftdi->out_ep,
                                   malloc(bufferSize), bufferSize, 
                                  ftdi_readstream_cb,
                                   &state, 0);
-
+        
         if (!transfer->buffer) {
             err = LIBUSB_ERROR_NO_MEM;
             goto cleanup;
         }
-
+        
         transfer->status = -1;
         err = libusb_submit_transfer(transfer);
         if (err)
@@ -208,22 +206,29 @@ ftdi_readstream(struct ftdi_context *ftdi,
     /*
      * Run the transfers, and periodically assess progress.
      */
-
+    
     gettimeofday(&state.progress.first.time, NULL);
-
+    
     do
     {
         FTDIProgressInfo  *progress = &state.progress;
         const double progressInterval = 1.0;
         struct timeval timeout = { 0, ftdi->usb_read_timeout };
         struct timeval now;
-
+        
         int err = libusb_handle_events_timeout(NULL, &timeout);
+        if (err ==  LIBUSB_ERROR_INTERRUPTED)
+            /* restart interrupted events */
+            err = libusb_handle_events_timeout(NULL, &timeout);  
         if (!state.result)
         {
             state.result = err;
         }
-
+        if (state.activity == 0)
+            state.result = 1;
+        else
+            state.activity = 0;
+        
         // If enough time has elapsed, update the progress
         gettimeofday(&now, NULL);
         if (TimevalDiff(&now, &progress->current.time) >= progressInterval)
@@ -231,49 +236,37 @@ ftdi_readstream(struct ftdi_context *ftdi,
             progress->current.time = now;
             progress->totalTime = TimevalDiff(&progress->current.time,
                                               &progress->first.time);
-
+            
             if (progress->prev.totalBytes)
             {
                 // We have enough information to calculate rates
-
+                
                 double currentTime;
-
+                
                 currentTime = TimevalDiff(&progress->current.time,
                                           &progress->prev.time);
-
+                
                 progress->totalRate = 
                    progress->current.totalBytes /progress->totalTime;
                 progress->currentRate = 
                    (progress->current.totalBytes -
                     progress->prev.totalBytes) / currentTime;
             }
-
-            state.result = state.callback(NULL, 0, progress, state.userdata);
+            
+            state.callback(NULL, 0, progress, state.userdata);
             progress->prev = progress->current;
-
+            
         }
     } while (!state.result);
-
+    
     /*
      * Cancel any outstanding transfers, and free memory.
      */
-
+    
  cleanup:
     fprintf(stderr, "cleanup\n");
-    if (transfers) {
-        int i;
-        for (xferIndex = 0; xferIndex < numTransfers; xferIndex++)
-        {
-            struct libusb_transfer *transfer = transfers[xferIndex];
-
-            if (transfer) {
-                    libusb_cancel_transfer(transfer);
-            }
-        }
-            libusb_handle_events(NULL);
-        free(transfers);
-    }
-
+    if (transfers)
+       free(transfers);
     if (err)
         return err;
     else
-- 
1.6.4.2


--
libftdi - see http://www.intra2net.com/en/developer/libftdi for details.
To unsubscribe send a mail to libftdi+unsubscribe@xxxxxxxxxxxxxxxxxxxxxxx   

Current Thread