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

classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

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

Dirk Niggemann
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 [hidden email]

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

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

Thomas Jarosch
Hi Dirk,

Am 11.04.2016 um 11:44 schrieb Dirk Niggemann:
[snip]
> 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

two things come to mind:

1. You might try to lower the latency timer

2. ftd2xx uses a background thread to constantly poll
   the device for data and it buffers received data in memory.

   Are you constantly polling the device or does your program
   also perform other duties right now?

Cheers,
Thomas


--
libftdi - see http://www.intra2net.com/en/developer/libftdi for details.
To unsubscribe send a mail to [hidden email]  

Loading...