libftdi Archives

Subject: FT2232H interface B in FT245 async fifo mode unreliable data transfer termination vs. ftd2xx

From: Dirk Niggemann <dirk.niggemann@xxxxxxxxx>
To: libftdi@xxxxxxxxxxxxxxxxxxxxxxx
Date: Mon, 11 Apr 2016 10:44:32 +0100
Hi,

I'm trying to build a user-mode application for a some hardware without linux 
driver support (Celestron Nightscape 8300 CCD camera). 

The camera uses an FT2232H chip with port A configured in CPU FIFO mode for 
commands and port B configured in FT245 async FIFO mode for image data 
transfers.

I've reverse-engineered the ftd2xx commands used to drive the camera using a 
stub DLL and determined the downloaded raw data format as well. 

I can make the command protocol (16-byte fixed frames at 50ms intervals, with 
17-byte (!) responses) work reliably with both libftd2xx and libftdi 1.2 on 
Linux but the data transfers are proving to be problematic.In libftd2x they're 
about as reliable as they are in the windows application that came with the 
camera (i.e. they work almost all of the time, with an occasional glitch) but 
using libftdi I cannot find a recipe for downloads without data corruption.

The command sequence to initiate an exposure looks something like the following:
1. Send command on port A to specify exposure region in CCD lines (the camera 
can only digitise whole CCD lines at a time), then check returned status.
2. Send command to initiate exposure, specifying duration, and check returned 
status.
3. Send status inquiry commands to the camera until it indicates it has 
completed the exposure and digitised the lines requested.
4. Read raw digitised CCD data from port B until no more data is available.
 
Whenever an exposure completes, the camera first digitises and writes a full 
raw CCD frame into its internal buffer. As soon as this process is completed, 
you need to start reading the raw data over port B. The timing seems to be very 
critical- if you wait more than a few ms after the returned status on the 
command port changes you're apt to miss some of the data and receive a 
corrupted image file. 

However, using libftdi the corruption happens on almost every download- this is 
with libftdi 1.2 running in Ubuntu 14.04 LTS in a Parallels VM on MacOS 10.9.5. 

The corruption takes the following two forms:

1.  The camera transfers arbitrary junk data at the start of the image. You may 
then actually receive some of the requested image data, but it will terminate 
early. This seems to relate to how long you wait before starting to read port B.
2. The image data terminates early. Reads repeatedly return 0 data after an 
arbitrary number of bytes have been transferred, and no more data becomes 
available, even if waiting several seconds.

The image data isn't packetized in any way- it consists of a byte stream 
containing as many 3448-word  16-bit digitized  raw CCD image lines as you 
requested in the exposure command. 
By default, the camera creates a full frame consisting of 2506 * 3448 * 2 
bytes, so each image should be exactly 17,281,376 bytes long. With libftdi i 
get anything from just over 60K to an image that's two bytes short.
 
When using FTDI-provided ftd2xx libraries the data transfers are very stable- 
you occasionally get glitches where the first exposure and read results in a 
short frame but I can't say if this a general bug in the camera firmware or due 
to the fact that my windows test environment is also a 64bit win7 VM running in 
parallels on MacOS 10.9.5. It's perfectly possible the USB redirection is 
introducing some timing instability. I certainly know that using my ftd2xx stub 
dlls results in data reads becoming very unreliable on windows. The logging I/O 
they generate seems to upset the read timing.

The original windows ftd2xx driver reads the data in 63448-byes chunks which 
FTDI claims is the optimal read chunksize. However, I think it should actually 
be 65536 - ((65536 / 64) * 2) i.e. 63488 or possibly even 65536 - ((65536 / 
512) *2), so 65280.
This is based on the fact that I believe the FT2232H  chip sends modem line 
status bytes every 512 bytes rather than every 64 bytes. I'm not sure that the 
ft2232h does this when in ft245 aync fifo mode as well. 

Trying to read 63448-byte chunks doesn't work in libftdi (it works OK  using 
libftd2xx)- The version I have has a hardcoded 16K read buffer chunksize limit. 
Removing this limit stops large reads working altogether as soon as you set the 
read chunksize over 16K.

Adjusting for best read chunksize below 16k seems to help performance a bit, 
but doesn't fix the issue 100%.

I've set SIO_RTS_CTS_HS on port B and followed the advice from elsewhere on the 
'net that suggests that you need to do an ftdi_setrts() for this to actually do 
anything, The original ftd2xx driver also activates RTS/CTS on windows. 
Do you know if flow control is implemented in libftdi for devices that are not 
in UART mode? I know that setting the baud rate, for instance, seems to have  
absolutely no effect on this chip as it's not programmed in UART mode.

Suggestions? I'd really prefer to use libftdi to using libftd2xx as it's 
open-source and more portable. I want to get this working on a pi and 
potentially other single-board ARM systems, as well as natively on the Mac, and 
I don't know ho good FTDIs support for ftd2xx on arbitrary non-windows systems 
is.

Regards,

Dirk









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

Current Thread