libftdi Archives

Subject: Re: Help debug dropped transfers in FT232H sync fifo application

From: Ed Jubenville <ejubenville@xxxxxxxxxx>
To: "libftdi@xxxxxxxxxxxxxxxxxxxxxxx" <libftdi@xxxxxxxxxxxxxxxxxxxxxxx>
Cc: "rick.walker@xxxxxxxxxxx" <rick.walker@xxxxxxxxxxx>
Date: Sat, 6 Feb 2021 00:12:34 +0000
At one time, libftdi was not thread-safe.  If that is still so, it could mean a lot of things, including indeterminate behaviors when accessed from separate threads.  That's a general statement about non-thread-safe libraries.  So yes, calling ftdi_read_data from one thread and ftdi_write_data from another thread would not be supported.  But that is easily fixed.  If it were me, I'd create wrapper functions for ftdi_read_data and ftdi_write_data, and have the wrappers lock a shared semaphore or critical section during their execution.  That way, your two threads would block each other from making concurrent calls into the library.  It is quick to try, and worth a shot, in my opinion.  The intermittent symptoms you've described could easily be attributable to undesirable thread interactions in the library, not by anything in the chip itself.


From: rick.walker@xxxxxxxxxxx <rick.walker@xxxxxxxxxxx>
Sent: Friday, February 5, 2021 1:49 PM
To: libftdi@xxxxxxxxxxxxxxxxxxxxxxx <libftdi@xxxxxxxxxxxxxxxxxxxxxxx>
Cc: rick.walker@xxxxxxxxxxx <rick.walker@xxxxxxxxxxx>
Subject: RE: Help debug dropped transfers in FT232H sync fifo application
 

Hi Ed,

 

Are you saying it is not supported to have ftdi_read_data() running at the same time in an independent thread from ftdi_write_data()?  After the initial setup, these are the only two functions that are called.

 

--

Rick

 

From: Ed Jubenville <ejubenville@xxxxxxxxxx>
Sent: Friday, February 5, 2021 1:42 PM
To: libftdi@xxxxxxxxxxxxxxxxxxxxxxx
Subject: Re: Help debug dropped transfers in FT232H sync fifo application

 

External Sender - Use caution opening files, clicking links, or responding to requests.

 

IIRC, libftdi is not designed to be thread-safe.  You might want to consider having your multiple threads use a semaphore, critical section, or whatever to provide thread safety outside of the library.

 

 


From: rick.walker@xxxxxxxxxxx <rick.walker@xxxxxxxxxxx>
Sent: Friday, February 5, 2021 1:31 PM
To: libftdi@xxxxxxxxxxxxxxxxxxxxxxx <libftdi@xxxxxxxxxxxxxxxxxxxxxxx>
Cc: tom_knotts@xxxxxxxxxxx <tom_knotts@xxxxxxxxxxx>; rick.walker@xxxxxxxxxxx <rick.walker@xxxxxxxxxxx>
Subject: Help debug dropped transfers in FT232H sync fifo application

 

 

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

 


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

 



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




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


Current Thread