Forum: Mikrocontroller und Digitale Elektronik Atmel TWI Fehlerbehandlungen


von Adib (Gast)


Lesenswert?

Hallo, bei mir kommunizieren zwei Atmels per TWI miteinander.

Ich habe auch hier im Forum viel geschaut aber weiss nicht so richtig 
wie Fehlerzustände zu vermeiden bzw. darauf zu reagieren ist.

Hin und wierder hängen die Leitungen entweder SCL oder SDA auf Low 
Pegel. Dann geht gar nichts mehr. Daher meine Fragen zur 
Fehlerbehandlung:
- wie kann ich feststellen ob vor dem Beginn eines Transfers SDA und SCL 
high sind? kann man das aus dem TWI Modul ableiten oder muss ich PINx 
der TWI Pins abfragen?
Ich habe den Eindruck dass der Master machmal trotzdem den Transfer 
initiieren kann.
- wenn der Master nicht mehr weiterkommt - wegen Timeout - reicht dann 
ein Stop condition zu generieren?
- kann man eventuell das TWI Modul sicher reseten, indem man es kurz 
disabled und dann wieder enabled?
- in einem Beispiel Programm hat der Master TWDR = 0xff gesetzt mit dem 
Kommentar "release SDA Line". Das kann ich so dem Manual nicht 
entnehmen.
- ein anderer Forumsbeitrag beschrieb, dasas der Slave immer nach dem 
Master gebootet werden muss?
- eigentlich wird ja der Pin als alternativ Funktion abgekoppelt. Haben 
die DDRx und PORTx Registerzustände eventuell doch einen Einfluss?

Mein Ziel wäre durch das Erkennen von Timeout und Fehlerzuständen der 
Kommunikation ein Reset des TWI zu veranlassen. bzw den 
Kommunikationspartner zu resetten.


Danke, Adib.

von Joachim .. (joachim_01)


Lesenswert?

Ich benutze die lib von Peter Fleury, die funktioniert einwandfrei. Wenn 
du sagst der Bus hängt, fallen mir zwei Möglichkeiten ein:
- Das Ack-Bit kommt nicht. das läßt sich durch n entsprechendes 
Status-Bit feststellen. Dann gibt's nen Timeout. Dadurch sieht's so aus 
als ob die SCL-Leitung auf Low hängt.
- Buskollision: Der Master ignoriert das Protokoll.
Ist mir mal passiert. Ein zweiter ATMega als Slave sendete auf 
Anforderung mehrere Bytes am Stück zurück. Ich dachte, er ließ sich 
einfach anhalten wie ein EEPROM im Sequential-Read-Mode indem man das 
Ack-Bit entsprechend setzt. Das ging zwar auch, der Slave sendete aber 
dann beim nächsten Takt auf SCK fleißig weiter.

>- ein anderer Forumsbeitrag beschrieb, dasas der Slave immer nach dem
>Master gebootet werden muss?
Jedenfalls muß sichergestellt sein, daß der Slave die erste Taktflanke 
auf der Taktleitung das auch rechtzeitig mitbekommt. Vermutlich meint er 
das damit.

von Adib T. (adib_t)


Lesenswert?

Peters lib arbeitet nach dem Polling Betrieb.
Er wartet auf das nächste Ereignis so:

  // wait until transmission completed
  while(!(TWCR & (1<<TWINT)));

Da ich nicht ewig warten kann/will habe ich ein timeout eingebaut. 
Anzahl der Schleifen auf 8000 gesetzt. Bei einem Timeout setzte ich die 
Stop condition.

Kann ich das denn überhaupt so einen Transfer abbrechen? Oder Sollte ich 
die TWI Einheit komplett disablen und dann wider enablen?

Zu Begin eines Mastertransfers wie kann ich da sicherstellen, dass der 
BUS wieder frei ist?
Peter setzt hier spontan das TWCR Register ohne zu testen, wie der 
Status ist.

Danke Adib.

von Peter D. (peda)


Lesenswert?

Adib T. schrieb:
> Da ich nicht ewig warten kann/will habe ich ein timeout eingebaut.

Die Wartezeit ist nicht ewig, sondern ergibt sich aus der Bitrate (z.B. 
100kHz * 9).
Ist der Slave auch ein MC, kann dieser das SCL etwas strecken, bis er 
seinen I2C-Interrupt beendet hat (einige µs).

Wenns ewig dauert, dann hat sich der Master oder der Slave verklemmt und 
dann hilft auch kein STOP setzen.

Das AVR HW-I2C hat aber nen Bug, was dazu führt, daß bei Kollisionen 
(Multimaster) das HW-I2C regelmäßig abschmiert. Da hilft dann nur 
Disable+Enable des HW-I2C. Und nur dazu ist ein Timeout nötig (z.B. 
1ms).
Das abgeschmierte HW-I2C macht sich dadurch bemerkbar, daß der Master 
SDA für immer auf low hält, also sollte der Timeout den SDA-Pin 
überwachen, z.B. über einen Pin-Change Interrupt.


Peter

von Peter D. (peda)


Lesenswert?

Adib T. schrieb:
> Kann ich das denn überhaupt so einen Transfer abbrechen?

Einen hängenden Transfer kann man nicht ohne komplettes Disable 
abbrechen.
Ein STOP setzen geht nur nach dem Empfang des ACK/NACK oder als 
Master-Receiver nach dem Senden des NACK.


Peter

von Peter D. (peda)


Lesenswert?

Adib T. schrieb:
> Zu Begin eines Mastertransfers wie kann ich da sicherstellen, dass der
> BUS wieder frei ist?

Als Single-Master immer.
Als Multi-Master kann es passieren, daß man das START eines anderen 
Masters überhört und dann gibts Kollisionen.
Aber nur beim AVR, andere (z.B. NXP) haben ein einwandfrei 
funktionierendes HW-I2C).


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