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