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.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.