Hallo Leute, ich beschäftige mich gerade mit der TWI- (aka I²C-) Schnittstelle auf einem ATXMEAG128D3. Ich verwende dazu die Treiber aus der Appnote AVR1308. Ein wenig ineffizienz geschrieben, aber eigentlich sehr schön, weil die Übertragung interrupt-gesteuert im Hintergrund verläuft. Und TWI ist ja nicht gerade schnell.. Solange es gut geht, geht es gut. Ab und an erhalte ich jedoch die Rückmeldung "Arbiration Lost". Normalerweise wäre hier die Ursache, dass ein zweiter Master auf den Bus zugreift - den gibt es hier aber nicht. In der Doku steht dann dazu: "When a device has lost arbitration, it must stop transmitting and wait until the next STOP condition before trying to take control of the bus again." Den Stop-Befehl müsste hier der (nicht existierende) andere Master schicken - kommt also nie. Meine Frage: Was muss man tun, um den Bus wieder in einen definierten und funktionierenden Zustand zu bringen? PS: Mir ist klar, dass dieser Fehler durch Störungen ausgelöst wird, deren Auftreten man vielleicht unwahrscheinlicher machen könnte. Das löst aber nicht mein grundsätzliches Problem - was tun, wenn doch einmal?
Wie wäre es damit den TWI zurückzusetzen und nochmal zu probieren? Ich hab von deiner lib keine Ahnung, wenn sie es aber nicht kann, bist aufgeschmissen.
Timeout heißt das Zauberwort. Danach eine neue Start-Message senden und weitermachen.
Ist vielleicht ein bisschen spät, aber mich würde schon interessieren, wie man eine Startmessage senden soll? Der XMega lässt das doch garnicht zu. Auch wenn er mittlerweile in einem IDLE Zustand ist, wartet er auf eine STOP Kondition. Ich hab das Problem auch, das durch ESD Beschuss der Master in einen Zustand kommt, aus dem man ihn nur erlösen kann, wenn man den SDA Pin von außen auf NULL zieht. Falls jemand eine gute Lösung hat würde mich das schon interessieren.
Die Aussage bezieht sich zwar auf einen ATmega (ohne X) aber TWI wird sich (hoffentlich) nicht fundamental unterscheiden: Im Falle eines "Arbitration lost" schicke ich eine (Re)Start-Condition. Das ist auch im Datenblatt so beschrieben, und hat bisher auch problemlos funktioniert.
Detlev T. schrieb: > Den Stop-Befehl müsste hier > der (nicht existierende) andere Master schicken - kommt also nie. Da hilft dann nur, das I2C kurz mal abzuschalten.
Detlev T. schrieb: > Solange es gut geht, geht es gut. Ab und an erhalte ich jedoch die > Rückmeldung "Arbiration Lost". Normalerweise wäre hier die Ursache, dass > ein zweiter Master auf den Bus zugreift - den gibt es hier aber nicht. Detlev T. schrieb: > Meine Frage: Was muss man tun, um den Bus wieder in einen definierten > und funktionierenden Zustand zu bringen? Man könnte versuchen rauszukriegen, was da wirklich passiert. Es könnte ja ein Problem dahinterstecken, das einem später auf die Füße fällt. MfG Klaus
Wie schon des öfteren erwähnt, beschreibt Philips in den Grundlagen zum I2C Bus, wie man einen hängenden Transfer abbricht und den Bus in einen definierten Zustand bringt. Einfach mal nachschlagen.
Danke für die vielen Vorschläge. @ Michael: leider unterscheidet sich der TWI in diesem Fall schon. Der Xmega lässt in dem Zustand gar keine Kommunikation zu. @ Peter: Das ist dem Master leider irgendwie vollkommen egal, die Statemachine bleibt in den Zustand stehen, wo sie war. Besser noch, nach einem Disable - Enable kann der TWI nicht mal mehr durch eine externe Stop Kondition erlöst werden. @Matthias: Es geht nicht darum irgendwelche SCL Clocks durchzutickern, sondern wie ich den XMega wieder aus dem Zustand raus bekomme, was kann Philips für Atmels implementation. Der Timeout scheint ja zu Funktionieren, da sich der Zustand von Busy nach Idle ändert (Datenblatt Seite 209). Aber er bleibt trotzdem in dem Zustand das er auf ein STOP wartet. Die Pins lasen sich leider auch nicht überschreiben. Noch ein paar Vorschläge?
Hallo Klaus, Deine Antwort verwirrt mich ein bisschen. Ich schieße mit 3,3 KV auf das Gerät, da kann ich schlecht messen. Ich kann mir nur "Ergebnisse" mit einer LED anzeigen. Und das Zeigt an, das es sich um ein Arbitration Lost handelt. Aus diesem Zustand muss der Prozessor dann wieder raus.
Alex schrieb: > @ Michael: leider unterscheidet sich der TWI in diesem Fall schon. > Der Xmega lässt in dem Zustand gar keine Kommunikation zu. ich weigere mich das zu glauben... normalerweise hast du im Fall einer lost arbitration die Möglichkeit, entweder TWI sofort freizugeben, oder zu warten bis der Bus wieder frei wird, und dann ein Restart zu senden. Aus der State Machine musst du auf jeden fall rauskommen. Was natürlich sein kann, dass du zwar versuchst, ein Restart zu senden, dabei aber aufgrund eines BusErrors sofort wieder die Arbitrierung verlierst. Dann wäre das Problem aber in der Hardware oder am Slave zu suchen. Für dich mag das so aussehen als ob du aus der StateMachine nicht rauskommst... Kannst du mal einen link auf das Datenblatt posten (ich bin mit den XMEGA nciht vertraut, keine Ahnung welchen du einsetzt)
:
Bearbeitet durch User
Alex schrieb: > @ Peter: Das ist dem Master leider irgendwie vollkommen egal, die > Statemachine bleibt in den Zustand stehen, wo sie war. Ein Disable sollte eigentlich alles resetten. Es kann sein, daß das einige Zyklen braucht, mal bis zum Enable noch 1µs warten. Beim ATmega8 hatte ich auch ein ähnliches Problem, da hat es geholfen. http://www.robotroom.com/Atmel-AVR-TWI-I2C-Multi-Master-Problem.html
Danke für die ganzen Antworten. Es scheint so als ob wir jetzt aus dem Zustand rauskommen. Aktuell schießen wir mit 6,5 KV auf das Gerät und der Bus läuft weiter. Es ist übrigens der ATxmega256A3B Die aktuelle Lösung sieht im Moment so aus (ist noch nicht optimiert) Dazu habe ich die twix.c vom CodeVision geändert im INIT twie_master.module->MASTER.CTRLB |= 0b00001101; // timeout 200us im ISR if (status & TWI_MASTER_ARBLOST_bm) { // arbitration lost res = TWIM_RES_ARBITRATION_LOST; // also clears the TWI busy flag goto clear_flag; } if (status & TWI_MASTER_BUSERR_bm) { // bus error res = TWIM_RES_BUS_ERROR; // also clears the TWI busy flag clear_flag: module->MASTER.STATUS = status; // clear flag bI2CBusError = true; goto trans_finished; } im MAIN if( bI2CBusError) { if(TWIE.MASTER.STATUS & 0x01) { //clear the arbitration lost flag: TWIE.MASTER.STATUS|=TWI_MASTER_ARBLOST_bm; // issue a RESTART condition on the bus. TWIE.MASTER.CTRLC = TWI_MASTER_CMD_RECVTRANS_gc; //TWIE.MASTER.CTRLC = (TWIE.MASTER.CTRLC & (~TWI_MASTER_CMD_gm)) | TWI_MASTER_CMD_STOP_gc; bI2CBusError = false; LED_LAMPE_OUT1(!LED_LAMPE_IN); } }
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.