From: Shawn Hoffman <godisgovernm...@gmail.com> --- CMakeLists.txt | 2 + examples/stream_test.c | 14 +++--- src/ftdi.h | 35 ++++---------- src/ftdi_stream.c | 106 +++++++++++++++++++++++++++-------------- 4 files changed, 89 insertions(+), 68 deletions(-)
diff --git a/CMakeLists.txt b/CMakeLists.txt index b495f6d..7c236ff 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,6 +4,8 @@ message(STATUS "CMake version: ${CMAKE_VERSION}") # Project project(libftdi1 C) +set(C_STANDARD 11) +set(C_STANDARD_REQUIRED TRUE) set(MAJOR_VERSION 1) set(MINOR_VERSION 5) set(PACKAGE libftdi1) diff --git a/examples/stream_test.c b/examples/stream_test.c index 10e0977..0f01589 100644 --- a/examples/stream_test.c +++ b/examples/stream_test.c @@ -69,7 +69,7 @@ static uint64_t blocks = 0; static uint32_t skips = 0; static uint32_t n_err = 0; static int -readCallback(uint8_t *buffer, int length, FTDIProgressInfo *progress, void *userdata) +readCallback(uint8_t *buffer, int length, struct ftdi_stream_progress *progress, void *userdata) { if (length) { @@ -124,11 +124,11 @@ 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 %d dropouts\n", - progress->totalTime, - progress->current.totalBytes / (1024.0 * 1024.0), - progress->currentRate / 1024.0, - progress->totalRate / 1024.0, + fprintf(stderr, "%10.02fs total time %9.3f MiB captured %7.1f kB/s curr rate %7.1f kB/s total_rate %d dropouts\n", + ftdi_stream_total_time(progress), + ftdi_stream_total_bytes(progress) / (1024.0 * 1024.0), + ftdi_stream_current_rate(progress) / 1024.0, + ftdi_stream_total_rate(progress) / 1024.0, n_err); } return exitRequested ? 1 : 0; @@ -214,7 +214,7 @@ int main(int argc, char **argv) outputFile = of; signal(SIGINT, sigintHandler); - err = ftdi_readstream(ftdi, readCallback, NULL, 8, 256); + err = ftdi_stream_read(ftdi, readCallback, NULL, 8, 256); if (err < 0 && !exitRequested) exit(1); diff --git a/src/ftdi.h b/src/ftdi.h index 186cf9e..a1b4912 100644 --- a/src/ftdi.h +++ b/src/ftdi.h @@ -19,9 +19,6 @@ #define __libftdi_h__ #include <stdint.h> -#ifndef _WIN32 -#include <sys/time.h> -#endif /* Define _FTDI_DISABLE_DEPRECATED to disable deprecated messages. */ #ifdef _FTDI_DISABLE_DEPRECATED @@ -421,27 +418,10 @@ enum ftdi_cbusx_func #define HIGH_CURRENT_DRIVE 0x10 #define HIGH_CURRENT_DRIVE_R 0x04 -/** - \brief Progress Info for streaming read -*/ -struct size_and_time -{ - uint64_t totalBytes; - struct timeval time; -}; - -typedef struct -{ - struct size_and_time first; - struct size_and_time prev; - struct size_and_time current; - double totalTime; - double totalRate; - double currentRate; -} FTDIProgressInfo; +struct ftdi_stream_progress; -typedef int (FTDIStreamCallback)(uint8_t *buffer, int length, - FTDIProgressInfo *progress, void *userdata); +typedef int (ftdi_stream_callback)(uint8_t *buffer, int length, + struct ftdi_stream_progress *progress, void *userdata); /** * Provide libftdi version information @@ -527,8 +507,13 @@ extern "C" int ftdi_write_data_set_chunksize(struct ftdi_context *ftdi, unsigned int chunksize); int ftdi_write_data_get_chunksize(struct ftdi_context *ftdi, unsigned int *chunksize); - int ftdi_readstream(struct ftdi_context *ftdi, FTDIStreamCallback *callback, - void *userdata, int packetsPerTransfer, int numTransfers); + int ftdi_stream_read(struct ftdi_context *ftdi, ftdi_stream_callback *callback, + void *userdata, int packets_per_transfer, int num_transfers); + uint64_t ftdi_stream_total_bytes(struct ftdi_stream_progress *progress); + double ftdi_stream_total_time(struct ftdi_stream_progress *progress); + double ftdi_stream_total_rate(struct ftdi_stream_progress *progress); + double ftdi_stream_current_rate(struct ftdi_stream_progress *progress); + struct ftdi_transfer_control *ftdi_write_data_submit(struct ftdi_context *ftdi, unsigned char *buf, int size); struct ftdi_transfer_control *ftdi_read_data_submit(struct ftdi_context *ftdi, unsigned char *buf, int size); diff --git a/src/ftdi_stream.c b/src/ftdi_stream.c index d146afd..0e80664 100644 --- a/src/ftdi_stream.c +++ b/src/ftdi_stream.c @@ -42,21 +42,35 @@ #include <stdlib.h> #include <stdio.h> -#ifndef _WIN32 -#include <sys/time.h> -#endif +#include <time.h> #include <libusb.h> #include "ftdi.h" +struct size_and_time +{ + uint64_t total_bytes; + struct timespec time; +}; + +struct ftdi_stream_progress +{ + struct size_and_time first; + struct size_and_time prev; + struct size_and_time current; + double total_time; + double total_rate; + double current_rate; +}; + typedef struct { - FTDIStreamCallback *callback; + ftdi_stream_callback *callback; void *userdata; int packetsize; int activity; int result; - FTDIProgressInfo progress; + struct ftdi_stream_progress progress; } FTDIStreamState; /* Handle callbacks @@ -66,7 +80,7 @@ typedef struct * state->result is only set when some error happens */ static void LIBUSB_CALL -ftdi_readstream_cb(struct libusb_transfer *transfer) +ftdi_stream_read_cb(struct libusb_transfer *transfer) { FTDIStreamState *state = transfer->user_data; int packet_size = state->packetsize; @@ -89,7 +103,7 @@ ftdi_readstream_cb(struct libusb_transfer *transfer) packetLen = packet_size; payloadLen = packetLen - 2; - state->progress.current.totalBytes += payloadLen; + state->progress.current.total_bytes += payloadLen; res = state->callback(ptr + 2, payloadLen, NULL, state->userdata); @@ -116,15 +130,16 @@ ftdi_readstream_cb(struct libusb_transfer *transfer) } /** - Helper function to calculate (unix) time differences + Helper function to calculate time differences \param a timeval \param b timeval + \return (a - b) as double */ static double -TimevalDiff(const struct timeval *a, const struct timeval *b) +timespec_diff(const struct timespec *a, const struct timespec *b) { - return (a->tv_sec - b->tv_sec) + 1e-6 * (a->tv_usec - b->tv_usec); + return (a->tv_sec - b->tv_sec) + 1e-9 * (a->tv_nsec - b->tv_nsec); } /** @@ -142,19 +157,18 @@ TimevalDiff(const struct timeval *a, const struct timeval *b) \param ftdi pointer to ftdi_context \param callback to user supplied function for one block of data \param userdata - \param packetsPerTransfer number of packets per transfer - \param numTransfers Number of transfers per callback + \param packets_per_transfer number of packets per transfer + \param num_transfers Number of transfers per callback */ - int -ftdi_readstream(struct ftdi_context *ftdi, - FTDIStreamCallback *callback, void *userdata, - int packetsPerTransfer, int numTransfers) +ftdi_stream_read(struct ftdi_context *ftdi, + ftdi_stream_callback *callback, void *userdata, + int packets_per_transfer, int num_transfers) { struct libusb_transfer **transfers; FTDIStreamState state = { callback, userdata, ftdi->max_packet_size, 1 }; - int bufferSize = packetsPerTransfer * ftdi->max_packet_size; + int bufferSize = packets_per_transfer * ftdi->max_packet_size; int xferIndex; int err = 0; @@ -183,14 +197,14 @@ ftdi_readstream(struct ftdi_context *ftdi, * Set up all transfers */ - transfers = calloc(numTransfers, sizeof *transfers); + transfers = calloc(num_transfers, sizeof *transfers); if (!transfers) { err = LIBUSB_ERROR_NO_MEM; goto cleanup; } - for (xferIndex = 0; xferIndex < numTransfers; xferIndex++) + for (xferIndex = 0; xferIndex < num_transfers; xferIndex++) { struct libusb_transfer *transfer; @@ -204,7 +218,7 @@ ftdi_readstream(struct ftdi_context *ftdi, libusb_fill_bulk_transfer(transfer, ftdi->usb_dev, ftdi->out_ep, malloc(bufferSize), bufferSize, - ftdi_readstream_cb, + ftdi_stream_read_cb, &state, 0); if (!transfer->buffer) @@ -224,7 +238,7 @@ ftdi_readstream(struct ftdi_context *ftdi, * fetching data for several to several ten milliseconds * and we skip blocks */ - if (ftdi_set_bitmode(ftdi, 0xff, BITMODE_SYNCFF) < 0) + if (ftdi_set_bitmode(ftdi, 0xff, BITMODE_SYNCFF) < 0) { fprintf(stderr,"Can't set synchronous fifo mode: %s\n", ftdi_get_error_string(ftdi)); @@ -235,15 +249,16 @@ ftdi_readstream(struct ftdi_context *ftdi, * Run the transfers, and periodically assess progress. */ - gettimeofday(&state.progress.first.time, NULL); + timespec_get(&state.progress.first.time, TIME_UTC); do { - FTDIProgressInfo *progress = &state.progress; + struct ftdi_stream_progress *progress = &state.progress; + // 1 second const double progressInterval = 1.0; struct timeval timeout = { ftdi->usb_read_timeout / 1000, (ftdi->usb_read_timeout % 1000) * 1000 }; - struct timeval now; + struct timespec now; int xfer_err = libusb_handle_events_timeout(ftdi->usb_ctx, &timeout); if (xfer_err == LIBUSB_ERROR_INTERRUPTED) @@ -259,27 +274,27 @@ ftdi_readstream(struct ftdi_context *ftdi, state.activity = 0; // If enough time has elapsed, update the progress - gettimeofday(&now, NULL); - if (TimevalDiff(&now, &progress->current.time) >= progressInterval) + timespec_get(&now, TIME_UTC); + if (timespec_diff(&now, &progress->current.time) >= progressInterval) { progress->current.time = now; - progress->totalTime = TimevalDiff(&progress->current.time, - &progress->first.time); + progress->total_time = timespec_diff(&progress->current.time, + &progress->first.time); - if (progress->prev.totalBytes) + if (progress->prev.total_bytes) { // We have enough information to calculate rates double currentTime; - currentTime = TimevalDiff(&progress->current.time, - &progress->prev.time); + currentTime = timespec_diff(&progress->current.time, + &progress->prev.time); - progress->totalRate = - progress->current.totalBytes /progress->totalTime; - progress->currentRate = - (progress->current.totalBytes - - progress->prev.totalBytes) / currentTime; + progress->total_rate = + progress->current.total_bytes / progress->total_time; + progress->current_rate = + (progress->current.total_bytes - + progress->prev.total_bytes) / currentTime; } state.callback(NULL, 0, progress, state.userdata); @@ -302,3 +317,22 @@ cleanup: return state.result; } +uint64_t ftdi_stream_total_bytes(struct ftdi_stream_progress *progress) +{ + return progress->current.total_bytes; +} + +double ftdi_stream_total_time(struct ftdi_stream_progress *progress) +{ + return progress->total_time; +} + +double ftdi_stream_total_rate(struct ftdi_stream_progress *progress) +{ + return progress->total_rate; +} + +double ftdi_stream_current_rate(struct ftdi_stream_progress *progress) +{ + return progress->current_rate; +} -- 2.44.0.windows.1 -- libftdi - see http://www.intra2net.com/en/developer/libftdi for details. To unsubscribe send a mail to libftdi+unsubscr...@developer.intra2net.com