Posts: 41
Threads: 9
Joined: Jan 2016
I'm just wondering if this is an issue with the FTDI API. If I use
Code: FT_GetQueueStatus(ftHandle, lpdwAmountInRxQueue)
it seems to max out at 65,536. However, if I bypass this and use
Code: FT_Read(ftHandle, lpBuffer, dwBytesToRead, ldpwBytesReturned)
and set dwBytesToRead to 512*1024 then it is possible for lpdwBytesReturned to be higher than 65,536.
Kind regards,
Francis
Posts: 2,853
Threads: 148
Joined: Nov 2013
I have never used the command to get the queue status, but it is possible that it only returns the amount in the queue (which could be full).
I would use the FT_Read (that's what I use).
Are you doing this in PureBasic? If so, how are you opening the FTDXXXX.dll? I downloaded PureBasic and I am interested in writing some sample code for SCP so that it can be used under Windows, Mac, and Linux.
Posts: 41
Threads: 9
Joined: Jan 2016
(01-27-2016, 04:30 PM)admin Wrote: Yes, you get as many bytes sent as requested.
I looked at PureBasic, and it looks to be a bit slow from the serial port side at the max baud rate of 115,200 if you are not using hardware handshaking (which the FTDI driver supports). If you are using the USB COM port without handshaking, you probably need a baud rate of 500,000 or more. The buffer on the FTDI chip is 4K, but the buffer in the COM port is 64K.
I am not sure how you can open a .dll with PureBasic, but if that is possible you could use the transfer routines in the FTDXXX.dll instead of opening a COM port.
I'm using the USB COM port, and I am using the FTDXXX.dll. Baud rate is not an issue as I can let the program wait until the Rx buffer is full and then receive the data. It just seems to max out at 64k, which fits in with what you say.
Kind regards,
Francis
Posts: 2,853
Threads: 148
Joined: Nov 2013
Are you actually opening a COM port? If you use the .dll you don't open a COM port, you just call the FT_Read and FT_Write to transfer data.
Posts: 2,853
Threads: 148
Joined: Nov 2013
Here is the code I used in Visual Basic for opening and closing the FTDI device, using the .dll:
Code: Public Sub OpenFTDI()
strDescription = "SuperCard Pro" + Chr$(0) ' null terminated name string
ftStatus = FT_OpenEx(strDescription, FT_OPEN_BY_DESCRIPTION, lngHandle) ' open device with specified name and store handle
If ftStatus = FT_OK Then
HasSCP = True
If FT_SetTimeouts(lngHandle, 100, 0) <> FT_OK Then GoTo BadFTDI ' set timeout to 100ms
ftStatus = FT_SetLatencyTimer(lngHandle, 2) ' set lowest latency possible
If ftStatus <> FT_OK Then GoTo BadFTDI
ftStatus = FT_SetUSBParameters(lngHandle, &H10000, &H10000) ' set USB receive/transmit buffer to 64K * 2
If ftStatus <> FT_OK Then GoTo BadFTDI
End If
Exit Sub
BadFTDI:
Call CloseFTDI
End Sub
' This routine closes the FTDI device driver, if it was opened.
Public Sub CloseFTDI()
If lngHandle <> 0 Then FT_Close (lngHandle) ' close device if open
HasSCP = False ' no SuperCard Pro
lngHandle = 0 ' release handle
End Sub
Posts: 41
Threads: 9
Joined: Jan 2016
(01-27-2016, 04:35 PM)admin Wrote: I have never used the command to get the queue status, but it is possible that it only returns the amount in the queue (which could be full).
I would use the FT_Read (that's what I use).
Are you doing this in PureBasic? If so, how are you opening the FTDXXXX.dll? I downloaded PureBasic and I am interested in writing some sample code for SCP so that it can be used under Windows, Mac, and Linux.
First you need to open the dll:
Code: hndFTDLL = OpenLibrary(#PB_Any, GetFolderPath(#CSIDL_SYSTEM) + "\ftd2xx.dll")
if hndFTDLL = 0
; Error loading 'ftd2xx.dll'
End
EndIf
You can then call the functions using something like:
Code: CallFunction(hndFTDLL, "FT_Read", ftHandle, @Buffer, BytesToRead, @BytesReturned)
All this is explained in more detail in the online PureBasic manual.
If I remember right, the demo version of PureBasic is quite restrictive in what you can do with it, so the above may not work if it is just the demo version you have.
Kind regards,
Francis
Posts: 41
Threads: 9
Joined: Jan 2016
(01-27-2016, 04:41 PM)admin Wrote: Are you actually opening a COM port? If you use the .dll you don't open a COM port, you just call the FT_Read and FT_Write to transfer data.
No I am not having to explicitly open a COM port. I'm just initialising the FTD2XX library and calling the functions such as FT_Read().
Kind regards,
Francis
Posts: 41
Threads: 9
Joined: Jan 2016
(01-27-2016, 04:44 PM)admin Wrote: Here is the code I used in Visual Basic for opening and closing the FTDI device, using the .dll:
Thanks! That's useful to know.
Kind regards,
Francis
Posts: 2,853
Threads: 148
Joined: Nov 2013
It's not optional to call FT_Open. It's best to use FT_OpenEx though, using the proper name. Otherwise, it's possible that you could be opening another FTDI device if one is present!
Thanks for the info on how to open the .dll. I got the full version because it is necessary for using .dll's.
Posts: 2,853
Threads: 148
Joined: Nov 2013
This should help you with the transfers. This is code I use for reading and writing data to the USB port:
Code: ' This routine gets data from the SCP USB port and stores "ReadLength" number of bytes starting
' at RawBuffer(RawOffset).
'
' RawBuffer = BYTE buffer
' RawOffset = LONG offset into buffer
' ReadLength = length of data to transfer
'
' lngTotalBytesRead > actual number of bytes transferred
' ftStatus > completion status
Public Sub GetFIFOData()
flTimedout = False ' clear timeout
flFatalError = False ' clear fatal error
lngTotalBytesRead = 0 ' clear total number of bytes
Do
lngBytesRead = 0 ' reset number of bytes read so far
ftStatus = FT_Read_Bytes(lngHandle, RawBuffer(RawOffset), ReadLength, lngBytesRead) ' get bytes from USB port
If (ftStatus = FT_OK) Or (ftStatus = FT_IO_ERROR) Then ' if return status is good or there is a FTDI I/O error
If lngBytesRead > 0 Then ' then check to see if length so far is > 0 and if so
lngTotalBytesRead = lngTotalBytesRead + lngBytesRead ' add length so far to total
Else
ftStatus = FT_ERROR ' otherwise, set return code to error
flTimedout = True ' and set timeout error
End If
Else
ftStatus = FT_ERROR ' if length so far is 0, then set return code to error
flFatalError = True ' and set fatal error
End If
Loop Until (lngTotalBytesRead = ReadLength) Or (flTimedout = True) Or (flFatalError = True) ' loop until all bytes read, timeout, or fatal error occurs
End Sub
' This routine sends "WriteLength" number of bytes to the SCP USB port starting at RawBuffer(RawOffset).
'
' RawBuffer = BYTE buffer
' RawOffset = LONG offset into buffer
' WriteLength = length of data to transfer
'
' lngTotalBytesWritten > actual number of bytes transferred
' ftStatus > completion status
Public Sub PutFIFOData()
ftStatus = FT_Write_Bytes(lngHandle, RawBuffer(RawOffset), WriteLength, lngBytesWritten)
End Sub
Note: Visual Basic treats memory as an array. So, RawBuffer(RawOffset) is the same thing as RawBuffer+RawOffset if you were dealing with memory directly.
|