Forum: Mikrocontroller und Digitale Elektronik ATxmega TWI Kollision


von Fabian K. (fabian_k)


Lesenswert?

Hallo,

ich habe das Problem mit dem ATxmega8E5 als TWI-Slave (mit 
TWI-Slave-Treiber von Atmel), dass hin und wieder mal Kollisionen 
auftreten.
Es wird der interne 32MHz-Oszillator verwendet und die Taktfrequenz 
beträgt 100kHz.

Der TWI-Interrupt kann durch nichts unterbrochen werden, alle anderen 
Interrupts haben eine höhere Interrupt-Vektor-Adresse (somit niedrigere 
Priorität) und den selben oder einen niedrigeren Interrupt-Level (können 
also nicht unterbrechen).

Kann die Ungenauigkeit des internen Oszillators zu Kollisionen führen?
100kHz bei ca. 10cm Leitungslänge dürften eigentlich nicht zu viel sein?

Danke im voraus.

MfG,
Fabian

von Thomas F. (tomasf)


Lesenswert?

Was verstehst Du unter "Kollisionen"? Betreibst Du TWI als 
Multi-Master-Bus?

Die Taktfrequenz spielt für den Slave keine Rolle, der Takt wird ja vom 
Master vorgegeben. Der Interrupt sollte auch unkritsch sein, das 
TWI-Modul solte automatisch Clock-Stretching machen, wenn die Daten 
nicht schnell genug verarbeitet werden.

Sind Pullup-Widerstände verbaut und richtig dimensioniert?

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Thomas F. schrieb:
> Was verstehst Du unter "Kollisionen"?
Und wie stellst du fest, dass was "kollidiert"?

von Mike (Gast)


Lesenswert?

Lothar Miller schrieb:
> Und wie stellst du fest, dass was "kollidiert"?

Ein kleiner Widerstand in der Leitung und Pull-ups an beiden Enden 
verraten das schnell, wenn beide an der Leitung ziehen.

von Fabian K. (fabian_k)


Lesenswert?

Sorry, dass ich erst so spät antworte, ich hab noch ein paar Tests 
gemacht.

Thomas F. schrieb:
> Was verstehst Du unter "Kollisionen"? Betreibst Du TWI als
> Multi-Master-Bus?
Das entsprechende Kollisions-Bit im TWI-Status-Register des ATxmega wird 
gesetzt.
Die SCL-Leitung wird nach der "Kollision" vom ATxmega auf Low gezogen. 
Deshalb kann der Master auch keine weitere Start-Bedingung senden, um 
das Kollisions-Bit wieder zu löschen. Der ATxmega kann also nach der 
"Kollision" nichts mehr senden, wenn man das Kollisions-Bit nicht 
manuell löscht.
Und nein, der einzige Master am Bus ist ein Raspberry Pi, der Daten vom 
ATxmega (Slave) abfragt.

> Die Taktfrequenz spielt für den Slave keine Rolle, der Takt wird ja vom
> Master vorgegeben. Der Interrupt sollte auch unkritsch sein, das
> TWI-Modul solte automatisch Clock-Stretching machen, wenn die Daten
> nicht schnell genug verarbeitet werden.
Das Clock-Stretching ist so eine Sache am RPi. Das funktioniert nur 
teilweise, ich weiß nicht ob die das Problem schon gelöst haben.
Wird SCL vom Slave auf Low gezogen, kann es passieren, dass Master und 
Slave dann asynchron laufen (Slave hinkt hinterher).

> Sind Pullup-Widerstände verbaut und richtig dimensioniert?
Es sind 1k8 Pull-Ups am RPi vorhanden (könnten ruhig etwas größer sein).

Die "Kollison" tritt sehr selten auf, ich muss den RPi schon ein paar 
1000x abfragen lassen. Aber sie tritt definitiv auf.

: Bearbeitet durch User
von Peter D. (peda)


Lesenswert?

Fabian K. schrieb:
> Das entsprechende Kollisions-Bit im TWI-Status-Register des ATxmega wird
> gesetzt.

Ich kenne speziell den Xmega nicht.
Beim standard AVR wird das Kollisionsbit TWWC gesetzt, wenn zum falschen 
Zeitpunkt auf das TWDR geschrieben wird. Es ist also ein Softwarefehler 
die Ursache.

von Fabian K. (fabian_k)


Lesenswert?

Peter Dannegger schrieb:
> Fabian K. schrieb:
>> Das entsprechende Kollisions-Bit im TWI-Status-Register des ATxmega wird
>> gesetzt.
>
> Ich kenne speziell den Xmega nicht.
> Beim standard AVR wird das Kollisionsbit TWWC gesetzt, wenn zum falschen
> Zeitpunkt auf das TWDR geschrieben wird. Es ist also ein Softwarefehler
> die Ursache.

Laut Datenblatt bzw. Manual, wenn es das MSB- oder NACK-Bit nicht 
übertragen werden konnte.
Ich verwende, wie oben schon erwähnt, den TWI-Slave-Treiber von Atmel.

Im Manual steht außerdem, dass die SCL-Leitung auf Low gezogen wird, 
sobald ein Interrupt-Flag gesetzt wurde und das so lange, bis es 
entweder manuell gelöscht, oder eine Aktion gesetzt wird.
Bei meiner "Kollision" wird ein Interrupt-Flag (APIF) und ein Status-Bit 
(COLL) gesetzt.

Jetzt versteh ich auch, wieso die SCL-Leitung nach der "Kollision" auf 
Low ist:
Der TWI-Slave-Treiber von Atmel hat natürlich keinerlei Fehlerbehandlung 
implementiert und löscht nicht mal das Interrupt-Flag, um den Bus (bzw. 
die SCL-Leitung) nach einer Kollision wieder freizugeben.
So wie es aussieht reicht es auch, das Collision-Status-Bit (COLL) zu 
löschen, um auch das Collision-Interrupt-Flag zu löschen (APIF).

Da es jetzt schon ewig ohne irgendeine "Kollision" läuft, sehe ich das 
Ganze jetzt einmal als hardware-bedingten Fehler an (ich glaubs aber 
immer noch nicht).
Ich werde das in Zukunft noch beobachten und zumindest eine vernünftige 
Fehlerbehandlung implementieren.

Falls doch noch jemand eine Idee hat, würde ich mich darüber freuen.

: Bearbeitet durch User
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.