Forum: Mikrocontroller und Digitale Elektronik [ATTiny44+PI4] TWI Slave nur mit langsamen Clocks


von Mampf F. (mampf) Benutzerseite


Lesenswert?

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
von Stefan F. (Gast)


Lesenswert?

Ich würde das mit einem Logic-Analyzer untersuchen.

von Mampf F. (mampf) Benutzerseite


Lesenswert?

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
von N. M. (mani)


Lesenswert?

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
}

von Mampf F. (mampf) Benutzerseite


Lesenswert?

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
von Alfred T. (atererus)


Lesenswert?

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
von c-hater (Gast)


Lesenswert?

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!

von (prx) A. K. (prx)


Lesenswert?

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
von c-hater (Gast)


Lesenswert?

(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.

von Peter D. (peda)


Lesenswert?

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.

von (prx) A. K. (prx)


Lesenswert?

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
von Mampf F. (mampf) Benutzerseite


Lesenswert?

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. 🙈

von Peter D. (peda)


Lesenswert?

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.

von (prx) A. K. (prx)


Lesenswert?

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.

von c-hater (Gast)


Lesenswert?

(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.

von c-hater (Gast)


Lesenswert?

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.

von (prx) A. K. (prx)


Lesenswert?

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.

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

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.

von c-hater (Gast)


Lesenswert?

(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.

von Stefan F. (Gast)


Lesenswert?

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.

von (prx) A. K. (prx)


Lesenswert?

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
von c-hater (Gast)


Lesenswert?

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...

von Stefan F. (Gast)


Lesenswert?

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?

von c-hater (Gast)


Lesenswert?

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?

von c-hater (Gast)


Lesenswert?

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?

von Stefan F. (Gast)


Lesenswert?

c-hater schrieb:
> Bei welchem Bustakt? Und welcher µC ist der Slave?

100 kHz Bustakt, ATtiny26 und ATtiny2313.

von c-hater (Gast)


Lesenswert?

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.

von Stefan F. (Gast)


Angehängte Dateien:

Lesenswert?

Der Rottweiler hat sich fest gebissen.

von c-hater (Gast)


Lesenswert?

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...

von Stefan F. (Gast)


Lesenswert?

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.

von c-hater (Gast)


Lesenswert?

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...

von Sebastian (Gast)


Lesenswert?

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

von Mampf F. (mampf) Benutzerseite


Lesenswert?

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
von Stefan F. (Gast)


Lesenswert?

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.

von Mampf F. (mampf) Benutzerseite


Lesenswert?

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 :)

von Mampf F. (mampf) Benutzerseite


Lesenswert?

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!

von Alfred T. (atererus)


Lesenswert?

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).

von Peter D. (peda)


Lesenswert?

(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
von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

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"

von c-hater (Gast)


Lesenswert?

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...

von Stefan F. (Gast)


Lesenswert?

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

von Stefan F. (Gast)


Lesenswert?

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.

von Peter D. (peda)


Lesenswert?

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.

von (prx) A. K. (prx)


Lesenswert?

@Stefan: Willst du nun ernsthaft mit c-hater über die Vorzüge von C 
diskutieren? ;-)

: Bearbeitet durch User
von (prx) A. K. (prx)


Lesenswert?

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
von (prx) A. K. (prx)


Lesenswert?


von MWS (Gast)


Lesenswert?

(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.

von (prx) A. K. (prx)


Lesenswert?

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. ;-)

von (prx) A. K. (prx)


Lesenswert?

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
von Sebastian W. (wangnick)


Lesenswert?

(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

von Mampf F. (mampf) Benutzerseite


Lesenswert?

Uiuiui, hätte ja nicht gedacht, dass ich da so ein Fass aufmache mit 
meinem ATTiny-I2C-Problem 🙈

von Sebastian (Gast)


Lesenswert?

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

von Peter D. (peda)


Lesenswert?

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.

von Sebastian W. (wangnick)


Lesenswert?

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

von (prx) A. K. (prx)


Lesenswert?

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.

von (prx) A. K. (prx)


Lesenswert?

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