Holgi's USB-Seite mit FTDI Chips


Letzte Änderung: 15.04.2003

Für erste Experimente mit eigenen USB-Schaltungen habe ich mir ein paar FT232BM und FT245BM von FTDI besorgt. Warum ausgerechnet diese ? Erstens sind sie einzeln leicht zu bekommen (z.B. bei Segor für 9,80 Euro) und zweitens gibt es bei FTDI fertige Treiber zur Installation unter W98 bis XP dazu. Treiber für W95 gibt es nicht.

Erste wichtige Hinweise: Wer mehrere FTDI Chips am USB Bus betreiben oder den BitBang Mode benutzen will sollte auf KEINEN Fall zuerst den VCP Treiber installieren. Ein EEPROM muß unbedingt eingesetzt werden. Sonst funktioniert z.B. der BitBang-Mode nicht. Alles was ich hier zum D2XX Treiber schreibe bezieht sich auf D2XX10401.zip. Es gibt bereits einen neueren. Habe ich noch nicht probiert.

FT232BM Testboard
FT245BM Testboard
Der erste Versuch: Ein einzelner FT232BM
Der zweite Versuch: Einen FT245BM zusätzlich anschließen
D2XX Direct Treiber und VCP Treiber gleichzeitig benutzen
USBTest1 sucht alle Boards für die der D2XX Treiber installiert wurde und zeigt Info's dazu an. Source für Visual C++ 5.
USB-LCD HD44780 kompatibles LCD-Textdisplay mit 2x40 Zeichen am FT245BM Testboard. BitBang-Mode. Source für Visual C++ 5.
BitBang Mode ein paar Zeitmessungen
FIFO Mode ein paar Zeitmessungen

USB AVR/ATMega Programmer für das FT245BM Testboard. Dazu braucht man eine einfache Zusatzplatine und dieses Programm. Ein schönes Beispiel was einen beim BitBang Mode so erwartet. Ziemlich langsam das ganze.

So sehen die beiden Testboards aus die ich hier benutze. Ich habe im Layout SMD und konventionelle Bauteile wild durcheinandergemischt. Was die Bastelkiste gerade so hergab ;)


FT232BM Testboard

FT232BM BoardFT232BM Board unten

FT232BM Testboard Schaltplan (auch als GIF) und Board Eagle3.5
Mit diesem Board kann man einen einfachen USB zu RS232 Konverter bauen. Ich habe keine vollständige RS232 Schnittstelle für z.B. ein Modem vorgesehen. Nur einen MAX232 für RxD und TxD sowie optional RTS / CTS Handshaking zur Ankopplung an Microcontroller.  Wenn man den MAX232 wegläßt kann an der Stiftleiste eine komplette RS232 Schnittstelle angeschlossen werden. Bei FTDI gibt es eine Applicationnote dazu.



FT245BM Testboard

FT245BM obenFT245BM unten

FT245BM Testboard Schaltplan (auch als GIF) und Board Eagle 3.5
Auf dieser Platine befinden sich ein FT245BM sowie EEPROM und Minimalbeschaltung. Zielschaltungen werden einfach an der 16pol Stiftleiste angeschlossen. Ich habe einen 3,3V Regler vorgesehen um VCCIO vom FT245BM eventuell mit 3,3V versorgen zu können. Dann arbeiten die Daten- und Handshakeleitungen mit 3,3V Pegel. Wer den nicht braucht kann ihn einfach weglassen.



Der erste Versuch: Ein einzelner FT232BM
Zunächst ging alles problemloser als ich dachte. Meine Schaltung aufgebaut, angeschlossen und den VCP Treiber installiert (der erste Fehler wie sich später herausstellte :(. Der VCP Treiber fügt problemlos einen virtuellen COM5 Port hinzu. Als Testschaltung habe ich mein serielles Thermometer mit PIC drangehängt. Funktioniert auf Anhieb. Dann das Monster Display für Winamp. Geht auch. Ich bin begeistert.



Der zweite Versuch: Einen FT245BM zusätzlich anschließen
Damit fingen die Probleme an. Das Thermometer funktioniert nicht mehr und Win hängt sich auf. Wieso ? Ohne programmiertes EEPROM haben beide Chips die gleiche VID und PID. Der Treiber kann sie nicht auseinanderhalten. Man muß zumindest eine eigene PID oder Seriennummer ins EEPROM einprogrammieren damit mehrere FT2xx Chips am USB Bus arbeiten können. Dazu braucht man das EEPROM- Programmiertool FTD2XXST von der FTDI Homepage. FTD2XXST benötigt den D2XX Direct Treiber. Mit VCP Treiber erkennt FTD2XXST keine FTDI Chips. Bei vorher installiertem VCP Treiber läßt sich der D2XX Direct Treiber aber nicht installieren. Also erstmal den VCP Treiber deinstallieren. Installation von D2XX geht immer noch nicht. Problem: Das Uninstallprogramm entfernt nicht alles. Das ganze endete in einer Odyssee durch Registry-Einträge und Windows System Verzeichnisse. Vorsichtig alles löschen was FTDI enthält.

Hat man alles entfernt kann man den D2XX Direct Treiber installieren. Das programmieren einer neuen PID oder Serienummer in das EEPROM klappt dann ohne Probleme. Ganz heißer Tip: Wenn man mit FTD2XXST rumspielt sollte man nur die Schaltung die man programmieren will am USB Bus anschließen. Alle bereits programmierten Schaltungen die den D2XX Direct Treiber benutzen sollte man vorsichtshalber abziehen. Ich habs schon geschafft die falsche Schaltung mit FTDI Chip zu programmieren.

Ist das EEPROM programmiert, muß man die Schaltung erstmal abziehen und in den entsprechenden INF Dateien ein Device mit der neuen PID eintragen. Siehe hier. PID und Seriennummer schreibt man für später am besten auf die Schaltung. Über die Seriennummer kann man seine Schaltung später eindeutig identifizieren. Danach stöpselt man die Schaltung wieder an und läßt von Win den Treiber (D2XX oder VCP) installieren.



D2XX Direct Treiber und VCP Treiber gleichzeitig benutzen

Wie kann ich einen FT232BM als COM-Port mit dem VCP Treiber und einen FT245BM mit dem D2XX Direct Treiber benutzen, wo die beiden Treiber sich gegenseitig zu stören scheinen ? Die Lösung zu dem Problem ist auf meinem Mist gewachsen und wird von FTDI nicht empfohlen. Falls es damit Probleme bei dir gibt bitte auf keinen Fall  FTDI damit nerven. Diese Lösung ist äußerst experimentell und funktioniert bei mir unter W98SE. Wie z.B. XP darauf reagiert und ob dies auch bei neueren Versionen der Treiber klappt weiß ich nicht.

Ich gehe hier davon aus das weder D2XX noch VCP Treiber installiert wurden. Zuerst muß man beim VCP Treiber in ftdibus.inf und ftdiport.inf alle Einträge mit VID 0403 und PID 6001 vor der Installation des VCP Treibers auskommentieren und nur in der ftd2xx.inf vom D2XX Direct Treiber aktiv lassen. Zuerst installiert man den D2XX Direct Treiber. Dann den VCP Treiber. Stehen VID 0403 und PID 6001 nur in der ftd2xx.inf kann man mit dem D2XX Direct Treiber und FTD2XXST neuen Schaltungen mit unprogrammiertem EEPROM erstmal eine andere PID verpassen. Danach trägt man die neuen Werte in die entsprechenden INF-Dateien ein und kann die Schaltung installieren. Dabei ist es wichtig das ein Eintrag entweder in der ftd2xx.inf oder in ftdibus.inf+ftdiport.inf vorkommt. Auf keinen Fall in allen drei INF-Dateien. Unten ein Beispiel für zwei FT232BM als COM-Ports mit VCP Treiber und zwei FT245BM über den D2XX Treiber. Bei den FT232BM habe ich PID's von 6100 und 6101 einprogrammiert, bei den FT245BM PID's von 6200 und 6201. Einträge in der INF Datei die nicht benutzt werden sollen entweder löschen oder besser mit einem Semikolon am Anfang der Zeile auskommentieren. Vieleicht braucht man sie ja noch mal.



Beispieleinträge für den D2XX Direct Treiber in ftd2xx.inf

[FtdiHw]
%USB\VID_0403&PID_6001.DeviceDesc%=FTD2XX, USB\VID_0403&PID_6001
%USB\VID_0403&PID_6200.DeviceDesc%=FTD2XX, USB\VID_0403&PID_6200
%USB\VID_0403&PID_6201.DeviceDesc%=FTD2XX, USB\VID_0403&PID_6201

[Strings]
USB\VID_0403&PID_6001.DeviceDesc="FTDI FT8U2XX Device"
USB\VID_0403&PID_6200.DeviceDesc="FTDI FT245BM HS Fifo 6200"
USB\VID_0403&PID_6201.DeviceDesc="FTDI FT245BM HS Fifo 6201"

"FTDI FT245BM HS Fifo 6201" zum Beispiel ist der Name der nachher im Gerätemanager unter USB für das Gerät auftaucht. Der DeviceDescriptor im EEPROM darf auch anders lauten.



Beim VCP Treiber muß man ftdibus.inf und ftdiport.inf ändern:

ftdibus.inf Beispiel

[FtdiHw]
%USB\VID_0403&PID_8372.DeviceDesc%=FtdiBus,USB\VID_0403&PID_8372
%USB\VID_0403&PID_6100.DeviceDesc%=FtdiBus,USB\VID_0403&PID_6100
%USB\VID_0403&PID_6101.DeviceDesc%=FtdiBus,USB\VID_0403&PID_6101

[ControlFlags]
ExcludeFromSelect=USB\VID_0403&PID_8372

[Strings]
USB\VID_0403&PID_8372.DeviceDesc="USB Serial Converter"
USB\VID_0403&PID_6100.DeviceDesc="FTDI FT232BM HS Serial Converter 6100"
USB\VID_0403&PID_6101.DeviceDesc="FTDI FT232BM HS Serial Converter 6101"



ftdiport.inf Beispiel

[FtdiHw]
%VID_0403&PID_8372.DeviceDesc%=FtdiPort,FTDIBUS\COMPORT&VID_0403&PID_8372
%VID_0403&PID_6100.DeviceDesc%=FtdiPort232,FTDIBUS\COMPORT&VID_0403&PID_6100
%VID_0403&PID_6101.DeviceDesc%=FtdiPort232,FTDIBUS\COMPORT&VID_0403&PID_6101

[Strings]
VID_0403&PID_8372.DeviceDesc="USB Serial Port"
VID_0403&PID_6100.DeviceDesc="FTDI FT232BM HS Serial Converter 6100"
VID_0403&PID_6101.DeviceDesc="FTDI FT232BM HS Serial Converter 6101"


BitBang Mode ein paar Zeitmessungen

Mit folgendem Programm hab ich ein paar Messungen durchgeführt wie lange die Schreib - und Lesezeiten im BitBang Mode so dauern.

      FT_SetLatencyTimer(fthandle,1); //1ms Latency Timer
      FT_SetBaudRate(fthandle,38400); //ByteTime 38400 * 16 = 1.6us

       time(&start);

       for(i=0; i<10000; i++)
        {
         UCHAR test,by;
         by=0x55;

         ftstatus=FT_Write(fthandle,&by,1,&written); //Write Buffer
         by=~by;
         ftstatus=FT_Write(fthandle,&by,1,&written); //Write Buffer
         ftstatus=FT_GetBitMode(fthandle,&test); //Read Byte
        }

       time(&stop);
       runtime=difftime(stop,start);
       printf("RunTime %d s\n",(int)runtime); 

Das Programm sendet 20000 Bytes einzeln mit FT_Write() und liest 10000 Bytes mit FT_GetBitMode() zurück. Am USB Bus nichts weiter angeschlossen. Ergebnis: 80s Programmlaufzeit.

Wenn man die FT_Write() Befehle wegläßt sind es noch 40s für FT_GetBitMode(). Also ca. 4ms pro Lesezyklus.
Ein FT_Write() Befehl braucht damit 2ms obwohl der Latency Timer auf 1ms eingestellt ist. 

Dann habe ich zusätzlich ein FT232BM Testboard (VCP Treiber) mit dem LCD-MonsterDisplay (19200Baud) verbunden und Winamp gestartet um mal zu sehen wie die Zeiten sich verlängern. Überraschung: Programmlaufzeit mit FT_Write() Befehlen nur noch 60s.  Ohne FT_Write() wieder 40s für FT_GetBitMode(). Die FT_Write() Befehle sind merkwürdigerweise durch den Datenverkehr auf dem USB Bus auf 1ms runtergegangen.

FT_Write() kann man beschleunigen wenn nicht jedes Byte einzeln abgeschickt wird. Einfach Pakete senden. Hier 10000 * 256 Byte.

       UCHAR buf[256];
       for(i=0; i<256; i++)
        {
          if(i%2 ==0 ) buf[i]=0x55;
          else buf[i]=0xAA;
        }

       for(i=0; i<10000; i++)
        {
         ftstatus=FT_Write(fthandle,&buf,256,&written); //Write Buffer
         ftstatus=FT_GetBitMode(fthandle,&test); //Read Byte
        }

Gemessene Zeit (wieder alleine auf dem USB Bus): 64s d.h. ca. 2ms pro Paket. Mit Winamp: 57s also wieder schneller. Ist schon seltsam. Das Ergebnis dürfte sich allerdings verschlechtern wenn auf dem USB Bus mehr los ist.

Ich habe leider noch keinen Weg gefunden FT_GetBitMode() zu beschleunigen. Tips dazu sind äußerst willkommen.


FIFO Mode ein paar Zeitmessungen 

Begriffserklärungen zu den Tabellen
Alleine:   FT245BM Testboard (D2XX Treiber) mit ATMega32 (8MHz) Testboard zum Datenaustausch alleine am USB Bus
Pthermo: Mit FT232BM Testboard (VCP Treiber) und meinem SerialThermometer mit PIC12F675, 9600Baud, nur alle 60s Datentransfer
Winamp: Mit FT232BM Testboard (VCP Treiber) mit MonsterDisplay, 19200Baud kontinuierlicher Datenstrom
Beide:     Beide Schaltungen oben zusätzlich angeschlossen

Bei der ersten Messung wird 3 * 10000 mal ein kompletter TX-FIFO (128 Byte) zum ATMega gesendet. Also drei FT_Write() Befehle nacheinander. Ergibt 3.840.000 Bytes. Der ATMega holt alles ab und macht damit nichts weiter. Der LatencyTimer vom FT245BM wurde auf 1ms eingestellt. Alle Messungen wurden mehrfach durchgeführt.
 

Alleine 60s
Mit Pthermo 32s
Mit Winamp 32s
Mit beiden 30s

Erstaunlich: Wie beim BitBang Mode wird der Datentransfer zum ATMega durch einen FT232BM (VCP Treiber) am USB Bus fast verdoppelt. Schließt man noch einen an gehts sogar noch etwas schneller. Schließe ich einen zweiten FT245BM (D2XX Treiber) z.B. mit dem USB-LCD Display an bleiben die Zeiten bei "Alleine". Also keine Beschleunigung. Kommt dann wieder ein FT232BM (VCP Treiber) hinzu gehts plötzlich schneller zur Sache. Merkwürdig. Muß wohl an den VCP Treibern liegen. 

Bei der zweiten Messung schreibt der ATMega alles was er empfängt sofort in den RX-FIFO vom FT245BM zurück. Da dieser dreimal so groß ist wie der TX-FIFO werden erst drei komplette TX-FIFO vom PC gesendet, und dann alle 384 Bytes aus dem RX-FIFO an einem Stück zurückgelesen. Das ganze wieder 10000 mal. Es werden 3.840.000 Bytes gesendet und zurückgelesen.
 

Alleine 79s
Mit Pthermo 46s
Mit Winamp 46s
Mit beiden 43s

Das gleiche Bild. Ist ein zusätzlicher FT232BM (VCP Treiber) angeschlossen gehts wieder erheblich schneller. Gegenüber dem BitBang Mode geht diesmal auch das Lesen schneller wenn man entsprechend große Pakete empfängt.

Richtig Durchsatz machen kann man nur wenn man RX- und TX-FIFO möglichst gut auffüllt. Beispiel wie oben, aber jeweils nur 5 Bytes senden und 15 Bytes empfangen: Alleine 101s, mit Winamp 53s. Also wesentlich langsamer als wenn man erst den FIFO ganz voll macht. Das gleiche Ergebnis bei nur einem Byte senden und drei Byte empfangen. 

Dritte Messung: Statt drei FT_Write() Befehlen nacheinander mit 128 Bytes nur einen FT_Write() Befehl mit 384 Bytes. Das ganze wieder 10000 mal. Der ATMega holt die Daten hier nur ab und schreibt sie nicht zurück.
 

Alleine 30s
Mit Winamp 20s

Vierte Messung: Wie oben, aber 768 Bytes an einem Stück senden. Das ganze 5000 mal.
 

Alleine 20s
Mit Winamp 15s

Fünfte Messung: 384 Bytes an einem Stück senden und wieder zurücklesen.
 

Alleine 55s
Mit Winamp 41s


Ich entwerfe keine Schaltungen oder Programme für andere. Dazu fehlt mir einfach die Zeit. Bei mir sind keine Bausätze, Platinen oder programmierte Chips zu den Schaltungen erhältlich. 
E-Mail

Zur Startseite