Guten Abend, ich hab einen ATTiny44, der per TWI an einem Pi4 hängt und habe festgestellt, dass das nur so richtig funktioniert, wenn ich den Clock auf 10kHz in der /boot/config.txt ändere. Bei 50kHz sind die Daten um 1 Bit verschoben (zB 0x40 statt 0x80). Bei 100kHz klappt der ACK nicht mehr. Der Tiny läuft bei mir mit dem internen 8MHz RC-Oszillator. Der Code ist mit -O2 kompiliert. Clock hab ich nicht kalibriert. Als Code habe ich diesen hier benutzt: https://github.com/svoisen/TinyWire/tree/master/TinyWireS Hat jemand ähnliche Erfahrungen mit dem TWI-Interface? (Ich hab noch andere I2C-Peripherie an dem gleichen Bus - die funktioniert problemlos mit dem Standard-Takt). Viele Grüße, Mampf
:
Bearbeitet durch User
Ich würde das mit einem Logic-Analyzer untersuchen.
Hmm, eventuell hat das was mit clock-stretching zu tun. > Wenn man einen Slave ansprechen will, der Clock Stretching beherrscht, > muss man die I2C Takt verringern, so das der Slave nicht dazu genötigt > wird Clock Stretching anzuwenden. Hab ich in einem anderen Thread gefunden. Hier zB auch über die Tinys: Beitrag "Re: Raspberry Pi und AVR verbinden mittels I2C/TWI" > M.a.W: Wer einen µC als Slave an einen RPi hängen will, der sollte > entweder den I2C-Takt extrem niedrig legen, oder einen µC mit sehr > kurzer worst case Reaktion auf Interrupts verwenden (wie etwa STM32 mit > Priorisierung). Auch sollte die Kommunikation mit einer CRC abgesichert > werden.
:
Bearbeitet durch User
Wie sieht denn dein Code genau aus? Was machst du in der Main sonst noch? Hintergrund wieso ich Frage:
1 | void loop() |
2 | {
|
3 | /**
|
4 | * This is the only way we can detect stop condition (http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&p=984716&sid=82e9dc7299a8243b86cf7969dd41b5b5#984716)
|
5 | * it needs to be called in a very tight loop in order not to miss any.
|
6 | * It will call the function registered via TinyWireS.onReceive(); if there is data in the buffer on stop.
|
7 | */
|
8 | TinyWireS_stop_check(); |
9 | }
|
N. M. schrieb: > Wie sieht denn dein Code genau aus? > Was machst du in der Main sonst noch? Das ist quasi nur das Beispiel, das ich auf meinem Tiny laufen lasse. In der Main mache ich sonst gar nichts 🤔 > Hintergrund wieso ich Frage: Oh ... 🙈 Das hatte ich überlesen!
:
Bearbeitet durch User
Bei langsame Signale kann es zu ungewünschte Ubergänge im logisch undefinierten Bereich kommen, und/oder (ground) bouncing. Also auch beim TWI clock. Die schnellen Treiber an moderne IC's können einen extra spike am Empfänger verursachen (nur zu sehen auf einem teuren GS/s Oscillographen). Versuchsweise könntest du ein kleinen serien Wiederstand (22~33 Ohm) in die SDC-Leitung (und dann auch in die SDA-Leitung) aufnehmen. Wenn Slave (oder Master) in firmware programmiert ist (Mikrokontroller oder CPLD), dann empfielt es sich ein "de-spike-ing" filter darin auf zu nehemen. (3 bis 5 Sample/s * max. SDC Frequenz). Und achte auf die 3V3 pegeln am RPi : der Tiny muss auch mit 3V3 betrieben werden. Am I/O beider componenten sind vermutlich nicht die I2C-Stanaard Spannung-Pegeln im Emfänger implementiert, bei software (bei dir im Tiny) sind sicherlich nicht die I2C pegeln sondern die CMOS pegeln implementiert. Wenn du herrausgefunden hasst das es nicht ans Software im Tiny liegt, dann Überlege mal ob es am einem spike am SDC liegen könnte ... LG, A.
:
Bearbeitet durch User
Mampf F. schrieb: > ich hab einen ATTiny44, der per TWI an einem Pi4 hängt und habe > festgestellt, dass das nur so richtig funktioniert, wenn ich den Clock > auf 10kHz in der /boot/config.txt ändere. Ist ja auch die denkbarst ungünstige Wahl der Konfiguration. Der Raspi kann kein Clock-Stretching und der Tiny44 kann I2C nur sehr notdürftig (via USI). Und dann auch noch Implementierung des Tiny-Programms in C, was mit Interrupts seine liebe Mühe hat, wo aber blöderweise gerade bei der notdürftigen I2C-Unterstützung des Tiny alles nur noch davon abhängt, dass entweder der Tiny schnell genug reagiert (um ohne Clockstretching auszukommen) oder aber der Master halt mit Clockstretching vernünftig umgehen kann. Sprich: krasser Fehler beim Design, nämlich bei der Wahl der Waffen und der Komponenten. Das passt halt einfach alles nicht zusammen. Als Hauptproblem würde ich hier allerdings diesen Raspi-Dreck ansehen. Clock-Stretching ist schließlich definitiv Teil des I2C-Standards, eben um auch Slaves zu unterstützen, die bezüglich der Antwortzeiten nicht so ganz auf der Höhe der Zeit sind. Wer das nicht kann, hat nicht das Recht, seine entsprechende Schnittstelle als I2C-Schnittstelle zu bezeichnen. Das ist reine Kundenverarschung!
Yep. Genau jene Kommunikation die sich zwischen RasPi und µC regelrecht anbietet, I2C, ist beim RasPi leider verbuggt. Oder war es zumindest bei V1 und V2, von den Nachfolgern weiss ich es nicht. Das ändert sich auch nicht durch eine bessere Implementierung von I2C im µC. Man hat da auch nicht mehr Zeit zur Reaktion. Das USI ist zwar nicht der Brüller, aber hier unschuldig.
:
Bearbeitet durch User
(prx) A. K. schrieb: > Das ändert sich auch nicht durch eine bessere Implementierung von I2C im > µC, als per USI im Tiny. Man hat da auch nicht mehr Zeit zur Reaktion. Mehr Zeit hat man natürlich nicht. Aber man kann diese besser nutzen. Z.B. auch so gut, dass es funktioniert. Auch wieder so ein "Wunder", was nur in Asm relativ einfach geht... Aber klar: auch in Asm hängt es stark davon ab, was der Tiny eigentlich im Kern tun soll, die Kommunikation ist ja eigentlich Nebensache. Aber es geht halt in Asm sehr viel mehr als in C. Eben deshalb, weil man die volle Kontrolle über alle Resourcen und die volle Kontrolle über das Timing hat.
Master ohne Clock Stretching geht nur für dumme Slaves, wo SCK nur Eingang ist. Ein MC als Slave benötigt Zeit, wenn er z.B. gerade einen anderen Interrupt bearbeitet, d.h. der Master muß Clock Stretching können oder arschlangsam sein. Korrekt implementierte I2C-Master habe ich bisher nur von Philips gesehen. Z.B. die AVRs und 8051 von Atmel haben massiver Fehler in der Hardware, obwohl sie das Interface von Philips abgekupfert haben.
Peter D. schrieb: > Ein MC als Slave benötigt Zeit, wenn er z.B. gerade einen anderen > Interrupt bearbeitet, d.h. der Master muß Clock Stretching können oder > arschlangsam sein. Auch ohne andere Interrupts wird es eng. Slave-µCs arbeiten grundlegend anders als die gängigen Hardware-Slaves in EEPROMs und Sensoren. Der Slave beim oben verlinkten 841 ist komplett neu designed, ändert aber nichts am Problem. Nur komplett autonom arbeitendes I2C-Module, bei denen die gesamte Message ohne Zusammenspiel von Hard- und Software übertragen wird, vermeidet das Problem wirklich. Gibts das?
:
Bearbeitet durch User
Wären Tinys mit echtem TWI besser geeignet? (Glaub der ATTiny45 hat TWI ...). Hätte kein Problem damit, das Ding einfach durch eine andere Variant zu ersetzen 🤔 Falls nicht gebe ich mich mit 10kHz zufrieden und hoffe, dass es stabil läuft. 🙈
Man kann es ja umgekehrt machen, d.h. den Pi4 als Slave. Der AVR kann ja als single Master Clock Stretching. Nur als Multimaster kackt er ab bei Arbitrationsverlust.
Mampf F. schrieb: > Wären Tinys mit echtem TWI besser geeignet? Nochmal: Nicht der Slave ist das eigentliche Problem, sondern der Master, der RasPi. Wenn du das Problem wirklich im Slave lösen willst, dann nimm einen zig MHz ARM oder sowas in der Art, und sorge dafür, dass dessen I2C-Interrupt höchste Priorität hat. C-haters Asm kann helfen, hoher Takt auch, aber wenn der Slave auch andere Interrupts nutzt, wird es ohne Interrupt-Prioritäten immer etwas spannend.
(prx) A. K. schrieb: > Auch ohne andere Interrupts wird es eng. Eng ja. Aber eben nicht zu eng. Bei 8Mhz Systemtakt und 100kHz-Bus geht das schon. In systemweit optimiertem Asm natürlich... Und bei 16kHz (bei einigen Tinys ja per PLL-Takt möglich) geht das schon recht problemlos, ja es gehen sogar konkurrierende Interrupts, zumindest einer. Der muss sich natürlich ganz dünn machen.
Peter D. schrieb: > Man kann es ja umgekehrt machen, d.h. den Pi4 als Slave. Der AVR kann ja > als single Master Clock Stretching. Es geht hier um einen Tiny. Der hat keine TWI-Schnittstelle wie die Megas, die du wohl nur kennst. Der hat ein USI und dessen rudimentäre I2C-Unterstützung. Mehr nicht.
I2C lässt sich als Master auch ganz ohne Hardware implementieren. Blöd ist aber, dass die Software-Struktur eines Zusammenspiels aus RasPi und µC den Master im µC meist nicht nahelegt. Ich war deshalb auf die serielle Schnittstelle umgestiegen. Das ist zwar umständlicher, weil Stream statt Message als Grundlage, ist aber verlässlich.
Eine andere Möglichkeit wäre, den Software-I2C-Treiber unter Raspbian zu nutzen: https://github.com/fivdi/i2c-bus/blob/master/doc/raspberry-pi-software-i2c.md Dieser unterstützt I2C-Clock-Stretching.
(prx) A. K. schrieb: > Ich war deshalb auf die serielle Schnittstelle umgestiegen. Das ist zwar > umständlicher, weil Stream statt Message als Grundlage, ist aber > verlässlich. Bei eine Tiny als Client (jedenfalls für alle ohne echte USART, also die allermeisten) gilt das aber auch nur bei recht geringen Bitraten. Und die Einschränkungen bezüglich konkurrierender Interrupts sind natürlich ähnlich rigide. Dazu kommt, dass UART-Kommunikation nur mit einiger zusätzlicher Mühe busfähig zu machen ist. Nö, das ist kein Ausweg, der Ausweg für den AVR-Slave ist: Asm. Oder halt: Master gegen was Brauchbares tauschen. Frank M. schlägt da ja was vor. Kenne ich nicht, kann also nicht sagen, ob die Sache hält, was sie verspricht. Aber zumindest theoretisch könnte das wohl durchaus funktionieren.
c-hater schrieb: > Und dann auch noch Implementierung des Tiny-Programms in C Du laberst Scheiße! Sorry, das muss man mal so klar und deutlich sagen. Dein dümmliche C-Bashing ist wie immer fehl am Platz. Suche dir dafür einen anderen Wort wo sich deinesgleichen tummeln. Da bekommst du dann auch die positive Zustimmung, die dir so sehr fehlt. Wenn der Raspi kein Clock-Stretching kann, dann darf man das auf dem Slave halt nicht nutzen. Basta. Dafür kann weder der ATtiny was, noch die Programmiersprache. Doch ob das hier überhaupt der Knackpunkt ist, liegt nach noch im Bereich der wilden Phantasien. Geprüft (gemessen) hat es noch niemand.
c-hater schrieb: > Bei eine Tiny als Client (jedenfalls für alle ohne echte USART, also die > allermeisten) gilt das aber auch nur bei recht geringen Bitraten. Ich schrieb, was ich tat. Den 841/441 kann man als Nachfolger des 84/44 von TE verstehen. Der heisst zwar Tiny und hat nur 14-Pins, aber zwei echte USARTs und einen echten TWI-Slave (ohne Master).
:
Bearbeitet durch User
Stefan ⛄ F. schrieb: > Du laberst Scheiße! Sagst du, aber frag' mal einen geistig Gesunden. > Wenn der Raspi kein Clock-Stretching kann, dann darf man das auf dem > Slave halt nicht nutzen. Du hast nicht verstanden, dass das ein Manko des Raspi ist. Der Standard sieht Clock-Stretching obligatorisch vor. Ein Master, der das nicht kann, taugt schlicht nix. > Dafür kann weder der ATtiny was, noch > die Programmiersprache. Das stimmt. Nur kann man eben mit Asm den Tiny soweit ertüchtigen, dass er kein Clockstretching mehr benutzen muss (zumindest nicht an einem 100kHz-Bus) und ihn damit sogar zu einem völlig unfähigen Master wie dem Raspi kompatibel machen. Genau das geht aber eben NUR in Asm relativ einfach. Was erneut die unendliche Überlegenheit von Asm aufzeigt, für alle Fälle, wo es "eng" wird. > Bereich der wilden Phantasien. Geprüft (gemessen) hat es noch niemand. Du bist definitiv ein Idiot! Man braucht das weder prüfen noch messen. Man kann das einfach am Code "ausrechnen". Eigentlich ist Ausrechnen noch zu viel gesagt, es handelt sich ja eigentlich um kaum mehr als ein simples Abzählen von Takten von Instruktionen. Das einzig halbwegs Anspruchsvolle dabei ist: finde den worst case des Gesamtsystems. Sowas fällt bei einem Programm, welches komplett in Asm implementiert ist, naturgemäß sehr viel leichter, weil das da schon im Source abzählbar dasteht...
c-hater schrieb: > Du bist definitiv ein Idiot! Ein Idiot, der es einfach macht. Meines Slaves empfangen 10 Bytes mit 4MHz Taktfrequenz in C völlig ohne Tricks und ohne Probleme - ohne Clock-Stretching. Dabei läuft nebenbei noch eine 10 Kanalige Soft-PWM. Aber was nicht sein darf, kann nicht sein, nicht wahr?
Stefan ⛄ F. schrieb: > Ein Idiot, der es einfach macht. Meines Slaves empfangen 10 Bytes mit > 4MHz Taktfrequenz in C völlig ohne Tricks und ohne Probleme - ohne > Clock-Stretching. Dabei läuft nebenbei noch eine 10 Kanalige Soft-PWM. Bei welchem Bustakt? Und welcher µC ist der Slave?
c-hater schrieb: > Bei welchem Bustakt? Und welcher µC ist der Slave? Und natürlich: Ist der Master wirklich ein RasPi mit der normalen Hardware-I2C-Schnittstelle?
c-hater schrieb: > Bei welchem Bustakt? Und welcher µC ist der Slave? 100 kHz Bustakt, ATtiny26 und ATtiny2313.
Stefan ⛄ F. schrieb: > 100 kHz Bustakt, ATtiny26 und ATtiny2313. OK, und was ist mit dem Master? Der ist ja schließlich hier der Knackpunkt. Mit einem standardmäßigen Master kann's jeder Doofe, weil halt das Protokoll dafür ausgelegt ist und eben Clock-Stretching für diesen Fall vorsieht.
Stefan ⛄ F. schrieb: > Der Rottweiler hat sich fest gebissen. Aha, aha. Da haben wir den Lügner wohl erwischt. Es läuft eben wohl doch nicht ohne Clock-Stretching. Sondern vermutlich mit der von Frank M. im Thread vorgeschlagenen Alternative zum Raspi-Normal. Oder an einem völlig anderen Master, der halt von Haus aus Clock-Stretching unterstützt (so wie es sein sollte). Die Lüge war also im Kern die Behauptung, dass der C-Scheiß auf dem Tiny ohne Clockstretching-Unterstützung durch den Master funktioniert. Und das kann nur eine Lüge sein. Um das heraus zu finden, brauchst du nicht einmal den Code zu zeigen, dazu muss man nur Rechnen können... Wäre aber trotzdem spannend, ihn zu sehen. Ich könnte dann taktgenau deine frechen Lüge nachweisen. Und, ganz ehrlich: ich hätte sogar richtig Spaß daran, genau das zu tun... Wenn du also auch nur einen Rest Glaubwürdigkeit bewahren willst, dann poste den Code. Notfalls auch nur das *.hex. Aber klar: Beides würde mir vollkommen reichen, dich der Lüge zu überführen, also wirst du das wohl eher nicht tun...
c-hater schrieb: > Es läuft eben wohl doch nicht ohne Clock-Stretching. Du hast keine Ahnung, über was du da urteilst. Ich habe keine Lust mich weiter mit die abzugeben, nachdem du mich Lügner genannt hast. Du hast mal wieder deinen Platz auf meiner List mit dem weisen Mann bekräftigt.
Stefan ⛄ F. schrieb: > Du hast keine Ahnung, über was du da urteilst. Ja, stimmt. Du hast schließlich immer noch nicht nicht den Code geposted, der das Unmögliche angeblich möglich macht...
Ein I2C-slave (oder wie die jetzt heissen) macht ja clock stretching nicht wegen I2C, sondern weil ein Rückgabewert noch nicht vorliegt z.B. weil Sensoren erst noch abgefragt werden müssen. Das kann man aber auf den Attiny oberhalb von I2C anders lösen ... (z.B. einen speziellen Wert für "ich bin noch nicht fertig" zurückliefern). LG, Sebastian
Gibt wohl noch einen weiteren Grund, wieso clock-stretching bei mir auch nicht gehen würde, selbst wenn es der Pi richtig könnte. Hab einen ADUM1251* als I2C-Isolator (so nebenbei passiert hier auch der Level-Shift von 3,3V <-> 5V) verbaut, dessen SCL-Pin nur Unidirektional ist. Der ADUM1250 könnte bidirektional. Hatte mich damals schon gewundert, wer jemals einen bidirektionalen SCL brauchen würde und dann eben die unidirektionale Variante benutzt. Ich muss gestehen - clock-stretching hab ich zwar schon seit langer Zeit immer mal wieder gehört, aber ich hab mir nie angeschaut, was eigentlich genau passiert. Jetzt mach das natürlich Sinn 🙈 Ich hab noch einen weiteren ADUM1251, an dem ein I2C ADC hängt und der funktioniert wunderbar mit 400kHz. Vielleicht macht der einfach kein Clock-Stretching. 🤔 *: https://www.analog.com/media/en/technical-documentation/data-sheets/ADUM1250_1251.pdf
:
Bearbeitet durch User
Clock-Stretching ist nur eine von vielen möglichen Knackpunkten. Bevor du da Zeit und Geld versenkst, überprüfe doch erstmal die Vermutung bezüglich des Clock Stretchings. Denn vielleicht hast du ein ganz anderes Problem. Der Klassiker bei I²C ist die Nutzung von zu hochohmigen Pull-Up Widerständen wie sie auf quasi allen Chinesischen Modulen bestückt sind. Und die billigen 1-Transistor Pegelwandler tun sich mit Serienwiderständen und schwachen Bustreibern schwer. Mit einem Oszilloskop prüft man die Qualität der Signalpegel. Wenn du dir keins leisten kannst, dann wird dir ein DSO-150 gute Dienste leisten. Dieses "Spielzeug" ist immer noch viel besser, als gar keins zu haben. Kostet ca. 40 Euro bei Amazon. Danach kannst du die Kommunikation auf Bitebene mit einem Logic Analyzer und dem Programm PulseView kontrollieren. Kostet ca 10 Euro bei Amazon. Wenn du Zeit hast bestellst du die Sachen zum halben Preis bei Aliexpress.
Stefan ⛄ F. schrieb: > Bevor du da Zeit und Geld versenkst, überprüfe doch erstmal die > Vermutung bezüglich des Clock Stretchings. Denn vielleicht hast du ein > ganz anderes Problem. Ach, tbh - ich bin mehr oder weniger mit den 10kHz zufrieden. Fand es nur seltsam und wollte deshalb nachfragen, ob es da known-issues gibt :) Solange es stabil läuft, ist alles in Ordnung :)
Stefan ⛄ F. schrieb: > dann wird dir ein DSO-150 gute Dienste > leisten. Dieses "Spielzeug" ist immer noch viel besser, als gar keins zu > haben. Kostet ca. 40 Euro bei Amazon. Nice! Das kannte ich nicht :) Danke für den Tipp!
Muss es denn unbedingt ein Tiny sein? Für weniger als 3 Euro gibt es arduino's. dan hängt man den Arduino ans USB von Pi und mit USB-UART ist die sache fertig. Ohne 3v3/5V wandler, und als extra via R-Pi In-System Programmierbar (z.b. avrdude).
(prx) A. K. schrieb: > I2C lässt sich als Master auch ganz ohne Hardware implementieren. So ist es und dann geht auch Clock Stretching. Das Bitwackeln benötigt eben für jede SCK-Flanke einen Timerinterrupt (5µs). Das Clock Stretching kann man ganz einfach implementieren, indem der Gate-Mode des Timers benutzt wird, d.h. der Timer rennt erst los, wenn der Slave SCK freigibt (SCK = 1). Da I2C ja keine Maximalzeiten kennt, gibt es auch keine Probleme mit Ressourcen. Jeder andere Interrupt darf den I2C-Master unterbrechen. Es müßte sich nur mal jemand auf den Hosenboden setzen und einen ordentlichen Treiber für den Pi schreiben.
:
Bearbeitet durch User
Peter D. schrieb: > (prx) A. K. schrieb: > >> I2C lässt sich als Master auch ganz ohne Hardware implementieren. > Es müßte sich nur mal jemand auf den Hosenboden setzen und einen > ordentlichen Treiber für den Pi schreiben. Gibt es bereits, schrieb ich oben: Beitrag "Re: [ATTiny44+PI4] TWI Slave nur mit langsamen Clocks"
Sebastian schrieb: > Ein I2C-slave (oder wie die jetzt heissen) macht ja clock stretching > nicht wegen I2C, sondern weil ein Rückgabewert noch nicht vorliegt z.B. > weil Sensoren erst noch abgefragt werden müssen. Neeeiiin. Das machen nur so richtig lausig beschissene *Anwendungs*-Implementierungen deshalb. Das Problem steckt (zumindest mit USI) ganz wo anders. An zwei Stellen im Treiber, also der Transport-Ebene. Erstmal muss der Slave überhaupt mal eine Aktivität am Bus erkennen (also eine start condition). Dann muss er schnell genug sein USI dazu konfigurieren, überhaupt erstmal eine Adresse zu empfangen. Das ist noch ein relativ einfaches Problem. Die zweite, noch viel kritischere Stelle ist das (jedes!) Byte-Ende. Hier ist das ACK schnell genug zu empfangen/zu senden und dann ggf. noch das nächste Byte zu empfangen/zu senden. Um das alles richtig zu machen, muss der Treiber allerdings erstmal herausfinden, wo in einem I2C-Transfer er eigentlich gerade steckt. Schafft er das alles nicht, passiert wieder unweigerlich Clock-Stretching (durch die Hardware). Hier kann man allerdings erheblich tricksen, indem man ab erkannter start condition "pollt". Das entschärft das Problem, verhindert aber dann auch effizient konkurrierende Interrupts in dieser ganzen langen Zeit des kompletten I2C-Transfers. Aber als Assembler-Programmierer muss man das eben nicht, da kann man auch dieses Problem tatsächlich noch vollständig in der entsprechenden ISR abhandeln. > Das kann man aber auf > den Attiny oberhalb von I2C anders lösen ... (z.B. einen speziellen Wert > für "ich bin noch nicht fertig" zurückliefern). Genau. So löst man das Problem auf Anwendungsebenene richtig, statt durch Missbrauch des Clock-Stretching-Mechanismus der Transport-Ebene. Davon sollte die Anwendungsebene im Idealfall ja garnix wissen. Ändert aber eben nur leider nichts an den Timing-Problemen auf der Transport-Ebene...
Ich denke auch, dass das Timing vom ACK der kritische Punkt ist. ACK soll ja bestätigen, dass das Byte angenommen wurde bzw. das ein Kommando erfolgreich ausgeführt wurde. Der Empfänger muss innerhalb eines Bustaktes entscheiden, ob er mit ACK antworten will - sonst wird daraus automatisch ein NAK. Die Entscheidung, ob der Slave mit ACK oder NAK antworten will erfordert oft irgendeine Prüfung. Und die braucht halt ihre Zeit. Dazu kommt: Wenn die Bytes in einer ISR verarbeitet werden, dann geht einem schon die Verzögerung des Interrupt-Aufrufes und der Prolog (Sichern der Register) von dieser kostbaren Zeit verloren. Macht man es hingegen in der Hauptschleife, können Interrupthandler (z.B. vom Timer) zu viel Zeit in Anspruch nehmen. Da muss man ziemlich aufpassen und sich auf wenige Aktionen beschränken. Clock Stretching kann man nutzen, um diese Zeitspanne zu verlängern. Das sollte sich dann aber immer noch im Rahmen von weit unter 1 ms abspielen, weil der ganze I²C so lange blockiert ist. Bei einigen Geräten kommt Clock Stretching gar nicht in Frage weil es nicht implementiert wurde. Wenn die Verarbeitung von Daten länger dauert, sollte man die Verarbeitung asynchron machen. Der Slave kann für den Status Flags (arbeite noch, fertig, Erfolg, Fehler) bereit stellen, die der Master jederzeit ohne warten zu müssen abfragen darf (Polling). Das Kommunikationsmuster aus Sicht des Master wäre dann: 1) Kommando Senden 2) Status abfragen 3) Wiederhole 2, wenn noch nicht fertig 4) Ergebnis abholen
C-hater, du hast das alles gut beschrieben, ich stimme dir weitgehend zu. Bis auf diesen Punkt: c-hater schrieb: > Aber als Assembler-Programmierer muss man das eben nicht, da > kann man auch dieses Problem tatsächlich noch vollständig in der > entsprechenden ISR abhandeln. Je nach Verhältnis zwischen CPU und Bustakt kann man das auch in C vollständig in der ISR abhandeln, ohne Klimmzüge zu machen. Doch der gcc Compiler optimiert inzwischen sehr gut. Er sichert nur die nötigsten CPU Register, deswegen kann es "einfach so" klappen. Und wenn nicht, dann gibt es immer noch "naked ISR", falls du das nicht kennst. Ein Blick ins Assembler Listing kann dabei ziemlich aufschlussreich sein, wenn man es denn lesen kann. Deswegen sage ich oft, dass ein kleines bisschen Assembler Kenntnisse auch für C Entwickler nützlich sind.
Die Philips Entwickler waren ja nicht doof. Das Clock Stretching ist genau dafür gedacht, denn Bus auf den langsamsten Slave zu synchronisieren. Das Clock Stretching kostet den Master auch keinerlei CPU-Zeit. Den nächsten Interrupt kriegt er erst, wenn SCK wieder auf high gegangen ist. Doof sind nur die vielen anderen Hardwareentwickler gewesen, die entweder die Spezifikation nicht gründlich gelesen haben oder ihre Hardware nicht getestet haben. Die Philips Dokumentatiion ist vorbildlich, damit sollte eigentlich jeder eine korrekt funktionierende Hardware entwickeln können.
@Stefan: Willst du nun ernsthaft mit c-hater über die Vorzüge von C diskutieren? ;-)
:
Bearbeitet durch User
Peter D. schrieb: > damit sollte eigentlich jeder eine korrekt funktionierende Hardware > entwickeln können. Broadcom hat es ja versucht. Nur eben fehlerhaft. Und seither offenbar keinen Finger mehr gerührt um den Bug zu beseitigen. Denn neu ist das Problem ja nicht.
:
Bearbeitet durch User
(prx) A. K. schrieb: > mit c-hater über die Vorzüge von C diskutieren? ;-) In diesem Thread und bei dieser Problemstellung sind Vorzüge für C nicht erkennbar. Da ist's wichtig, dass sich der emulierte Slave möglichst wie richtige Hardware verhält und das ist am Einfachsten mit Assembler machbar, man muss es halt auch können und nicht nur darüber phantasieren. Wäre zur reinen Funktionalität das I2C-Protokoll sprechen zu können, eine kompliziertere Verarbeitung von Messwerten, etc. gefragt, dann erst macht eine Hochsprache Sinn. Und selbst dann würde man die I2C-Fähigkeit als HAL in Assembler ausführen. Da weiß man einfach was man bekommt, während man Hochsprachen durch entsprechende Parameter da hinschubsen muss, wo man hin will. (prx) A. K. schrieb: > Und seither offenbar keinen Finger mehr gerührt um den > Bug zu beseitigen. Es wurde der Punkt des "good enough" erreicht.
Sebastian schrieb: > Ein I2C-slave (oder wie die jetzt heissen) macht ja clock stretching > nicht wegen I2C, sondern weil ein Rückgabewert noch nicht vorliegt z.B. > weil Sensoren erst noch abgefragt werden müssen. Das Problem kann auch dann auftreten, wenn die alle zur Reaktion im I2C-Interrupt nötige Information bereits fertig vorliegt. Zudem betrifft es nicht nur Lese- sondern auch Schreiboperationen. Anmerkungen aus der damaligen Fehlersuche zufolge, kann es kurioserweise helfen, die Reaktionszeit innerhalb des Interrupts erheblich zu vergrössern, um die kritische Schwelle von 1/2 Takt sicher zu überschreiten. ;-)
MWS schrieb: > Da ist's wichtig, dass sich der emulierte Slave möglichst wie > richtige Hardware verhält Ursache des altbekannten Broadcom/RPi-Problems mit I2C ist eine fehlerhafte Implementierung der Hardware des Masters. Es tritt auch bei völlig korrekt implementiertem Slave auf. Clock Stretching durch den Slave ist Teil der I2C-Spezifikation und kein Fehlverhalten. Ohne Änderung seitens des Masters kann man im Slave lediglich versuchen, um den Bug des Masters herum zu manövrieren. Ob per hinreichend schnellem Slave-Controller, c-haters Steckenpferd Asm vs C, Verzicht auf weitere Interrupts, Polling an kritischen Stellen...
:
Bearbeitet durch User
(prx) A. K. schrieb: > Originalquelle und Analyse zum Bug: > https://www.advamation.de/technik/raspberrypi/rpi-i2c-bug.html Die Analyse ist gut dokumentiert, der eigentliche Fehler wurde aber schon am 24-Dez-2012 von mir beschrieben: https://www.raspberrypi.org/forums/viewtopic.php?p=241137&sid=107cfa0001dbddcc90051bab9f370a28#p241137. LG, Sebastian
Uiuiui, hätte ja nicht gedacht, dass ich da so ein Fass aufmache mit meinem ATTiny-I2C-Problem 🙈
Peter D. schrieb: > Die Philips Dokumentatiion ist vorbildlich, Ist das so? Immerhin enthält sie keine Empfehlung, geschweige denn ein Gebot, auf Anwendungsebene kein "lausiges" "beschissenes" clock stretching durchzuführen. Siehe z.B. Sensirion SHT21 hold master mode, der SCL low bis zu 85ms (!) stretcht (für den es allerdings auch die Alternative no hold master mode gibt). LG, Sebastian
Sebastian schrieb: > Immerhin enthält sie keine Empfehlung, geschweige denn ein > Gebot, auf Anwendungsebene kein "lausiges" "beschissenes" clock > stretching durchzuführen. Woher sollten sie auch Deine ganz persönlichen Animositäten kennen? Das Clock Stretching ist ein vorzügliches Mittel zur Übertragungssicherung, wenn mal ein Slave auch noch andere Sachen machen muß. Was nützt mir ein Übertragungsverfahren, welches mir sämtliche Echtzeitanforderungen der Applikation zur Sau macht. Daher löst auch eine Implementierung in Assembler nicht das Problem. Assembler mag zwar das pure I2C beschleunigen, jedoch zu Lasten der eigentlichen Applikation.
Peter D. schrieb: > Woher sollten sie auch Deine ganz persönlichen Animositäten kennen? > Das Clock Stretching ist ein vorzügliches Mittel zur > Übertragungssicherung, wenn mal ein Slave auch noch andere Sachen machen > muß. Die Zitate sind von c-hater, insofern war mein Beitrag oben über Bande, sorry. Ich halte die I2C-Spezifikation auch für eine der Besseren. Sie hat aber meiner Meinung nach eine Schwäche. Es heisst dort: "Clock stretching is optional and in fact, most slave devices do not include an SCL driver so they are unable to stretch the clock." An dieser Stelle wäre es besser zu sagen: "Clock stretching is optional for a slave, and in fact ...". So wie zur Zeit geschrieben kann sich Broadcom trotz der Errata zu leicht herausreden, und die Raspberry-Nutzer haben weiter ihre I2C-Probleme ... LG, Sebastian
Sebastian W. schrieb: > most slave devices do not include an SCL driver so > they are unable to stretch the clock. Übersetzt: Wenn der Slave aufgrund seiner Arbeitsweise kein Clock Stretching benötigt, dann muss er es auch nicht implementieren. ;-) Heutzutage können jedoch auch winzige Sensoren der Hühnerfutterklasse dank Nutzung einbauter Mikrocontroller hochkomplexe Geräte sein. Und da hat man u.U. das Thema am Hals.
Sebastian W. schrieb: > So wie zur Zeit geschrieben kann sich Broadcom trotz der Errata zu > leicht herausreden Können sie nicht wirklich. Sie haben es ja implementiert, waren sich der Notwendigkeit also bewusst.
:
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.