Moin,
ich teile dann mal meine Erkenntnisse :-) Nachdem ich da mehrere Tage
intensive Tests habe laufen lassen und 2 Atmel 64k EE's geopfert habe,
die einige Millionen Random Zugriffe gemacht haben, Schreiben und Lesen
per Pagewrite im zufälligen Wechsel, wieder und wieder rund um die Uhr.
Einwandfreies Design ist vorausgesetzt, kurze Leitungen, 100Khz statt
400khz (auch wenn es geht), ausreichende Pull Ups (4.7K bei mir), dazu
100nF Blocker an dem EE. Es reicht ein einziger Störpuls aus, damit die
beiden Statemachines des uC und des EE aus dem Takt kommen.
1. Auch wenn das Datenblatt es zulässt ein EE mit 3,3V zu betreiben: Mit
5V (Vcc und Pull Ups an 5V) geht es deutlich stabiler! Mit 3.3V trat es
trotzdem noch 2 Mal bei den Tests auf.
2. Ein "hängender I2C Bus" bei einem STM32 ist nicht mehr zu resetten,
da habe ich alles Denkbare versucht, sowhl die I2C hardware des STM32 zu
resetten als auch das "klingeln" an der SCL Leitung.
3. Es müssen ZWINGEND während der Buskommunikation alle zeitintensiven
Ints unterbunden werden! Mag sein, dass es da Lücken gibt, wo es geht,
zb nach dem Startbit und vor der Adressierung aber erst seit ich bei den
Zugriffen totale Stille einkehren liess läuft es seit nunmehr 3 Tagen
durch.
4. Einwandfreie Software, die jeden Fehler der Event Flags abfängt und
dann direkt STOP sendet und den Bus freigibt.
Tiefer wollte ich da nicht mehr einsteigen, vielleicht hilft es ja
jemandem...
Gruss,
Christian
Meine Geraete sind meist Kleinserien (so 100 bis 1.000 St.), die aber
meist über 10 Jahre im Betrieb sind. Der Spitzenreiter liegt z.Zt. bei
15 Jahren. Ich persönlich benutze nur Soft-I2C: einschalten und
vergessen.
Ehrlich gesagt habe ich Mühe zu verstehen, warum man wegen ein paar
lahmen ICs, die da angebunden werden müssen, sich mit der
HW-Implementierung herumschlaegt.
Chris J. schrieb:> 3. Es müssen ZWINGEND während der Buskommunikation alle zeitintensiven> Ints unterbunden werden!
Ich habe auch Deinen anderen Thread dazu gelesen. Auch dort waren
scheinbar irgendwelche Nicht-I2C-Interrupts die Ursache dafür, dass sich
die I2C-Peripherie aufhing.
Aber ich verstehe das nicht: I2C arbeitet synchron mit einer Clock,
warum sollen da irgendwelche Interrupts (wenn sie korrekt programmiert
sind), den I2C-Bus zum Hangup bringen? Wenn irgendwelche "zeitintensive"
Interrupts die Flanke von Data oder Clock etwas verzögern, was solls?
Der STM32 bestimmt den Takt! Lass ihn doch um mehrere msec jittern, das
tut dem Master (und auch dem Slave) nicht weh.
Also: Mir fehlt eine einleuchtende Begründung, warum ich das tun sollte.
Mehmet K. schrieb:> Ehrlich gesagt habe ich Mühe zu verstehen, warum man wegen ein paar> lahmen ICs, die da angebunden werden müssen, sich mit der> HW-Implementierung herumschlaegt.
z.B. wenn der Controller noch was anderes zu tun hat als tausende Takte
in den Warteschleifen für Soft I2C zu hängen!
Frank M. schrieb:> Aber ich verstehe das nicht: I2C arbeitet synchron
Ganz genau... man bräuchte ein LA/Oszilloskop Bild vom Problem. Man kann
ja im Fehler Fall einen Ausgang setzen und darauf triggern.
Frank M. schrieb:> I2C arbeitet synchron mit einer Clock,> warum sollen da irgendwelche Interrupts (wenn sie korrekt programmiert> sind), den I2C-Bus zum Hangup bringen?
Ich habe jetzt nicht mitbekommen, welcher STM32 gemeint ist. STM32F4xx
hat einen ellenlangen Eintrag zu I2C im Errata Sheet, STM32F10x immerhin
auch zwei Seiten in Bezug auf Wechselwirkung mit anderen IRQs.
Frank M. schrieb:> Aber ich verstehe das nicht: I2C arbeitet synchron mit einer Clock,> warum sollen da irgendwelche Interrupts (wenn sie korrekt programmiert> sind), den I2C-Bus zum Hangup bringen? Wenn irgendwelche "zeitintensive"> Interrupts die Flanke von Data oder Clock etwas verzögern, was solls?> Der STM32 bestimmt den Takt! Lass ihn doch um mehrere msec jittern, das> tut dem Master (und auch dem Slave) nicht weh.>> Also: Mir fehlt eine einleuchtende Begründung, warum ich das tun sollte.
Das wäre eine Begründung:
Walter T. schrieb:> Ich habe jetzt nicht mitbekommen, welcher STM32 gemeint ist. STM32F4xx> hat einen ellenlangen Eintrag zu I2C im Errata Sheet, STM32F10x immerhin> auch zwei Seiten in Bezug auf Wechselwirkung mit anderen IRQs.
Also geht es hier um Workarounds für Bugs in den Chips und nicht
wirklich um I2C. Ein extremer Workaround ist alles in SW zu machen.
MfG Klaus
Chris J. schrieb:> ich teile dann mal meine Erkenntnisse :-) Nachdem ich da mehrere Tage> intensive Tests habe laufen lassen
Mich hat es einige Minuten gekostet Errata von ST zu finden und den
vorgeschlagenen Fix per copy&paste einzufügen.
Chris J. schrieb:> Ein "hängender I2C Bus" bei einem STM32 ist nicht mehr zu resetten,> da habe ich alles Denkbare versucht, sowhl die I2C hardware des STM32 zu> resetten als auch das "klingeln" an der SCL Leitung.
Das ist auch Quatsch!
♪Geist schrieb:> Mich hat es einige Minuten gekostet Errata von ST zu finden und den> vorgeschlagenen Fix per copy&paste einzufügen.
Welcher war das?
Ich habe mir gerade mal das "STM32F40x and STM32F41x Errata sheet" vom
Juli 2017 angeschaut und finde im Kapitel "2.4 I2C peripheral
limitations" nichts bzgl. Problemen mit anderen Interrupts.
Frank M. schrieb:> Aber ich verstehe das nicht: I2C arbeitet synchron mit einer Clock,> warum sollen da irgendwelche Interrupts (wenn sie korrekt programmiert> sind), den I2C-Bus zum Hangup bringen? Wenn irgendwelche "zeitintensive"> Interrupts die Flanke von Data oder Clock etwas verzögern, was solls?> Der STM32 bestimmt den Takt! Lass ihn doch um mehrere msec jittern, das> tut dem Master (und auch dem Slave) nicht weh
Ich habe zu Hause mit Bordmitteln gearbeitet und nach Veränderungen
jeweils Test laufen lassen. Dazu gegoogelt und einen Beitrag gefunden,
dass bestimmte Flags unbedingt atomar bearbeitet werden müssen, zb das
EV_6 Flag. Es gibt sicherlich viele Lücken, wo Ints laufen können aber
dazu müsste ich viele neue Tests machen und dazu fehlt mir etwas der
Nerv. Mir flackert auch etwas die Anzeige, da die PWM Ints nicht
durchkommen, ggf. schraube ich da noch etwas herum.
In diesem Fall ist die Soft I2C sicherlich besser, da die Hardware
nunmal echt komplex ist. Für so eine einfache Sache viel zu aufwendig.
Da bin ich auch reingefallen: Errata sheet:
When the EV7, EV7_1, EV6_1, EV6_3, EV2, EV8, and EV3 events are not
managed before the current byte is being transferred, problems may be
encountered such as receiving an extra byte, reading the same data twice
or missing data.
Deswegen INT Sperren:
Workaround 2
Use I2C interrupts and boost their priorities to the highest one in the
application to make them uninterruptible
Wurde in den SpdPeriph Libs bereits durch ST behoben:
Workaround 3 (only for EV6_1 and EV6_3 events used in method 2)
EV6_1 event (used in master receiver 2 bytes):
Stretch SCL line between ADDR bit is cleared and ACK is cleared:
a) ADDR=1
b) Configure SCL I/O as GPIO open-drain output low
c) Clear ADDR by reading SR1 register followed by reading SR3