libftdi Archives

Subject: Help debug dropped transfers in FT232H sync fifo application

From: "rick.walker@xxxxxxxxxxx" <rick.walker@xxxxxxxxxxx>
To: "libftdi@xxxxxxxxxxxxxxxxxxxxxxx" <libftdi@xxxxxxxxxxxxxxxxxxxxxxx>
Cc: "tom_knotts@xxxxxxxxxxx" <tom_knotts@xxxxxxxxxxx>, "rick.walker@xxxxxxxxxxx" <rick.walker@xxxxxxxxxxx>
Date: Fri, 5 Feb 2021 21:31:46 +0000
 
Dear libftdi users and developers,
 
I am using an FT232H in synchronous FIFO mode for a scientific instrument control system and am having occasional skipped transfers.Here is a summary of how I use libftdi in hope that you may suggest a way to solve my problem.
 
Here is an abstract of my initialization code:
 
    #define CHUNKSIZE 4096
    unsigned char buf2ft[CHUNKSIZE];
    struct ftdi_context ftdic;
 
    assert(ftdi_init(&ftdic) >= 0);
    retval=ftdi_usb_open_desc(&ftdic, 0x0403, 0x6014, NULL, NULL);
    assert(ftdi_set_latency_timer(&ftdic, 2) == 0);
    assert(ftdi_read_data_set_chunksize(&ftdic, CHUNKSIZE) >= 0);
    assert(ftdi_write_data_set_chunksize(&ftdic, CHUNKSIZE) >= 0);
    assert(ftdi_set_bitmode(&ftdic, 0xff, BITMODE_SYNCFF) >= 0);
    assert(ftdi_usb_purge_buffers(&ftdic) == 0);
 
From this point on I have two threads.  The first is the RX thread which sits in a tight loop calling ftdi_read_data().  I have seen no problems with this code:
 
    void *rxthread(void *ptr)
    {
        int ret;
        int i;
 
        unsigned char buffromft[MAXSIZE];
        while (!exitRequested) {
            ret = 0;                // check for partial read
            while (ret == 0) {
               ret = ftdi_read_data(&ftdic, buffromft, MAXSIZE);
            }
 
            // launch tokens into the processing pipeline
            for (i = 0; i < ret; i++) {
                parse(buffromft[i]);
            }
        }
        return ((void *) NULL);
    }
 
The other thread is the TX thread.  My code accumulates user tokens in an array for transmission.  When a token is written to the first element of the array, I start a 250us callback signal.  If the array is filled, or if the 250us signal fires then I call ftdi_write_data() to transfer the array.  This strategy gives me low latency for sporadic transfers while still allowing the system to burst to high data rates when needed.
 
The core portion is the write code:
 
    if ((ret = ftdi_write_data(&ftdic, buf2ft, ftindex)) < 0) {
        fprintf(stderr, "bad write: %d\n", ret);
    } else if (ret != ftindex) {
        fprintf(stderr, "partial write: %d < %d\n", ret, ftindex);
    }
 
    // debugging to see what was transferred to libftdi
    printf("ftdi write: ");
        for (i = 0; i < ftindex; i++) {
            printf("%02x ", buf2ft[i]);
        }
    printf("\n");
 
Most of the time, my transfers consist of occasional small blocks of only 11 or 15 bytes. In all cases, I see the ftdi_write_data() accepting the data and returns the proper byte count transferred. 
 
To the best of my understanding, the data is properly accepted by the libftdi library for transmission.
 
On our target FPGA, we take the output of the FT232 FIFO Verilog block and echo the data bytes to another  FIFO and then to a 480Kb/s serial port for debugging.  This gives us a way to see what actually is received by the target FPGA.
 
What we observe is that a few percent of the transfers for the smaller packet sizes (~11 bytes) get lost.  I see them go into libftdi, but they don't get delivered to the hardware interface of the FT232H chip.
 
There could be some problem with our Verilog reading the FT232 fifo port, but I can't think of any problems that would result in an entire transfer being deleted.
 
Alternatively, I might not be using the libftdi interface properly or there might be a bug in the library.
 
Thank you if you've read this message so far, and I would be very happy for any suggestions that might help solve this bug.
 
kind regards,
--
Rick Walker
 

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

Current Thread