EmbeddedRelated.com
Forums
Memfault State of IoT Report

FTDI FTD2xx driver problem with DLP-2232PB device

Started by Kris February 8, 2006
Excuse me for the repeat, but I badly need somebody's help.
So, once again, just to draw attention:

Mark Borgerson wrote:
> If you want any more help, you're going to have to show us what is > going on inside your wrapper functions.
Here are the functions from the Wrapper class: public class Wrapper { private static IntPtr m_USBhandler; [DllImport("FTD2XX.dll", EntryPoint="FT_Open")] public static extern uint FT_Open(int iDevice, ref IntPtr ftHandle); [DllImport("FTD2XX.dll", EntryPoint="FT_Close")] public static extern uint FT_Close(IntPtr ftHandle); [DllImport("FTD2XX.dll", EntryPoint="FT_Read")] public static extern uint FT_Read(IntPtr ftHandle, byte[] lpBuffer, uint dwBytesToRead, ref uint lpdwBytesReturned); [DllImport("FTD2XX.dll", EntryPoint="FT_Write")] public static extern uint FT_Write(IntPtr ftHandle, byte[] lpBuffer, uint dwBytesToWrite, ref uint lpdwBytesWritten); [DllImport("FTD2XX.dll", EntryPoint="FT_Purge")] public static extern uint FT_Purge(IntPtr ftHandle, uint dwMask); public static bool OpenDevice() { if (((FT_Status)Wrapper.FT_Open(1, ref m_USBhandler)) == FT_Status.Ok) { return true; } else { return false; } } public static bool CloseDevice() { if (((FT_Status)Wrapper.FT_Close(m_USBhandler)) == FT_Status.Ok) { return true; } else { return false; } } public static void PurgeAll() { FT_Status opResult; if ((opResult = (FT_Status)Wrapper.FT_Purge(m_USBhandler, (uint)FT_PurgeRXTX.TX & FT_PurgeRXTX.RX))) != FT_Status.Ok) { throw new USBException("Could not purge the buffers.", opResult); } } public static uint CheckQueue() { uint bytesToReceiveNum = 0; FT_Status opResult; if ((opResult = (FT_Status)Wrapper.FT_GetQueueStatus(m_USBhandler, ref bytesToReceiveNum)) != FT_Status.Ok) { throw new USBException("Could not check the USB device queue status.", opResult); } else { return bytesToReceiveNum; } } public static byte[] ReadData(uint bytesToReceiveNum) { uint readBytesNumber = 0; byte[] receivedBytes = new byte[bytesToReceiveNum]; FT_Status opResult; if ((opResult = (FT_Status)Wrapper.FT_Read(m_USBhandler, receivedBytes, bytesToReceiveNum, ref readBytesNumber)) != FT_Status.Ok) { throw new USBException("Could not read data from the USB device.", opResult); } else if (bytesToReceiveNum != readBytesNumber) { throw new USBException("Could not retreive the full data from the USB device.", FT_Status.OtherError); } else { return receivedBytes; } } public static void WriteData(byte[] data) { uint bytesToWriteNum = (uint)data.Length; uint writtenBytesNumber = 0; FT_Status opResult; if ((opResult = (FT_Status)Wrapper.FT_Write(m_USBhandler, data, bytesToWriteNum, ref writtenBytesNumber)) != FT_Status.Ok) { throw new USBException("Could not write the data into the USB device.", opResult); } else if (bytesToWriteNum != writtenBytesNumber) { throw new USBException("Could not write the full data into the USB device.", FT_Status.OtherError); } } } For me, it seems to be ok, but may be there is some problem. Thank you in advance, Kris
In article <1140017316.053269.264040@z14g2000cwz.googlegroups.com>, 
kris.robin@gmail.com says...
> Excuse me for the repeat, but I badly need somebody's help. > So, once again, just to draw attention: > > Mark Borgerson wrote: > > If you want any more help, you're going to have to show us what is > > going on inside your wrapper functions. > > > Here are the functions from the Wrapper class: > > public class Wrapper > { > private static IntPtr m_USBhandler;
<<SNIP CODE>
> > > For me, it seems to be ok, but may be there is some problem. >
It looks like you're doing the same things I do with the FT245, except that I never use the Purge or GetQueueStatus calls. I purge buffers by calling the Read function until there is no data left. I don't use GetQueueStatus, but just read until there is nothing left. in WinXP, I have set up and installed the FTDI driver using their Vendor ID and the product ID for my device. Here is the code to open the device: void __fastcall TFormLink::BTOpenClick(TObject *Sender) { // try to find and open a CF-1 interface char devstring[100]; DWORD numdevs, devindex = 0; if(FTH != 0) { // if already open, close first FT_Close(FTH); FTH = 0; } fts = FT_ListDevices( &numdevs, NULL, FT_LIST_NUMBER_ONLY); if(numdevs >0) fts = FT_Open(0, &FTH); strcpy(devstring, "No CF-1 Interface Found" ); EDDevice->Text = (const char *)devstring; // assume no device if(fts == FT_OK) { // if found change message, open device FT_ResetDevice(FTH); FT_SetTimeouts(FTH, 300,300); EDDevice->Text = "CF-1 USB Interface"; } } The code which traverses a directory list and copies each file from the data logger is this: void __fastcall TFormLink::BTXferClick(TObject *Sender) { char *fullstring, fnstring[15], cmdstring[16]; int i,spos; FILE *fp; static char spbuff[4098]; long bytecount; DWORD numwritten, num2read,numread; AnsiString str; char *fnp; if(FTH == 0) return; // exit if not open // transfer files that are selected for(i= 0; i < LBoxdir->Items->Count; i++){ if(LBoxdir->Selected[i]){ str = LBoxdir->Items->Strings[i]; fullstring = str.c_str(); strcpy(cmdstring, "s"); strncpy(&fnstring[0],fullstring,13); for(spos = 0; spos < 14; spos++){ if (fnstring[spos] == ' ') fnstring[spos] = 0; } // truncate string at trailing spaces strcat(cmdstring,fnstring); strcat(cmdstring, "\n"); // now collect the data from USB port bytecount = 0; num2read = 256; EDCount->Text = 0; EDFolder->Text = TCDO1->Directory+"\\" + / (const char *)fnstring; fnp = EDFolder->Text.c_str(); fp = fopen( fnp, "wb"); // now send the command //and file name to the cf-1 Application->ProcessMessages(); // catch up on windows //message handling FT_Write(FTH,cmdstring, strlen(cmdstring), &numwritten); //send the file name timeout = 50; // sets 5-second timeout to start file while(timeout > 0){ fts = FT_GetQueueStatus(FTH, &num2read); if((fts == FT_OK) && (num2read > 0)){ FT_Read(FTH,&spbuff[0],num2read,&numread); if(numread > 0){ if(fp != NULL) fwrite(&spbuff[0],numread,1, fp); bytecount+= numread; EDCount->Text = bytecount; timeout = 4; // reset timeout counter to 0.4 } } Application->ProcessMessages(); // catch up on windows //message handling } if(fp!= NULL) fclose(fp); } // end of if(selected... } // end of for(i= 0 .... } As you can see, it's pretty simple: Send a command and read the returned data until there is no more (as indicated by the timeout). No need for purges or GetQueueStatus() (Which may not even be valid for the FT245). In your code you use the apparent global variable (or object field) "m_USBhandler" in all your functions. I would suggest that you check that this handle is valid before using it. I'm always suspicious of object handles---especially if the handle is global. This could be even more of a problem in a multi-threaded application where another thread might be using the same handle. if m_USBhandler is an object field, try making it a static global. Can you simply link in the FTDI.sys driver and get the program working with normal C code, rather than using DLLImport and the wrapper functions? (I don't know C# well enough to know if this is possible. My C# system is still in its unopened box--waiting for a lull in the consulting schedule). Mark Borgerson
Kris

 > [DllImport("FTD2XX.dll", EntryPoint="FT_Open")]
 > public static extern uint FT_Open(int iDevice, ref IntPtr ftHandle);

I'm not sure that it makes a difference but in my C# code I used out 
rather than ref.

> public static bool OpenDevice() > { > if (((FT_Status)Wrapper.FT_Open(1, ref m_USBhandler)) == > FT_Status.Ok) > { > return true; > } > else > { > return false; > } > }
Are you certain that there is just the one FTDI device on your system?
> public static void PurgeAll() > { > FT_Status opResult; > > if ((opResult = (FT_Status)Wrapper.FT_Purge(m_USBhandler, > (uint)FT_PurgeRXTX.TX & FT_PurgeRXTX.RX))) > != FT_Status.Ok) > { > throw new USBException("Could not purge the buffers.", > opResult); > } > }
Don't you mean or (|) rather than and (&) here? You won't be purging anything otherwise. Otherwise your functions look pretty reasonable. Andrew
Kris wrote:

> Mark Borgerson wrote: > >>If you want any more help, you're going to have to show us what is >>going on inside your wrapper functions. > > > Here are the functions from the Wrapper class: > > public class Wrapper > { > private static IntPtr m_USBhandler; > > [DllImport("FTD2XX.dll", EntryPoint="FT_Open")] > public static extern uint FT_Open(int iDevice, ref IntPtr ftHandle); >
<snip> I just finished solving a problem where I needed to call a vendor's dll from VB6 and perl. And I was having all sorts of problems. It turned out that the vendor's dll parameter passing used the _cdelc ('C' convention) for passing parameters instead of the _stdcall parameter passing convention. I ended up writing a wrapper dll in VC6 that used the _stdcall parameter passing convention, and this solved all of my problems. Since I'm mainly a hardware/VHDL guy, I've only dabbled in VC6, so it took lots of googling before I was able to make my wrapper dll work. But, I did. If FTDI supplies a C header file, you might be able to tell what parameter passing convention is used. I know that all of the Win32 API dlls, such as kernel32.dll, use the _stdcall convention. It is my understanding that any non-C programs linking to a dll require the _stdcall parameter passing convention. BTW, the difference betweeen the two calling conventions is that when using _cdecl, the calling program cleans up the stack after the call, but with _stdcall, the called (dll) program does the cleanup. Any of you real software guys out there, please feel free to chime in if my info is inaccurate. Urb _______________________________________________________________________________ Posted Via Uncensored-News.Com - Accounts Starting At $6.95 - http://www.uncensored-news.com <><><><><><><> The Worlds Uncensored News Source <><><><><><><><>

Memfault State of IoT Report