Bin gerade dabei den TWI in einem SAM4e interrupt basiert zu gestalten. Da ich früher schon bei den ASF-Funktionen schon das Problem hatte, dass beim schreiben auf dem Bus sich gelegentlich, nach 5min bis 4 std, der Bus aufhängt, habe ich dieses Problem nun erneut. Jetzt bin ich etwas schlauer geworden. Es schein so als ginge ein CLK Puls verloren. Habe mir vor einer Woche ein Picoscope gekauft, das kleinste mit 10MHz, hier ist meiner Meinung nach die zu schwache CLK zu sehen. Ich habe mal Diagramme angehängt eines mit der einwandfreien Übermittlung und die Anderen sind die fehlerhaften Übertragungen wo die schwache CLK zu sehen ist. Weiß einer wie man dem Abhilfe schaffen kann? Pullups verkleinern? Diese sind derzeit 4K7. Leitungslänge ca. 20cm auf der Platine zu 6 Slaves. Wie könnte man die Verklemmung in der SOftware lösen? Die Datenleitung (blau) scheint von dem Slave (PCA9555) auf low gehalten zu werden, da auch kein Reset der MCU hilft. Ich muss immer erst die PCA9555 resetten durch Spannung aus und wieder an. Ich sende immer das gleiche Paket im 100ms Takt. Der Fehler ist wie auf den Diagremmen zu sehen unterschiedlich und kommt teilweise erst nach 6000 bis 8000 Paketen. Teilweise aber auch schon früher.
Michael schrieb: > Pullups verkleinern? Diese > sind derzeit 4K7. Probiers docch mal aus. Schau in die Datenblätter aller Geräte wieviel Strom das schwächste davon maximal an seinen I²C-Pins versenken kann und rechne Dir entsprechend aus wie klein der Pullup sein darf. Garantiert darf er schon noch etwas kleiner als 4.7k sein, so aus dem Bauch raus. Die Flanken sehen schon arg verschliffen aus auf deinem Oszillogramm (aber bedenke: auch der Oszi-Tastkopf hat noch ne nicht zu vernachlässigende Kapazität, steht er schon auf 1:10?) Außerdem finde ich es seltsam daß der Master hier mal zwischenzeitlich einen erheblich kürzeren Taktimpuls erzeugt (der ist nicht "schwächer" wie Du schreibst, der ist einfach kürzer!), da ist noch irgendwas faul an der Implementation des Masters. Machst Du das in Software?
:
Bearbeitet durch User
Tastköpfe sind auf 1:1. Habe auch gerade noch ein altes Tektronix 200Mhz Scope an die SCL gehängt. Bei dem Scope geht leider nur noch ein Kanal. Auf jeden Fall sind auch hier die Flanken sehr schwach. Ich probiere es mal aus die Pullups zu verkleinern. Vll bekomme ich auch die Kapazität der Leitung gemessen.
Michael schrieb: > das > kleinste mit 10MHz, hier ist meiner Meinung nach die zu schwache CLK zu > sehen. Deiner Meinung nach hast du einen "schwachen" Clock. Meiner Meinung nach hast du mit dieser Messung und Darstellung nur bewiesen dass du ein Mess-System anwendest das für deinen Zweck nichts taugt. Dein Mess-System (Oszilloskop oder Tastkopf oder beides) haben nicht genug Bandbreite um deine Messaufgabe genau genug zu erfüllen. Also: nix "schwache CLK", sondern bandbegrenzendes System das die die Flanken verschleift und nicht nachvollziehbar macht
Das mag sein. Deshalb erwähte ich auch die 10MHz. Habe deshlab gerade nocheinmal mit dem Tektronix verglichen. Bin jetzt mit dem Bustakt auf 50kHz zurückgegangen um Messfehler auszuschließen. Beide Tastköpfe (von PicoScope 10MHz und Tektronix) zeigen einen ordentlichen Rechteck am Calibrator pin (100kH Signal). Dennoch glaube ich das es an der "schwachen" Clock liegt. Es wäre schon purer Zufall, dass immer wenn die Übertragung funktioniert, das Scope die Clk Pulse "sauber" erfasst und nur bei Fehlerhafter Übertragung die Bandbreite mal gerade nicht reichte um die Clock wie sonst darzustellen.
Michael schrieb: > Dennoch glaube ich das es an der "schwachen" Clock liegt. Welche Fakten bringen dich denn dazu von "schwach" zu sprechen. Stelle mal dein physikalisches Übretragungssystem (Sender bis Empfänger) für uns nachvollziehbar dar, dann reden wir über "schwach"
Bernd K. schrieb: > Probiers docch mal aus. Schau in die Datenblätter aller Geräte wieviel > Strom das schwächste davon maximal an seinen I²C-Pins versenken kann und > rechne Dir entsprechend aus wie klein der Pullup sein darf. Da braucht man nicht schauen, ein standardkonformer I2C Treiber muß 3mA und 400 pF schaffen. MfG Klaus
Michael schrieb: > Weiß einer wie man dem Abhilfe schaffen kann? Pullups verkleinern? Diese > sind derzeit 4K7. bei um 3V 4,7k? ich würde an Hand der Datenblätter aller Beteiligten den sink Strom prüfen und mindestens auf 1mA gehen, also 3,3k bis runter je nach Chip auf 1,1k ist halt ne Frage der kapazitiven Lasten. sitzen die beiden (SDA SCL) I2C pullup Rs wirklich am Ende der Leitung alleine ! nicht das irgendwelche I2C Chips eigene am I2C Slave haben. Gerne werden auch pullup Rs auch schon mal am Master bestückt -> raspberry Pi z.B. das ist eher kontraproduktiv.
Michael schrieb: > Wie könnte man die Verklemmung in der SOftware lösen? I2C-Controller haben oft kein Bus-Reset, d.h. man muß es in SW machen. Der Master muß dazu sein I2C disablen und SCL als open-drain händisch takten (max 100kHz), bis SDA wieder high ist. Das kann maximal 9 SCL-Takte dauern.
Ich glaube aber nicht, daß es wirklich ein HW Problem ist. Wenn man sich die Fehlerbilder genau ansieht (ist bei der Auflösung nicht leicht) erkennt man CLK-Signale, die extrem niedrig sind. Gleichzeitig sind sie aber auch kürzer als die anderen. Da Slaves nur verlangsamen können, muß da ein Timing-Problem beim Master sein. Da das nicht immer auftritt, könnte ich mir eine Störung durch einen Interrupt oder ein ähnliches asynchrones Ereigniss vorstellen. MfG Klaus
isidor schrieb: > Dein Mess-System (Oszilloskop oder Tastkopf oder beides) haben > nicht genug Bandbreite um deine Messaufgabe genau genug zu > erfüllen. Nein, das hat mit der Bandbreite des Messwerkzeugs nichts zu tun. Das hier zu sehende Bild ist typisch für einen I²C-Bus der knapp am Limit dessen vorbeischrammt wo ich schon längst sagen würde mir persönlich wär das schon zu heikel für ein zuverlässiges System. Auch wenns scheinbar gerade so eben noch funktioniert. Man sieht ganz deutlich (wenn man sich mal vor Augen führt wie I²C funktioniert) bei den aufsteigenden Flanken wie die Leitungskapazität von den Pullups langsam (zu langsam!) geladen wird, immerhin wird bei I²C ja nicht aktiv high getrieben sondern der Ausgangstreiber lässt einfach los und der Pullup muss die Leitung wieder hoch ziehen. Also eins der folgenden würd ich tun: * kürzere Leitung (wahrscheinlich nicht möglich) * kleinere Pullups * niedrigere Taktfrequenz. Und zusätzlich und vor allem: * Rausfinden was es mit diesem einen seltsam kurzen Takt auf sich hat der da alle Naselang mal auftritt. Er ist so kurz daß in der kurzen Zeit der Pullup die Leitung nicht mehr auf high gezogen bekommt. Erzeugt der Master so einen kurzen Takt (warum in aller Welt?) oder ist das ein Slave der Clock-Stretching versucht mit nem ziemlich unglücklichen Timing? Der Master scheint ihn mit zu zählen und kommt auf 9, der Slave mit dem er gerade spricht zählt nur 8 und bleibt dann im ACK hängen.
:
Bearbeitet durch User
Bernd K. schrieb: > Nein, das hat mit der Bandbreite des Messwerkzeugs nichts zu tun. Jetzt wo ich mir es nochmal anschaue muss ich dir Recht geben. Es sind ja hochfrequente Spikes zu sehen. Die Pullups sind auf jeden Fall zu schwach, bzw die Clockrate zu hoch.
Die Signale sind grenzwertig, sollten aber funktionieren. Es gibt eine saubere fallende Flanke. Das Problem ist eindeutig und ausschließlich der zu kurze Clk-Puls. ich würd aber trotzdem auch an den Pullups drehen...
:
Bearbeitet durch User
isidor schrieb: > Die Pullups sind auf jeden Fall zu schwach, bzw die Clockrate zu hoch. Grundsätzlich würde ich auch kleinere Pullups nehmen, bei 3.3V so 2k2. Aber hier sind beliebig viele Takte fast (wären ganz, wenn Pullup kleiner) korrekt im Pegel und einzelne dann wieder nicht. Die Pullups ändern sich zwischendurch nicht! Das Timing kann man nicht genau ausmachen, die 'langsame' Anstiegszeit ist aber typisch - eben wegen des Pullups. Bei dem Problempunkt schient mir die Periodendauer einmal zu klein zu sein. Ich tippe auf ein Problem im Master - Software. Übrigens, die Bandbreite des Skopes ist für diesen Zweck ok, denn sonst würden die fallenden Flanken nicht so steil dargestellt.
Michael Reinelt schrieb: > Das Problem ist eindeutig und ausschließlich der zu kurze Clk-Puls. .... der aber nicht durch die Prozessor-Hardware verusacht sein muss. Mir machen die starken Spikes zu denken. Es gibt starke "undershoots" aber auch Überschwinger, die können das Bussystem durecheinander bringen. Es kann natürlich eine Fehlmessung des Oszilloskops sein, oder ein magelhafter Massebezug. Wichtig ist es die Bus-Topologie geradlinig auszuführen und keine wilden Stern-Anordnungen zu wählen. Niederohmige Pullups vermindern auch die Über-/Unterschwinger. Aber auch eine "innige" Masseverbindung unter allen Busteilnehmern ist wichtig. Haben wir schon über ausreichend Abblock-Kondensatoren gesprochen?
isidor schrieb: > Es kann natürlich eine Fehlmessung > des Oszilloskops sein, oder ein magelhafter Massebezug. Von zweiterem gehe ich auch aus. Und/oder von einem Schaltnetzteil in der Nähe (sieht bei mir genauso aus, wenn ich den Notebook eingesteckt habe. Notebook ausstecken => Signal sauber) Übrigens: Die messung gehört unbedingt mit 1:10 Taskopf wiederholt. Dann sind die Flanken vermutlich auch wesentlich sauberer. Der zu kurze Clk-Puls ist mit an Sicherheit grenzender Wahrscheinlichkeit ein Software-Problem am Master.
Michael Reinelt schrieb: > Übrigens: Die messung gehört unbedingt mit 1:10 Taskopf wiederholt. Dann > sind die Flanken vermutlich auch wesentlich sauberer. Das eben nicht. Denn ein 1:1 Tastkopf würde die scharfen Spikes glattbügeln. Die Spikes sind wesentlich steiler als die Signalflanken am I2C Bus. Daher hat der Bus selbst ein Problem.
isidor schrieb: > Die Spikes sind wesentlich steiler als die > Signalflanken am I2C Bus. Daher hat der Bus selbst ein Problem. Oder die Spikes werden direkt in den Tastkopf eingestreut und haben gar nichts mit der Schaltung zu tun. Solange der Tastkopf mit den unsäglich langen Masseclips irgendwo an GND geklemmt wird, solange glaube ich nicht, dass die Spikes auf dem Bus vorhanden sind. Schließe mal deinen 10:1-Tastkopf mit dem Massclip kurz und halte das Gebilde über einen Schaltregler ...
isidor schrieb: > Michael Reinelt schrieb: >> Übrigens: Die messung gehört unbedingt mit 1:10 Taskopf wiederholt. Dann >> sind die Flanken vermutlich auch wesentlich sauberer. > > Das eben nicht. Denn ein 1:1 Tastkopf würde die scharfen Spikes > glattbügeln. Die Spikes sind wesentlich steiler als die > Signalflanken am I2C Bus. Daher hat der Bus selbst ein Problem. Das eben schon. I2c ist sehr empfindlich auf Leitungskapazitäten, und mit einem 1:1 taskopf fügst du erhebliche Kapazität hinzu, mit 1:10 entsprechend weniger. Seeing is believing.
HildeK schrieb: > Oder die Spikes werden direkt in den Tastkopf eingestreut und haben gar > nichts mit der Schaltung zu tun. Da hast du allerdings auch wieder Recht. Dann gilt wieder mein Eingangs erwähntes Bandbreite-Problem ..... dagegen spricht aber dass das Oszilloskop nur 10 Mhz Bandbreite hat, solche Spikes sind dafür gefühlsmässig schon zu hochfrequent, könnten also bei der Bandbreite gar nicht in Erscheinung treten ..... und es gilt: wer misst, misst Mist. Also eigentlich müssten wir alle selbst dabei sein .....
Danke erstmal für die zahlreichen Tips. Nachdem ich den I2C nun mit 50 kHz betreibe sehen die Flanken schon deutlich besser aus. Zusätzlich habe ich die Pullups noch verringert (jeweils 2k35). Noch schönere Flanken. Bis gerade eben funktionierte auch alles ganz gut. Nach 5h 12min ist er dann doch wieder hängen geblieben. Diesmal aber mit korrekter Übertragung auf dem Scope. Das Ack kam noch, dann wurde Stop gesendet und dann war es vorbei. 8022146 Pakete hat er geschafft. Danach verbleibt die Datenleitung wieder auf Low, SCL ist high. Wieviel Zeit dazwischen vergeht kann ich nicht sagen. Das habe ich leider nicht mit auf dem Schirm. Ist bloß der Aktelle Pegel wenn ich aus dem Single Modus raus gehe. Muss auch gestehen, dass ich den Debugger zwar angeschlossen hatte aber irgendwie nicht gestartet :) Lief quasi stand alone. Bevor ich irgendwas weiter sage, lasse ich es noch einmal die Nacht über laufen. Nicht dass jetzt der deaktivierte Debugger noch irgendwie reingespuckt hat, da das AVR Studio auch noch offen war und ich dort trocken etwas Code sortiert habe. Hier auch mal der Code. Wundert euch nicht dass hier noch so viele Printfs oder zusätzliche (unnütze) Abfragen drinn sind. Ich war / bin ziemlich verzweifelt mit dem twi :/ Im prinziep, startet das Ganze sobald was im Puffer steht (SlaveAdresse,SlaveInternAdresse,Datenbyteanzahl,Byte1,Byte2) über die Funktion Twi_Tx_TriggerNextTransfer(). Danach ist der Handler dran.
1 | void Twi_Tx_TriggerNextTransfer(Twi *p_twi){ |
2 | uint8_t buffer_out = 0; |
3 | gl_twi0_state = TWI0TX_BUSY; |
4 | /* Set write mode, slave address and 3 internal address byte lengths */
|
5 | p_twi->TWI_MMR = 0; |
6 | if (TWI0->TWI_SR & TWI_SR_TXRDY){ |
7 | if (Twi0_TxBufferOut(&buffer_out)){ |
8 | p_twi->TWI_MMR = TWI_MMR_DADR(buffer_out)| ((1 << TWI_MMR_IADRSZ_Pos) & TWI_MMR_IADRSZ_Msk); |
9 | if (Twi0_TxBufferOut(&buffer_out)){ |
10 | // Set internal address
|
11 | p_twi->TWI_IADR = 0; |
12 | p_twi->TWI_IADR = buffer_out; |
13 | }
|
14 | }
|
15 | //Enable Interrupt -> interrupt will occur immediately because the TXCOMP and TXRDY Flag is set
|
16 | TWI0->TWI_IER = TWI_IER_TXRDY | TWI_IER_TXCOMP | TWI_IER_NACK; |
17 | }
|
18 | }
|
19 | |
20 | enum {TX_BEGIN,TX_DATA,TX_END,TX_STOP}; |
21 | |
22 | void TWI0_Handler (void){ |
23 | static uint32_t status = TX_BEGIN; |
24 | static uint32_t cnt; |
25 | uint32_t twi_status; |
26 | uint8_t buffer_out; |
27 | |
28 | if (status == TX_BEGIN){ |
29 | // Load count of Databytes
|
30 | if(Twi0_TxBufferOut(&buffer_out)){ |
31 | cnt = buffer_out; |
32 | if (cnt == 0){ |
33 | //ERROR
|
34 | }
|
35 | status = TX_DATA; |
36 | }
|
37 | }
|
38 | |
39 | if (status == TX_DATA){ |
40 | twi_status = TWI0->TWI_SR; |
41 | if (twi_status & TWI_SR_NACK) { |
42 | printf("ED"); |
43 | }
|
44 | else if (twi_status & TWI_SR_TXRDY) { |
45 | if(Twi0_TxBufferOut(&buffer_out)){ |
46 | TWI0->TWI_THR = buffer_out; |
47 | cnt--; |
48 | }
|
49 | else { |
50 | Twi0_TxBufferClear(); |
51 | status = TX_BEGIN; |
52 | }
|
53 | }
|
54 | |
55 | if (cnt == 0){ |
56 | //all bytes send, wait for TXRDY to send STOP
|
57 | status = TX_END; |
58 | }
|
59 | }
|
60 | |
61 | else if (status == TX_END){ |
62 | twi_status = TWI0->TWI_SR; |
63 | if (twi_status & TWI_SR_NACK) { |
64 | printf("EE"); //bus läuft nach diesem Fehler weiter -> da nur das letzte Byte nicht verstanden wurde |
65 | }
|
66 | else if (twi_status & TWI_SR_TXRDY) { |
67 | TWI0->TWI_CR = TWI_CR_STOP; |
68 | status = TX_STOP; |
69 | TWI0->TWI_IDR = TWI_IDR_TXRDY; |
70 | }
|
71 | }
|
72 | |
73 | else if (status == TX_STOP){ |
74 | twi_status = TWI0->TWI_SR; |
75 | if (twi_status & TWI_SR_NACK) { |
76 | printf("ES"); |
77 | }
|
78 | if (twi_status & TWI_SR_TXCOMP) { |
79 | status = TX_BEGIN; |
80 | printf("t"); |
81 | //DISABLE INTERRUPT
|
82 | TWI0->TWI_IDR = TWI_IDR_TXCOMP | TWI_IDR_TXRDY | TWI_IDR_NACK; |
83 | gl_twi0_state = TWI0TX_CMPL; |
84 | }
|
85 | else if (twi_status & TWI_SR_TXRDY) { |
86 | status = TX_BEGIN; |
87 | printf("X"); |
88 | //DISABLE INTERRUPT
|
89 | TWI0->TWI_IDR = TWI_IDR_TXCOMP | TWI_IDR_TXRDY | TWI_IDR_NACK; |
90 | }
|
91 | |
92 | }
|
93 | }
|
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.