Add SPDX identifiers to the core library and ftdi_eeprom tool
[libftdi] / src / ftdi_stream.c
index cf3acf5..f5f1287 100644 (file)
@@ -3,8 +3,9 @@
                              -------------------
     copyright            : (C) 2009 Micah Dowty 2010 Uwe Bonnes
     email                : opensource@intra2net.com
+    SPDX-License-Identifier: (LGPL-2.1-only AND MIT)
  ***************************************************************************/
+
 /***************************************************************************
  *                                                                         *
  *   This program is free software; you can redistribute it and/or modify  *
@@ -13,7 +14,7 @@
  *                                                                         *
  ***************************************************************************/
 
-/* Adapted from 
+/* Adapted from
  * fastftdi.c - A minimal FTDI FT232H interface for which supports bit-bang
  *              mode, but focuses on very high-performance support for
  *              synchronous FIFO mode. Requires libusb-1.0
@@ -41,6 +42,9 @@
 
 #include <stdlib.h>
 #include <stdio.h>
+#ifndef _WIN32
+#include <sys/time.h>
+#endif
 #include <libusb.h>
 
 #include "ftdi.h"
@@ -56,59 +60,59 @@ typedef struct
 } FTDIStreamState;
 
 /* Handle callbacks
- * 
+ *
  * With Exit request, free memory and release the transfer
  *
- * state->result is only set when some error happens 
+ * state->result is only set when some error happens
  */
-static void
+static void LIBUSB_CALL
 ftdi_readstream_cb(struct libusb_transfer *transfer)
 {
-   FTDIStreamState *state = transfer->user_data;
-   int packet_size = state->packetsize;
-
-   state->activity++;
-   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 = 0;
-
-       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;
-           
-           res = state->callback(ptr + 2, payloadLen,
-                                 NULL, state->userdata);
-
-           ptr += packetLen;
-           length -= packetLen;
-       }
-       if (res)
-       {
-           free(transfer->buffer);
-           libusb_free_transfer(transfer);           
-       }
-       else
-       {
-           transfer->status = -1;
-           state->result = libusb_submit_transfer(transfer);
-       }
-   }
-   else
-   {
-       fprintf(stderr, "unknown status %d\n",transfer->status); 
-       state->result = LIBUSB_ERROR_IO;
-   }
+    FTDIStreamState *state = transfer->user_data;
+    int packet_size = state->packetsize;
+
+    state->activity++;
+    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 = 0;
+
+        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;
+
+            res = state->callback(ptr + 2, payloadLen,
+                                  NULL, state->userdata);
+
+            ptr += packetLen;
+            length -= packetLen;
+        }
+        if (res)
+        {
+            free(transfer->buffer);
+            libusb_free_transfer(transfer);
+        }
+        else
+        {
+            transfer->status = -1;
+            state->result = libusb_submit_transfer(transfer);
+        }
+    }
+    else
+    {
+        fprintf(stderr, "unknown status %d\n",transfer->status);
+        state->result = LIBUSB_ERROR_IO;
+    }
 }
 
 /**
@@ -120,12 +124,12 @@ ftdi_readstream_cb(struct libusb_transfer *transfer)
 static double
 TimevalDiff(const struct timeval *a, const struct timeval *b)
 {
-   return (a->tv_sec - b->tv_sec) + 1e-6 * (a->tv_usec - b->tv_usec);
+    return (a->tv_sec - b->tv_sec) + 1e-6 * (a->tv_usec - b->tv_usec);
 }
 
 /**
     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
@@ -145,8 +149,8 @@ TimevalDiff(const struct timeval *a, const struct timeval *b)
 
 int
 ftdi_readstream(struct ftdi_context *ftdi,
-                      FTDIStreamCallback *callback, void *userdata,
-                      int packetsPerTransfer, int numTransfers)
+                FTDIStreamCallback *callback, void *userdata,
+                int packetsPerTransfer, int numTransfers)
 {
     struct libusb_transfer **transfers;
     FTDIStreamState state = { callback, userdata, ftdi->max_packet_size, 1 };
@@ -160,52 +164,55 @@ ftdi_readstream(struct ftdi_context *ftdi,
         fprintf(stderr,"Device doesn't support synchronous FIFO mode\n");
         return 1;
     }
-    
+
     /* We don't know in what state we are, switch to reset*/
     if (ftdi_set_bitmode(ftdi,  0xff, BITMODE_RESET) < 0)
     {
         fprintf(stderr,"Can't reset mode\n");
         return 1;
     }
-    
+
     /* Purge anything remaining in the buffers*/
-    if (ftdi_usb_purge_buffers(ftdi) < 0)
+    if (ftdi_tcioflush(ftdi) < 0)
     {
-        fprintf(stderr,"Can't Purge\n");
+        fprintf(stderr,"Can't flush FIFOs & buffers\n");
         return 1;
     }
 
     /*
      * Set up all transfers
      */
-    
+
     transfers = calloc(numTransfers, sizeof *transfers);
-    if (!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) {
+        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,
+                                  malloc(bufferSize), bufferSize,
+                                  ftdi_readstream_cb,
                                   &state, 0);
-        
-        if (!transfer->buffer) {
+
+        if (!transfer->buffer)
+        {
             err = LIBUSB_ERROR_NO_MEM;
             goto cleanup;
         }
-        
+
         transfer->status = -1;
         err = libusb_submit_transfer(transfer);
         if (err)
@@ -213,8 +220,8 @@ ftdi_readstream(struct ftdi_context *ftdi,
     }
 
     /* Start the transfers only when everything has been set up.
-     * Otherwise the transfers start stuttering and the PC not 
-     * fetching data for several to several ten milliseconds 
+     * Otherwise the transfers start stuttering and the PC not
+     * fetching data for several to several ten milliseconds
      * and we skip blocks
      */
     if (ftdi_set_bitmode(ftdi,  0xff, BITMODE_SYNCFF) < 0)
@@ -227,20 +234,20 @@ 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 timeout = { 0, ftdi->usb_read_timeout * 1000};
         struct timeval now;
-        
+
         int err = libusb_handle_events_timeout(ftdi->usb_ctx, &timeout);
         if (err ==  LIBUSB_ERROR_INTERRUPTED)
             /* restart interrupted events */
-            err = libusb_handle_events_timeout(ftdi->usb_ctx, &timeout);  
+            err = libusb_handle_events_timeout(ftdi->usb_ctx, &timeout);
         if (!state.result)
         {
             state.result = err;
@@ -249,7 +256,7 @@ ftdi_readstream(struct ftdi_context *ftdi,
             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)
@@ -257,37 +264,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;
+
+                progress->totalRate =
+                    progress->current.totalBytes /progress->totalTime;
+                progress->currentRate =
+                    (progress->current.totalBytes -
+                     progress->prev.totalBytes) / currentTime;
             }
-            
+
             state.callback(NULL, 0, progress, state.userdata);
             progress->prev = progress->current;
-            
+
         }
     } while (!state.result);
-    
+
     /*
      * Cancel any outstanding transfers, and free memory.
      */
-    
- cleanup:
+
+cleanup:
     fprintf(stderr, "cleanup\n");
     if (transfers)
-       free(transfers);
+        free(transfers);
     if (err)
         return err;
     else