Hallo,
leider kommt es doch immer wieder mal vor, dass meine E2's sich
aufhängen und das Programm dann endlos in einer Abfrage eines Events
hängen bleibt. Ich benutze die I2C Hardware des Chips, frage Fehler
"meistens" ab aber nicht hinter jedem einzelnen Befehl, weil das
Programm dadurch sehr unübersichtlich wird und es auch keine sinnvolle
Reaktion darauf gibt, dann steht die Kiste eben still, merke ich an den
Anzeigen ja. Da das bis zu 4-fach geschachtelt ist muss ein ERROR auch
bis nach ganz oben an den Aufrufer durchgereicht werden, globale ERROR
Variable nutze ich nicht.
Man muss halt jede Lib Funktion nochmal kapseln und davon gibt es
reichlich. Prinzipiell kann jedes Event eben nicht kommen.
Ist allerdings nicht so wie bei einer Soft I2C, dass man mal eben an den
Pins wackeln kann, die sind schon fest mit der Hardware verbunden und
manuell gar nicht ansprechbar, das macht die Statemachine des Chips.
Hat da schon mal jemand was Kluges ausgefrickelt, ob solche Aufhänger zu
resetten? Schalte ich i2C ab gegen die Pins in High-Z, hängen also auf
+5V. Nützt auch nichts.
Gruss,
Christian
Die I2C Peripherie hat eine Reset Funktion über ein bestimmtes Bit im
Register. weiß ich grad nicht auswendig, musst du mal nach suchen. Im
Zweifelsfall einfach über den RCC resetten. Ich verwende für meine
asynchrone (per Interrupts statt Warte Schleife) I2C Ansteuerung
nebenher einen Timer, um Timeouts zu erkennen und eben diese Reset
Funktion zu nutzen. Die I2C Peripherie der STM32 ist da besonders
zickig, wenn die einen "low" Störimpuls sehen gehen die dauerhaft auf
"busy" o.ä.
I2C_Cmd(I2C_KANAL,DISABLE);// I2C abschalten, damit Bus still bleibt
Mann muss ihn vor der Config abschalten, sonst hat man seltsame
Glitches, beim LA zu sehen. Aber die Reset Funktion muss ich auch mal
suchen, bisher noch nicht gewusst, dass es sowas überhaupt gibt.... die
Idee mit dem Timer ist gut! Da braucht man ja nur eine zeit wo man eie
Variable zurück setzt und fertig.
Hmmm..... meinst Du 22.6.1: SWRST: Sofwtare Reset Bit?
Christian J. schrieb:> Mann muss ihn vor der Config abschalten, sonst hat man seltsame> Glitches
Hm, das Problem habe ich nicht. Ich schalte ihn einfach ein:
Christian J. schrieb:> Hmmm..... meinst Du 22.6.1: SWRST: Sofwtare Reset Bit?
Ja genau.
Christian J. schrieb:> Da braucht man ja nur eine zeit wo man eie> Variable zurück setzt und fertig.
Ich starte/resette den Timer immer wenn eine Operation gestartet wird,
und wenn der Timer-Interrupt vor dem I2C-Interrupt kommt war das ein
Timeout, und ich fange ganz von vorne an (reinitialisiere auch den
externen IC).
Die lieben E-Techniker bauen immer Platinen mit ganz viel I2C weil das
ja so schön einfach ist, und als Programmierer darf man sich dann mit
sowas rumschlagen ;-)
Oder so? Bin nicht so der register Fan...
/* Enable I2C2 reset state */
RCC_APB1PeriphResetCmd(RCC_APB1Periph_I2C2, ENABLE);
/* Release I2C2 from reset state */
RCC_APB1PeriphResetCmd(RCC_APB1Periph_I2C2, DISABLE);
Christian J. schrieb:> Oder so? Bin nicht so der register Fan...>> /* Enable I2C2 reset state */> RCC_APB1PeriphResetCmd(RCC_APB1Periph_I2C2, ENABLE);> /* Release I2C2 from reset state */> RCC_APB1PeriphResetCmd(RCC_APB1Periph_I2C2, DISABLE);
Würde ich nur so machen wenn das SWRST Bit nicht geht.
Mit direkten Registerzugriffen zu programmieren find ich einfacher, weil
die schön ausführlich im Reference Manual dokumentiert sind, und man
einfach nur machen muss was da steht. Bei den Library-Funktionen muss
man erstmal in den Source-Code schauen was die überhaupt machen, das mit
dem Reference Manual abgleichen und sich dann rückwärts überlegen wann
man welche Funktion aufrufen muss damit die richtigen Bits gesetzt
werden.
Christian J. schrieb:> Hat da schon mal jemand was Kluges ausgefrickelt, ob solche Aufhänger zu> resetten?
Du solltest deine Hardware zurechtfrickeln damit dein I2C-Bus
störungsfrei funktioniert.
Herzeigen willst du deinen Aufbau und deine Schaltung ja sowieso
nicht denn dann kämen womöglich grössere Peinlichkeiten ans
Tageslicht.
Also belasssen wir es lieber bei dieser vernebelten Situation
und stochern so weiter. Wenn deine Annahmen über Elektronik
und Schaltungsphysik am I2C Bus so professionell sind wie beim
Thema NRF24 dann ist das auch besser so
(Beitrag "Re: Welche NRF24L01+ 2.4 Ghz Transmitter taugen?").
Und du frickelst besser weiter nur an der Software herum.
Arduinoquäler schrieb:> Du solltest deine Hardware zurechtfrickeln damit dein I2C-Bus> störungsfrei funktioniert.
Das ist nicht zielführend. Oft ist es einfacher/billiger/leichter,
Fehler in Software abzufangen als alles massiv gegen Störungen zu
schirmen. Der I2C-Bus ist notorisch empfindlich (insbesondere bei den
STM32) und eine Fehlerbehandlung ist ohnehin nötig, denn irgendwann wird
doch ein Fehler auftreten. Leider hat I2C ja weder Checksum noch
differentielle Übertragung, was da ganze besonders spaßig macht.
Christian J. schrieb:> Muss ich nach dem Reset das Ganze wieder neu initialisieren?
Glaub schon... Ruf die Initialisierungsfunktion einfach erneut auf ;-)
Statt eines externen EEPROMs kann man auch den internen Flash
beschreiben, wenn man's schlau macht hält der auch genau so lange.
Dr. Sommer schrieb:> Christian J. schrieb:>> Muss ich nach dem Reset das Ganze wieder neu initialisieren?>> Glaub schon... Ruf die Initialisierungsfunktion einfach erneut auf ;-)> Statt eines externen EEPROMs kann man auch den internen Flash> beschreiben, wenn man's schlau macht hält der auch genau so lange.
Ja.... nur ist der eh schon fast randvoll..... und so einfach ist das
auch nicht, geht ja nur blockweise.
So.... gucken ob es passt.
Moin,
alle 2-3 Tage steht meine schöne Anzeigetafel an der Wald still, weil
sich der I2C Bus aufhängt. Wo genau weiss ich nicht, hängt ja nicht am
Debugger aber meist kommt ein sog. Event einfach nicht. 2x EE je 64kb,
4,7kOhm an 5V, angesteuert durch OD Ausgang des F103.
Blind geschrieben mein Versuch alles was mit I2C zu tun hat, also der
Master im F103 und das EEPROM zu resetten. Irgendwann schlägt der WDT ja
zu nach 10s und dann wird immer und immer wieder versucht das EEPRPOM
anzusprechen.
Hat sich schon mal jemand damit intensiver befasst EE's und anderes aus
dem Schlaf zu klingeln?
1
uint8_tEE_Reset_Hardware()
2
{
3
4
GPIO_InitTypeDefGPIO_InitStruct;// Port Init Struct
Chris J. schrieb:> Wo genau weiss ich nicht
Ich weiss es auch nicht, aber ich bin mir ziemlich sicher
dass dein (mieser) Hardware-Aufbau schuld ist.
Aber daran kann es ja nach deiner Auffassung sicherlich
nicht liegen. Es ist immer der Hersteller eines Chips oder
der fehlerhafte Compiler dran schuld.
Arduinoquäler schrieb:> Christian J. schrieb:>> Hat da schon mal jemand was Kluges ausgefrickelt, ob solche Aufhänger zu>> resetten?>> Du solltest deine Hardware zurechtfrickeln damit dein I2C-Bus> störungsfrei funktioniert.
Dem schließe ich mich an.
Man sollte sich mal klarmachen, dass I2C KEINE Maßnahmen zur
Fehlererkennung- und Korrektur hat. Das verlässt sich auf 0% Fehlerrate
auf physikalischer Ebene.
Wenn also der Bus aus elektrischen Gründen Bitfehler hat, dann ist das
Kind schon im Brunnen. Da ist der Fehler auf Hardwareebene zu finden und
zu beheben.
Was ich aus der Praxis sagen kann:
Ich kann von den I2C-Blöcken von ST nichts negatives berichten. Mein
Arbeitgeber hat mehrere hunderttausend Platinen mit STM32 und I2C im
Feld, wo das ohne Probleme läuft.
Was klar sein muss ist, dass I2C ein störanfälliger Bus ist, und
besondere Sorgfalt verlangt. Er ist aber zuverlässig, vorausgesetzt man
hat das sauber ausgelegt und in Betrieb genommen.
Christian J. schrieb:> Hat da schon mal jemand was Kluges ausgefrickelt, ob solche Aufhänger zu> resetten?
Vielleicht solltest Du erstmal versuchen, die Ursache zu finden als an
den Symptomen herumzudoktern.
Viele I2C-Beispiele, die man so im Netz findet, vergessen nämlich, nach
einem Daten-Transfer (bzw. vor dem nächsten) I2C_FLAG_BUSY abzufragen.
Das funktioniert dann solange gut, wie man nur Daten tröpfchenweise
liest oder schreibt. Kommen zum Beispiel mehrere I2C-Transferblöcke
direkt hintereinander, hängt sich ohne Berücksichtigung des Busy-Flags
die I2C-Peripherie einfach weg und ist nicht mehr ansprechbar. Da nutzt
auch kein 9-maliges Pinwackeln mehr, nur noch ein HW-Reset des STM32.
Frank M. schrieb:> Vielleicht solltest Du erstmal versuchen, die Ursache zu finden als an> den Symptomen herumzudoktern.
Nein! Für das I2C EEPROM baue ich mir eine Schaltung mit MOSFET
damit ich mir bei "Bedarf" das EEPROM aus- und neu einschalten
kann. Das ist wahre Ingenieuerskunst.
Von wegen schlechte Hardware, paahhh ....
Frank M. schrieb:> Kommen zum Beispiel mehrere I2C-Transferblöcke> direkt hintereinander, hängt sich ohne Berücksichtigung des Busy-Flags> die I2C-Peripherie einfach weg und ist nicht mehr ansprechbar
Es reicht schon eine eingekoppelte negative Flanke...
Frank M. schrieb:> Da nutzt> auch kein 9-maliges Pinwackeln mehr, nur noch ein HW-Reset des STM32.
Schon mal das Reset-Bit der I2C-Peripherie ausprobiert? Das hat bei mir
immer geholfen.
Hmm schrieb:> Ich kann von den I2C-Blöcken von ST nichts negatives berichten. Mein> Arbeitgeber hat mehrere hunderttausend Platinen mit STM32 und I2C im> Feld, wo das ohne Probleme läuft.
Welcher STM32 und synchrone oder asynchrone Ansteuerung? Bei den alten
(F1, F4) ist die asynchrone Ansteuerung sehr kompliziert, da kann man
leicht Fehler machen die zu Instabilitäten führen. Diese Komplexität ist
mMn etwas sehr negatives an dieser Hardware.
Vermutlich hängt sich hier der EEPROM-IC auf. Die Peripherie vom STM32
wird ja resettet. Hat der IC denn keinen Reset-Eingang?
Frickelfritze schrieb:> Nein! Für das I2C EEPROM baue ich mir eine Schaltung mit MOSFET> damit ich mir bei "Bedarf" das EEPROM aus- und neu einschalten> kann. Das ist wahre Ingenieuerskunst.
Wenns nicht anders geht... Auch bei guter Hardware muss man immer davon
ausgehen, dass Fehlübertragungen passieren. Die Software müsste dann
dafür sorgen, dass diese abgefangen werden. Das ist bei I²C, wie wir
sehen, aber schwierig (keine Checksum, Slave und Master hängen sich
auf). Bei CAN z.B. wird da explizit drauf geachtet, und temporäre
Störungen/Verschlucker können einen CAN kaum dauerhaft aus dem Takt
bringen.
Dr. Sommer schrieb:> Wenns nicht anders geht... Auch bei guter Hardware muss man immer davon> ausgehen, dass Fehlübertragungen passieren.
Seltsam. 99% aller PCs haben keine Möglichkeit die Datenübertragung
zwischen Prozessor und Arbeitsspeicher zu validieren da ihnen
die Paritätsprüfung fehlt. Es gibt viele, viele weitere Beispiele
wo man sich auf die Übertragung einfach verlässt. Weil sie in der Tat
zuverlässig ist. Aber hier beim I2C redest du diese Notwendigkeit
herbei. Ich behaupte dass I2C - wenn es richtig gemacht ist - genau
so zuverlässig ist wie ein Speicherinterface (als Beispiel) beim PC.
Aber eigentlich klingt mir diese Meinung eher wie das Fähnchen im
Wind.
Dr. Sommer schrieb:> Es reicht schon eine eingekoppelte negative Flanke...
Ist bei mir noch nicht aufgetreten.
> Schon mal das Reset-Bit der I2C-Peripherie ausprobiert? Das hat bei mir> immer geholfen.
Nein, habe ich nicht, aber das werde ich mal testen. Ich bin damals mal
lediglich in die Busy-Flag-Falle getippt, als ich die ersten Versuche
mit STM32 und I2C machte. Da orientiert man sich erstmal an bereits
vorhandenen Sourcen im Netz. Es hat mich nach einigen Recherchen doch
arg gewundert, wieviele Beispiele im Netz dieses Flag einfach
schlichtweg ignorieren.
Frickelfritze schrieb:> Ich behaupte dass I2C - wenn es richtig gemacht ist - genau> so zuverlässig ist wie ein Speicherinterface (als Beispiel) beim PC.
Also m.W. ist das Speicherinterface differentiell, hat Push-Pull-Stufen
und ist perfekt gelayoutet. Das ist schonmal ne ganz andere Nummer als
die typischen verwaschenen Flanken von I²C. Und bei wichtigen
Anwendungen verlässt man sich ja doch eben nicht drauf. Bei der
Software-Entwicklung macht man es sich ganz schön leicht wenn man sagt
"die Hardware passt schon" ;-)
Frank M. schrieb:> Ist bei mir noch nicht aufgetreten.
Da hatte ich schon jede Menge Probleme mit... Wenn man eine
störungsreiche Umgebung (z.B. Fahrzeug) hat kann man viel "Spaß" mit
sowas haben.
Moin,
ein Lochrasteraufbau ist so eine Sache... ist schließlich ein
Bastelprojekt. Kuperkabel, ca 3-4cm lang kreuz und quer. I2C ist wie SPI
ein Platinenbus über kurze Strecken, wäre er länger wäre es zb ein LIN
BUS, der deutlich robuster ist, jedoch physikalisch ähnlich wie I2C
funktioniert und logisch wie RS232.
Mit Störungen muss immer gerechnet werden. Ich vermute grob geschätzt,
dass von den rund 260.000 Lesezugriffen in 3 Tagen, nämlich jede Sekunde
einer irgendeiner faul ist. Das ist immer noch eine verschwindend kleine
Fehlerrate.
Die Idee das EE mit einem Pin zu versorgen hatte ich auch schon, nur
sind es 3.3V, reicht nicht. Und ein Mosfet gibt es nicht, der 3.3V
schaltet, nur einer dieser Steine mit eingebauter Ladungspumpe.
Die Idee mit dem 9 Mal bimmeln stammt aus einer AppNote von Microchip,
die die mal rausgegeben haben. Auf den Seite den I2C Konsortiums finden
sich auch Hinweise, allerdings dieser nicht. Nur dass I2C Hardware mit
einem reset versehen werden kann durch Strom-Wegnehmen.
Frank M. schrieb:> Nein, habe ich nicht, aber das werde ich mal testen. Ich bin damals mal> lediglich in die Busy-Flag-Falle getippt, als ich die ersten Versuche> mit STM32 und I2C machte.
Kannst Du das mit dem Busy mal beschreiben? Ich papp mal meinen Code
dran... der ist eigentlich schon "totoptimiert".
Hallo,
dieses Problem kommt auch mir bekannt vor. Busy Bit...oder sagen wir:
Stress Bit. >:->
Vllt mein Beitrag, so ich mich noch erinnere...
Hier wurde ja schon einiges genannt. Timeout, halbwegs vernünftige
Verdrahtung. Aber eines hattet Ihr noch nicht genannt. Man kann das
EPROM neu starten. Dafür gibt's es eine Prozedur. Siehe AN1471 von ST,
"What happens to the M24xxx I²C EEPROM if the I²C bus communication is
stopped?".
Soweit ich mich weiter erinnere, habe ich den I2C Controller als letzte
Option doch vom Netz genommen und direkt via GPIO dies durchgeführt.
Und zumindest bei den ST EEPROM steht auch im DB, dass die sich intern
erst mal vom Netz hängen, wenn sie mit Schreiben noch nicht fertig sind.
Das kriegt man dann aber über den Timeout hin. Man lässt ihn mehr als
ein mal ablaufen und sendet nach jeden Timerablauf eine START condition
in Erwartung des ACK. Damit bügelt man schon einiges weg.
MfG
Strippe schrieb:> Soweit ich mich weiter erinnere, habe ich den I2C Controller als letzte> Option doch vom Netz genommen und direkt via GPIO dies durchgeführt.>> Und zumindest bei den ST EEPROM steht auch im DB, dass die sich intern> erst mal vom Netz hängen, wenn sie mit Schreiben noch nicht fertig sind.> Das kriegt man dann aber über den Timeout hin. Man lässt ihn mehr als> ein mal ablaufen und sendet nach jeden Timerablauf eine START condition> in Erwartung des ACK. Damit bügelt man schon einiges weg.
Also irgendwie müsstest Du diesen Text mal in Deutsche übersetzen. Vom
Netz? Steckdose? Und ein EE was schreibt ist tot, blind und merkt gar
nichts. Daher ballert man ja Starts drauf, erst wenn es ACK'ed ist es
wieder frei und kann weiter Daten schlucken.
1
/* Warte bis I2C Interface frei */
2
while(I2C_GetFlagStatus(I2C1,I2C_FLAG_BUSY));
3
4
/* ACK ein */
5
I2C_AcknowledgeConfig(I2C_KANAL,ENABLE);
6
7
/* Wenn das E2PROM noch in einem Schreibzyklus ist muss die Start
8
Bedingung so oft wiederholt werden, bis es antwortet */
Auch bei mir hat der Anschluss eines i2c-LCDs an stm32f103 aus mir bis
heute unerfindlichen Gründen per hw-i2c nicht geklappt. Prima
funktioniert hat es dann mit sw-I2c. Ist auch nicht viel langsamer. So
kann man jedenfalls testen, ob die Hardware in Ordnung ist.
> von den rund 260.000 Lesezugriffen in 3 Tagen, nämlich jede Sekunde> einer irgendeiner faul ist.
3 Tagen haben ungefähr 260.000 Sekunden.
> Das ist immer noch eine verschwindend kleine Fehlerrate.
Nein, das ist ungefähr 100% Fehlerrate.
Chris J. schrieb:> Kannst Du das mit dem Busy mal beschreiben? Ich papp mal meinen Code> dran... der ist eigentlich schon "totoptimiert".
Der Test ist in Deinem Source zumindest in der Funktion
EE_TestDevice(uint8_t eeno) drin:
1
while(I2C_GetFlagStatus(I2C1,I2C_FLAG_BUSY));
Die Abfrage passiert hier vor jedem I2C-IO. Das ist hier in Ordnung so.
Dasselbe gilt auch für die Write-Funktionen EE_WriteDataSet() und
EE_WriteByte(). Auch bei der Funktion EE_ReadByte() ist sie drin.
Aber in der Funktion EE_ReadDataSet() scheint diese Abfrage zu fehlen,
jedenfalls sehe ich sie auch beim zweiten Hingucken nicht. Stattdessen
findet man hier einen ominösen delay-Aufruf. Das kommt mir sehr spanisch
vor. Delays sollte man immer hinterfragen.
An der Stelle solltest Du nachbessern, zumindest die obige Busy-Abfrage
hinter den delay-Aufruf - also vor den i2c_init()-Aufruf setzen.
Frank M. schrieb:> Aber in der Funktion EE_ReadDataSet() scheint diese Abfrage zu fehlen,> jedenfalls sehe ich sie auch beim zweiten Hingucken nicht. Stattdessen> findet man hier einen ominösen delay-Aufruf. Das kommt mir sehr spanisch> vor. Delays sollte man immer hinterfragen.
Du meinst das hier? Das steht deshalb drin, weil der letzte
Schreibzugriff nicht "delayed" wird, d.h. die CPU wartet nicht, bis er
abgeschlossen ist, sondern rennt weiter. Und wenn dann direkt ein
Lesezugriff kommt reagiert das EE nicht auf die Start Condition. Das
kann auch ein Busy Bit nicht erkennen, für die CPU ist der Vorgang
abgeschlossen. Schreibe ich aber fortlaufend findet die Prüfung bei
jedem neuen Eintritt in die Routine statt.
Ich hab die Routinen mit einem Test umgeben, der mir alle denkbaren
Möglichkeiten erzeugte, alles durcheinander zu benutzen und nachher zu
vergleichen. Dabei fiel mir das so auf. Im LA wurde die typische
Schreibzeit mit 3,2ms gemessen, da sind 4ms halt "grosszügig."
Das Ganze ist halt nur sowas wie auf dem Bild, typischer
Lötrasteraufbau....
/* Nach vorherigem Schreibzugriff warten */
if (f_lastwrite) {
DelayMs(4);
f_lastwrite = 0;
}
Christian J. schrieb:> Ist allerdings nicht so wie bei einer Soft I2C,
Hast du das ganze mal mit Soft I2C probiert? Bei dem Projekt dürften ein
paar ms mehr doch kein Problem sein.
Karl K. schrieb:> Hast du das ganze mal mit Soft I2C probiert?
Ist ne Glaubensfrage: Bei einem Hobbyprojekt geht es ja grad darum die
Hardware auszureizen, da ist der Weg das Ziel. Ich will ja wissen wie
das alles da drin funktioniert :-)
Frank M. schrieb:> Dann setze doch mal die Zeile while (I2C_GetFlagStatus(I2C1,> I2C_FLAG_BUSY));>> genau darunter.
Frank, das ist nicht richtig. Es geht nicht darum, dass die I2C Prime
Cell fertig ist, sondern das EEPROM. Es gibt keinen Indikator dafür, es
reagiert einfach nicht. Sobald das STOP kommt geht es in den Write Mode
und solange ist es taubstumm.
Alles ok :-)
Chris J. schrieb:> Es gibt keinen Indikator dafür, es reagiert einfach nicht.
Doch, und genau das ist der Lösungsweg. Ich zitiere aus dem
Datenblatt des AT24C128 für den Schreibvorgang:
-----------------------------------------------------------
ACKNOWLEDGE POLLING: Once the internally-timed write cycle
has started and the EEPROM inputs are disabled, acknowledge
polling can be initiated. This involves sending a start
condition followed by the device address word. The
read/write select bit is representative of the operation
desired. Only if the internal write cycle has completed will
the EEPROM respond with a zero, allowing the read or write
sequence to continue.
-----------------------------------------------------------
Man wartet nach dem Schreiben eines Blocks solange bis das
EEPROM ein Acknowledge liefert, dann ist es fertig mit
seiner internen Maschinerie.
So "einfach" ist das.
Guckst Du hier :-)
Kann sein, dass ich da noch etwas "unschön" habe, da ich vor dem
Schreiben abfrage, ob es fertig ist. Im LA sieht das alles schon ganz
schnuckelig aus.
Das Problem trat ja nur auf, wenn Schreiben und Lesen im Wechsel
erfolgten.
Das Blöde ist immer, dass man sich nicht traut etwas anzufassen was ja
funktioniert. Selbst die Abstürze habe ich jetzt im Griff durch das
"klingeln" und resetten der Hardware + Watchdog. Irgendwann fängt es
sich wieder und es geht weiter. 4.7kOhm für 2 EEPROMs bei 100khz. 400khz
gehen auch, jedenfalls im Debugger aber .... naja, lieber etwas weniger
Gas, dafür auch weniger Unfälle.
Dieser kleine STM32F103 auf dem 2,50 Euro Board ist jedenfalls eine
schweinegeile Maschine für "Physical Computing", für alles andere nehme
ich lieber F429.
Chris J. schrieb:> * Wenn das E2PROM noch in einem Schreibzyklus ist muss die Start> Bedingung so oft wiederholt werden, bis es antwortet */
Nein, eine Start-Bedingung zu senden reicht nicht, siehe
mein Zitat.
Es muss die Adresse des EEPROMs gesendet werden und das
(irgendwann) darauf folgende ACK gilt als Bestätigung dass
das EEPROM wieder frei ist.
STM Apprentice schrieb:> Nein, eine Start-Bedingung zu senden reicht nicht, siehe> mein Zitat.
Das steckt im
/ Adressiere das E2PROM
I2C_Send7bitAddress(I2C_KANAL, EE, I2C_Direction_Transmitter);
mit drin. Das ist eine Statemachine, die Zieladresse ist bereits
dauerhaft hinterlegt. Da ist eine etwas andere Denke nötig, da diese SM
nur angestossen wird und dann von allein läuft, während die CPU weiter
rennt. Nur an den Events, die alle interruptfähig sind kann sie
erkennen, dass was passiert ist.
Chris J. schrieb:> do {> /* Erzeuge START Bedingung */> if (i2c_start() == ERROR)> return ERROR;> if (I2C_WaitForEvent(200, I2C_EVENT_MASTER_MODE_SELECT) != SUCCESS)> return ERROR;
Du springst ja schon mit Error heraus bevor du die Adresse
sendest. Allerdings weisss ich nicht genau welche
Fehlerbedingungen bei dir dazu führen ....
STM Apprentice schrieb:> Du springst ja schon mit Error heraus bevor du die Adresse> sendest. Allerdings weisss ich nicht genau welche> Fehlerbedingungen bei dir dazu führen
Das ist das EV5. Die SM gibt einen Start auf den Bus und guckt, ob
dieser überhaupt frei ist, d.h. SDA = high. Ist er es nicht, kommt das
EV5 nicht und man muss einen Timeout einleiten. Es ist schwierig zu
unterscheiden welcher der beiden Teilnehmer die Events auslöst. Ich bin
da auch noch nicht ganz durchgedrungen.
Du könntest aber recht haben.... ich muss das mal in Ruhe mit dem LA
anschauen, jetzt gehts erstmal auf den Modellflugplatz bei dem Wetter.
Ist eher was für Regentage.
Auf dem LA Diagramm war allerdings in einer testanwendung, die viele
Bytes per Pagewrite wegschrieb eindeutig zu sehen, dass erst so 3-4
Starts kommen im Abstand von 0,5ms und dann die Antwort nach ca 3,2ms.
Das war also alles richtig, daher habe ich es so gelassen.
Möglicherweise nochmal drüber nachdenken und nachmessen.
1
/* ----- Erzeuge Start Bedingung ------ */
2
staticuint8_ti2c_start()
3
{
4
inttimeout=I2C_TIMEOUT;
5
6
I2C_GenerateSTART(I2C_KANAL,ENABLE);
7
/* Warte auf I2C EV5. Bus frei, Start akzeptiert */
Frickelfritze schrieb:> Chris J. schrieb:>> Wo genau weiss ich nicht>> Ich weiss es auch nicht, aber ich bin mir ziemlich sicher> dass dein (mieser) Hardware-Aufbau schuld ist.>> Aber daran kann es ja nach deiner Auffassung sicherlich> nicht liegen. Es ist immer der Hersteller eines Chips oder> der fehlerhafte Compiler dran schuld.
Aber es kommt vor ;-)
Some Cortex-M3 cores can cause data corruption when ldrd instructions
with overlapping destination and base registers are used. This option
avoids generating these instructions. This option is enabled by default
when -mcpu=cortex-m3 is specified.
@Christian
wenn du den GCC benutzt setze mal -mcpu=cortex-m3
Das bewirkt machmal Wunder bei der HW SPI und dem busy Bit;-)
-mfix-cortex-m3-ldrd
Some Cortex-M3 cores can cause data corruption when ldrd instructions
with overlapping destination and base registers are used. This option
avoids generating these instructions. This option is enabled by default
when -mcpu=cortex-m3 is specified.
https://gcc.gnu.org/onlinedocs/gcc-4.7.4/gcc/ARM-Options.html
Christian J. schrieb:> Ich benutze die I2C Hardware des Chips, frage Fehler> "meistens" ab aber nicht hinter jedem einzelnen Befehl
Das ist bei HW-I2C aber Pflicht.
Z.B. nach NACK auf Adresse/Daten wird Dir das HW-I2C was husten, wenn Du
weitere Daten in das Senderegister schreibst.
Hier mal ein einfaches SW-I2C (AVR):
https://www.mikrocontroller.net/attachment/119775/xeeprom.cChristian J. schrieb:> Ist allerdings nicht so wie bei einer Soft I2C, dass man mal eben an den> Pins wackeln kann
Nach I2C-Disable sind die Pins wieder normale IOs.
N'Abeeeend,
ich habe die Ursache für das Aufhängen des EE's gefunden, was ja
sporadisch aber doch regelmässig auftrat.
Es lag an den vielen Ints, die bei mir rumfleuchen und von denen zb der
des RF Moduls oder die Bespielung der HC595 Kette mit 6 Bausteinen recht
lange dauern kann. Seitdem ist nun seit 3 Tagen Ruhe im Karton.
Sicherheitshalber habe ich alle Kommandos gekapselt, auch wenn einige es
vielleicht nicht brauchen.