Forum: Mikrocontroller und Digitale Elektronik I2C - "best practice" bei NACK vom Slave


von Ralf G. (dl5eu)


Lesenswert?

Hallo zusammen,

ich möchte einen I2C-Slave mit einem FT2232H (MPSSE) ansteuern. Nun 
passiert es manchmal, dass der Slave auf das Schreiben in eines seiner 
Register mit NACK antwortet, wahrscheinlich weil er gerade keine Daten 
annehmen kann. In einem mir vorliegenden Treiber wird in einem solchen 
Fall das Schreiben so lange wiederholt, bis der Slave die Daten annimmt 
und mit ACK quittiert oder aber ein Timeout auftritt, was dann als 
Fehler gewertet wird. Ob der Slave-IC Clock Stretching verwendet weiß 
ich nicht, da ich im Netz kein ausführliches Datenblatt zu dem IC finden 
kann. Und selbst wenn, der FT2232H unterstützt Clock Stretching meines 
Wissens nicht.

Meine Frage ist: gibt es eine "best practice", wie man in einem solchen 
Fall vorgehen sollte? Das u.U. mehrfache Wiederholen des Schreibbefehls 
funktioniert zwar, denn irgendwann ist der Slave bereit die Daten 
anzunehmen. Trotzdem wüsste ich gerne, ob es vielleicht noch andere, 
elegantere Lösungen für diesen Fall gibt. Natürlich könnte ich vor dem 
Senden eines Bytes prüfen, ob der Slave SCL freigegeben hat, aber wenn 
das Clock Stretching zwischen dem 1. und 8. Bit erfolgt bringt mir das 
nichts, weil der FT2232H das bei einem "Clock Out Byte" nicht handeln 
kann. Und jedes Byte per Programm bitweise auf den Bus zu legen kann ja 
wohl auch nicht die Lösung sein.

Bitte keine Antworten der Art "verwende doch einen anderen IC", denn die 
Hardware ist gegeben und ich kann sie nicht ändern.

Vielen Dank für Eure Hilfe.

Grüße,

Ralf

von Andreas H. (ahz)


Lesenswert?

Ralf G. schrieb:
> gibt es eine "best practice", wie man in einem solchen
> Fall vorgehen sollte?

Nein, gibt es nicht.

Das liegt simpel daran, dass unterschiedliche I2C Slaves mit dem NACK 
unterschiedliche Sachen kennzeichnen. NACk beim Read kann z.B. heissen, 
dass keine weiteren Daten verfügbar sind, was kein Fehler sein muss, 
während ein NACK bei einem WRITE z.B. entweder "Not Ready - Try again 
later" oder "(Sub-)address not know" heissen kann.

Welchen Slave hast Du denn? Vielleicht gibts da ja Erfahrungswerte.

/regards

P.S: Hast Recht. Dein FTDI kann kein Clk-stretching mit MPSSE. Siehe 
Kapitel 8.2 "Clock Stretching" in "AN_411FTx232H MPSSE I2C MasterExample 
in C#"

von Ralf G. (dl5eu)


Lesenswert?

Hallo Andreas,

der Slave ist ein STV0910. Dazu gehört auch noch ein STV6120. Beide 
sitzen in einem DVB-S/S2-Tunermodul. Mehr als ein 4-seitiges 
Kurzdatenblatt habe ich dazu nicht finden können.

Ralf

von Andreas H. (ahz)


Lesenswert?

Ralf G. schrieb:
> Mehr als ein 4-seitiges
> Kurzdatenblatt habe ich dazu nicht finden können.

Ja, die Datenblattlage ist da wirklich dürftig.
Was Komplettes bekommst Du da (vermutlich) nur als potentieller 
Großkunde :/

BATC hat allerdings eine Spec der FTS-4335 Serie von FINETECH rumliegen:

https://wiki.batc.org.uk/File:FTS-4335_Series_F2.pdf

Die FTS-4335 haben genau diesen Chipset und in der Spec sind anscheinend 
auch die Register für I2C beschrieben. Vieleicht hilfts ja :)

/regards

von hard werker (Gast)


Lesenswert?

Andreas H. schrieb:
> BATC hat allerdings eine Spec der FTS-4335 Serie von FINETECH rumliegen:

Not bad, sir! Räspäggd!

von Ralf G. (dl5eu)


Lesenswert?

Hallo,

Dieses Datenblatt habe ich, aber da steht m.W. auch nicht drin, ob der 
STV0910 Clock-Stretching verwendet. Und selbst wenn, der FT2232H kann es 
ja nicht.

Egal, da es sich hier um ein "Rufen Sie bitte später noch mal an" 
handelt und mehrfaches Schreiben und Prüfen auf ACK, gekoppelt mit einem 
Timeout, das Problem löst ist dies in Ermangelung einer festgelegten 
Vorgehensweise oder "best practice" vielleicht nicht das eleganteste, 
aber ein zulässiges Mittel.

Grüße,

Ralf

von Michael U. (amiga)


Lesenswert?

Hallo,

Ralf G. schrieb:
> Egal, da es sich hier um ein "Rufen Sie bitte später noch mal an"
> handelt und mehrfaches Schreiben und Prüfen auf ACK, gekoppelt mit einem
> Timeout, das Problem löst ist dies in Ermangelung einer festgelegten
> Vorgehensweise oder "best practice" vielleicht nicht das eleganteste,
> aber ein zulässiges Mittel.

Das wird nur selten klappen, Clock Stretching kann den Takz irgendwann 
festhalten, wenn der Slave einen Moment mehr Zeit braucht. Der Slave 
erwartet dann, daß es in der Übertragung genau da weitergeht, wo die 
war, wenn er Clock wieder frei gibt.
Das Problem ist nicht "rufen Sie später nochmal an" sondern "Moment, ich 
bin noch am sortieren" mitten in einer Byteübertragung. Sonst bräuchte 
man garkein ClockStretching, es würd NACK/ACK völlig reichen.
Ein Slave, der ClockStretching benutzt, kommt mit einem Master, der es 
nicht kann, nicht klar.
Hat mich vor Jahren mal sehr genervt, weil die erste I2C-Appnote vom AVR 
es nicht drin hatte und ich mich da auch erst schlau machen mußte.

Gruß aus Berlin
Michael

von Oliver S. (oliverso)


Lesenswert?

Ralf G. schrieb:
> Dieses Datenblatt habe ich, aber da steht m.W. auch nicht drin, ob der
> STV0910 Clock-Stretching verwendet. Und selbst wenn, der FT2232H kann es
> ja nicht.

Ist doch auch völlig egal. Der Slave sagt dir durch das NACK, daß er 
schon alle Daten hat, oder die Daten nicht angenommen hat, oder daß er 
keine weiteren Daten annehmen will, oder daß er ganz kaputt ist, oder 
daß der BUS gestört ist, oder was auch immer.

Ein NACK ist schlicht und einfach "keine Reaktion".

Was das für die Funktion bedeutet, und was dann dafür jeweils die 
sinnvollste Vorgehensweise ist, ist die ureigenste Aufgabe, die du als 
Entwickler lösen musst.

Mach einfach deinen Job.

Oliver

von Ralf G. (dl5eu)


Lesenswert?

Hallo,

Michael U. schrieb:
> Ein Slave, der ClockStretching benutzt, kommt mit einem Master, der es
> nicht kann, nicht klar.

das sehe ich auch so, aber wie geschrieben, ist die Hardware in ihrer 
jetzigen Form gegeben und momentan muss ich damit leben und ob der Slave 
überhaupt Clock-Stretching verwendet weiß ich nicht.

Oliver S. schrieb:
> Was das für die Funktion bedeutet, und was dann dafür jeweils die
> sinnvollste Vorgehensweise ist, ist die ureigenste Aufgabe, die du als
> Entwickler lösen musst.

Genau. Ich wollte ja nur wissen, ob es ein standardisiertes Verfahren 
oder "best practice" gibt, wie solche Fälle behandelt werden (sollten). 
In meinem Fall (Hobbyprojekt) spielt es keine Rolle, warum die Daten 
manchmal nicht angenommen werden und wenn mehrere Schreibversuche 
innerhalb einer festgelegten Zeitspanne zum Erfolg führen reicht das. 
Leben hängt davon nicht ab :-)

Ralf

von hard werker (Gast)


Lesenswert?

Ralf G. schrieb:
> der Slave ist ein STV0910. Dazu gehört auch noch ein STV6120.

Ich würde es mal von einer anderen Seite betrachten. Die
genannten Chips sind mit hoher Wahrscheinlichkeit nicht
von der Sorte "hochdynamisch", werden also das Clock-
Stretching nicht nutzen bzw. implementiert haben. Das sind
"einfache" Gesellen die Teilerwerte einstellen (Synthesizer)
und HF-Pfade umschalten bzw. konfigurieren. Daher würde ich
bei der genannten Problematik eher von eine unzuverlässig
aufgebauten Hardware ausgehen die man mit der Intelligenz
des ansteuernden Treibers versucht zur Zuverlässigkeit zu
bringen (zwingen).

Ralf G. schrieb:
> In einem mir vorliegenden Treiber wird in einem solchen
> Fall das Schreiben so lange wiederholt, bis der Slave die Daten annimmt
> und mit ACK quittiert oder aber ein Timeout auftritt, was dann als
> Fehler gewertet wird.

Wenn man den Treiber als gottgegeben hinnehmen muss dann ist
man hier am Ende. Aber es gäbe auch die Möglichkeit mittels
FT2232 das I2C-Protokoll mit Bitbanging zu implementieren. Und
wenn ich die Zeit dazu hätte und mich das Problem nervt dann
würde ich versuchen mit einem einfachen Mikrocontroller das
Clock-Stretching mit dieser Ziel-Hardware zu provozieren. Ich
lehne mich mal aus dem Fenster und sage dass ich keines
bekommen würde. Denn das Clock-Stretching braucht ja nur
ein Slave der selbst - wie bereits gesagt - "hochdynamisch"
ist und beim Datenaustausch in Zeitnot gerät, was ich bei der
vorliegenden Hardware für unwahrscheinlich halte.

Also, wie schaut die komplette Hardware aus? Lange Leitungen,
schwache Pullups, unterschiedliche Potentiale zwischen
Master und Slave (gibts nicht, gell), schlechte Stromver-
sorgung, schlechte Abblockung? Jede Menge Möglichkeiten
für Kommunikationsfehler.

In der Software: versehentlich falsche Clockrate? Ich
erinnere mich beim FT2232 an eine unübersichtliche Einstellung
der SPI-Clockrate, wenn das bei I2C auch so ist .... es
gibt viele Fehlerquellen wobei ich das Clock-Stretching nicht
für die tatsächliche Problematik halte.

Wie so oft gilt auch hier: YMMV

von Peter D. (peda)


Lesenswert?

"best practice" ist, nach dem NACK ein STOP zu senden.

von Kochstudio (Gast)


Lesenswert?

best partice ist auch besser mit einem Ozi im dunklen stochern als ohne 
:-)

von Purzel H. (hacky)


Lesenswert?

Ich wuerde NIE ein "repeat until Ack" machen. Das ist nicht 
zielfuehrend. Erstens bleibt dir der Prozess da blockiert, zweitens kann 
was kaputt gehen, denn eine Million zyklen sind schnell erreicht. Das 
reicht fuer eine EEPROM speicherstelle.
Allenfalls man mit dem Oszilloskop das Timing pruefen, allenfalls den 
Delay messen und fuer die anderen Male vorhalten. Falls ich annehme das 
Device muesste zu einem Zeitpunktmit einem Ack antworten, den Fall 
dokumentieren und den Hersteller anfragen.
Du willst ja nicht mit Hardware arbeiten, die du nicht verstehst. Denn 
dann geht das Vertrauen in die Zuverlaessigkeit gegen Null. Das geht 
nicht. Sorry. Das Vertrauen in die Zuverlaessigkeit muss 100% sein, 
sonst sollte man's sein lassen.

von hard werker (Gast)


Lesenswert?

Purzel H. schrieb:
> Ich wuerde NIE ein "repeat until Ack" machen. Das ist nicht
> zielfuehrend. Erstens bleibt dir der Prozess da blockiert, zweitens kann
> was kaputt gehen, denn eine Million zyklen sind schnell erreicht. Das
> reicht fuer eine EEPROM speicherstelle.

Er hat aber keine I2C Slaves mit Speicherstellen. Wenn du
aufgepasst hast dann wirst du wissen dass es sich um
programmierbare Hardware handelt deren Inhalt sehr flüchtig
ist, also nur solange Spannung da ist ihren Zustand behält.

Nix EEPROM oder Flash oder so ...

Purzel H. schrieb:
> Das Vertrauen in die Zuverlaessigkeit muss 100% sein,
> sonst sollte man's sein lassen.

Da stimme ich dir zu, deshalb auch meine Vermutung dass der
Harware-Aufbau nicht ausreichend stabil ist.

"Kann ich meinen Rasensprenger mit einer 15 Meter langen
I2C Bus Leitung steuern?" Radio Eriwan: "Im Prinzip ja."

von Ralf G. (dl5eu)


Lesenswert?

Ach du meine Güte, was habe ich denn hier angerichtet? Ich habe doch nur 
eine einfach zu beantwortende Frage gestellt. Lest doch bitte nochmal 
mein erstes Posting durch:

Ralf G. schrieb:
> Meine Frage ist: gibt es eine "best practice", wie man in einem solchen
> Fall vorgehen sollte? Das u.U. mehrfache Wiederholen des Schreibbefehls
> funktioniert zwar, denn irgendwann ist der Slave bereit die Daten
> anzunehmen. Trotzdem wüsste ich gerne, ob es vielleicht noch andere,
> elegantere Lösungen für diesen Fall gibt.

Hier ist vielleicht hinzuzufügen, dass der Slave zum Zeitpunkt des 
Datenempfangs eventuell einfach nur beschäftigt ist und keine Daten 
annehmen kann, aus welchen Gründen auch immer. Immerhin kann so etwas 
laut Spezifikation vorkommen (NXP UM10204, Seite 10, Punkt 3.1.6) und 
dann bekommt man vom Slave ein NACK.

hard werker schrieb:
> Wenn man den Treiber als gottgegeben hinnehmen muss dann ist
> man hier am Ende.

Ralf G. schrieb:
> die Hardware ist gegeben

Wenn ich den mir vorliegenden Treiber unverändert verwenden könnte oder 
möchte hätte ich meine Frage nicht gestellt. Dieser Treiber verwendet 
libusb und ist für Linux gedacht. Dummerweise gibt es aber (mindestens) 
einen wesentlichen Unterschied im Verhalten von libusb unter Linux und 
libusb unter Windows der in meinem Fall zum Tragen kommt und auf den ich 
hier aber nicht näher eingehen will. Dazu habe ich in einem anderen 
Forum eine ganz konkrete Frage gestellt aber bisher keine Antwort 
bekommen. Ist wahrscheinlich wieder einmal zu speziell...

hard werker schrieb:
> Aber es gäbe auch die Möglichkeit mittels
> FT2232 das I2C-Protokoll mit Bitbanging zu implementieren.

Wenn ich die MPSSE des FT2232H verwende muss ich schon genug "von Hand" 
machen (START und STOP-Bedingung generieren, ACK und NACK generieren und 
aufpassen, dass nicht unbeabsichtigt GPIO-Leitungen geändert werden).

hard werker schrieb:
> Also, wie schaut die komplette Hardware aus? Lange Leitungen,
> schwache Pullups, unterschiedliche Potentiale zwischen
> Master und Slave (gibts nicht, gell), schlechte Stromver-
> sorgung, schlechte Abblockung? Jede Menge Möglichkeiten
> für Kommunikationsfehler.

Nochmal, die Hardware existiert bereits und wurde nicht von mir 
entwickelt,  aber ich werde anhand des Schaltbilds und des Layouts 
prüfen, ob evtl. einer der genannten Punkte als Fehlerquelle in Frage 
kommen könnte und ob in einem solchen Fall evtl. Änderungen mit 
einfachen Mitteln möglich sind.

hard werker schrieb:
> In der Software: versehentlich falsche Clockrate? Ich
> erinnere mich beim FT2232 an eine unübersichtliche Einstellung
> der SPI-Clockrate, wenn das bei I2C auch so ist

Die Clockrate habe ich auf 400 kHz eingestellt (und nachgemessen). Bei 
100 kHz tritt das Problem aber auch auf.

Peter D. schrieb:
> "best practice" ist, nach dem NACK ein STOP zu senden.

Und dann? War es das? Ein NACK muss ja nicht immer ein Fehler sein 
(siehe oben). Übrigens macht mein Code genau das und das nicht nur nach 
einem NACK, sondern immer dann, wenn eine Aktion (z.B. Schreiben in ein 
oder Lesen aus einem Register) beendet ist.

Purzel H. schrieb:
> Ich wuerde NIE ein "repeat until Ack" machen. Das ist nicht
> zielfuehrend. Erstens bleibt dir der Prozess da blockiert

Zur Erinnerung:

Ralf G. schrieb:
> mehrfaches Schreiben und Prüfen auf ACK, gekoppelt mit einem
> Timeout

Purzel H. schrieb:
> Du willst ja nicht mit Hardware arbeiten, die du nicht verstehst.

Nein, will ich nicht. Leider geben aber viele Hersteller detaillierte 
Informationen zu ihren Produkten nur gegen ein NDA heraus, was in meinem 
Fall (Hobby) keine Option ist. Wären ausführliche Datenblätter zum 
STV0910 (und STV6120) verfügbar hätte ich sie wahrscheinlich im Netz 
gefunden.

Vielleicht sollte ich die Frage als beantwortet betrachten, sonst gibt 
es hier noch einen Glaubenskrieg ;-)

Vielen Dank und viele Grüße,

Ralf

von hard werker (Gast)


Lesenswert?

Ralf G. schrieb:
> Vielleicht sollte ich die Frage als beantwortet betrachten, sonst gibt
> es hier noch einen Glaubenskrieg

Nun ja, auf Probleme mit Pfusch am Bau gibt es halt keine
klaren Antworten. Höchstens den Lösungsvorschlag "alles
von vorne".

Wenn ich jemals Probleme mit I2C gehabt hätte (die ich
nicht selbst zu verantworten hatte) würde ich dich vielleicht
verstehen. Tu ich aber nicht.

von Peter D. (peda)


Lesenswert?

Z.B. ein AT24C512C hat eine Schreibzeit von max 5ms. D.h. nach einen 
NACK probiert man es für max 5ms nochmal.
Es hängt also immer vom jeweiligen Slave ab.

Ob ein Slave Clock Stretching benötigt, kann man daran erkennen, ob SCL 
nur ein Eingang oder auch ein Ausgang ist. Ein Eingang benötigt kein 
Clock Stretching, d.h. der Master kann mit maximaler Bitrate senden.

von Ralf G. (dl5eu)


Lesenswert?

Hallo Peter,

Peter D. schrieb:
> Ob ein Slave Clock Stretching benötigt, kann man daran erkennen, ob SCL
> nur ein Eingang oder auch ein Ausgang ist.

Danke für den Hinweis. Leider habe ich diese Information bezüglich des 
STV0910 nicht.

Grüße,

Ralf

von Kochstudio (Gast)


Lesenswert?

Peter D. schrieb:
> Ob ein Slave Clock Stretching benötigt, kann man daran erkennen, ob SCL
> nur ein Eingang oder auch ein Ausgang ist

und woran kann man wiederum das erkenne. vielleicht daran das der 
Baustein CLK Stretching macht? -> rekursiv

von S. R. (svenska)


Lesenswert?

Ralf G. schrieb:
> Meine Frage ist: gibt es eine "best practice", wie man in einem solchen
> Fall vorgehen sollte? Das u.U. mehrfache Wiederholen des Schreibbefehls
> funktioniert zwar, denn irgendwann ist der Slave bereit die Daten
> anzunehmen.

Eine "best practice" gibt es nicht, weil das korrekte Verhalten von der 
Anwendung abhängt. An Stellen, wo ich mit temporären Aussetzern rechnen 
muss, sehe ich meist eine geringe Anzahl an Wiederholungen (mit kurzer 
Verzögerung nach jedem Versuch) vor.

Im vom Peda genannten Beispiel also "wenn der Flash ein NACK wirft, dann 
5ms warten und nochmal probieren", aber gepaart mit "maximal drei 
Versuche". Wenn es dann immernoch nicht geht, ist wohl was kaputt.

Den Versuchszähler kann man auch halb-global machen, d.h. "maximal drei 
Versuche für die gesamte Initialisierungssequenz". Einen kurzen ESD auf 
der Leitung kann man damit ausgleichen, aber eine allgemein schlechte 
Leitung wirft dann trotzdem Fehler.

Kochstudio schrieb:
>> Ob ein Slave Clock Stretching benötigt, kann man daran erkennen,
>> ob SCL nur ein Eingang oder auch ein Ausgang ist
> und woran kann man wiederum das erkenne.

Sowas könnte im Datenblatt stehen.
Hier offensichtlich nicht, daher hilft das nicht weiter.

von Rainer V. (a_zip)


Lesenswert?

Ralf G. schrieb:
> Vielleicht sollte ich die Frage als beantwortet betrachten, sonst gibt
> es hier noch einen Glaubenskrieg ;-)

Na ja, Glaubenskrieg wird es erst, wenn die "hater" auf die Bühne 
kommen. Die Frage nach best practice scheint ja wirklich (negativ) 
beantwortet zu sein. Und da du "nur" bastelst, sollte es das sein, mit 
dem du klar kommst. Letztlich kommt das wahrscheinlich darauf an, was 
mit dem erwarteten Wert passieren soll/muß. Davon wird abhängen, wie 
schnell du zu dem Schluß "kaputt" kommst. Obs dann wirklich kaputt ist, 
ist eine weitere Frage...
Gruß Rainer

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.