Forum: Mikrocontroller und Digitale Elektronik I2C Konflikt


von Michael (Gast)


Lesenswert?

Hallo zusammen,

ich habe mal eine grundsätzliche Frage.

Ich arbeite mit einem MSP430FR5729 und spreche über I2C zwei Devices an.

Hin und wieder bricht der Bus "zufällig" zusammen und keine 
Kommunikation ist dann mehr möglich. Der MSP430 hängt dann meist in 
folgender Zeile:
1
while (UCB0CTL1 & UCTXSTP);             // Ensure stop condition got sent

Klar, ich könnte diese Zeile sinnvoller gestalten mit einem Zähler drum 
herum und/oder einem Watchdog als zusätzliche Sicherheit.

Aber was kann denn grundsätzlich die Ursache für diesen plötzlichen 
Bus-Crash sein?

von Joe F. (easylife)


Lesenswert?

Da solltest du mal mit einem Oszilloskop oder einem Logic-Analyzer 
nachschauen, wie die Signale kurz vor und beim "crash" aussehen.
Vermutlich hält einer der Slaves die Clock low (clock stretching) und 
lässt sie nicht wieder los.
Für eine gewisse Zeit ist dies zulässig, wenn ein Slave z.B. 
signalisieren möchte, dass er z.Zt. busy ist.
Er sollte den Bus natürlich nicht dauerhaft blockieren.

: Bearbeitet durch User
von Wolfgang (Gast)


Lesenswert?

Michael schrieb:
> Klar, ich könnte diese Zeile sinnvoller gestalten mit einem Zähler drum
> herum und/oder einem Watchdog als zusätzliche Sicherheit.

Das nützt aber dem Bus nichts, falls einer der Slaves Mist baut.

von Klaus R. (klara)


Lesenswert?

Michael schrieb:

> Hin und wieder bricht der Bus "zufällig" zusammen und keine
> Kommunikation ist dann mehr möglich. Der MSP430 hängt dann meist in
> folgender Zeile:
> while (UCB0CTL1 & UCTXSTP);             // Ensure stop condition got
> sent
>
Da hätte ich vermutlich eine Lösung:
Beitrag "I2C hängt sich auf"

mfg klaus

von Sascha (Gast)


Lesenswert?

Vlt. hilft dir das:
Ich hatte auch mal das Problem, dass sich der I2C-Bus aufhängt und ich 
quasi an selber Stelle fest saß. Trat immer sporadisch auf. Bis ich das 
einmal reproduzieren konnte und da hatte ich einen Page-Write-Zugriff 
versucht (also quasi mehrere Bytes nacheinander ab Page-Startadresse 
schreiben), hab aber dann kein einziges Daten-Byte geschickt. Also 
Start, alle Vorbereitungen zum Schreiben und dann die Stop-Condition. 
Das EEPROM hat dann den Bus blockiert und nicht mehr hergegeben, also 
Spannung weg und wieder dran und schon liefs wieder bis zur nächsten 
Runde.
War einfach ein vergessenes -1 bei der Berechnung der Anzahl zu 
schreibender Pages. Hat niemand gemerkt, bis ein Datenblock genau am 
Ende einer Page zuende war... lief schon Jahre in Serie bis dieser 
EEPROM-Code von mir in meine Software eingebaut wurde ;-)

von msp430_i2c (Gast)


Lesenswert?

Hallo zusammen,

danke für zahlreichen Tipps. Bisher bekämpfe ich das Problem mit Hilfe 
eines Watchdogs, die Ursache habe ich dennoch noch nicht gefunden.

Gruß

von Klaus R. (klara)


Lesenswert?

Hallo,
hast Du Dir den von mir aufgezeigten Thread durchgelesen? Im Kern geht 
es dabei um einen erweiterten I2C-INIT. Der löst gewisse Blockaden. In 
Deinem Fall kann es allerdings noch eine andere Ursache sein.
mfg Klaus

von Peter D. (peda)


Lesenswert?

Wenn man für I2C-Master keine Interrupts benutzt, sondern eh wartet, 
kann man das auch ganz bequem per Bit-Banging machen. Dann kann sich 
nichts aufhängen und mehr Code ist es auch nicht.

von Klaus (Gast)


Lesenswert?

Peter D. schrieb:
> Wenn man für I2C-Master keine Interrupts benutzt, sondern eh wartet,
> kann man das auch ganz bequem per Bit-Banging machen. Dann kann sich
> nichts aufhängen und mehr Code ist es auch nicht.

Nur, wenn der Code nicht in Ordnung ist.

Beim TO versucht der Master ein STOP auf den Bus zu legen und den 
Zustand der Leitungen dahingegen zu überprüfen. Auf dem Bus kommt aber 
kein Stop an (IMHO weil SDA vom Slave festgehalten wird), das 
entsprechende Controlerbit wird daher nicht gesetzt.

Wenn man die Überprüfung, ob auf dem Bus ein STOP angekommen ist, im 
eigenen Code nicht macht, sondern nur eine Bitzeit wartet, hängt der 
BitBang Code nicht, und es sieht erstmal gut aus. Man könnte sich aber 
bei Verwendung der HW auch die Abfrage des Bits im Controler sparen und 
einfach eine Bitzeit warten. Dann läuft das Programm ebenfalls weiter. 
Der Bus hängt in beiden Fällen, man merkts nur später. Ein LA würde es 
einem gleich zeigen und wenn man Glück hat, auch seit wann er schon 
hängt. Da ist der wirkliche Bug.

Einen Slave kann man abschießen, mit eigenem Code oder mit Hilfe der 
Hardware. Vielfach reicht es, das letzte Byte eines Reads nicht mit NAK 
zu quitieren oder einen Read in der Mitte eines Bytes im Debugger 
abzuwürgen und den Code neu zu starten. Oder es ist so ein "Page 
Problem" wie bei Sascha.

MfG Klaus

von Peter D. (peda)


Lesenswert?

Einen blockierenden Slave kann man ganz einfach mit Bit-Banging lösen.
Man testet vor jedem Start, ob SDA high ist und erzeugt bei Bedarf bis 
zu 9 SCL-Takte.
Soweit mir bekannt, hat aber kein Hardware-I2C eine solche Funktion.
Daneben gibt es HW-I2C, die sich auch ganz von selber aufhängen können, 
weil sie einen Bug haben. Z.B. bei den ATmega AVRs reicht es schon, wenn 
noch ein Master am Bus hängt, d.h. man Multimaster-I2C benutzen will.

von c-hater (Gast)


Lesenswert?

Peter D. schrieb:

> Daneben gibt es HW-I2C, die sich auch ganz von selber aufhängen können,
> weil sie einen Bug haben. Z.B. bei den ATmega AVRs reicht es schon, wenn
> noch ein Master am Bus hängt, d.h. man Multimaster-I2C benutzen will.

Die TWI-Logik der AVRs hat meines Wissens nach keine diesbezüglichen 
Fehler.

Weder sind solche in irgendwelchen errata beschrieben noch konnte ich 
jemals selber welche feststellen.

Kann es mal sein, dass einfach DU den doch recht ausführlichen Teil 
des DB zum Thema TWI-MM nicht vollständig gelesen hast oder nicht alle 
dort ausführlich beschriebenen Restriktionen im Code aller beteiligten 
Master korrekt umgesetzt hast?

Als da im Wesentlichen sind:

1) Wann darf ich überhaupt nicht senden...
2) Was muß ich tun, wenn ich einen Konflikt mit einem anderen Master
   bemerke...
3) Welche Grundbedingungen gibt es dafür, dass ich diesen Konflikt
   überhaupt zuverlässig bemerken KANN...

von Joe F. (easylife)


Lesenswert?

...und genau darum würde es helfen, mit einem entsprechenden Analyzer 
auf den Bus zu gucken, um herauszufinden was kurz vor dem Fehlerfall 
passiert ist, und warum die Stop-Condition nicht stattfindet (ob SDA 
oder SCL auf low gehalten wird).

Eventuell sind ja auch einfach die Pegel grottig, oder die Pull-Ups 
stimmen nicht, oder das Timing ist kaputt.
Daher auch besser zusätzlich mit einem Oszilloskop angucken.

: Bearbeitet durch User
von Peter D. (peda)


Lesenswert?

c-hater schrieb:
> Weder sind solche in irgendwelchen errata beschrieben noch konnte ich
> jemals selber welche feststellen.

Z.B. hier:
http://www.robotroom.com/Atmel-AVR-TWI-I2C-Multi-Master-Problem.html

Alle dort beschriebenen Fehler konnte ich reproduzieren.
Vermutlich hat Atmel die Multimasterfunktion nie getestet.

Da Philips/NXP seine 8051 mit I2C eingestampft hat, wollte ich ein Gerät 
auf AVR umrüsten. Schon bei nur einem neuen AVR-Modul krachte es.

Als Lösung hab ich dann letztendlich ein Timeout aufsetzen müssen, das 
bei den 3 Fehlern das klemmende TWI kurz disabled, enabled und den 
vergeigten Transfer wiederholt. Ist nicht schön, aber es geht nicht 
anders.
Die alten Philips/NXP liefen völlig ohne Timeout stabil.

Formal sieht das AVR-TWI wie von Philips abgekupfert aus (gleiche 
Register, Bits, States), ich konnte also den C-Code vom 8051 übernehmen. 
Bloß bei der Hardware sind Atmel eben die besagten 3 Fehler passiert und 
niemand hats geprüft.

Die Atmel 8051 mit I2C haben übrigens die gleichen Fehler, wie die AVRs.
Und da ist es eindeutig der Atmel, da ich ja den gleichen Code und den 
gleichen Compiler (Keil C51) wie beim Philips 8051 benutzt habe.

: Bearbeitet durch User
von Peter D. (peda)


Lesenswert?

c-hater schrieb:
> 1) Wann darf ich überhaupt nicht senden...

Theoretisch kann ich immer senden, da jeder Multimaster den Bus 
überwachen muß und somit das Stop eines anderen erkennt.
Die Startbedingung darf das HW-I2C erst nach dem Erkennen eines Stop und 
der vorgeschriebenen Wartezeit auf den Bus legen, bzw. sofort, falls der 
Bus bereits idle ist.
Praktisch kann ich das Startbit beim Philips 8051 jederzeit setzen.

c-hater schrieb:
> 2) Was muß ich tun, wenn ich einen Konflikt mit einem anderen Master
>    bemerke...

Theoretisch muß ich nur die Arbitration-Lost States behandeln.
Praktisch klappt das aber nur beim Philips 8051 zu 100% zuverlässig.

c-hater schrieb:
> 3) Welche Grundbedingungen gibt es dafür, dass ich diesen Konflikt
>    überhaupt zuverlässig bemerken KANN...

Alle HW-I2C müssen einfach nur den von Philips definierten I2C-Standard 
einhalten.

von Joe F. (easylife)


Lesenswert?

Peter D. schrieb:
> c-hater schrieb:
>> 3) Welche Grundbedingungen gibt es dafür, dass ich diesen Konflikt
>>    überhaupt zuverlässig bemerken KANN...
>
> Alle HW-I2C müssen einfach nur den von Philips definierten I2C-Standard
> einhalten.

Wenn ich das mal noch erleben dürfte... ;-)

von c-hater (Gast)


Lesenswert?

Peter D. schrieb:

>> 1) Wann darf ich überhaupt nicht senden...
>
> Theoretisch kann ich immer senden

Das DB sagt hingegen:

Note that arbitration is not allowed between:
• A REPEATED START condition and a data bit.
• A STOP condition and a data bit.
• A REPEATED START and a STOP condition.
It is the user software’s responsibility to ensure that these illegal 
arbitration conditions never occur. This implies that in multi-master 
systems, all data transfers must use the same composition of SLA+R/W and 
data packets. In other words: All transmissions must contain the same
number of data packets, otherwise the result of the arbitration is 
undefined.


>> 2) Was muß ich tun, wenn ich einen Konflikt mit einem anderen Master
>>    bemerke...
>
> Theoretisch muß ich nur die Arbitration-Lost States behandeln.

Das DB sagt hingegen:

When a contending master discovers that it has lost the arbitration 
process, it should immediately switch to Slave mode to check whether it 
is being addressed by the winning master.

> Alle HW-I2C müssen einfach nur den von Philips definierten I2C-Standard
> einhalten.

Es gibt Sachen, die nicht explizit im Standard stehen müssen, weil sie 
sich aus der Logik der Sache selber zwingend ergeben.

von Peter D. (peda)


Lesenswert?

c-hater schrieb:
> Note that arbitration is not allowed between:
> • A REPEATED START condition and a data bit.
> • A STOP condition and a data bit.
> • A REPEATED START and a STOP condition.

Schau Dir mal den Standard an. Das meint nur, daß dort kein Unterschied 
festgestellt werden kann.
Die Arbitration kann man nur verlieren, wenn man ein Datenbit 1 sendet, 
aber auf dem Bus Datenbit 0 liest.

Da die Master nicht hellsehen können, ist es natürlich möglich und 
erlaubt, daß 2 Master gleichzeitig ein Start senden. Sie können sogar 
die gleiche Slaveadresse senden ohne die Arbitration zu verlieren. Und 
auch das ist natürlich erlaubt.

c-hater schrieb:
> All transmissions must contain the same
> number of data packets, otherwise the result of the arbitration is
> undefined.

Das meint wiederum nur, daß nicht einer Daten und der andere Stop senden 
kann, wenn bisher die Daten identisch waren, also die Arbitration noch 
nicht entschieden. Das ergibt sich aber auch klar aus dem Standard.
Ich sichere das dadurch ab, daß das erste Datenbyte die Masteradresse 
ist, d.h. spätestens danach ist die Arbitration entschieden.

c-hater schrieb:
> When a contending master discovers that it has lost the arbitration
> process, it should immediately switch to Slave mode to check whether it
> is being addressed by the winning master.

Genau das mache ich doch, ich halte mich genau an den Philips 
Beispielcode.
Der unterlegene und adressierte Master muß danach in den State 0x68 
gehen (Arbitration lost in SLA+R/W as Master; own SLA+W has been 
received; ACK has been returned).

c-hater schrieb:
> Es gibt Sachen, die nicht explizit im Standard stehen müssen, weil sie
> sich aus der Logik der Sache selber zwingend ergeben.

Da bin ich voll d’accord, aber Atmel hat das leider verpennt.

Ich hatte mich sehr gründlich mit I2C beschäftigt, eh ich das Gerät 
entwickelt habe. Und auch der Philips Beispielcode war allererste Sahne, 
der lief auf Anhieb einwandfrei.
Der Ärger ging erst mit den Atmels los.
Man findet von Atmel auch nur Single-Master Beispiel Code und keinen für 
Multi-Master. Das hätte mich eigentlich schon warnen sollen.

: Bearbeitet durch User
von Lattice User (Gast)


Lesenswert?

Peter D. schrieb:
> c-hater schrieb:
>> Note that arbitration is not allowed between:
>> • A REPEATED START condition and a data bit.
>> • A STOP condition and a data bit.
>> • A REPEATED START and a STOP condition.
>
> Schau Dir mal den Standard an. Das meint nur, daß dort kein Unterschied
> festgestellt werden kann.
> Die Arbitration kann man nur verlieren, wenn man ein Datenbit 1 sendet,
> aber auf dem Bus Datenbit 0 liest.

In der Rev 03 von 2007 steht folgendes:

There is an undefined condition if the arbitration procedure is still in 
progress at the moment when one master sends a repeated START or a STOP 
condition while the other master is still sending data. In other words, 
the following combinations result in an
undefined condition:
• Master 1 sends a repeated START condition and master 2 sends a data 
bit.
• Master 1 sends a STOP condition and master 2 sends a data bit.
• Master 1 sends a repeated START condition and master 2 sends a STOP 
condition.

>
> Da die Master nicht hellsehen können, ist es natürlich möglich und
> erlaubt, daß 2 Master gleichzeitig ein Start senden. Sie können sogar
> die gleiche Slaveadresse senden ohne die Arbitration zu verlieren. Und
> auch das ist natürlich erlaubt.
>
> c-hater schrieb:
>> All transmissions must contain the same
>> number of data packets, otherwise the result of the arbitration is
>> undefined.
>
> Das meint wiederum nur, daß nicht einer Daten und der andere Stop senden
> kann, wenn bisher die Daten identisch waren, also die Arbitration noch
> nicht entschieden. Das ergibt sich aber auch klar aus dem Standard.

Das es unter obigen Bedingungen nicht entscheiderbar ist, wird im 
ursprünglichen Standard (von 2000) nicht erwähnt. War den Verfassern 
eventuell auch nicht bewusst.

> Ich sichere das dadurch ab, daß das erste Datenbyte die Masteradresse
> ist, d.h. spätestens danach ist die Arbitration entschieden.

Defintiv best Praxis.
Bei einem reinem Messageprotokoll wie bei robotroom kann man auch anders 
dafür sorgen, z.B. feste Länge, oder die Länge geht aus den Daten am 
Anfang hervor (z.B. Längenbyte) und niemals implizit durch die STOP 
Condition.

>
> c-hater schrieb:
>> When a contending master discovers that it has lost the arbitration
>> process, it should immediately switch to Slave mode to check whether it
>> is being addressed by the winning master.
>
> Genau das mache ich doch, ich halte mich genau an den Philips
> Beispielcode.
> Der unterlegene und adressierte Master muß danach in den State 0x68
> gehen (Arbitration lost in SLA+R/W as Master; own SLA+W has been
> received; ACK has been returned).
>
> c-hater schrieb:
>> Es gibt Sachen, die nicht explizit im Standard stehen müssen, weil sie
>> sich aus der Logik der Sache selber zwingend ergeben.
>
> Da bin ich voll d’accord, aber Atmel hat das leider verpennt.

Wenn Grenzfälle im Standard nicht diskutiert werden, passiert sowas 
nunmal. Atmel sind nicht der einzigen die Bockmist machen.

>
> Ich hatte mich sehr gründlich mit I2C beschäftigt, eh ich das Gerät
> entwickelt habe. Und auch der Philips Beispielcode war allererste Sahne,
> der lief auf Anhieb einwandfrei.
> Der Ärger ging erst mit den Atmels los.
> Man findet von Atmel auch nur Single-Master Beispiel Code und keinen für
> Multi-Master. Das hätte mich eigentlich schon warnen sollen.

Der Fehler ist vermutlich, dass der Atmel Multi-Master beim Senden nicht 
die START/STOP/REPEATET START auf dem BUS selbst monitored, sondern erst 
wenn man den STOP Status des Masters bestätigt damit wieder anfängt. Das 
gibt halt eine übles Wettrennen.

Dieser Bug liegt aber nicht an Unklarheiten im Standard, sondern hat 
wirklich jemand gepennt. Sowas passiert gerne wenn die Spec Schreiber, 
Hardware Leute, Software Leute nicht vom Anfang an miteinander reden. 
(auch schon erlebt).

Software: Da stimmt was nicht, die Hardware ist buggy.
Hardare: Steht so in der Spec.
Spec Schreiber: Kann man nicht mehr ändern wegen vorgeschrieben 
Prozeduren (ISO und so)

von Tishima (Gast)


Lesenswert?

Hallo,

ich würde mal mit dem I2C Sniffer von Peter Danneger auf dem Bus 
lauschen was so passiert.
Hat der Peter hier mal gepostet.


gruß,
Björn

von Michael (Gast)


Lesenswert?

Hallo zusammen,

nach langen Stunden vor dem Oszilloskop habe ich herausfinden können, 
dass im Fehlerfall die Spannung auf dem I2C Bus um ca. 1 Volt abfällt.

Der MSP430 erkennt dann keine gültige Stop Bedingung mehr und hängt sich 
an beschriebener Code-Zeile auf.

Nach weiteren herumsuchen habe ich dann herausgefunden, dass sich ein 
Slave Device über die I2C Leitungen mit Strom versorgt, da dessen 
Versorgungsspannung im Fehlerfall einbricht.

Nun die spannende Frage: Warum?

Ich halte euch auf dem Laufenden.

Grüße

von Joe F. (easylife)


Lesenswert?

Michael schrieb:
> nach langen Stunden vor dem Oszilloskop habe ich herausfinden können,
> dass im Fehlerfall die Spannung auf dem I2C Bus um ca. 1 Volt abfällt.

AHA.
Ersmal messen ist immer gut ;-)

Um was für ein Slave-Device handelt es sich denn?

von Michael (Gast)


Lesenswert?

Hallo,

das blöde ist, dass der Fehler zufällig auftaucht und nicht 
reproduzierbar ist. Von daher war ich froh, überhaupt mal was messen zu 
können.

Es handelt sich um einen Beschleunigungssensor.

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.