XMEGA-TWI: Was tun nach "Arbitration Lost"?

OP #2907634
Lesenswert?

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?
Gast #3354861
Lesenswert?

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.
(Firma: Brainit GmbH) #3354864
Lesenswert?

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.
Gast #3354976
Lesenswert?

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
Gast #3355264
Lesenswert?

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?
Gast #3355320
Lesenswert?

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.
(Firma: Brainit GmbH) #3355351
Lesenswert?

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)
#3355355
Lesenswert?

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
Gast #3355470
Lesenswert?

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);
  }
}

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren