TWI-Multi-Master für ATMEGA in C
Der TWI-Bus wird in der Regel als "Single-Master-Bus" zentralistisch von
einem einzelnen Master regiert, der um sich herum passive Slaves
beschäftigt.
Der Multi-Master-Bus erlaubt dagegen den hierarchiefreien Betrieb
mehrere gleichberechtigter Master an einem gemeinsamen Bus mit der
Möglichkeit, dass jeder mit jedem direkt kommunizieren kann.
Und zusätzliche Slaves dürfen sich die Master natürlich auch halten.
Diese Freiheit will erkauft werden:
Es muss sichergestellt sein, dass zu jedem Zeitpunkt immer nur ein
einziger Master eine Transaktion startet und ausführt.
Da ich im Netz bisher keine fertige Lösung für einen Multi-Master
gefunden habe, habe ich hier einen eigenen Versuch gestartet.
Er baut auf dem TWI-Master und dem TWI-Slave der Atmel AppNotes auf, die
ich neulich durchforstet und für meine eigene Verwendung vereinheitlicht
habe:
Beitrag "Re: TWI-Master für ATMEGA in C (ohne TWI-Start/Stop, ACK/NACK)"
Der Programmcode ist in der zip-Datei beigefügt, eine ausführliche
Beschreibung - auch der Tests - gibts in der Readme.pdf.
mfg
Michael S.
Michael S. schrieb:> Diese Freiheit will erkauft werden:> Es muss sichergestellt sein, dass zu jedem Zeitpunkt immer nur ein> einziger Master eine Transaktion startet und ausführt.
Das liegt aber nicht am I2-Bus, sondern an Atmel. Deren AVR und 8051
hängen sich auf, wenn 2 Master zugleich versuchen zu senden.
Die I2C-Spezifikation ermöglicht natürlich das gleichzeitige Senden, ein
Master verliert die Arbitration und kann es später versuchen. Ansonsten
wäre der Status "Arbitration lost" ja völlig sinnlos.
Mit den NXP/Philips 8051-ern (P87C751, P80C562, P89C668) hat das auch
super geklappt, bis sie eingestellt wurden. Der Multimaster-I2C
funktionierte auf Anhieb und exakt nach den Beispielen in den
Application Notes.
Den P89C668 habe ich durch den AT89C51RE2 ersetzt und schon hing der
Bus.
Als Würg-Äraund mache ich folgendes. Sobald er die Arbitration verliert,
wird das HW-I2C disabled und wieder enabled. Anderenfalls erzeugt er
nach dem Stop des gewinnende Mastes wirre Impulse und kann nie mehr
senden.
Beim Ersatz des P87C751 durch den ATmega8 gab es ähnliche Probleme, der
ausgeflippte Master hielt SDA für immer auf Low.
http://www.robotroom.com/Atmel-AVR-TWI-I2C-Multi-Master-Problem.html
Es ist daher überhaupt nicht verwunderlich, daß es von Atmel keine
I2C-Multimaster Codebeispiele gibt. Dann hätten sie ja merken müssen,
daß es nicht geht.
Mit einen funktionierenden I2C wäre Multimaster natürlich ne feine
Sache. Niemand muß auf den anderen Rücksicht nehmen oder einen ihn
ständig pollen.
Peter
Peter Dannegger schrieb:
>> Es muss sichergestellt sein, dass zu jedem Zeitpunkt immer nur ein>> einziger Master eine Transaktion startet und ausführt.
Diese Aussage hätte ich besser formulieren können:
Es muss sichergestellt sein, dass - wenn mehrere Master zeitgleich eine
Transaktion starten - dieser Konflikt aufgelöst wird und nur einer von
ihnen den Bus übernimmt.
> Das liegt aber nicht am I2-Bus, sondern an Atmel. Deren AVR und 8051> hängen sich auf, wenn 2 Master zugleich versuchen zu senden.
Diese Aussage kann ich zumindest für den ATMEGA48 nicht bestätigen.
Ich habe in allen meinen Tests drei Master gleichzeitig gestartet.
Es gab nie grundsätzliche Probleme, niemand hat sich aufgehängt.
Oder sollte an meinen Testbedingungen etwas nicht stimmen?
Einige Schwierigkeiten hatte ich nur nach einem Repeated Start.
Aber auch das war mit einem "Workaround" (pollen von SCL vor dem Setzen
von TWEA) lösbar.
Im Übrigen soll es ja von BASCOM und bei der Arduino-Fraktion
Bibliotheken für den Multimaster geben - ein Zeichen dafür, dass es
nicht grundsätzlich nicht funktioniert.
Michael S.
Hallo.
Mit Verwunderung lese ich über derlei Probleme bei AVRs mit
Multi-Master-I2C.
Das hätte ich nicht gedacht, zumal die Specs von Philips diesbezüglich
doch recht einfach und eindeutig sind.
Michael S. schrieb:> Im Übrigen soll es ja von BASCOM und bei der Arduino-Fraktion> Bibliotheken für den Multimaster geben - ein Zeichen dafür, dass es> nicht grundsätzlich nicht funktioniert.
Bin mir nicht ganz sicher, aber ich meine gelesen zu haben, dass deren
I2C "nur" in SW läuft, weil/um auf beliebigen I/O laufen zu können.
Vlt. kann das mal ein Experte aus der BASCOM und Arduino-Fraktion
verifizieren.
Grüße.
Michael S. schrieb:> Ich habe in allen meinen Tests drei Master gleichzeitig gestartet.> Es gab nie grundsätzliche Probleme, niemand hat sich aufgehängt.
Vieleicht hast Du nur Glück gehabt oder der Traffic ist zu gering.
Ich habe 6 I2C-Teilnehmer, die sich pausenlos unterhalten und der Fehler
trat manchmal erst nach einer Stunde auf. Das Debuggen war daher sehr
langwierig.
Das I2C läuft völlig im Interrupt, das Main wertet nur die Pakete aus
und erzeugt neue Pakete. Der I2C kommt dadurch nie zur Ruhe.
In dem Link von David Cook ist auch sehr schön zu sehen, wie SDA am Ende
dauerhaft auf low bleibt.
Und er verwendet den ATMega168, also muß der ATMega48 den Bug auch
haben.
Peter
Peter Dannegger schrieb:
> In dem Link von David Cook ist auch sehr schön zu sehen, wie SDA am Ende> dauerhaft auf low bleibt.
Ich habe mir den Beitrag von David Cook angeschaut.
Er erkennt folgendes Problem:
Nach einem TWI-Stop nimmt der Master an, der Bus sei frei - und
übersieht dabei, dass er bereits wieder durch einen anderen Masters
belegt ist.
Er sendet einfach drauf los ...
Sein Workaround:
Nach einem Stop wird in der ISR per Software geprüft, ob der Bus
wirklich frei ist.
Rein zufällig habe ich eine ähnlich wirkende Prüfung eingebaut:
Bevor ein TWI-Start (TWEA) gesendet wird, polle ich per Software für
einige Microsekunden SCL.
Nur wenn SCL ständig HIGH ist, wird TWEA gesetzt, wenn nicht, dann wird
gewartet.
Folgende Beobachtung hat diese Warteschleife/Prüfung erforderlich
gemacht:
Um eine Transaktion zu starten wird das Bit TWEA gesetzt (ein TWI-Start
angefordert).
Die Hardware wartet auch brav, bis der Bus frei ist, erst dann wird die
Start-Condition auf den Bus gegeben.
Aber während der gesamten Wartezeit reagiert die TWI-Hardware nicht als
Slave:
offenbar kann sie zu diesem Zeitpunkt nur den Bus testen.
Wird nun dieser wartende Master als Slave adressiert, dann antwortet er
nicht (bzw. mit NACK) - es kommt keine Verbindung zustande.
Folgerung: Auf jedem Master darf erst dann das Bit TWEA gesetzt werden,
wenn der Bus wirklich frei ist.
Ich werde das Testszenario von David Cook bei Gelegenheit mal
durchspielen.
Michael S.
>Rein zufällig habe ich eine ähnlich wirkende Prüfung eingebaut:>>Bevor ein TWI-Start (TWEA) gesendet wird, polle ich per Software für>einige Microsekunden SCL.>Nur wenn SCL ständig HIGH ist, wird TWEA gesetzt, wenn nicht, dann wird>gewartet.
Damit kannst Du nicht verhindern, dass zwei Master gleichzeitig
loslegen.
Peter S. schrieb:> Damit kannst Du nicht verhindern, dass zwei Master gleichzeitig> loslegen.
Völlig klar. Verhindern kann man es grundsätzlich nicht.
Aber die Wahrscheinlichkeit reduzieren.
Und einen besseren Vorschlag hat David Cook auch nicht.
Im Gegenteil - wenn ich es richtig verstehe, dann hat er sogar in einer
ISR eine Warteschleife eingebaut.
Michael S.
Michael S. schrieb:> Nach einem TWI-Stop nimmt der Master an, der Bus sei frei - und> übersieht dabei, dass er bereits wieder durch einen anderen Masters> belegt ist.> Er sendet einfach drauf los ...
Das ist nur einer der Bugs. Ist nicht schön, aber er bewirkt nicht das
Hängen.
Wenn ein Master sendet und ein anderer sendet etwas später, weil er das
Start nicht mitbekommen hat, kommt es zur Kollision. D.h. beide kriegen
das Ereignis "Arbitration lost" oder "Bus Error". Beide können also
drauf reagieren und später nochmal senden.
Ich habe das natürlich auch versucht, d.h. der Master, der STOP sendet,
verläßt nicht erst den Interrupt, sondern pollt bis STOP vorbei ist und
löscht sofort das Interruptflag.
Es hat aber garnichts gebracht, die Bus-Hänger waren vielleicht ein
bischen seltener.
Da ich ja schon einen über viele Jahre funktionierenden Code mit
NXP-Chips hatte, war es auch einfach, ihn auf Atmel anzupassen.
Softwaremäßig ist er ja identisch (gleiche Bits, Register und Zustände)
aber leider nicht harwaremäßig. Daher wußte ich auch recht schnell, daß
es kein Softwarefehler sein kann.
Beim AVR war noch eine Fallgrube, daß das Interruptflag nicht unabhängig
von den anderen Bits gelöscht werden kann. Ich mußte daher noch ein
Schattenregister anlegen, damit das Flag wirklich erst am Ende des
Interrupthandlers gelöscht wird. Beim 8051 kann man die Bits ja einzeln
setzen, da gibt es dieses Problem nicht.
Peter
Peter S. schrieb:
> Damit kannst Du nicht verhindern, dass zwei Master gleichzeitig> loslegen.
Und noch ein Gedanke dazu:
Wenn die Software einen freien Bus erkennt, können unmittelbar DANACH
immer noch mehrere Master gleichzeitig starten. Klar.
Das stellt aber an sich kein Problem dar.
Denn es folgt ja noch die Prüfung durch die TWI-Hardware (entweder
wartet der Master, weil er einen besetzten Bus erkennt oder es gibt
einen Arbitrierungsfehler).
Im dümmsten Falle schlägt danach ein Repeated Start fehl (das Problem
sollte meine Warteschleife lösen).
Aber die Schwierigkeite, über die David Cook berichtet, sollten nicht
auftreten.
Theoretisch.
Michael S.