Forum: Mikrocontroller und Digitale Elektronik FTDI FT230X: Fragen zu CTS und TXDEN


You were forwarded to this site from EmbDev.net. Back to EmbDev.net
von Georg P. (perthil)


Lesenswert?

Hallo,

Ich muss einen FT230X mit einer half-duplex Schnittstelle (RS485) 
ansteuern. Dazu würde ich Python mit pyserial verwenden.
Ich entwickle unter Linux, aber das Programm soll auch unter Windows 
laufen.

Hinter dem FT230X sitzt ein AVRtiny der als Adapter für eine proprietäre 
Schnittstelle dient. Dafür soll ich die SW schreiben.

Der FT230X muss einzelne Blöcke (2-20 Bytes lang) senden. Da es auch 
Blöcke gibt, die keine Antwort erwarten, die aber eine Pause von ca. 1 
Byte dazwischen benötigen, dachte ich dafür kann man ja den CTS# Eingang 
des FT230X benutzen. Um zu erkennen, dass ein neuer Block kommt soll 
TXDEN verwendet werden. Der muss also auch nach jedem Block 
zurückgesetzt werden.
Sobald der TXDEN inaktiv ist, wird also der CTS# des FT230X gesetzt um 
zu verhindern, dass neue Daten kommen, bevor die Pausenzeit vorbei ist.

In der FAQ bei FTDI steht aber bezüglich des CTS# Eingangs:

If CTS# is logic 1 it is indicating the external device cannot accept 
more data. the FTxxx will stop transmitting within 0~3 characters, 
depending on what is in the buffer.

Die Frage ist also, wie ist der Buffer des FTDI Chips aufgebaut?
Was muss darin stehen, dass immer sofort gestoppt wird, und wie 
generiere
ich das mit Python?

Entspricht der gesamte Buffer nur einem Block, oder können mehrere 
Blöcke im Buffer stehen?

Da ich auch TXDEN verwende hat das wohl auch Auswirkungen darauf. Wenn 
also mehrere Blöcke im Buffer stehen können, wird dann auch der TXDEN 
nach jedem Block deaktiviert? Und wenn ja, wie lange? Und wenn nicht, 
wie sorge ich dafür dass immer nur ein Block im Buffer steht, so dass 
auch der TXDEN inaktiv wird?

Wenn immer nur ein Block im Buffer stehen kann (entspricht einem 
pyserial write() Aufruf) muss der USB Treiber ja immer warten, bis alle 
Bytes dieses Blocks gesendet sind. Wird das eventuell so gemacht?

Bei FTDI habe ich schon gefragt, aber noch keine Antwort. Aber 
vielleicht hat hier ja jemand Erfahrung mit RS485 und FTDI.

Das ganze soll natürlich möglichst hohe Übertragungsraten erreichen. Die 
proprietäre Schnittstelle schafft ca. 3000 Byte/s, da sollte man 
möglichst nah ran kommen. Soweit ich weiß läuft USB mit 1KHz, da hängt 
es dann von der Blockgröße ab, was man erreicht.

Im Augenblick habe ich noch keine HW zum Testen, das dauert wohl noch 
ein paar Wochen. Aber dann soll es schon SW für den AVR geben. Wie immer 
halt.

Danke schon Mal,

VG

von Vanye R. (vanye_rijan)


Lesenswert?

> muss der USB Treiber ja immer warten, bis alle Bytes dieses
> Blocks gesendet sind.

Was der USB-Treiber macht haengt natuerlich davon ab wie er programmiert
wird. Das ist halt der Nachteil wenn du dir das Leben einfach macht
mit Python wo doch alles fertig ist. Da hast du halt keinen Einfluss 
drauf.
Aber den Source des Treiber wirst du doch trotzdem lesen koennen.

> Soweit ich weiß läuft USB mit 1KHz, da hängt
> es dann von der Blockgröße ab, was man erreicht.

Das war bei USB1.0 so. Ab USB2 sollte das bei 1/8ms liegen.
Aber ja, das Geheimnis hoher Geschwindigkeit liegt in der Blockgroesse,
und auch wie der Treiber darauf reagiert wenn du ihm z.B nur 1Byte 
schickst. Wartet er dann auf 63 weitere? Hat er einen Timeout und sendet 
irgendwann einfach trotzdem. Das haengt dann von deinem Treiber und 
eventuell dessen Konfiguration ab.

Vanye

von Georg P. (perthil)


Lesenswert?

Beim FT230X steht im Datenblatt USB 2.0 Full Speed compatible. Das wäre 
dann wohl 1ms Zyklus.

Unter Linux habe ich mal gesucht, was pyserial so macht. Soweit ich das 
gesehen habe ruft es Funktionen aus termios auf. Das gehört zum Linux 
System. Da habe ich auch Mal reingeschaut, aber es dann nicht weiter 
verfolgt.

Darum geht es ja erst Mal nur sekundär, zuerst brauche ich Mal die Info 
über den FT230X, also was muss ich am USB senden, dass der FT230X den 
TXDEN so ansteuert, dass es meiner Blockgröße entspricht, und wie kann 
ich verhindern, das der nächste TXDEN zu schnell kommt (dafür soll der 
CTS verwendet werden). Von FTDI habe ich dazu nichts gefunden.

Inzwischen habe ich auch Antwort von FTDI, die verweisen aber nur auf 
Dokumente die ich schon kenne, die aber meine Fragen nicht beantworten. 
Und dann sagen sie noch, ich solle es mit einer HW von ihnen testen. Das 
sieht dann so aus als wollten sie die Info nicht herausgeben, oder viel 
schlimmer, dass sie die Info gar nicht haben (Der Entwickler ist nicht 
mehr in der Firma).

VG

von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

Georg P. schrieb:
> Wenn immer nur ein Block im Buffer stehen kann (entspricht einem
> pyserial write() Aufruf)

Wenn der FT230 einigermaßen clever gebaut ist enthält er einen großen 
Ringpuffer, der mit jedem USB-Transfer weiter aufgefüllt wird. Die 
Ausgabe-Blockgröße hätte dann also relativ wenig mit der Struktur der 
write() -Aufrufe zu tun.

Mit einem USB-fähigen Mikrocontroller wär das ziemlich einfach 
umzusetzen, auch so dass es unabhängig vom Timing des PC ist. Mit 
Emulation eines COM-Port (CDC-ACM) oder ohne. Muss es unbedingt ein 
ATtiny sein?

von Georg P. (perthil)


Lesenswert?

Hallo,

Aber irgendwie muss der FT230X ja den TXDEN für die RS485 ansteuern,
dazu braucht er eine Info, wann er mit dem Senden fertig ist. Und wie 
genau er das macht ist mir nicht klar. Wenn es ein Ringbuffer ist, wird 
der TXDEN also erst inaktiv, wenn er leer ist?

Ein anderer Controller mit USB ist auch möglich, ich habe schon Mal 
einen PIC18 dazu verwendet. Mit dem gab es aber Probleme wenn er mehrere 
Tage lang durch lief, irgendwann fing die UART dann an Daten zu 
schicken, die um ein Bit versetzt waren. Da ging dann gar nichts mehr.

Von den AVRs gibt es da ja nicht viel Auswahl. Im Endeffekt bleibt nur 
der, der auch bei den Arduinos drauf ist.

Außerdem war die Idee, dass man den AVR auch weglassen kann, damit man 
nur den FT230X mit dem proprietären physikalischen Interface dran 
verwenden kann. Aber dann halt nicht mit dem selben, auch proprietären, 
Protokoll.

VG

von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

Georg P. schrieb:
> Wenn es ein Ringbuffer ist, wird der TXDEN also erst inaktiv, wenn er
> leer ist?

Das klingt sehr plausibel denke ich.

Es gibt jede Menge Controller mit USB-Schnittstelle. Viele Cortex-M 
haben das, z.B. die meisten STM32. Sogar auch die ESP32S3. Für die STM32 
spricht dass es gute Freeware Tools gibt.

Ist das RS485 Protokoll denn fix? Kannst du nicht den Paketen ihre Länge 
voran stellen? Dann kannst du auf dem AVR problemlos die einzelnen 
Pakete unterscheiden und es ist egal, ob dazwischen das TXDEN aus geht 
oder nicht.

von Vanye R. (vanye_rijan)


Lesenswert?

> Ein anderer Controller mit USB ist auch möglich, ich habe schon Mal
> einen PIC18 dazu verwendet.

Sowas ist eigentlich die intelligentere Loesung weil du dein Protokoll
kennst und dann entsprechend Nachrichten orientiert handeln kannst.

> Mit dem gab es aber Probleme wenn er mehrere
> Tage lang durch lief, irgendwann fing die UART dann an Daten zu
> schicken, die um ein Bit versetzt waren.

Oh..du hast also einen Programmierfehler und anstatt den zu finden
und zu beheben wechselst du die Hardware?

Vanye

von Georg P. (perthil)


Lesenswert?

Hallo,

Wäre schön gewesen, wenn es ein SW-Fehler gewesen wäre. Ich habe ewig 
gesucht und nichts gefunden was die Daten, die die UART ausgibt erst 
nach mehreren Tagen Betrieb um ein Bit verschiebt. Das Bit was gefehlt 
hat war dann im nächsten Byte.

Ich habe den PIC18 dann durch ein FTDI Modul ersetzt, dann ging es.

Ich hatte den PIC probiert, weil ich noch Portpins benötigt habe, die 
über USART gesetzt werden sollten. Das ging mit dem FTDI natürlich 
nicht, aber er hatte immerhin Portpins, allerdings werden die über USB 
angesprochen.

Aber darum geht es hier nicht. Sondern um das Timing von TXDEN und CTS 
des FT230X.

VG

von Georg P. (perthil)


Lesenswert?

Niklas G. schrieb:
> Ist das RS485 Protokoll denn fix? Kannst du nicht den Paketen ihre Länge
> voran stellen? Dann kannst du auf dem AVR problemlos die einzelnen
> Pakete unterscheiden und es ist egal, ob dazwischen das TXDEN aus geht
> oder nicht.

Es läuft physikalisch nur über eine Leitung, also RS485. Das ist fix.

Das Problem ist nicht, dass der TXDEN dazwischen weggeht, sondern, dass 
er das nicht macht. Dann ist zwischen zwei Blöcken keine Pause von ca. 1 
Byte. Die wird aber benötigt. Die Frage ist also, wie generiere ich 
diese Pause, wenn die PC-Software nicht auf eine Antwort warten muss und 
somit sofort den nächsten Block sendet. Selbst wenn ich dazwischen auf 
der PC-Seite 1 Byte warte (ca 300µs) ist ja nicht garantiert, dass der 
Buffer des FT230X schon leer ist. Der FT230X könnte ja noch gar nicht 
alles gesendet haben, und dann hängt er es an den Ringbuffer und der 
TXDEN geht nicht weg.

Für die Pause sollte der AVR über den CTS# Eingang des FT230X sorgen. Da 
die Blöcke ohne Antwort auch nur 2 Byte haben können, beim FT230X aber 
steht, dass es bis zu 3 Byte dauern kann bis der Sender stoppt, geht das 
wohl so nicht. Der AVR muss auch zuerst erkennen, was gesendet wird, und 
kann erst dann den CTS# aktivieren. Was muss man also über USB senden, 
dass der CTS# den FT230X rechtzeitig stoppt.

Laut FTDI ist das abhängig vom Bufferinhalt. Wie genau wird aber 
nirgends erklärt, und auch auf meine Nachfrage dazu habe ich keine Info 
bekommen. Die sagen nur, man soll den latency timer auf 2ms setzen, dann 
werden incomplete frames sofort gesendet. Was genau ein incomplete frame 
ist wird nirgends erklärt, und was in diesem Fall mit TXDEN und CTS# 
passiert auch nicht.

Ich habe leider von USB zu wenig Ahnung, deshalb auch die Frage ob das 
vom PC aus geht. Die FTDI Treiber stellen dazu ja eigentlich nur write() 
und flush() zur Verfügung. Es muss ja nicht zwangsweise jeder write() 
Aufruf sofort an den FT230X gesendet werden, soweit ich weiß passiert 
das eh nur jede ms. Wenn also ein write() kommt, bevor der USB Block 
(hat glaube ich 64 Byte) voll ist, könnte er ja einfach den Block 
vollschreiben und dann alles zusammen schicken. Was passiert dann mit 
dem TXDEN?

Ein flush() könnte helfen, aber nur, wenn er wartet, bis der Buffer des 
FT230X leer ist, ich vermute aber er wartet nur bis die Daten über USB 
gesendet sind. Wenn es so ist, gibt es irgendeinen Weg zu warten bis der
FT230X alles gesendet hat?

Na ja, ich warte jetzt Mal auf die HW, und dann muss ich es wohl 
probieren.

VG

von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

Georg P. schrieb:
> Die wird aber benötigt.

Warum?

von Georg P. (perthil)


Lesenswert?

Weil die angeschlossenen Geräte das so haben wollen. Die gibt es schon.

VG

von Georg P. (perthil)


Lesenswert?

Das muss ich vielleicht noch näher erklären:

Der AVR generiert eine proprietäre serielle Modulation. Das was der AVR 
ausgibt soll einen möglichst kurzen Zeitversatz haben. Das soll so sein, 
damit die Zeit bis zu einer Antwort nicht zu lang wird und dadurch der 
gewünschte Durchsatz nicht erreicht werden kann. Da läuft eine zyklische 
Abfrage und da soll eine möglichst große Anzahl von Abfragen pro Sekunde 
erreicht werden. Und die Antwort wird ja auch nochmal durch den AVR 
verzögert.

Also fängt der AVR schon mit dem ersten empfangenen Byte vom FT230X an 
zu senden. Wenn er das Ende des Blocks erkennt hört er auf zu Senden und 
schaltet auf Empfang um. Auch da gibt er die empfangenen Bytes sofort 
weiter.

Wenn der gesendete Block jetzt keine Antwort erwartet muss er eine kurze 
Pause vor dem nächsten zu sendenden Block einlegen. Dazu sollte der CTS# 
verwendet werden.
Der AVR läuft also synchron zur seriellen Schnittstelle des FT230X. Er 
benutzt auch den Takt vom FT230X.

Man könnte jetzt die Baudrate des FT230X größer machen, aber da benötigt 
man einen Buffer im AVR der, wenn keine Antwort erwartet wird, auch 
irgendwann voll ist. Somit muss man da den FT230X erst recht bremsen.

Oder man macht die Baudrate des FT230X kleiner. Dann muss man aber die 
Antworten buffern. Und der Durchsatz geht auch runter.

Oder man verdoppelt sie. Dann kann man eigene Bits für Blockstart und 
Blockende einbauen und wäre nicht auf den TXDEN angewiesen. Und man 
könnte einen NOP einbauen. Dann hätte man auch die Pause. Das hört sich 
irgendwie gut an, ich glaube, das werde ich probieren wenn das mit TXDEN 
und CTS# nicht geht. Mal sehen ob der AVR die Baudrate noch schafft. 
Sind ja dann ca. 6000 Bytes/s.

Oder der AVR schickt alles zurück, was vom FT230X kommt. Dann hätte man 
am PC immer eine Antwort auf die man warten kann und somit die 
notwendige Pause. CTS# bräuchte man dann nicht mehr, aber den TXDEN 
schon. Das ist einfach zu realisieren und, da die Blöcke ohne Antwort 
nicht oft auftreten, sollte es den Durchsatz auch nicht vermindern.

Ach ja, noch was zum TXDEN. Im Protokoll der angeschlossenen Geräte gibt 
es ein Start of Frame Signal. Da der TXDEN vor dem Senden gesetzt wird 
hat der AVR genug Zeit um dieses Signal zu erzeugen bevor das erste 
Datenbyte geschickt wird. Damit wird die durch den AVR verursachte 
Verzögerung sinnvoll genutzt und trotz AVR ist es dann nur wenig 
langsamer.

Viel Text und viele Möglichkeiten. Schade nur, dass man wegen fehlender 
Doku so viel Aufwand hat.

Mir hilft es immer sehr wenn ich versuche das was ich vorhabe jemandem 
zu erklären. Auch, wenn ich hier nicht zuviel sagen darf.

Danke für's durchlesen und für's nachfragen.

VG

von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

Also mit dem AVR einen FT230 extern zu "bremsen" find ich irgendwie 
enorm gefrickelt, gerade wenn man einen bestimmten Durchsatz und Latenz 
erreichen möchte.

Mit einem einzelnen USB-fähigen Controller könnte man das viel einfacher 
umsetzen, hätte die Garantie dass das Timing funktioniert, und hat sogar 
weniger Bauteileaufwand und -Kosten. Wenn man ein bisschen was 
leistungsfähigeres als AVR wählt (z.B. STM32) wird das Umsetzen des 
Timings wahrscheinlich auch entspannter.

von Georg P. (perthil)


Lesenswert?

Das ist wohl richtig.

Die HW wird mir so gestellt. Und mit USB will der Kunde möglichst wenig 
zu tun haben. Das ist ihm zu kompliziert. Er möchte auch nichts anderes 
als AVR. Wenn es gar nicht geht ist er vielleicht bereit einen der 
wenigen AVRs mit USB zu nehmen. Mal sehen.

Außerdem: Braucht man dann nicht auch einen eigenen Treiber dafür? Und 
wie sieht es dann mit den USB IDs aus. Braucht man da dann auch eigene?

Da zieht er gar nicht mit. Er hätte gerne was, das in Windows und Linux 
ohne Treiberinstallation und Systemanpassung (Stichwort udev für Linux) 
geht.

Wenn es da eine andere Möglichkeit als mit FTDI gibt, bitte her damit.
Das kann ich ihm ja dann vorschlagen.

VG

von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

Georg P. schrieb:
> Und mit USB will der Kunde möglichst wenig zu tun haben. Das ist ihm zu
> kompliziert. Er möchte auch nichts anderes als AVR.

Wenn du die Software machst kann ihm der Controller doch herzlich egal 
sein...?!

Georg P. schrieb:
> Außerdem: Braucht man dann nicht auch einen eigenen Treiber dafür?

Nein. Mit WinUSB funktioniert das völlig ohne manuelle 
Treiberinstallation/Konfiguration. Einfach anstecken und funktioniert. 
Es ist sogar einfacher, weil man keinen COM-Port auswählen muss, und die 
PC-Software das Gerät anhand VID&PID identifizieren kann.

Georg P. schrieb:
> Braucht man da dann auch eigene?

Ja, du müsstest eine VID kaufen (derzeit 6000$) oder schummeln. Die 
kannst du aber für alle Kunden wieder verwenden, halt mit anderer PID. 
Ist praktisch eine Investition, wie eine Software-Lizenz.

Georg P. schrieb:
> Systemanpassung (Stichwort udev für Linux)

Das wird mit dem COM-Port aber auch nicht gehen, weil der User dafür 
auch Rechte erteilt bekommen muss (typischerweise plugdev Gruppe). On 
man jetzt eine udev-Regel anlegt um allen Usern Zugriff auf das Gerät zu 
geben (= 1 Datei kopieren) oder den User zu einer Gruppe hinzufügt um 
Zugriff zum COM-Port zu geben ist jetzt nicht so der Unterschied.

Alternativ implementierst du die CDC-ACM Klasse (virtueller COM-Port) 
die sich aus PC-Sicht dann genau so verhält wie die Konstellation mit 
dem FT230. Das geht IIRC rein technisch auch mit VID=0... Ist aber auch 
nicht besonders toll.

Georg P. schrieb:
> Da zieht er gar nicht mit

Das Argument dass ohne FT230 die Hardware billiger wird zieht gar 
nicht...?

: Bearbeitet durch User
von Georg P. (perthil)


Lesenswert?

Niklas G. schrieb:
> Das Argument dass ohne FT230 die Hardware billiger wird zieht gar
> nicht...?

Nein, er sagt, das akzeptiert er. Da sind keine großen Stückzahlen 
dahinter.

VG

von Georg P. (perthil)


Lesenswert?

Niklas G. schrieb:
> Das wird mit dem COM-Port aber auch nicht gehen,

Also bei mir braucht bei Linux der User nur in der Gruppe dialout zu 
sein. Und bei Windows muss ich gar nichts machen.

VG

von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

Georg P. schrieb:
> Also bei mir braucht bei Linux der User nur in der Gruppe dialout zu
> sein

Mit custom USB Protokoll muss man eine Datei nach /etc/udev/rules.d 
kopieren, ähnlicher Aufwand. Das kann auch als Teil des 
Installationspakets (.deb o.ä.) automatisch passieren.

Georg P. schrieb:
> Und bei Windows muss ich gar nichts machen.

Du musst immer noch den COM-Port auswählen (war es jetzt COM23 oder 
COM56?). Auch das entfällt bei Custom USB Protokoll.

Ein weiterer Vorteil davon wäre dass die Protokoll-Umsetzung sehr 
flexibel ist, du kannst rein per Software Update Anpassungen am 
Timing/Protokollstruktur ausliefern. Bei der FT230-Lösung mit den 
hart-verdrahteten Signalen ist man da schon festgelegter.

von Georg P. (perthil)


Lesenswert?

Niklas G. schrieb:
> Du musst immer noch den COM-Port auswählen

Ja, aber welcher Laptop oder PC hat heutzutage noch COM-Ports? Wenn es 
nur eines gibt, kann es auch nur das sein. Somit entfällt das in den 
meisten Fällen.

Und wegen der Flexibilität:
Bei dem proprietären Protokoll sind keine Änderungen zu erwarten, da 
hängt zuviel dran, was dann auch geändert werden müsste. Sollte das 
wirklich Mal der Fall sein, kann man ja einen neuen Adapter machen. Das 
geht dann in den anderen Kosten unter.

VG

von Niklas G. (erlkoenig) Benutzerseite


Angehängte Dateien:

Lesenswert?

Georg P. schrieb:
> Wenn es
> nur eines gibt, kann es auch nur das sein. Somit entfällt das in den
> meisten Fällen.

Tja...

von Thomas Z. (usbman)


Lesenswert?

Georg P. schrieb:
> Wenn es
> nur eines gibt, kann es auch nur das sein. Somit entfällt das in den
> meisten Fällen.

je nachdem wie das gebaut ist bekommst du schon unterschiedliche com 
ports wenn du nur an eine andere USB Buchse ansteckst.

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.