Forum: FPGA, VHDL & Co. FT2232H in FT245 FIFO Mode - kein Burst möglich


von Thomas L. (thomers)


Angehängte Dateien:

Lesenswert?

Servus, ich schon wieder.

Ich habe das Problem, dass ich aus meinem FPGA (Cyclone II) über den 
FT2232H im FT245 FIFO Mode (siehe Screenshot FT245_fifo.png) keinen 
Burst raus bekomme.

Gerichtet habe ich nach den Angaben aus der FTDI Application Note 130 
(Signalverlauf siehe burst.png).
1
A write operation can be started when TXE# is low. WR# is brought low when the data is valid. 
2
A burst operation can be done on every clock providing TXE# is still low. The external system must monitor TXE# and its own WR# to check that data has been accepted. 
3
Both TXE# and WR# must be low for data to be accepted.

Wenn ich mein Design debugge, kommt, wie geplant, der Signalverlauf, der 
in ft232_burst.png zu sehen ist, raus.

Allerdings kommt am PC nur ein einziges Byte an, nämlich jenes, das vor 
dem low-setzen von WR_int an FT245DOut anlag (in diesem Falle 5).

Ich habe es zwar schon geschafft, meine Daten rauszuschicken, wenn ich 
immer nur ein Byte für 2 Takte WR# low anlege, aber dann brauche ich pro 
Byte min. 8 Take (inkl. warten auf TXE# etc) .. und das ist zu langsam 
... .

Mache ich auch hier mal wieder etwas falsch? Hat jemand nen Tipp?

Danke.

Grüße

Thomers

von Thomas L. (thomers)


Lesenswert?

Der FTDI-Support ist auch schon dran, meldet sich aber leider seit ner 
Weile nicht mehr.

Hat evtl. jemand einen Code-Ausschnitt der TX state machine bzw. ein 
funktionierendes Beispiel? Oder zumindest einen Signalverlauf oder 
ähnliches?

Es häng nur noch an der einen kleinen Sache. Hab eigentl. keine Lust, 
nur wegen der Angelegenheit eine anders Board raussuchen zu müssen...

gruß

thomers

von ich (Gast)


Lesenswert?

Meine Vermutung:
Du bist im asynchronen 245 FIFO-Mode. Wie man in den synchronen Mode 
schaltet weis ich allerdings spontan nicht.

von olof (Gast)


Lesenswert?

könnte es sein, dass du mit dem FT_PROG in den CPU fifo mode gehen 
musst?

von Thomas L. (thomers)


Lesenswert?

also lt. FT_Prog (siehe Bild oben) bin ich im FT245 FIFO mode.

im CPU FIFO mode funktioniert nichtmal die rx-strecke. inwiefern sollte 
das besser laufen?

ich weiß nicht, ob das wichtig is, aber wenn ich am PC beim 
initialisieren des Chips mit SetBitMode alle bits auf sync fifo mode 
setzte, dann sperrt der chip total und ich kann ohne abziehen des USB 
nicht mal mehr programmieren.

von Uwe Bonnes (Gast)


Lesenswert?

Verilog Code habe ich hier schon mal gepostet.

Ansonsten muessen beide FT2232H Interfaces im EEPROM auf 245 Fifo 
stehen, und dann kann mit mittels SetBitMode in den synchronen FIFO 
Modus schalten.

Am Oszi sieht man dann, dass ein FIFO ClK von 60 MHz vom FTDI geliefert 
wird.

von Thomas L. (thomers)


Lesenswert?

Habe ich im Prinzip so gemacht. Den BitMode setzte ich mit (C#):
1
SetBitMode(0xFF, FTDI.FT_BIT_MODES.FT_BIT_MODE_SYNC_FIFO);

Ist das so richtig? Wenn ja frage ich mich, warum dann der Chip dicht 
macht.

@Uwe: wo hast du den Verilog code gepostet? kann ihn leider nicht 
finden.

von Uwe Bonnes (Gast)


Angehängte Dateien:

Lesenswert?

Vielleicht hab's ich auch noch nicht gepostet...

ppms ist ein "Puls per Millisecond".  usb_offline ist ein Signal aus dem 
Digital Clock Manager, das anzeigt, dass die Clock vom FT2232 stabil 
anliegt. Wenn kein FT2232 Clock anliegt, wird das FIFO zurueckgesetzt, 
bei stabilen Takt wird nach 20 ms ein Signal nach aussen gegeben, dass 
Daten der Fifo Block bereit fuer Daten ist.

Sendet man nur Bytes, ist das Svnchronisieren kein Problem. Bei uns 
werden 8 2-Byte Worte als Block gesendet. Aktiviert der Block 
fifo_throttle, so ist immer noch zumindestens Platz fuer einen Block, 
und der Sender hoert erst auf der naechsten Blockgrenze auf und wenn 
fifo_throttle deaktiviert, dann beginnt der Sender wieder an einer 
Blcokgrenze

usbb_clk ist das vom DCM aufgereitete FT2232 clock
PC-seitig laeuft eine Abwandlung von libftdi-1.0/examples/stream_test.c.

Auf der Top Ebene ermeoglicht
   always @(posedge usb_clk)
      if(tx_nextdata)
        data2ft <= fifo_rd_data;
die Benutzung der Ausgangsregister des FPGAs. Das Timing mit einem 
XC6SLX ist aber nicht voellig hinzukriegen. Im UCF File habe ich

# Spartan6 kann 5.666 (16.666 - 11) ohne Phaseshift nicht erreichen
#          daher auf 5.94 erweitert
NET "usb_adbus<*>" OFFSET = OUT 5.94 ns             AFTER  "usb_clk_in";
NET "usb_wr_n"     OFFSET = OUT 5.94 ns             AFTER  "usb_clk_in";
NET "usb_txe_n"    OFFSET = IN  9.5 ns VALID 10.5 ns BEFORE 
"usb_clk_in";

   frequency_supervisor
     #(2)
   f0
   (
    .fin                                (usb_clk_inbuf),
    /*AUTOINST*/
    // Outputs
    .fin_good                           (fin_good),
    // Inputs
    .clk                                (clk));

   assign                usb_offline = !fin_good || !usb_clk_valid;

mit
assign usb_clk_valid = ( ( locked_int == 1'b 1 ) && ( status_int[1] == 
1'b 0 ) );
aus der DCM. Der DCM wird mit !fin_good zurueckgesetzt.

Das CMD File ist fuer Icarus Iverilog.

von steffen (Gast)


Lesenswert?

Thomas L. schrieb:
> Habe ich im Prinzip so gemacht. Den BitMode setzte ich mit (C#):SetBitMode(0xFF, 
FTDI.FT_BIT_MODES.FT_BIT_MODE_SYNC_FIFO);
> Ist das so richtig? Wenn ja frage ich mich, warum dann der Chip dicht
> macht.
>
> @Uwe: wo hast du den Verilog code gepostet? kann ihn leider nicht
> finden.

Das klingt nach nem Timingproblem. Das Problem habe ich auch gerade. Ich 
denke das hängt mit einem Metastabilenzustand zusammen. Der FT2232H 
zieht dann TXE# nicht mehr runter und "hängt". Mit dem Recycle Kommando 
bekommst du den wieder hin auch ohne abziehen.

Gruß Steffen

von Johann (Gast)


Lesenswert?

Ich will ja nichts sagen aber warum macht IHR das alles so kompliziert?

Ich verwende einen FIFO. Sofern 1 Byte im FIFO steht wird dieser über 
den FT2232H übertragen.

Wenn man nun Blöcke senden möchte ist das doch auch kein Problem. Wenn 
mehr als 8 Bytes im FIFO stehen lese ich halt 8 Bytes aus und übertrage 
diese.

Das Timinig kann man nicht erreichen. Ich habe einen Logikanalysator mal 
dazwischengeschaltet. Das Signal TXE# kommt gegenüber dem 60MHz Clock so 
stark verzögert das man das angegebene Timing nicht mehr einhalten kann.

von Christian R. (supachris)


Lesenswert?

Naja, laut DB kommt das TXE# spätestens 7,15ns nach der steigenden 
Flanke. Da das ja das FIFO Full-Flag repräsentiert, muss man das schon 
beachten, sonst gibts ja Datenverlust. Und bei 60MHz hätte man da ja 
immer noch 9ns Zeit, um WE# wegzunehmen und den Transfer anzuhalten.
Problem an der Sache ist allerdings, dass die 7,15ns des Flags und die 
11ns minimale Setup-Zeit für WE# nicht zu den 16.66ns Cycle passen. Da 
ist Datenverlust eigentlich vorprogrammiert.
Das versteh ich auch nicht, und setze den FT2232H deswegen nicht ein. 
Wir nehmen den Cypress FX2LP, da gibts die gleichen Probleme bei 
maximaler Geschwindigkeit, aber den kann man wenigstens mit externem 
IFCLK füttern, dann kann man das umgehen.

von Steffen (Gast)


Lesenswert?

Ich hab keinen Datenverlust sondern im Moment immernoch ein Byte zu viel 
;)

Aber mal im Ernst man kann ja auch eine Periode später reagieren. Wenn 
man sich überlegt das WE# bzw TWE# im Idealfall nur alle 512 Byte 
gesetzt werden ist es kein Problem. FTDI spezifiziert seinen Chip daher 
auch "nur" mit 25MB/s und nicht wie viele hier im Forum berichten mit ~ 
40MB/s.

Gruß Steffen

von Christian R. (supachris)


Lesenswert?

">25MB/s" steht im Datenblatt. Alleine diese Angabe ist ziemlich 
sinnbefreit. Ändert aber nichts an der Tatsache, dass das da unsauber 
ist und kaum umgangen werden kann. Selbst wenn man immer einen Takt 
Latenz einrechnet, kann es ja sein, dass es doch mal eher kommt.
Am sichersten kommt man wahrscheinlich, wenn man hofft, dass 9ns Setup 
am WE ausreichen. Die Flag-Delay Zeit ist leider meist wirklich ziemlich 
lang.
Beim FX2 funktioniert das auch, wir haben den mit 40MHz IFCLK genauso 
"überfahren", die 18,5ns Setup konnte ich nicht einhalten. Aber bisher 
ist noch nichts weggekommen. Mittlerweile haben wir das aber auf 20MHz 
reduziert, dann passen alle Setup- und Hold-Zeiten. Reicht bei 16 Bit 
Busbreite immer noch, um 38...40MB/s zu erreichen.

von Steffen (Gast)


Lesenswert?

So ich hab mein zusätzliches Byte gefunden... wenn man seine Datei halt 
nicht als Binary öffnet generiert das Betriebssystem zu jedem 0x0A ein 
0x0D :)

Ich halte das FTDI timing relativ gut ein. Ich brauche 5.6ns von der 
steigenden Flanke d.h. 16.66ns - 5.6ns = 11.06ns, wenn allerdings die 
Periode auf Grund von Jitter ein wenig kürzer wird (sagen wir 15ns) 
halte ich die Spec nicht mehr ein.

von Thomas L. (thomers)


Lesenswert?

Also bei mir haut es nun inzwischen nahzu perfekt hin.
Habe alles, sowohl VHDL als auch die SW, nochmal komplett von null auf 
neu geschrieben, gleich ein paar sachen anders gemacht, diesemal statt 
der .net-dll die c/cpp-dll genommen und alles in C++ geschrieben und 
inzwischen bekomme ich auch bursts rein, so wie ich es möchte.
Keine Ahnung, wieso es vorher nicht funktionierte.

Es gibt nur noch ein Problem: ziemlich unvorhersehbar und zufällig geht 
das TXE# auf einmal für sehr lange auf low, sodass ich keine Daten 
rausschreiben kann, mein leider relativ kleiner FIFO (8kb, mehr geht 
nicht in den FPGA) ziemlich fix voll ist. Nun wäre das nicht so schlimm 
wenn TXE# zeitnah wieder high würd, da würde ich einfach den FIFO leeren 
und auf ein neues Bild warten .. allerdins bleibt das Signal für mehrere 
100 ms auf low .. und dadurch bricht mir die Framerate derbe ein.
Das scheint entweder das von Steffen weiter oben beschriebene Problem zu 
sein (Timing, lsg: recycle) oder, wie ich schonmal irgendwo gelesen 
habe, ein Problem von Windows, dass es manchmal den USB Puffer einfach 
sperrt oder so und damit der FT2232H auch nicht weiter zum PC schreiben 
kann.

Gruß

Thomers

von Christian R. (supachris)


Lesenswert?

Thomas L. schrieb:
> geht
> das TXE# auf einmal für sehr lange auf low, sodass ich keine Daten
> rausschreiben kann

Wohl eher auf high? Du darfst keine Daten schreiben, wenn TXE# high ist, 
sagt ja schon der Name. Aber das liegt mit ziemlicher Sicherheit am 
Betriebssystem. Wir haben das ebenfalls beobachtet. Gerade XP hat 
manchmal ewige Latenzzeiten. Ist durchaus normal, und kann nur durch 
große Puffer bzw. Daten Schreben nur auf Anforderung behoben werden. Für 
Streaming gibts isochrone Transfers, da wird dir die Bandbreite 
garantiert.

Das mit dem Timing wird im Normalfall schon gut gehen. Denn das einzige 
Problem ist ja, dass wenn TXE# wirklich mal lange braucht, nimmst du 
eventuell dann das WE# zu spät weg und der FTDI sieht da noch einen 
Transfer bei der näcgsten Flanke des Taktes, der ja aber dann eh schief 
geht, weil FIFO voll. Im FPGA ist das unkritisch, da reichen die 
verbleibenden 9ns locker zu, um das Lesen aus dem FIFO zu sperren.

von steffen (Gast)


Lesenswert?

Auf der PC-Seite kann man den FIFO noch bis 64kByte aufbohren ggf. 
bringt das schon ein wenig. Hast du den Prozess mal priorisiert?

http://msdn.microsoft.com/en-us/library/ms686277%28v=vs.85%29.aspx

Manchmal bewirkt das Wunder ;) Ggf. andere USB Geräte mit dran? Alter 
Hub etc?

Gruß Steffen

von Thomas L. (thomers)


Lesenswert?

Ok, das Problem, dass TXE# ewig lang auf auf *high steht tritt in 2 
mustern auf:

1. nur ab und zu (alle 10-20 sekunden), wenn ich zwar andere usb-geräte 
dran habe, aber diese gerade keine last erzeugen oder der laptop auf 
akku läuft
2. mehmals pro sekunde, wenn ich noch ein anderes schwer beschäftigtes 
USB Gerät (z.B. Vector CANcaseXL) dran habe

punkt 1 stört mich an sich nicht wirklich, da geht die Framerate nur 
abundzu mal 1-2 frames runter.
punkt 2 stört allerdins desöferten, da das gerät druchaus parallel zur 
CANbox laufen soll.

aber ich denke mal, dass ich da nicht viel machen kann.
was ich schon versucht habe: treiber-prio höher, programm- & thread-prio 
höher und treiberseitig mehr transferbuffer.

was ich noch nicht probiert habe: per SetUSBParameters den USB puffer 
sehr zu erhöhen (z.B. von 4kb zu 65kb), da ich die .NET-dll verwende und 
es da die funktion SetUSBParameters nicht gibt.

HAT JEMAND ahnung, wie das mit der .NET-DLL geht?

gruß

thomers

von Potter (Gast)


Lesenswert?

Keine Ahnung was Dein FTDI macht, aber ich gehe mal davon aus, dass das 
CDC ist. Und dann werden da eben nur Daten übertragen, wenn der USB 
sonst nichts zu tun hat. Das ist nämlich genau so vorgesehen. Und bei 
Deinen Datenmengen noch weitere USB-Geräte parallel in Betrieb zu nehmen 
ist eine ganz schlechte Idee. Dadurch werden die Zeitslots mit 
Sicherheit nicht größer!

Gruß Potter

von Christian R. (supachris)


Lesenswert?

Wie kommst du eigentlich immer drauf, dass die FTDI Chips irgendwas mit 
CDC machen? Die tunneln die serielle mit einer Vendor Device Class, 
sonst liefen sie ja mit der usbser.sys ohne extra Treiber. Und die 
schnellen Versionen im FIFO Modus haben erst recht kein CDC.
Klar ist aber, dass USB für sowas eigentlich nicht ausgelegt ist, bei 
hoher Buslast bei anderen Teilnehmern bricht das zusammen. Wichtig ist, 
dass man die Devices so verteilt, das mööglichst nicht 2 schnelle Geräte 
an einem Root Hub hängen. Leider haben die meisten Motherboards nur 2 
EHCI Root Controller, bei mehr als 2 HighSpeed Geräten fängt also das 
große Teilen und der Kampf um dden Bus an.

von Thomas L. (thomers)


Lesenswert?

Ok, prinzipiell habe ich mir das auch so gedacht und gemeint, dass ich 
damit leben muss.

ABER, jez noch was lustiges:
das display, welches ich abgreife, bekommt vom controller 20 bilder pro 
sekunde. das schafft die kombination aus meinem HW-design und der PC-SW 
auch durchschnittlich, manchmal habe ich allerdins auch konstant nur 16 
bilder pro sekunde. nun hat mich das gewundert und ich habe es auf die 
anderen USB geräte/last geschoben.
aber das geile: machmal, wenn ich NUR meine HW dran habe, bekomme ich im 
durchschnitt die 16 bilder pro sekunde raus. WENN ich jez aber meinen 
usb-mp3-player anschließe und mit einem media-player (egal, welcher) 
mucke höre, geht die framerate auf einmal auf die 20 BILDER pro sekunde 
hoch! wenn ich das aktuelle lied pausiere, geht sie wieder auf 15 bilder 
pro sekunde.
das ist aber nur, wenn ich die musik höre. wenn ich daten auf den 
usb-speicher hoch- oder runte lade, passiert das nicht.

kann mir das einer erklären? werden die treiber-prios verändert oder 
schaufelt windows mehr usb-puffer frei, wenn eine höhere last dran 
hängt?
ich verstehe es nicht.

gruß

thomers

von xilinx6 (Gast)


Lesenswert?

der thread ist zwar schon echt alt, aber zu dem Timing habe ich eine 
Frage:
Kann es sein, dass inzwischen der Setup-Time Wert für 'WR# setup time to 
CLKOUT (WR# low after TXE# low)' geändert wurde?

Denn oben steht in einem Thread:
>Problem an der Sache ist allerdings, dass die 7,15ns des Flags und die
>11ns minimale Setup-Zeit für WE# nicht zu den 16.66ns Cycle passen. Da
>ist Datenverlust eigentlich vorprogrammiert.

Mit dem Datenblatt von http://www.ftdichip.com/Products/ICs/FT2232H.htm 
kann ich das nicht nachvollziehen.
Oder übersehe ich etwas?

Danke

von Christian R. (supachris)


Lesenswert?

Stimmt, sind jetzt 8 ns. Da hat man etwas mehr Zeit. Aber prinzipiell 
müsste es auch gehen, den FIFO notfalls zu "überfahren", wenn man 
schnell genug die Logik im FPGA stoppen kann (was bei der Flag Setup 
Time für einen FPGA kein Thema sein dürfte), dann schreibt man notfalls 
das letzte Wort doppelt in den FTDI, wenn man das #WR nicht schnell 
genug weggenommen bekommt, aber da der FIFO im FTDI eh voll ist, solle 
es verloren gehen und damit alles OK sein.

von xilinx6 (Gast)


Lesenswert?

ich habe noch eine andere Frage dazu:
Wenn ich beispielsweise 200.000 bytes (am Stück) per libftdi periodisch 
lesen möchte, dann habe ich momentan das problem, dass ab und zu mein 
Counter im FPGA "falsch" zählt.
Das heißt, dass obwohl ich nur 200.000 bytes lese, er nicht wieder bei 0 
steht für das nächste Mal.
Generell kann ja auch der Fehler mal auftreten dass nicht 200.000 bytes 
am Stück gelesen werden können.
Wie erkennte ich am besten, dass eine neue Transaktion gestartet wurde?
Wenn es sonst einmal zu einem Fehler kommt, dann würde dies "nie 
auffallen"!

Oder muss ich dann etwa zuerst z.B. schreiben nun will ich lesen, sodass 
ich den Anfang erkenne?

Danke.

von Christian R. (supachris)


Lesenswert?

xilinx6 schrieb:
> Wie erkennte ich am besten, dass eine neue Transaktion gestartet wurde?

Im Prinzip gar nicht, denn der Transfer kann ja auch den verschiedensten 
Gründen pausiert werden. 200.000 Byte gehen ja sowieso nicht komplett in 
den FIFO des FTDI.

> Oder muss ich dann etwa zuerst z.B. schreiben nun will ich lesen, sodass
> ich den Anfang erkenne?

Genau so.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.