Slow data rate FT245BM to PC

Aug 25, 2005 5 Replies

I am working on a PIC project that uses an FT245BM to transfer data to the PC over USB. I am transferring about 3MB of data and want to do it as fast as possible. However, my current solution is way too slow. Maybe someone can point out what I am doing wrong.



Let me start off by saying that I know VB isn't a speed demon, but I don't think it is the bottle neck here. I am running this on a P4



3.2Ghz machine, so even VB is quick.

Here are the symptoms of my problem. The 245's TXE seems to go high (signaling that the internal buffer is full) for "long" periods of time even though I am doing FT_Reads as fast as possible on the PC. I've run into issues like this before using the FTDI chips, but was able to solve them by tweaking the timeouts, latency timer, and buffer sizes. However, this time, tweaking the settings just seem to slow things down even more.



Here are the basic init commands I am using (note this is not runnable code)



FT_OpenEx("Device Name", FT_OPEN_BY_DESCRIPTION, lngHandle) FT_SetTimeouts(lngHandle, 500, 0) FT_SetLatencyTimer(lngHandle, 1) FT_SetChars(lngHandle, 126, 1, 0, 0) FT_SetUSBParameters(lngHandle, 16384, 0) FT_Purge(lngHandle, 3)


Here is the code I use to poll the device:



--------------------------------------------------------------------- Do lngBytesRead = 0 queue_length = 0 ftStatus = FT_GetQueueStatus(lngHandle, queue_length) If queue_length > 32000 Then queue_length = 32000 End If ftStatus = FT_Read(lngHandle, strReadBuffer, queue_length, lngBytesRead)



If (ftStatus = FT_OK) Or (ftStatus = FT_IO_ERROR) Then If lngBytesRead > 0 Then bigarray() = StrConv(strReadBuffer, vbFromUnicode) ReDim Preserve bigarray(lngBytesRead) CopyMem imgarray(data_buffer_pointer), bigarray(0),UBound(bigarray) data_buffer_pointer = UBound(bigarray) + data_buffer_pointer lngTotalBytesRead = lngTotalBytesRead + lngBytesRead Else



End If Else flFatalError = True End If DoEvents Loop Until (lngTotalBytesRead >= 3145728) Or (cancel_but = True) Or (flFatalError = True)



---------------------------------------------------------------------



The code functions well, it is just a bit slow. It can take up to 30 seconds to transfer 3 megs. I tried not using the FT_GetQueueStatus and just used a fixed number for the FT_Read. This seemed to be less efficient.



Any suggestions would be helpful. Thanks!



Zach



Using one of FTDI's examples, I recoded this using VC++ 6.0. It was a little faster, but still nowhere close to the rated speed. Here is the main loop I used to empty the receive buffer (I know it does not store the data yet):

while(t

Did you try to remove the DoEvents?

Yes, I tried removing the DoEvents. Still nowhere near the rated speed.

Your rash assumption about USB on VB is wrong.

The generic driver used in Windows _is_ the basic bottleneck.

I am not a PC driver programmer. So I can not address the problems there.

How slow exactly _is_ "way too"? Try to give some hard numbers. Ahh... now I see you did, at the far end of your post:

Well, let's see: that means you got at least 100 kByte/s, or .8 Mbit/s of payload throughput. That's only one order of magnitude below the baud rate. What USB transfer mode are you using?

You should also try to relate them with the bandwidth of the interface between your PIC and the FT245BM, and the speed of the PIC itself.

It may feel quick, but that doesn't mean it actually is. You're trying to talk to a low-level driver here --- there could be all kinds of internal delays involved, not the least the context switching time between your application and the kernel's USB layer.

How long is "long"?

Hans-Bernhard Broeker (broeker@physik.rwth-aachen.de) Even if all the snow were burnt, ashes would remain.

Join the Discussion

Have something to add? Share your thoughts — no account required.

Didn't find your answer?

Ask the community — no account required