OpenDCC: USB

Einleitung

    Am USB-Bus hat jeder Teilnehmer eine eindeutige VID und PID (VID: Vendor ID = Herstellerkennung, PID: Product ID, Produktkennung).
    Die hier vorgestellten Schaltungen basieren zumeist auf dem FT232RL von FTDI. Für die OpenDCC Projekte wurde mir von FTDI eine eigene PID innerhalb der für FTDI vergebenen VID zugeteilt. Im Linux-Kernel ab Version 2.6.31.2 sind diese VID und PID als bekannte Devices enthalten, damit werden diese Geräte ohne manuelle Einstellungen als serielle Schnittstelle erkannt.

VID und PID bei OpenDCC

Erstinbetriebnahme des USB

    Nach dem Aufbau einer OpenDCC Schaltung muß die USB-Verbindung konfiguriert werden. Dies gliedert sich in zwei Teile:
  • Treiber am PC installieren
  • FTDI Chip konfigurieren

Konfiguration und Installation der FTDI Treiber

    Diese Anleitung gilt für die Treiberversion 2.06.02 oder aktueller!
    Zur Nutzung der USB Schnittstelle von OpenDCC ist ein VirtuellerComPort (VCP) Treiber nötig. Dieser emuliert eine serielle Schnittstelle im PC, auf die dann die Steuerungssoftware zugreifen kann. Der tatsächliche Datenverkehr wird aber über die USB-Verbindung hergestellt. Der virtuelle COM-Port wird als weiterer COM-Port eingetragen (also z.B. COM5), die Anwendung wird dann auf diesen COM-Port eingestellt.
    Diesen VCP-Treiber (und weitere Informationen) findet man bei FTDI.

Das ZIP-Archiv von FTDI wird es in ein beliebiges Verzeichnis entpackt. Nun müssen die VID und PID für OpenDCC in zwei dieses Treibers eingetragen werden. Hierzu sind in den Dateien die folgenden kursiven, roten Zeilen zu ergänzen oder die bereits fertig angepassten Dateien (INI Dateien für OpenDCC.zip) zu verwenden.
Ftdibus.inf

[FtdiHw]
%USB\VID_0403&PID_6001.DeviceDesc%=FtdiBus.NT,USB\VID_0403&PID_6001
%USB\VID_0403&PID_BFD8.DeviceDesc%=FtdiBus.NT,USB\VID_0403&PID_BFD8
%USB\VID_0403&PID_BFD9.DeviceDesc%=FtdiBus.NT,USB\VID_0403&PID_BFD9
%USB\VID_0403&PID_BFDA.DeviceDesc%=FtdiBus.NT,USB\VID_0403&PID_BFDA
%USB\VID_0403&PID_BFDB.DeviceDesc%=FtdiBus.NT,USB\VID_0403&PID_BFDB
%USB\VID_0403&PID_BFDC.DeviceDesc%=FtdiBus.NT,USB\VID_0403&PID_BFDC
%USB\VID_0403&PID_BFDD.DeviceDesc%=FtdiBus.NT,USB\VID_0403&PID_BFDD

[FtdiHw.NTamd64]
%USB\VID_0403&PID_6001.DeviceDesc%=FtdiBus.NTamd64,USB\VID_0403&PID_6001
%USB\VID_0403&PID_BFD8.DeviceDesc%=FtdiBus.NTamd64,USB\VID_0403&PID_BFD8
%USB\VID_0403&PID_BFD9.DeviceDesc%=FtdiBus.NTamd64,USB\VID_0403&PID_BFD9
%USB\VID_0403&PID_BFDA.DeviceDesc%=FtdiBus.NTamd64,USB\VID_0403&PID_BFDA
%USB\VID_0403&PID_BFDB.DeviceDesc%=FtdiBus.NTamd64,USB\VID_0403&PID_BFDB
%USB\VID_0403&PID_BFDC.DeviceDesc%=FtdiBus.NTamd64,USB\VID_0403&PID_BFDC
%USB\VID_0403&PID_BFDD.DeviceDesc%=FtdiBus.NTamd64,USB\VID_0403&PID_BFDD

[Strings]
Ftdi="FTDI"
DESC="CDM Driver Package"
DriversDisk="FTDI USB Drivers Disk"
USB\VID_0403&PID_6001.DeviceDesc="USB Serial Converter"
USB\VID_0403&PID_BFD8.DeviceDesc="USB-IF OpenDCC V1.2"
USB\VID_0403&PID_BFD9.DeviceDesc="USB-IF DCC Sniffer V1.0"
USB\VID_0403&PID_BFDA.DeviceDesc="USB-IF OpenDCC Throttle V1.0"
USB\VID_0403&PID_BFDB.DeviceDesc="USB-IF OpenDCC Gateway V1.0"
USB\VID_0403&PID_BFDC.DeviceDesc="USB-IF OpenDCC GBM V1.0"
USB\VID_0403&PID_BFDD.DeviceDesc="USB-IF OpenDCC GBMBoost V1.0"
SvcDesc="USB Serial Converter Driver"
ClassName="USB"

[FtdiHw]
%VID_0403&PID_6001.DeviceDesc%=FtdiPort232.NT,FTDIBUS\COMPORT&VID_0403&PID_6001
%VID_0403&PID_6010.DeviceDesc%=FtdiPort2232.NT,FTDIBUS\COMPORT&VID_0403&PID_6010
%VID_0403&PID_6011.DeviceDesc%=FtdiPort2232.NT,FTDIBUS\COMPORT&VID_0403&PID_6011
%VID_0403&PID_BFD8.DeviceDesc%=FtdiPort232.NT,FTDIBUS\COMPORT&VID_0403&PID_BFD8
%VID_0403&PID_BFD9.DeviceDesc%=FtdiPort232.NT,FTDIBUS\COMPORT&VID_0403&PID_BFD9
%VID_0403&PID_BFDA.DeviceDesc%=FtdiPort232.NT,FTDIBUS\COMPORT&VID_0403&PID_BFDA
%VID_0403&PID_BFDB.DeviceDesc%=FtdiPort232.NT,FTDIBUS\COMPORT&VID_0403&PID_BFDB
%VID_0403&PID_BFDC.DeviceDesc%=FtdiPort232.NT,FTDIBUS\COMPORT&VID_0403&PID_BFDC
%VID_0403&PID_BFDD.DeviceDesc%=FtdiPort232.NT,FTDIBUS\COMPORT&VID_0403&PID_BFDD

[FtdiHw.NTamd64]
%VID_0403&PID_6001.DeviceDesc%=FtdiPort232.NTamd64,FTDIBUS\COMPORT&VID_0403&PID_6001
%VID_0403&PID_6010.DeviceDesc%=FtdiPort2232.NTamd64,FTDIBUS\COMPORT&VID_0403&PID_6010
%VID_0403&PID_6011.DeviceDesc%=FtdiPort2232.NTamd64,FTDIBUS\COMPORT&VID_0403&PID_6011
%VID_0403&PID_BFD8.DeviceDesc%=FtdiPort232.NTamd64,FTDIBUS\COMPORT&VID_0403&PID_BFD8
%VID_0403&PID_BFD9.DeviceDesc%=FtdiPort232.NTamd64,FTDIBUS\COMPORT&VID_0403&PID_BFD9
%VID_0403&PID_BFDA.DeviceDesc%=FtdiPort232.NTamd64,FTDIBUS\COMPORT&VID_0403&PID_BFDA
%VID_0403&PID_BFDB.DeviceDesc%=FtdiPort232.NTamd64,FTDIBUS\COMPORT&VID_0403&PID_BFDB
%VID_0403&PID_BFDC.DeviceDesc%=FtdiPort232.NTamd64,FTDIBUS\COMPORT&VID_0403&PID_BFDC
%VID_0403&PID_BFDD.DeviceDesc%=FtdiPort232.NTamd64,FTDIBUS\COMPORT&VID_0403&PID_BFDD

[Strings]
FTDI="FTDI"
DESC="CDM Port Driver Package (OpenDCC Mod)"
DriversDisk="FTDI USB Drivers Disk"
PortsClassName = "Ports (COM & LPT)"
VID_0403&PID_6001.DeviceDesc="USB Serial Port"
VID_0403&PID_6010.DeviceDesc="USB Serial Port"
VID_0403&PID_6011.DeviceDesc="USB Serial Port"
VID_0403&PID_BFD8.DeviceDesc="USB-IF OpenDCC V1.2"
VID_0403&PID_BFD9.DeviceDesc="USB-IF DCC Sniffer V1.0"
VID_0403&PID_BFDA.DeviceDesc="USB-IF OpenDCC Throttle V1.0"
VID_0403&PID_BFDB.DeviceDesc="USB-IF OpenDCC Gateway V1.0"
VID_0403&PID_BFDC.DeviceDesc="USB-IF OpenDCC GBM V1.0"
VID_0403&PID_BFDD.DeviceDesc="USB-IF OpenDCC GBMBoost V1.0"
SvcDesc="USB Serial Port Driver"
SerEnum.SvcDesc="Serenum Filter Driver"
Die Veränderung der DESC Variablen ist in beiden Dateinen optional, hilft aber bei der Indentifizierung in der Softwareliste.
Da aktuelle Systeme (besonders Vista) bevorzugt zuerst online nach Treibern suchen, empfiehlt es sich den Treiber vor dem ersten Verbinden zu installieren. Als besonders hilfreich erweist sich an dieser Stelle das windowsinterne Driver Installation Framework (DIFx).
Hierfür einfach mal im System nach der Datei DPInst*.exe suchen, in das Verzeichnis kopieren in welchem der Treiber ausgepackt wurde und direkt starten.
Hinweise:
  • Sollten die Treiber als ungültig abgewiesen werden, muss DPInst im legacy mode über den Parameter DPInst.exe -lm in der Konsole (cmd) gestartet werden.
  • für x64 Systeme muss DPInstx64.exe verwendet werden.
Jetzt die OpenDCC Baugruppe mit dem PC verbinden. Eine neue Hardware wird erkannt und die registrierten Treiber werden verwendet. Wenn man noch keine Treiber installiert hat (s.oben), so ist jetzt bei der Frage nach den passenden Treibern auf das entsprechende Verzeichnis zu verwiesen.
Im Geräte-Manager sollte nun ein neuer serieller Port sowie ein neues USB Device erscheinen. Wenn die Hardware bereits die OpenDCC PID und VID enthält, dann wird das auch angezeigt. Bei neuer Hardware fehlt das noch und man muß das noch konfigurieren.

Konfiguration des USB-Chips

    Damit die Hardware nicht nur als 'irgendein' serieller Port, sondern als OpenDCC-Baugruppe erkannt wird, muß man PID und VID in den FTDI Chip hineinschreiben:
  • FT_Prog Screenshot
    Mit dem Konfigurationprogramm FT_Prog wird nun die richtige Herstellerkennung und Produktkennung gemäß obiger Tabelle eingetragen. Zur Vereinfachung kann man auch das jeweilige Template (z.B. OpenDCC_V1.2.xml) laden, damit sind alle notwendigen Einstellungen bereits vorgenommen.
    Nach dem Eintrag der richtigen Kennung kann man mit 'Cycle Device' ("Lupe") ein Neueinlesen des Busses veranlassen.
  • Durch Drücken auf das Blitzsymbol werden der USB-Chip und das EEPROM konfiguriert, damit ist dann die richtige Kennung im Chip abgelegt.
  • Jetzt abschließend die OpenDCC Baugruppe nochmal vom PC trennen und kurz warten bis Port und Device im Gerätemanager verschwinden.
  • Stellt man nun die Verbindung von OpenDCC Baugruppe und PC wieder her, dann sollte die OpenDCC Baugruppe korrekt in der Deviceübersicht in der Systemsteuerung erscheinen.

    Die OpenDCC Zentrale 1 wurde gefunden und wird mittels des VCP-Treibers (=Virtual Com Port) als serielle Schnittstelle (im Bild: COM6) im Gerätemanager angezeigt.


  • Konfiguration unter Linux
    Unter Linux kann der FTDI Chip bzw. dessen EEPROM auch mittels des Utilities ftdi_eeprom aus der GPL Library libftdi (http://www.intra2net.com/en/developer/libftdi/) beschrieben werden. Das Kommandozeilen Utility dürft bei den Paketen der meisten Distributionen nicht automatisch dabei sein, es ist daher ggf. ein manuelles Übersetzen erforderlich:
  • Elementare Abhängigkeiten z.B. Debian Wheezy apt-get install cmake libusb-1.0-0-dev libconfuse-dev
  • Quellcode mittels git beziehen: git clone git://developer.intra2net.com/libftdi
  • Übersetzen:
    cd libftdi
    mkdir build
    cd build
    cmake  -DCMAKE_INSTALL_PREFIX="/opt" ../
    make
    sudo make install # optional die relevant Binaries siehe 4.)         
  • Relevante Binaries
    examples/find_all # Test ob FTDI USB Device(s) gefunden wird
    examples/eeprom # Auslesen aktuelles EEPROM
    ftdi_eeprom/ftdi_eeprom # relevantes Binary
    ftdi_eeprom/example.conf # Beispiel Konfiguration mit weiteren Parametern
  • Beispiel Befehl für das Setzen der Product und Vendor ID (teilweise ist nach dem Beschreiben des EEPROM ein Reset des Bausteines notwendig):
    ftdi_eeprom --flash-eeprom ftdi-opendcc.conf
  • Beispiel Konfiguration (ftdi-opendcc.conf)
    vendor_id=0x0403                        # Vendor ID
    product_id=0xBFD8                       # Product ID
    product="USB-IF OpenDCC V1.2"           # Product description  

Tipps

    Normalerweise wartet der FTDI-Chip 16ms, bis er ein empfangenes Kurzpaket (so wie das z.B. bei Zentralen der Fall ist) an den Host weiterreicht. Das bremst die Performance erheblich aus. In obigen Treibern ist diese Latenz auf 2ms verkürzt. ([FtdiPort.NT.HW.AddReg], HKR,,"LatencyTimer",0x00010001,2
    Man kann das auch bei einem bereits installierten Treiber nachholen: Hierzu (in Windowssystemen) in den Eigenschaften des COMport die Paketgröße und die maximale Wartezeit einstellen. Hierzu wird im Gerätemanager der Port angewählt, es öffnet sich das Eigenschaftsfenster der Com-Port-Schnittstelle. Hier kann man dann unter 'Anschlusseinstellungen -> Erweitert…' die erweiterten Einstellungen vornehmen, u.a. Puffergröße (für Z1: 64) und max. Latenz (2ms) einstellen.
    Wenn durch mehrere FTDI-Devices immer höherer COM-Ports entstehen, kann man mittels FTClean.exe alle FT-Treiber deinstallieren und alle Zuweisungen der Com Port Nummern löschen.
    Gezielte Zuweisung ist mit einem weiteren Tool von FTDI möglich: COMPort_Assignment Utility
    Man kann sich (unter Windows XP) den Device-Manager als Verknüpfung auf den Desktop holen, dann muß man nicht immer über Arbeitsplatz, rechte Maus, Eigenschaften usw. da hin. Einfach von devmgmt.msc eine Verknüpfung erstellen.
    Dem FT232R kann man eine Seriennummer mitgeben. Anhand dieser erkennt das Betriebssystem den Baustein wieder und man bekommt beim Anstecken immer den gleichen COM-Port zugewiesen. Auch mehrere Boxen lassen sich so unterscheiden. Nähere Informationen hierzu findet man in der AN123 von FTDI.
    Wenn man verhindern will, dass jedes FTDI-Gerät eine erneuten COM-Port bekommt, dann beschreibt die AN107 den Weg dazu:
    In der Registry wird bei HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\UsbFlags\ folgender (binary) Eintrag "IgnoreHWSerNum04036001" = 01 angelegt. Nun wird für alle Geräte vom Hersteller mit VID = 0403 (FTDI) und PID = 6001 (USB Serial Port, default) der COM-Port behalten (solange man am gleichen USB-Port ansteckt).
    Für hartnäckige Fälle benötigt man die Datei FTClean.zip. Bei Win2K, Windows XP SP3, und Vista lässt sich der eventuell schon installierte VCP-Treiber (z.B. 2.08.14) für vorherige Anwendungen für Z1, Sniffer usw. nicht aktualisieren. Der "alte" Treiber lässt sich dabei weder mit normalen Mitteln, noch durch gutes Zureden entfernen, es kommt die Windows-Meldung "Es ist schon der aktuellste Treiber geladen": Genau hier hilft FTClean! Das Programm entfernt nur die FTDI Treiber - aber die dann alle!
    Also Vorsicht wenn auf dem Rechner noch andere (nicht OpenDCC) Anwendungen über FDTI - Devices betrieben werden.

Linux

    Die Kennungen für OpenDCC Projekte werden bei Linux i.d.R. als Patch eingereicht und sind in Treiber ftdi_sio mit abgelegt. Sollte eine Baugruppe noch nicht erkannt und richtig zugeordnet werden, so kann man mittels ftdi_sio new_id den FDTI-Treiber davon überzeugen, sich auch für diese Baugruppe zuständig zu fühlen.
    Beispiel: (als root eingeben)
      echo 0403 BFDD > /sys/bus/usb-serial/drivers/ftdi_sio/new_id

Links

Windows 8

    Unter Windows 8 müssen Treiber signiert sein, daher wird der obige Treiber nicht akzeptiert (es kommt eine Fehlermeldung, dass der Hash-Wert nicht stimmt). Um da vorbei zukommen, muß man die Signaturprüfung abschalten. Auf heise.de gibt es eine Anleitung, wie man das machen kann.