Ich betreibe seit einiger Zeit ein Multimaster TWI System. Dieses funktioniert auch recht gut. Allerdings passiert es ab und zu (wahrscheinlich durch einen Wackelkontakt) wenn der 1. Master senden will dass er bei folgenden Status stehen bleibt: TWI_REP_START 0x10 // 16 Repeated START has been transmitted TWI_MTX_ADR_NACK 0x20 // 32 SLA+W has been tramsmitted and NACK received Der 2.Master bekommt davon aber nichts mit, bei ihm ist der letzte Status der einer komplett abgeschlossenen Übertragung. Ich kann auch wieder eine Übertragung durch den 2. Master anstoßen die den 1. dann wieder in normale Funktion versetzt. Dabei sind allerdings 2 Übertragungen notwendig, die erste versteht der 1.Master noch nicht geht da aber in den normalen Zustand. Bei der zweiten Übertragung läuft wieder alles normal. Nun die Frage. Wie kann ich den 1. Master sagen er soll wieder in den Grundzustand gehen. Ohne den µC zu reseten, so dass er für Empfang und Senden wieder bereit ist? Mir kommt es so vor als würde er ein Stop vom 2. Master benötigen um wieder normal zu laufen. Doch es soll unabhängig vom 2. Master laufen. Die Lösung Wackelkontakt beseitigen ist ausgeschlossen, es soll ein System werden, dass Übertragungsschwierigkeiten erkennt. Danke schon mal im voraus!!
Thomas Frosch schrieb: > TWI_REP_START 0x10 // 16 Repeated START has been transmitted > TWI_MTX_ADR_NACK 0x20 // 32 SLA+W has been tramsmitted and NACK > received Dann bist Du immer noch der aktive Master, der den Bus belegt. Du mußt ein STOP senden. Generell sollte man auf alle Interrupts, die unerwartet sind, ein STOP senden. Ist man der aktive Master, gibt man damit den Bus frei. Ist man ein Slave, wird das Stop nur intern ausgewertet, d.h. der Slave wechselt in den nicht adressierten Zustand. Peter
Dass habe ich schon von anfang an so implementiert. Doch der Fehler tritt trotzdem auf. Selbst wenn ich im nachhinein per PC über uart dem µC sag er soll einfach mal so ein Stop senden (egal ob Stop mit oder ohne ACK) bleibt er dabei. Gibt es noch andere Möglichkeiten? Wenn ich den Bus belege warum kann dann der 2.Master trotzdem eine Übertragung starten? Weil er gar nicht mitbekommen hat dass der Bus belegt ist?
Ich vermute mal, es geht um AVRs. Da ist Multimaster ne äußerst komplizierte Sache, da das I2C der AVRs einen schweren Bug hat: http://www.robotroom.com/Atmel-AVR-TWI-I2C-Multi-Master-Problem.html Ich rate davon ab, AVRs als Multimaster zu verwenden. Peter
Ja das habe ich auch schon mal gelesen. Verstehe ich das richtig, sein Workaround besteht darin nach dem Senden/Empfangen einfach zu prüfen ob SCL und SDA beide längere Zeit High sind und lässt erst dann wieder ein Senden zu wenn diese Zeit abgelaufen ist?
Ich bin mir nicht sicher, ob das allein hilft. Ich habe 2 Timeouts eingebaut: 1. Wenn man als Master STOP sendet und es nicht von selber rückgesetzt wird. 2. Wenn der SDA-Pin konstant auf Low bleibt (Test per Flankeninterrupt). Dann wird das I2C für ne Weile disabled und neu initialisiert. Zusätzlich testet der Master, wenn er senden will, ob SDA/SCL für 50µs auf high bleiben und erst dann wird das START-Bit gesetzt. Ist also ganz schön aufwendig (externer Interrupt, Timerinterrupt, Warteschleife). Peter
Wie testest du den 1. Fall also er sendet stop aber setzt sich nicht zurück. Also wie testest du, dass er sich nicht zurück gesetzt hat? Und das mit dem Neu initialisieren geht ganz einfach mit den standard initialisierungsschritten? Oder muss ich irgend ein Bit vorher ausschalten, etwas warten und dann wieder ganz normal initialisieren? Wäre für mich ein super Workaround.
Thomas Frosch schrieb: > Wie testest du den 1. Fall also er sendet stop aber setzt sich nicht > zurück. Also wie testest du, dass er sich nicht zurück gesetzt hat? Ich hab nen Timerinterrupt der alle 1ms aufgerufen wird und verschiedene Sachen macht. Wenn also nach 1ms immer nocht STOP gesetzt ist, disabled er das I2C und ruft I2C_init auf. Und wenn nach 1ms kein Flankeninterruptbit gesetzt ist, aber SDA = 0, dann auch. Ich hab damals noch nen ATmega8 benutzt, d.h. kein Pin-Change-Interrupt und hab dann nen Draht von SDA nach INT0 gepatcht. Es scheint zu gehen, aber man hat eben manchmal 1..2ms den I2C blockiert und muß ein Retry machen. Ich hab mir den Code nochmal angeguckt und warscheinlich nen Fehler entdeckt: Nach den 50µs wird das Startbit gesetzt aber nicht zurückt, wenn der andere Master schneller ist. Ich sollte besser das Starbit nach 10µs zurücksetzen. Dann könnten die beiden Timeouts vielleicht überflüssig sein. Aber es läuft so und never touch a running system. Peter
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.