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
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?
Thomas F. schrieb: > Was verstehst Du unter "Kollisionen"? Und wie stellst du fest, dass was "kollidiert"?
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.
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
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.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.