libftdi Archives

Subject: [PATCH] Fixed purge & added purge_test.c; Fixed C++ bit-or's & const.

From: Eric Schott <els6@xxxxxxx>
To: libftdi@xxxxxxxxxxxxxxxxxxxxxxx
Date: Mon, 10 Apr 2017 09:54:15 -0400
The FTDI1 purge functionality with FT4232H was not implementing
behavior equivalent to Linux tcflush(3). Added examples/purge_test
which (when using a loopback connector) tests purge/tcflush for both
Linux and FTDI1 UARTs.  Testing showed the ftdi.h definitions for
SIO_RESET_PURGE_TX and SIO_RESET_PURGE_RX were "swapped" (i.e., the
former flushed the hardware's RX queue and the latter flushed the
hardware TX queue).  After correcting the definitions, the purge
function for the FT4232H works similarly to the behavoir to the Linux
driver for this chip.  While the Linux driver correctly purges the
FT232, neither the pre- or post-fix of the FTDI1 library flushed
correctly for the FT232.

For FTDI1 C++ implementation, corrected a const and changed the purge
(and ModemCtl) definitions to not use an enumeration value of zero for
a bit masks.  For the later, the enumerations were defined so programs
compiled with the old ftdi.hpp include would work as previously (doing
nothing when the enumeration with the zero value was bit-or'ed into
the argument).

The provided patch is at the user's risk.
No licensing of this patch can preclude its use by the governement of
the United States or The Applied Research Laboratory of The
Pennsylvania State University.
---
 examples/CMakeLists.txt                            |   2 +
examples/purge_test.c | 602 +++++++++++++++++++++
 examples/purge_test_results/README.txt             |  14 +
 .../purge_test_results/purge-16550A-115200.lis     |  26 +
 examples/purge_test_results/purge-16550A-1200.lis  |  26 +
 .../purge_test_results/purge-ft232-kernel-1200.lis |  33 ++
 .../purge-ft232-libftdi1-post-fix-1200.lis         |  33 ++
 .../purge-ft232-libftdi1-pre-fix-1200.lis          |  34 ++
 .../purge-ft4232-kernel-115200.lis                 |  31 ++
 .../purge-ft4232-kernel-1200.lis                   |  31 ++
 .../purge-ft4232-libftdi1-post-fix-115200.lis      |  30 +
 .../purge-ft4232-libftdi1-post-fix-1200.lis        |  30 +
 .../purge-ft4232-libftdi1-pre-fix-115200.lis       |  32 ++
 .../purge-ft4232-libftdi1-pre-fix-1200.lis         |  32 ++
 ftdipp/ftdi.cpp                                    |  26 +-
 ftdipp/ftdi.hpp                                    |  12 +-
 src/ftdi.h                                         |   4 +-
 17 files changed, 984 insertions(+), 14 deletions(-)
 create mode 100644 examples/purge_test.c
 create mode 100644 examples/purge_test_results/README.txt
 create mode 100644 examples/purge_test_results/purge-16550A-115200.lis
 create mode 100644 examples/purge_test_results/purge-16550A-1200.lis
 create mode 100644 examples/purge_test_results/purge-ft232-kernel-1200.lis
create mode 100644 examples/purge_test_results/purge-ft232-libftdi1-post-fix-1200.lis create mode 100644 examples/purge_test_results/purge-ft232-libftdi1-pre-fix-1200.lis create mode 100644 examples/purge_test_results/purge-ft4232-kernel-115200.lis create mode 100644 examples/purge_test_results/purge-ft4232-kernel-1200.lis create mode 100644 examples/purge_test_results/purge-ft4232-libftdi1-post-fix-115200.lis create mode 100644 examples/purge_test_results/purge-ft4232-libftdi1-post-fix-1200.lis create mode 100644 examples/purge_test_results/purge-ft4232-libftdi1-pre-fix-115200.lis create mode 100644 examples/purge_test_results/purge-ft4232-libftdi1-pre-fix-1200.lis

diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt
index 1263c62..bf21557 100644
--- a/examples/CMakeLists.txt
+++ b/examples/CMakeLists.txt
@@ -18,6 +18,7 @@ if (EXAMPLES)
     add_executable(serial_test serial_test.c)
     add_executable(baud_test baud_test.c)
     add_executable(stream_test stream_test.c)
+    add_executable(purge_test purge_test.c)
     add_executable(eeprom eeprom.c)

     # Linkage
@@ -30,6 +31,7 @@ if (EXAMPLES)
     target_link_libraries(serial_test ftdi1)
     target_link_libraries(baud_test ftdi1)
     target_link_libraries(stream_test ftdi1)
+    target_link_libraries(purge_test ftdi1)
     target_link_libraries(eeprom ftdi1)

     # libftdi++ examples
diff --git a/examples/purge_test.c b/examples/purge_test.c
new file mode 100644
index 0000000..d2c9001
--- /dev/null
+++ b/examples/purge_test.c
@@ -0,0 +1,602 @@
+/* purge_test.c
+ *
+ * Test for purge TX/RX functions.
+ *
+ * The chip must be wired to loop TX data to RX data (loopback).
+ *
+ * This program works with "standard" linux drivers and the FTDI1 library.
+ *
+ * Usage: purge_test [-b baud] [-i interface] [-n msg-size] [-N note] device-specifier
+ *   See usage below for more information on command usage.
+ *
+ * This program works well with the FT4231H which is newer and has large
+ * FIFOs. This program does not work well with FT232, either pre or post
+ * switching the SIO_RESET_PURGE_TX/SIO_RESET_PURGE_RX values.
+ *
+ * This needs testing with other devices, which I do not have.
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+#include <unistd.h>
+#include <getopt.h>
+#include <signal.h>
+#include <errno.h>
+#include <ftdi.h>
+#include <termios.h>        // For baudcodes & linux UARTs
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+
+static struct ftdi_context *ftdi = NULL;
+static int dev_fd = -1;
+static char * dev_string = NULL;
+static int baud = 9600;
+static int baud_code = -1;
+static enum ftdi_interface interface = INTERFACE_A;
+static int msg_size = 80;
+
+
+static volatile long long usec_test_start;
+
+
+
+static int ascii2int(const char * str, const char * pgm_name);
+static int baud_2_baud_code(int baud);
+static long int char_cnt_2_usec(int char_count);
+static long int drain();
+static int flush(int queue_selector);
+static long long int get_time_usec();
+
+static const int flushQueueSelector[] = {
+    TCIFLUSH, TCOFLUSH, TCIOFLUSH }; /* See /usr/include/bits/termios.h */
+static const char * flushTestName[] = {
+  "Input-only", "Output-only", "Input+Output" };
+static const char * expected[] = {
+    "last half of message",
+    "first half of message",
+    "a handful of mid-message characters",
+};
+
+
+static const char * chip_types[] = {
+    "am",
+    "bm",
+    "2232C",
+    "R",
+    "2232H",
+    "4232H",
+    "232H",
+    "230X",
+};
+
+#ifndef ARRAY_SIZE
+#  define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0]))
+#endif
+
+
+
+/**********************************************************************
+ */
+static void
+usage(const char *argv0)
+{
+   fprintf(stderr,
+           "Usage: %s [options...] device-specifier\n"
+           "Flush test for UARTS.\n"
+       " with loopback connector\n"
+ " [-b baud] baud rate (e.g., 300, 600, 1200, ...230400)\n" + " [-i {a|b|c|d}] FTDI interface for chips which have multiple UARTS\n"
+           "    [-n msg-size]    Number of bytes in test message\n"
+           "    [-N note]        Note for the output\n"
+           "\n"
+ " device-specifier String specifying the UART. If the first character\n" + " is the '/' character, the program assumes a Linux UART\n" + " is to be tested and the string would be something like\n" + " '/dev/ttyS0' or '/dev/ttyUSB0'. Otherwise, the program\n" + " assumes an FTDI device is being tested with the FTDI1\n" + " library. The device-specifier must be a string\n" + " accepted by the ftdi_usb_open_string function. An\n"
+       "                     example would be 'i:0x0403:0x6011[:index]'.\n"
+       "\n"
+ "NOTE: To function correctly, this program requires a loopback connector\n"
+       "      attached to the UART under test.\n"
+           "\n"
+           "Adapted from stream_test.c 2017. Eric Schott <els6@xxxxxxx>\n"
+           "Copyright (C) 2009 Micah Dowty <micah@xxxxxxx>\n"
+ "Adapted for use with libftdi (C) 2010 Uwe Bonnes <bon@xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx>\n",
+           argv0);
+   exit(1);
+}
+
+
+/**********************************************************************
+ */
+int main(int argc, char **argv)
+{
+    int c, i;
+    int option_index;
+    int test;
+    unsigned char * msg;
+    unsigned char * retMsg;
+    char * note = NULL;
+    size_t retMsgSize;
+    long int msg_xmit_time_us;
+    static struct option long_options[] = {{NULL},};
+
+ while ((c = getopt_long(argc, argv, "n:b:i:N:", long_options, &option_index)) !=- 1)
+        switch (c)
+        {
+        case -1:
+            break;
+        case 'b':
+            baud = ascii2int(optarg, argv[0]);
+            break;
+        case 'i':
+            if (optarg == NULL || strlen(optarg) != 1)
+                usage(argv[0]);
+            switch (optarg[0])
+            {
+            case 'a':
+            case 'A':
+                interface = INTERFACE_A;
+                break;
+
+            case 'b':
+            case 'B':
+                interface = INTERFACE_B;
+                break;
+
+            case 'c':
+            case 'C':
+                interface = INTERFACE_C;
+                break;
+
+            case 'd':
+            case 'D':
+                interface = INTERFACE_D;
+                break;
+
+            default:
+                usage(argv[0]);
+            }
+            break;
+        case 'n':
+            msg_size = ascii2int(optarg, argv[0]);
+            if (msg_size < 1)
+            {
+ fprintf(stderr, "msg-size [-n] must be an integer greater than 0\n");
+                usage(argv[0]);
+            }
+            break;
+        case 'N':
+            note = optarg;
+            break;
+        default:
+            usage(argv[0]);
+        }
+
+    if (optind == argc)
+        usage(argv[0]);
+
+    if (optind == argc - 1)
+    {
+        // Exactly one extra argument- a dump file
+        dev_string = argv[optind];
+    }
+    else if (optind < argc)
+    {
+        // Too many extra args
+        usage(argv[0]);
+    }
+
+    baud_code = baud_2_baud_code(baud);
+    if (baud_code < 1)
+    {
+        fprintf(stderr, "Invalid baud [-b]\n");
+        usage(argv[0]);
+    }
+
+    if (dev_string[0] == '/')
+    {
+        struct termios termios;
+        dev_fd = open(dev_string, O_NOCTTY | O_RDWR);
+        if (dev_fd < 0)
+        {
+            fprintf(stderr, "Error opening Linux device \"%s\": %s\n",
+                    dev_string, strerror(errno));
+            return EXIT_FAILURE;
+        }
+
+        if (! isatty(dev_fd))
+        {
+            fprintf(stderr, "Not a TTY device: \"%s\"\n", dev_string);
+            return EXIT_FAILURE;
+        }
+
+        if (tcgetattr(dev_fd, &termios) == -1)
+        {
+ fprintf(stderr, "Error getting TTY attributes for \"%s\": %s\n",
+                    dev_string, strerror(errno));
+            return EXIT_FAILURE;
+        }
+
+        cfmakeraw(&termios);
+
+        termios.c_cflag &=
+            ~(CSTOPB | CRTSCTS);
+
+        termios.c_cflag &= ~CSIZE;
+        termios.c_cflag |= CS8;
+
+        cfsetspeed(&termios, baud_code);
+
+        termios.c_cflag |=
+            CLOCAL;
+
+        termios.c_cc[VMIN] = 1;    // Character at a time input
+        termios.c_cc[VTIME] = 0;    // with blocking
+
+        if (tcsetattr(dev_fd, TCSAFLUSH, &termios) == -1) {
+ fprintf(stderr, "Error setting TTY attributes for \"%s\": %s\n",
+                    dev_string, strerror(errno));
+            return EXIT_FAILURE;
+        }
+    }
+    else
+    {
+
+        if ((ftdi = ftdi_new()) == 0)
+        {
+            fprintf(stderr, "ftdi_new failed\n");
+            return EXIT_FAILURE;
+        }
+
+        if (ftdi_set_interface(ftdi, interface) < 0)
+        {
+            fprintf(stderr, "ftdi_set_interface failed\n");
+            ftdi_free(ftdi);
+            return EXIT_FAILURE;
+        }
+
+        if (ftdi_usb_open_string(ftdi, dev_string) < 0)
+        {
+ fprintf(stderr,"Error opening ftdi device \"%s\": %s\n", dev_string,
+                    ftdi_get_error_string(ftdi));
+            ftdi_free(ftdi);
+            return EXIT_FAILURE;
+        }
+
+ if (ftdi_set_line_property2(ftdi, BITS_8, STOP_BIT_1, NONE, BREAK_OFF) < 0)
+        {
+ fprintf(stderr,"Error setting line properties ftdi device \"%s\": %s\n", dev_string,
+                    ftdi_get_error_string(ftdi));
+            ftdi_free(ftdi);
+            return EXIT_FAILURE;
+        }
+
+        if (ftdi_set_baudrate(ftdi, baud) < 0)
+        {
+ fprintf(stderr,"Error setting baud rate for ftdi device \"%s\": %s\n", dev_string,
+                    ftdi_get_error_string(ftdi));
+            ftdi_free(ftdi);
+            return EXIT_FAILURE;
+        }
+
+        if (ftdi_setflowctrl(ftdi, SIO_DISABLE_FLOW_CTRL))
+        {
+ fprintf(stderr,"Error setting flow control for ftdi device \"%s\": %s\n", dev_string,
+                    ftdi_get_error_string(ftdi));
+            ftdi_free(ftdi);
+            return EXIT_FAILURE;
+        }
+
+    }
+
+    printf("Purge (tcflush) test for device %s\n", dev_string);
+    if (note)
+    {
+        printf("Note: %s\n", note);
+    }
+    if (dev_fd < 0)
+    {
+        if (ftdi->type >0 && ftdi->type < ARRAY_SIZE(chip_types))
+            printf("FTDI chip type is %d (%s)\n",
+                   ftdi->type, chip_types[ftdi->type]);
+        else
+            printf("FTDI chip type is %d (unknown)\n", ftdi->type);
+    }
+
+    printf("# purge_test" );
+    for (c = 1; c < argc; ++c)
+    {
+        const char *p = argv[c];
+        while (*p != '\0')
+        {
+            if (*p == ' ')
+                break;
+            ++p;
+        }
+        if (*p == ' ')
+            printf(" '%s'", argv[c]);
+        else
+            printf(" %s", argv[c]);
+    }
+    printf("\n");
+
+    msg_xmit_time_us = char_cnt_2_usec(msg_size);
+ printf("%d chars at %d baud takes about %.0f ms to transmit\n", msg_size,
+           baud, msg_xmit_time_us * .001);
+
+    msg = malloc(msg_size + 1);
+    if (msg == NULL)
+    {
+        fprintf(stderr, "Could not allocate send message buffer\n");
+        return EXIT_FAILURE;
+    }
+
+    {
+        char dataChar = '0' + ((get_time_usec() / 1000) % 31);
+        char next = 'A';
+        for (i = 0; i < msg_size; ++i) {
+            if (dataChar == '`')
+            {
+                msg[i] = next++;
+                ++dataChar;
+            }
+            else
+                msg[i] = dataChar++;
+
+            if (dataChar > 'z') {
+                dataChar = '`';
+            }
+        }
+        msg[msg_size] = '\0';
+    }
+
+    printf("TX Message is \"%s\"\n", msg);
+
+    retMsgSize = 2 * msg_size;
+    retMsg = malloc(retMsgSize);
+    if (retMsg == NULL)
+    {
+        fprintf(stderr, "Could not allocate received message buffer\n");
+        return EXIT_FAILURE;
+    }
+
+    flush(TCIOFLUSH);
+
+    for (test = 0; test <= 2; ++test)
+    {
+        long long usec_delay;
+        long long usec_to_now;
+        int rc;
+
+        printf("\n********  Test purge %s; expect %s  ********\n"
+           "  --              Flushing UART\n",
+               flushTestName[test], expected[test]);
+        flush(TCIOFLUSH);
+        usleep(msg_xmit_time_us);
+        flush(TCIOFLUSH);
+        usleep(100000);
+
+        usec_test_start = get_time_usec();
+        if (dev_fd >= 0)
+            rc = write(dev_fd, msg, msg_size);
+        else
+            rc = ftdi_write_data(ftdi, msg, msg_size);
+
+        if (rc != msg_size)
+        {
+            fprintf(stderr, "Data write was short: %d: %s\n",
+                    rc, ftdi_get_error_string(ftdi));
+            exit(1);
+        }
+        usec_to_now = get_time_usec() - usec_test_start;
+        usec_delay = msg_xmit_time_us / 2 - usec_to_now;
+        if (usec_delay < 0)
+            usec_delay = 0;
+ printf(" -- %9.1f ms Write completes; delaying to TX midpoint (%.1f ms)\n",
+               usec_to_now * .001, usec_delay * .001);
+        if (usec_delay > 0)
+            usleep(usec_delay);
+
+        printf("  -- %9.1f ms Issuing %s flush (purge)\n",
+               (get_time_usec() - usec_test_start) * .001,
+               flushTestName[test]);
+        flush(flushQueueSelector[test]);
+
+ printf(" -- %9.1f ms Calling drain to wait for transmit to complete\n",
+               (get_time_usec() - usec_test_start) * .001);
+        drain();
+
+        usec_to_now = get_time_usec() - usec_test_start;
+
+        /* If input only flush, check drain time. */
+        if (flushQueueSelector[test] == TCIFLUSH &&
+            usec_to_now < (msg_xmit_time_us * 90ll) / 100ll)
+        {
+            usec_delay = (msg_xmit_time_us * 110ll) / 100ll - usec_to_now;
+ printf(" -- %9.1f ms Drain() completed too early; expected at least %.1f ms\n"
+                   "                  Delaying for %.1f ms\n",
+                   usec_to_now * .001,
+                   ((msg_xmit_time_us * 90ll) / 100ll) * .001,
+                   usec_delay * .001);
+            usleep(usec_delay);
+        }
+        else
+    {
+ printf(" -- %9.1f ms Drain() reports completed; timing OK; delaying for 4 bytes\n",
+                   (get_time_usec() - usec_test_start) * .001);
+            usleep(char_cnt_2_usec(4));
+        }
+
+        printf("  -- %9.1f ms Reading data.\n",
+               (get_time_usec() - usec_test_start) * .001);
+        if (dev_fd >= 0)
+            rc = read(dev_fd, retMsg, retMsgSize);
+        else
+            rc = ftdi_read_data(ftdi, retMsg, retMsgSize - 1);
+
+        usec_to_now = get_time_usec() - usec_test_start;
+        if (rc < 0)
+        {
+            fprintf(stderr, "  -- %9.1f ms Read returned error %s\n",
+                    usec_to_now * .001,
+ (dev_fd >= 0 ? strerror(errno) : ftdi_get_error_string(ftdi)));
+            exit(1);
+        }
+        retMsg[rc] = '\0';
+        printf("  -- %9.1f ms Read returns %d bytes; msg: \"%s\"\n",
+               usec_to_now * .001, rc, retMsg);
+
+        usleep(char_cnt_2_usec(10));
+
+    }
+
+
+    if (dev_fd >= 0)
+    {
+        close(dev_fd);
+    }
+    else
+    {
+        ftdi_usb_close(ftdi);
+        ftdi_free(ftdi);
+    }
+
+    exit (0);
+}
+
+/**********************************************************************
+ */
+static int ascii2int(const char * str, const char * pgm_name)
+{
+    int rc;
+    char * endptr;
+    if (str == NULL || strlen(str) == 0)
+        usage(pgm_name);
+    rc = strtol(str, &endptr, 10);
+    if (endptr == str || *endptr != '\0')
+        usage(pgm_name);
+    return rc;
+}
+
+
+/**********************************************************************
+ */
+static struct Baud_Table {
+    int32_t baud, baud_code;
+} baud_table [] =
+{
+    { 50,     B50     },
+    { 75,     B75     },
+    { 110,    B110    },
+    { 134,    B134    },
+    { 150,    B150    },
+    { 200,    B200    },
+    { 300,    B300    },
+    { 600,    B600    },
+    { 1200,   B1200   },
+    { 1800,   B1800   },
+    { 2400,   B2400   },
+    { 4800,   B4800   },
+    { 9600,   B9600   },
+    { 19200,  B19200  },
+    { 38400,  B38400  },
+    { 57600,  B57600  },
+    { 115200, B115200 },
+    { 230400, B230400 },
+    { -1,     -1,     }
+};
+
+/**********************************************************************
+ */
+static int baud_2_baud_code(int baud)
+{
+    struct Baud_Table *p;
+
+    for (p = baud_table ; p->baud != -1; ++p) {
+        if (p->baud == baud)
+            break;
+    }
+    return p->baud_code;
+}
+
+
+static long int char_cnt_2_usec(int char_count)
+{
+ long long bits = 8 + 1 + 1; /* Number of bits in each character */
+    bits *= (char_count == 0 ? 1 : char_count); /* Total number of bits */
+    bits *= 1000000;                            /* Convert to us */
+ lldiv_t parts = lldiv(bits, baud); /* Number of us for message */
+    return (parts.quot + 1);
+}
+
+
+static long int drain()
+{
+    long int rc = 0;
+    long long start_time = get_time_usec();
+    if (dev_fd >= 0)
+        rc = tcdrain(dev_fd);
+    else
+    {
+        long int sleep_interval = char_cnt_2_usec(10);
+        while (1) {
+            unsigned short modem_status = 0;
+            int rc = ftdi_poll_modem_status(ftdi, &modem_status);
+            if (rc < 0)
+                return -1;
+            if (modem_status & (1 << (6 + 8))) {
+                break;
+            }
+            usleep(sleep_interval);
+        }
+    }
+    if (rc < 0)
+        return rc;
+    usleep(char_cnt_2_usec(2));
+    return get_time_usec() - start_time;
+}
+
+
+static int flush(int queue_selector)
+{
+    int rc;
+    if (dev_fd >= 0)
+        rc = tcflush(dev_fd, queue_selector);
+    else
+    {
+        switch (queue_selector) {
+
+        case TCIOFLUSH:
+            rc = ftdi_usb_purge_buffers(ftdi);
+            break;
+
+        case TCIFLUSH:
+            rc = ftdi_usb_purge_rx_buffer(ftdi);
+            break;
+
+        case TCOFLUSH:
+            rc = ftdi_usb_purge_tx_buffer(ftdi);
+            break;
+
+        default:
+            errno = EINVAL;
+            return -1;
+        }
+    }
+
+    return rc;
+}
+
+
+static long long int get_time_usec()
+{
+    struct timeval tv;
+    gettimeofday(&tv, NULL);
+    return tv.tv_sec * 1000000ll + tv.tv_usec;
+}
diff --git a/examples/purge_test_results/README.txt b/examples/purge_test_results/README.txt
new file mode 100644
index 0000000..8daa99e
--- /dev/null
+++ b/examples/purge_test_results/README.txt
@@ -0,0 +1,14 @@
+This directory contains test output for tests of the purge (tcflush())
+operations.  The 16550 files display the Linux driver default behavior.
+The remaining files display behavior for other tests cases.
+
+The tests run three tests which consist of
+  - Queuing a block of data for TX output
+  - Waiting for 1/2 the transmit time
+  - Issuing one of the three purge (flush) operations
+  - Waiting for the TX hardware queue to empty (drain)
+
+The FTDI1 library purge function for the FT4232H works similarly to
+the behavoir to the Linux driver for this chip.  While the Linux
+driver correctly purges the FT232, neither the pre- or post-fix of the
+FTDI1 library flushed correctly for the FT232.
diff --git a/examples/purge_test_results/purge-16550A-115200.lis b/examples/purge_test_results/purge-16550A-115200.lis
new file mode 100644
index 0000000..3067786
--- /dev/null
+++ b/examples/purge_test_results/purge-16550A-115200.lis
@@ -0,0 +1,26 @@
+Purge (tcflush) test for device /dev/ttyS0
+Note: Standard 16550A UART
+# purge_test -b 115200 -n 100 '-NStandard 16550A UART' /dev/ttyS0
+100 chars at 115200 baud takes about 9 ms to transmit
+TX Message is "KLMNOPQRSTUVWXYZ[\]^_AabcdefghijklmnopqrstuvwxyzBabcdefghijklmnopqrstuvwxyzCabcdefghijklmnopqrstuvwx"
+
+********  Test purge Input-only; expect last half of message ********
+  --       0.0 ms Write completes; delaying to TX midpoint (4.3 ms)
+  --       4.4 ms Issuing Input-only flush (purge)
+  --       4.4 ms Calling drain to wait for transmit to complete
+  --      10.5 ms Output (drain( should be completed; delaying for 4 bytes
+ -- 10.5 ms Read returns 53 bytes; msg: "zBabcdefghijklmnopqrstuvwxyzCabcdefghijklmnopqrstuvwx"
+
+********  Test purge Output-only; expect first half of message ********
+  --       0.0 ms Write completes; delaying to TX midpoint (4.3 ms)
+  --       4.7 ms Issuing Output-only flush (purge)
+  --       4.7 ms Calling drain to wait for transmit to complete
+  --       6.9 ms Output (drain( should be completed; delaying for 4 bytes
+ -- 6.9 ms Read returns 64 bytes; msg: "KLMNOPQRSTUVWXYZ[\]^_AabcdefghijklmnopqrstuvwxyzBabcdefghijklmno"
+
+******** Test purge Input+Output; expect a handful of mid-message characters ********
+  --       0.0 ms Write completes; delaying to TX midpoint (4.3 ms)
+  --       4.4 ms Issuing Input+Output flush (purge)
+  --       4.4 ms Calling drain to wait for transmit to complete
+  --       6.0 ms Output (drain( should be completed; delaying for 4 bytes
+  --       6.0 ms Read returns 16 bytes; msg: "zBabcdefghijklmn"
diff --git a/examples/purge_test_results/purge-16550A-1200.lis b/examples/purge_test_results/purge-16550A-1200.lis
new file mode 100644
index 0000000..79e942f
--- /dev/null
+++ b/examples/purge_test_results/purge-16550A-1200.lis
@@ -0,0 +1,26 @@
+Purge (tcflush) test for device /dev/ttyS0
+Note: Standard 16550A UART
+# purge_test -b 1200 -n 100 '-NStandard 16550A UART' /dev/ttyS0
+100 chars at 1200 baud takes about 833 ms to transmit
+TX Message is "?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_AabcdefghijklmnopqrstuvwxyzBabcdefghijklmnopqrstuvwxyzCabcdefghijkl"
+
+********  Test purge Input-only; expect last half of message ********
+  --       0.0 ms Write completes; delaying to TX midpoint (416.6 ms)
+  --     416.8 ms Issuing Input-only flush (purge)
+  --     416.8 ms Calling drain to wait for transmit to complete
+  --     849.9 ms Output (drain( should be completed; delaying for 4 bytes
+ -- 849.9 ms Read returns 50 bytes; msg: "qrstuvwxyzBabcdefghijklmnopqrstuvwxyzCabcdefghijkl"
+
+********  Test purge Output-only; expect first half of message ********
+  --       0.0 ms Write completes; delaying to TX midpoint (416.6 ms)
+  --     416.7 ms Issuing Output-only flush (purge)
+  --     416.8 ms Calling drain to wait for transmit to complete
+  --     550.6 ms Output (drain( should be completed; delaying for 4 bytes
+ -- 550.6 ms Read returns 64 bytes; msg: "?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_AabcdefghijklmnopqrstuvwxyzBabc"
+
+******** Test purge Input+Output; expect a handful of mid-message characters ********
+  --       0.0 ms Write completes; delaying to TX midpoint (416.6 ms)
+  --     416.7 ms Issuing Input+Output flush (purge)
+  --     416.8 ms Calling drain to wait for transmit to complete
+  --     551.4 ms Output (drain( should be completed; delaying for 4 bytes
+  --     551.5 ms Read returns 14 bytes; msg: "qrstuvwxyzBabc"
diff --git a/examples/purge_test_results/purge-ft232-kernel-1200.lis b/examples/purge_test_results/purge-ft232-kernel-1200.lis
new file mode 100644
index 0000000..5d516fd
--- /dev/null
+++ b/examples/purge_test_results/purge-ft232-kernel-1200.lis
@@ -0,0 +1,33 @@
+Purge (tcflush) test for device /dev/ttyUSB0
+Note: FT232 with Linux drivers
+# purge_test -b 1200 '-NFT232 with Linux drivers' -n 60 /dev/ttyUSB0
+60 chars at 1200 baud takes about 500 ms to transmit
+TX Message is "JKLMNOPQRSTUVWXYZ[\]^_AabcdefghijklmnopqrstuvwxyzBabcdefghij"
+
+********  Test purge Input-only; expect last half of message ********
+  --              Flushing UART
+  --       0.0 ms Write completes; delaying to TX midpoint (250.0 ms)
+  --     250.1 ms Issuing Input-only flush (purge)
+  --     250.1 ms Calling drain to wait for transmit to complete
+  --     275.2 ms Drain() completed too early; expected at least 450.0 ms
+                  Delaying for 274.8 ms
+  --     550.1 ms Reading data.
+ -- 550.1 ms Read returns 32 bytes; msg: "fghijklmnopqrstuvwxyzBabcdefghij"
+
+********  Test purge Output-only; expect first half of message ********
+  --              Flushing UART
+  --       0.0 ms Write completes; delaying to TX midpoint (250.0 ms)
+  --     250.1 ms Issuing Output-only flush (purge)
+  --     250.1 ms Calling drain to wait for transmit to complete
+ -- 274.2 ms Drain() reports completed; timing OK; delaying for 4 bytes
+  --     307.7 ms Reading data.
+ -- 307.7 ms Read returns 35 bytes; msg: "JKLMNOPQRSTUVWXYZ[\]^_Aabcdefghijkl"
+
+******** Test purge Input+Output; expect a handful of mid-message characters ********
+  --              Flushing UART
+  --       0.0 ms Write completes; delaying to TX midpoint (250.0 ms)
+  --     250.1 ms Issuing Input+Output flush (purge)
+  --     250.2 ms Calling drain to wait for transmit to complete
+ -- 274.8 ms Drain() reports completed; timing OK; delaying for 4 bytes
+  --     308.3 ms Reading data.
+  --     308.3 ms Read returns 8 bytes; msg: "efghijkl"
diff --git a/examples/purge_test_results/purge-ft232-libftdi1-post-fix-1200.lis b/examples/purge_test_results/purge-ft232-libftdi1-post-fix-1200.lis
new file mode 100644
index 0000000..a5106b2
--- /dev/null
+++ b/examples/purge_test_results/purge-ft232-libftdi1-post-fix-1200.lis
@@ -0,0 +1,33 @@
+Purge (tcflush) test for device i:0x403:0x6001:1
+Note: FT232 with FTDI1 drivers post-fix
+FTDI chip type is 0 (unknown)
+# purge_test -b 1200 '-NFT232 with FTDI1 drivers post-fix' -n 60 i:0x403:0x6001:1
+60 chars at 1200 baud takes about 500 ms to transmit
+TX Message is "3456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_Aabcdefghijklmn"
+
+********  Test purge Input-only; expect last half of message ********
+  --              Flushing UART
+  --       0.3 ms Write completes; delaying to TX midpoint (249.7 ms)
+  --     250.1 ms Issuing Input-only flush (purge)
+  --     250.3 ms Calling drain to wait for transmit to complete
+ -- 518.1 ms Drain() reports completed; timing OK; delaying for 4 bytes
+  --     551.6 ms Reading data.
+ -- 568.3 ms Read returns 60 bytes; msg: "3456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_Aabcdefghijklmn"
+
+********  Test purge Output-only; expect first half of message ********
+  --              Flushing UART
+  --       0.2 ms Write completes; delaying to TX midpoint (249.8 ms)
+  --     250.1 ms Issuing Output-only flush (purge)
+  --     250.3 ms Calling drain to wait for transmit to complete
+ -- 267.1 ms Drain() reports completed; timing OK; delaying for 4 bytes
+  --     300.6 ms Reading data.
+  --     300.9 ms Read returns 0 bytes; msg: ""
+
+******** Test purge Input+Output; expect a handful of mid-message characters ********
+  --              Flushing UART
+  --       0.2 ms Write completes; delaying to TX midpoint (249.8 ms)
+  --     250.1 ms Issuing Input+Output flush (purge)
+  --     250.7 ms Calling drain to wait for transmit to complete
+ -- 267.6 ms Drain() reports completed; timing OK; delaying for 4 bytes
+  --     301.1 ms Reading data.
+ -- 301.4 ms Read returns 29 bytes; msg: "RSTUVWXYZ[\]^_Aabcdefghijklmn" diff --git a/examples/purge_test_results/purge-ft232-libftdi1-pre-fix-1200.lis b/examples/purge_test_results/purge-ft232-libftdi1-pre-fix-1200.lis
new file mode 100644
index 0000000..921bdb6
--- /dev/null
+++ b/examples/purge_test_results/purge-ft232-libftdi1-pre-fix-1200.lis
@@ -0,0 +1,34 @@
+Purge (tcflush) test for device i:0x403:0x6001:1
+Note: FT232 with FTDI1 drivers pre-fix
+FTDI chip type is 0 (unknown)
+# purge_test -b 1200 '-NFT232 with FTDI1 drivers pre-fix' -n 60 i:0x403:0x6001:1
+60 chars at 1200 baud takes about 500 ms to transmit
+TX Message is "3456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_Aabcdefghijklmn"
+
+********  Test purge Input-only; expect last half of message ********
+  --              Flushing UART
+  --       0.3 ms Write completes; delaying to TX midpoint (249.7 ms)
+  --     250.1 ms Issuing Input-only flush (purge)
+  --     250.3 ms Calling drain to wait for transmit to complete
+  --     267.3 ms Drain() completed too early; expected at least 450.0 ms
+                  Delaying for 282.7 ms
+  --     550.1 ms Reading data.
+  --     550.3 ms Read returns 0 bytes; msg: ""
+
+********  Test purge Output-only; expect first half of message ********
+  --              Flushing UART
+  --       0.2 ms Write completes; delaying to TX midpoint (249.8 ms)
+  --     250.1 ms Issuing Output-only flush (purge)
+  --     250.3 ms Calling drain to wait for transmit to complete
+ -- 267.3 ms Drain() reports completed; timing OK; delaying for 4 bytes
+  --     300.7 ms Reading data.
+ -- 301.0 ms Read returns 29 bytes; msg: "RSTUVWXYZ[\]^_Aabcdefghijklmn"
+
+******** Test purge Input+Output; expect a handful of mid-message characters ********
+  --              Flushing UART
+  --       0.2 ms Write completes; delaying to TX midpoint (249.8 ms)
+  --     250.1 ms Issuing Input+Output flush (purge)
+  --     250.9 ms Calling drain to wait for transmit to complete
+ -- 268.2 ms Drain() reports completed; timing OK; delaying for 4 bytes
+  --     301.7 ms Reading data.
+ -- 315.7 ms Read returns 31 bytes; msg: "3456789:;<=>?@ABCDEFGHIJKLMNOPQ" diff --git a/examples/purge_test_results/purge-ft4232-kernel-115200.lis b/examples/purge_test_results/purge-ft4232-kernel-115200.lis
new file mode 100644
index 0000000..204cb78
--- /dev/null
+++ b/examples/purge_test_results/purge-ft4232-kernel-115200.lis
@@ -0,0 +1,31 @@
+Purge (tcflush) test for device /dev/ttyUSB1
+Note: FT4232-linux-driver
+# purge_test -b 115200 -n 100 -NFT4232-linux-driver /dev/ttyUSB1
+100 chars at 115200 baud takes about 9 ms to transmit
+TX Message is ">?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_AabcdefghijklmnopqrstuvwxyzBabcdefghijklmnopqrstuvwxyzCabcdefghijk"
+
+********  Test purge Input-only; expect last half of message ********
+  --       0.1 ms Write completes; delaying to TX midpoint (4.3 ms)
+  --       4.6 ms Issuing Input-only flush (purge)
+  --       4.7 ms Calling drain to wait for transmit to complete
+  --       5.6 ms Drain() completed too early; expected at least 7.8 ms
+                  Delaying for 3.9 ms
+  --       9.8 ms Output (drain) should be completed; delaying for 4 bytes
+  --      10.3 ms Reading data.
+ -- 10.3 ms Read returns 60 bytes; msg: "fghijklmnopqrstuvwxyzBabcdefghijklmnopqrstuvwxyzCabcdefghijk"
+
+********  Test purge Output-only; expect first half of message ********
+  --       0.0 ms Write completes; delaying to TX midpoint (4.3 ms)
+  --       4.4 ms Issuing Output-only flush (purge)
+  --       4.4 ms Calling drain to wait for transmit to complete
+  --       5.1 ms Output (drain) should be completed; delaying for 4 bytes
+  --       5.5 ms Reading data.
+ -- 5.5 ms Read returns 58 bytes; msg: ">?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_Aabcdefghijklmnopqrstuvw"
+
+******** Test purge Input+Output; expect a handful of mid-message characters ********
+  --       0.0 ms Write completes; delaying to TX midpoint (4.3 ms)
+  --       4.4 ms Issuing Input+Output flush (purge)
+  --       4.4 ms Calling drain to wait for transmit to complete
+  --       5.5 ms Output (drain) should be completed; delaying for 4 bytes
+  --       5.9 ms Reading data.
+  --       5.9 ms Read returns 23 bytes; msg: "fghijklmnopqrstuvwxyzBa"
diff --git a/examples/purge_test_results/purge-ft4232-kernel-1200.lis b/examples/purge_test_results/purge-ft4232-kernel-1200.lis
new file mode 100644
index 0000000..2235df2
--- /dev/null
+++ b/examples/purge_test_results/purge-ft4232-kernel-1200.lis
@@ -0,0 +1,31 @@
+Purge (tcflush) test for device /dev/ttyUSB1
+Note: FT4232-linux-driver
+# purge_test -b 1200 -n 100 -NFT4232-linux-driver /dev/ttyUSB1
+100 chars at 1200 baud takes about 833 ms to transmit
+TX Message is "23456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_AabcdefghijklmnopqrstuvwxyzBabcdefghijklmnopqrstuvwxyz"
+
+********  Test purge Input-only; expect last half of message ********
+  --       0.0 ms Write completes; delaying to TX midpoint (416.6 ms)
+  --     416.7 ms Issuing Input-only flush (purge)
+  --     416.8 ms Calling drain to wait for transmit to complete
+  --     441.2 ms Drain() completed too early; expected at least 750.0 ms
+                  Delaying for 475.5 ms
+  --     916.7 ms Output (drain) should be completed; delaying for 4 bytes
+  --     950.1 ms Reading data.
+ -- 950.2 ms Read returns 51 bytes; msg: "cdefghijklmnopqrstuvwxyzBabcdefghijklmnopqrstuvwxyz"
+
+********  Test purge Output-only; expect first half of message ********
+  --       0.0 ms Write completes; delaying to TX midpoint (416.6 ms)
+  --     416.7 ms Issuing Output-only flush (purge)
+  --     416.8 ms Calling drain to wait for transmit to complete
+  --     441.3 ms Output (drain) should be completed; delaying for 4 bytes
+  --     474.9 ms Reading data.
+ -- 474.9 ms Read returns 56 bytes; msg: "23456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_Aabcdefghi"
+
+******** Test purge Input+Output; expect a handful of mid-message characters ********
+  --       0.0 ms Write completes; delaying to TX midpoint (416.7 ms)
+  --     416.9 ms Issuing Input+Output flush (purge)
+  --     417.0 ms Calling drain to wait for transmit to complete
+  --     442.2 ms Output (drain) should be completed; delaying for 4 bytes
+  --     475.6 ms Reading data.
+  --     475.6 ms Read returns 7 bytes; msg: "NOPQRST"
diff --git a/examples/purge_test_results/purge-ft4232-libftdi1-post-fix-115200.lis b/examples/purge_test_results/purge-ft4232-libftdi1-post-fix-115200.lis
new file mode 100644
index 0000000..6985763
--- /dev/null
+++ b/examples/purge_test_results/purge-ft4232-libftdi1-post-fix-115200.lis
@@ -0,0 +1,30 @@
+Purge (tcflush) test for device i:0x403:0xdaed
+Note: FT4232-libftdi1-post-fix
+FTDI chip type is 5 (4232H)
+# purge_test -b 115200 -n 100 -NFT4232-libftdi1-post-fix -i B i:0x403:0xdaed
+100 chars at 115200 baud takes about 9 ms to transmit
+TX Message is "?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_AabcdefghijklmnopqrstuvwxyzBabcdefghijklmnopqrstuvwxyzCabcdefghijkl"
+
+********  Test purge Input-only; expect last half of message ********
+  --       0.2 ms Write completes; delaying to TX midpoint (4.2 ms)
+  --       4.4 ms Issuing Input-only flush (purge)
+  --       4.5 ms Calling drain to wait for transmit to complete
+  --       9.0 ms Output (drain) should be completed; delaying for 4 bytes
+  --       9.4 ms Reading data.
+ -- 9.8 ms Read returns 51 bytes; msg: "pqrstuvwxyzBabcdefghijklmnopqrstuvwxyzCabcdefghijkl"
+
+********  Test purge Output-only; expect first half of message ********
+  --       0.2 ms Write completes; delaying to TX midpoint (4.1 ms)
+  --       4.4 ms Issuing Output-only flush (purge)
+  --       4.6 ms Calling drain to wait for transmit to complete
+  --       5.1 ms Output (drain) should be completed; delaying for 4 bytes
+  --       5.4 ms Reading data.
+ -- 5.7 ms Read returns 52 bytes; msg: "?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_Aabcdefghijklmnopqr"
+
+******** Test purge Input+Output; expect a handful of mid-message characters ********
+  --       0.2 ms Write completes; delaying to TX midpoint (4.2 ms)
+  --       4.6 ms Issuing Input+Output flush (purge)
+  --       4.9 ms Calling drain to wait for transmit to complete
+  --       5.2 ms Output (drain) should be completed; delaying for 4 bytes
+  --       5.5 ms Reading data.
+  --       6.7 ms Read returns 3 bytes; msg: "tuv"
diff --git a/examples/purge_test_results/purge-ft4232-libftdi1-post-fix-1200.lis b/examples/purge_test_results/purge-ft4232-libftdi1-post-fix-1200.lis
new file mode 100644
index 0000000..406d12d
--- /dev/null
+++ b/examples/purge_test_results/purge-ft4232-libftdi1-post-fix-1200.lis
@@ -0,0 +1,30 @@
+Purge (tcflush) test for device i:0x403:0xdaed
+Note: FT4232-libftdi1-post-fix
+FTDI chip type is 5 (4232H)
+# purge_test -b 1200 -n 100 -NFT4232-libftdi1-post-fix -i B i:0x403:0xdaed
+100 chars at 1200 baud takes about 833 ms to transmit
+TX Message is "MNOPQRSTUVWXYZ[\]^_AabcdefghijklmnopqrstuvwxyzBabcdefghijklmnopqrstuvwxyzCabcdefghijklmnopqrstuvwxyz"
+
+********  Test purge Input-only; expect last half of message ********
+  --       0.4 ms Write completes; delaying to TX midpoint (416.3 ms)
+  --     416.8 ms Issuing Input-only flush (purge)
+  --     417.1 ms Calling drain to wait for transmit to complete
+  --     853.7 ms Output (drain) should be completed; delaying for 4 bytes
+  --     887.2 ms Reading data.
+ -- 887.8 ms Read returns 51 bytes; msg: "cdefghijklmnopqrstuvwxyzCabcdefghijklmnopqrstuvwxyz"
+
+********  Test purge Output-only; expect first half of message ********
+  --       0.5 ms Write completes; delaying to TX midpoint (416.2 ms)
+  --     416.7 ms Issuing Output-only flush (purge)
+  --     417.0 ms Calling drain to wait for transmit to complete
+  --     434.0 ms Output (drain) should be completed; delaying for 4 bytes
+  --     467.4 ms Reading data.
+ -- 467.9 ms Read returns 51 bytes; msg: "MNOPQRSTUVWXYZ[\]^_AabcdefghijklmnopqrstuvwxyzBabcd"
+
+******** Test purge Input+Output; expect a handful of mid-message characters ********
+  --       0.2 ms Write completes; delaying to TX midpoint (416.4 ms)
+  --     416.7 ms Issuing Input+Output flush (purge)
+  --     417.0 ms Calling drain to wait for transmit to complete
+  --     433.8 ms Output (drain) should be completed; delaying for 4 bytes
+  --     467.5 ms Reading data.
+  --     468.5 ms Read returns 2 bytes; msg: "cd"
diff --git a/examples/purge_test_results/purge-ft4232-libftdi1-pre-fix-115200.lis b/examples/purge_test_results/purge-ft4232-libftdi1-pre-fix-115200.lis
new file mode 100644
index 0000000..395c546
--- /dev/null
+++ b/examples/purge_test_results/purge-ft4232-libftdi1-pre-fix-115200.lis
@@ -0,0 +1,32 @@
+Purge (tcflush) test for device i:0x403:0xdaed
+Note: FT4232-libftdi1-pre-fix
+FTDI chip type is 5 (4232H)
+# purge_test -b 115200 -n 100 -NFT4232-libftdi1-pre-fix -i B i:0x403:0xdaed
+100 chars at 115200 baud takes about 9 ms to transmit
+TX Message is "JKLMNOPQRSTUVWXYZ[\]^_AabcdefghijklmnopqrstuvwxyzBabcdefghijklmnopqrstuvwxyzCabcdefghijklmnopqrstuvw"
+
+********  Test purge Input-only; expect last half of message ********
+  --       0.1 ms Write completes; delaying to TX midpoint (4.2 ms)
+  --       4.4 ms Issuing Input-only flush (purge)
+  --       4.5 ms Calling drain to wait for transmit to complete
+  --       4.8 ms Drain() completed too early; expected at least 7.8 ms
+                  Delaying for 4.7 ms
+  --       9.6 ms Output (drain) should be completed; delaying for 4 bytes
+  --      10.0 ms Reading data.
+ -- 10.2 ms Read returns 52 bytes; msg: "JKLMNOPQRSTUVWXYZ[\]^_AabcdefghijklmnopqrstuvwxyzBab"
+
+********  Test purge Output-only; expect first half of message ********
+  --       0.1 ms Write completes; delaying to TX midpoint (4.3 ms)
+  --       4.4 ms Issuing Output-only flush (purge)
+  --       4.6 ms Calling drain to wait for transmit to complete
+  --       8.9 ms Output (drain) should be completed; delaying for 4 bytes
+  --       9.3 ms Reading data.
+ -- 9.6 ms Read returns 50 bytes; msg: "abcdefghijklmnopqrstuvwxyzCabcdefghijklmnopqrstuvw"
+
+******** Test purge Input+Output; expect a handful of mid-message characters ********
+  --       0.2 ms Write completes; delaying to TX midpoint (4.1 ms)
+  --       4.4 ms Issuing Input+Output flush (purge)
+  --       4.7 ms Calling drain to wait for transmit to complete
+  --       5.0 ms Output (drain) should be completed; delaying for 4 bytes
+  --       5.4 ms Reading data.
+  --       5.6 ms Read returns 0 bytes; msg: ""
diff --git a/examples/purge_test_results/purge-ft4232-libftdi1-pre-fix-1200.lis b/examples/purge_test_results/purge-ft4232-libftdi1-pre-fix-1200.lis
new file mode 100644
index 0000000..823f8e6
--- /dev/null
+++ b/examples/purge_test_results/purge-ft4232-libftdi1-pre-fix-1200.lis
@@ -0,0 +1,32 @@
+Purge (tcflush) test for device i:0x403:0xdaed
+Note: FT4232-libftdi1-pre-fix
+FTDI chip type is 5 (4232H)
+# purge_test -b 1200 -n 100 -NFT4232-libftdi1-pre-fix -i B i:0x403:0xdaed
+100 chars at 1200 baud takes about 833 ms to transmit
+TX Message is "KLMNOPQRSTUVWXYZ[\]^_AabcdefghijklmnopqrstuvwxyzBabcdefghijklmnopqrstuvwxyzCabcdefghijklmnopqrstuvwx"
+
+********  Test purge Input-only; expect last half of message ********
+  --       0.2 ms Write completes; delaying to TX midpoint (416.4 ms)
+  --     416.7 ms Issuing Input-only flush (purge)
+  --     416.8 ms Calling drain to wait for transmit to complete
+  --     433.6 ms Drain() completed too early; expected at least 750.0 ms
+                  Delaying for 483.0 ms
+  --     917.0 ms Output (drain) should be completed; delaying for 4 bytes
+  --     950.6 ms Reading data.
+ -- 951.6 ms Read returns 51 bytes; msg: "KLMNOPQRSTUVWXYZ[\]^_AabcdefghijklmnopqrstuvwxyzBab"
+
+********  Test purge Output-only; expect first half of message ********
+  --       0.3 ms Write completes; delaying to TX midpoint (416.4 ms)
+  --     416.7 ms Issuing Output-only flush (purge)
+  --     416.9 ms Calling drain to wait for transmit to complete
+  --     851.5 ms Output (drain) should be completed; delaying for 4 bytes
+  --     884.9 ms Reading data.
+ -- 885.4 ms Read returns 51 bytes; msg: "abcdefghijklmnopqrstuvwxyzCabcdefghijklmnopqrstuvwx"
+
+******** Test purge Input+Output; expect a handful of mid-message characters ********
+  --       0.2 ms Write completes; delaying to TX midpoint (416.5 ms)
+  --     416.7 ms Issuing Input+Output flush (purge)
+  --     417.1 ms Calling drain to wait for transmit to complete
+  --     434.1 ms Output (drain) should be completed; delaying for 4 bytes
+  --     467.5 ms Reading data.
+  --     467.8 ms Read returns 2 bytes; msg: "ab"
diff --git a/ftdipp/ftdi.cpp b/ftdipp/ftdi.cpp
index 92b6e1f..e6bae47 100644
--- a/ftdipp/ftdi.cpp
+++ b/ftdipp/ftdi.cpp
@@ -144,12 +144,26 @@ int Context::reset()

 int Context::flush(int mask)
 {
-    int ret = 1;
+    int ret;

-    if (mask & Input)
-        ret &= ftdi_usb_purge_rx_buffer(d->ftdi);
-    if (mask & Output)
-        ret &= ftdi_usb_purge_tx_buffer(d->ftdi);
+    switch (mask & (Input | Output)) {
+    case Input:
+        ret = ftdi_usb_purge_rx_buffer(d->ftdi);
+        break;
+
+    case Output:
+        ret = ftdi_usb_purge_tx_buffer(d->ftdi);
+        break;
+
+    case Input | Output:
+        ret = ftdi_usb_purge_buffers(d->ftdi);
+        break;
+
+    default:
+        d->ftdi->error_str = "Wrong arguments";
+        ret = -101;
+        break;
+    }

     return ret;
 }
@@ -219,7 +233,7 @@ int Context::read_chunk_size()
     return chunk;
 }

-int Context::write(unsigned char *buf, int size)
+int Context::write(const unsigned char *buf, int size)
 {
     return ftdi_write_data(d->ftdi, buf, size);
 }
diff --git a/ftdipp/ftdi.hpp b/ftdipp/ftdi.hpp
index a438d96..ae6adbc 100644
--- a/ftdipp/ftdi.hpp
+++ b/ftdipp/ftdi.hpp
@@ -55,16 +55,16 @@ public:
      */
     enum Direction
     {
-        Input,
-        Output
+        Input = 0x2,
+        Output = 0x1,
     };

     /*! \brief Modem control flags.
      */
     enum ModemCtl
     {
-        Dtr,
-        Rts
+        Dtr = 0x2,
+        Rts = 0x1,
     };

     /* Constructor, Destructor */
@@ -100,7 +100,7 @@ public:

     /* I/O */
     int read(unsigned char *buf, int size);
-    int write(unsigned char *buf, int size);
+    int write(const unsigned char *buf, int size);
     int set_read_chunk_size(unsigned int chunksize);
     int set_write_chunk_size(unsigned int chunksize);
     int read_chunk_size();
@@ -108,7 +108,7 @@ public:

     /* Async IO
     TODO: should wrap?
-    int writeAsync(unsigned char *buf, int size);
+    int writeAsync(const unsigned char *buf, int size);
     void asyncComplete(int wait_for_more);
     */

diff --git a/src/ftdi.h b/src/ftdi.h
index bb66c53..acc1869 100644
--- a/src/ftdi.h
+++ b/src/ftdi.h
@@ -173,8 +173,8 @@ enum ftdi_module_detach_mode


 #define SIO_RESET_SIO 0
-#define SIO_RESET_PURGE_RX 1
-#define SIO_RESET_PURGE_TX 2
+#define SIO_RESET_PURGE_TX 1
+#define SIO_RESET_PURGE_RX 2

 #define SIO_DISABLE_FLOW_CTRL 0x0
 #define SIO_RTS_CTS_HS (0x1 << 8)
--
2.1.4



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