Hallo zusammen,
ich möchte mit einem STM32F205 ein EEPROM vom Typ "24LC32" über I2C
ansteuern und bekomme das auch gut hin... Außer einer Kleinigkeit.
Man kann das 24LC32 Pageweise schreiben, wenn man nach Übermittlung von
32 Byte (= 1 Page) die STOP - Condition sendet, so entkoppelt sich das
EEPROM vom I2C Bus und startet seinen internen Schreibzyklus. Während
dieser Zeit reagiert das EEPROM nicht auf I2C - Signale... und das kann
man sich zunutze machen für sogenanntes "ACK Polling".
Man sendet dabei eine START - Condition, gefolgt von einem AdressByte
und wartet dananch auf das ACK vom EEPROM. Das tut man solang, bis das
ACK tatsächlich kommt - dann ist nämlicher der interne Schreibzyklus des
EEPROMs abgeschlossen.
Soweit zur Erklärung. Ich habe jetzt folgendes Problem: Das ACK sehe ich
am Oszilloskop, die FW erkennt es aber nicht, zur Illustration hier noch
das "ACK Polling" Codesegment:
Zusammengefaßt: das ACK sehe ich am Oszilloskop, allerdings detektiert
es die FW nicht.
Für das gleiche EEPROM habe ich schon mehrere Funktionen für I2C -
Zugriff programmiert (auch mit ACK - Abfrage natürlich...), die jeweils
einwandfrei funktionieren.
Mein aktueller Workaround sieht so aus, dass ich nach jedem Page - Write
einfach 10ms warte.
Ich bitte Euch um Antworten.
Gruß, Johann
Joey4711 schrieb:> Mein aktueller Workaround sieht so aus, dass ich nach jedem Page - Write> einfach 10ms warte.
Meiner auch (5ms). Auch wenn ich fürchte, daß Dir das nicht hilft.
.. und bringt leider nichts.
Die anhängenden Bilder zeigen das Ganze einmal mit und einmal ohne den
vorgeschlagenen STOP - Puls, beides funktioniert nicht.
Im Datenblatt des 24LC04 (hatte ich gerade zur Hand) steht auf Seite 8
auch explizit ein Flußdiagramm, wo ersichtlich ist, daß da ein STOP
nicht hineingehört.
Beim AVR geht das Ganze auf einwandfrei, nur beim STM32 (hier:
STM32F103) will das nicht so recht. Das könnte mit dem Errata-Sheet der
I2C-Hardware erklärt werden.
A. K. schrieb im Beitrag #4224198:
> Ich bezog mich eher auf> die I2C-Statemachine des µC.
Stimmt, das EEPROM ist ja eh erst einmal tot, solange es schreibt - da
sollte das nichts ausmachen.
Joey4711 schrieb:> beides funktioniert nicht
Was funktioniert nicht? Wird der state==ERROR nie verlassen?
Walter T. schrieb:> Was funktioniert nicht? Wird der state==ERROR nie verlassen?
Richtig. "state==ERROR" wird nie verlassen. Es scheint also nicht am
STOP Pulse zu liegen
Walter T. schrieb:> Stimmt, das EEPROM ist ja eh erst einmal tot, solange es schreibt - da> sollte das nichts ausmachen.
Yep, aber hab grad nachgesehen. ST erlaubt als Reaktion auf NACK bei der
Adressierung auch ein REPEATED START, also ist STOP unnötig. Schaden tut
es aber auch nicht.
Walter T. schrieb:> Im Datenblatt des 24LC04 (hatte ich gerade zur Hand) steht auf Seite 8> auch explizit ein Flußdiagramm, wo ersichtlich ist, daß da ein STOP> nicht hineingehört.
Das Datenblatt des 24LC04 kann nur sagen, was den 24LC angeht und nicht
was den I2C Bus allgemein. Der 24LC braucht offensichtlich kein STOP.
Aber wie willst du in der Pause zwischen deinen Polls irgendein anderes
I2C Device ansprechen, wenn du den Bus nicht mit STOP freigegeben hast?
Das Polling mit Auswertung des ACKs hat doch gerade den Zweck, den Bus
nicht zu blockieren. Es reicht ja auch, beim nächsten Schreiben
ausnahmsweise das ACK nach dem Adressbyte mal auszuwerten und das
Schreiben solange zu verzögern, bis es kommt (oder eine Timeout "EEPROM
kaputt" signalisiert). Dann braucht man nicht sinnlos zu pollen.
Walter T. schrieb:> Mir fehlt auch irgendwie die Stelle, wo Du auf den Ack-Timeout wartest.
Der Master taktet das ACK selbst, da kann es kein Timeout geben.
MfG Klaus
Klaus schrieb:> Der Master taktet das ACK selbst, da kann es kein Timeout geben.
Deswegen auch:
Walter T. schrieb:> [unsinnige Bemerkung von mir gelöscht]
Manchmal braucht es ein wenig Zeit, bis man wieder im I2C drin steckt.
Walter T. schrieb:> Wieso schickst Du eigentlich immer wieder eine 7-Bit Addresse und nicht> I2C_SendData?
Das was du als Control Byte bezeichnest, das nennt der Rest der Welt
eine I2C Adresse.
Walter T. schrieb:> Wieso schickst Du eigentlich immer wieder eine 7-Bit Addresse und nicht> I2C_SendData? Im Datenblatt-Flußdiagramm will das EEPROM ein "Control> Byte".
Weil im "Control Byte" die Adresse, gefolgt von einem R/W - Bit,
enthalten ist... Und weil ichs mir gerade mit I2C_SendData am
Oszilloskop angesehen habe und das am Oszilloskop gleich aussieht und
auch der Fehler erhalten bleibt.
Klaus schrieb:> Es reicht ja auch, beim nächsten Schreiben> ausnahmsweise das ACK nach dem Adressbyte mal auszuwerten und das> Schreiben solange zu verzögern, bis es kommt
Nein!
Die SDA-Leitung muß bei SCL = 1 stabil sein, sonst verletzt man die
I2C-Spezifikation.
Joey4711 schrieb:> Weil im "Control Byte" die Adresse, gefolgt von einem R/W - Bit
+ die Pagenummer (Block Address)
Aber ja: Es entspricht tatsächlich der Adresse.
Peter D. schrieb:> Nein!> Die SDA-Leitung muß bei SCL = 1 stabil sein, sonst verletzt man die> I2C-Spezifikation.
Was hat den das damit zu tun. Der Master darf nach jedem Byte eine
Transaktion mit STOP abbrechen. Ein I2C EEPROM, das gerade schreibt,
beantwortet seine Adresse nicht, stellt sich tot. Das liefert halt ein
NAK. Mehr steckt in den tollen Begriff "ACK Polling" nicht drin.
Und so wie man jedem anderen Peripheral normalerweise nicht wartet, bis
es endlich fertig ist, sondern beim nächsten Ansprechen schaut, ob es
schon fertig, geht das natürlich beim EEPROM auch.
MfG Klaus
Klaus schrieb:> Was hat den das damit zu tun.
Er wollte ja auf das ACK warten und das geht nicht.
Kommt ein NACK, muß man neu abfragen, d.h. Start + Adresse neu senden.
Hallo Herr Dannegger,
also die geforderte Bedingung (SDA Leitung stabil während SCL auf HIGH
ist) ist erfüllt (siehe auch die Screenshots weiter oben).
Was mich irritiert ist, dass alle andere I2C Aktionen einwandfrei
funktionieren; mein Verdacht ist, dass es eine "Besonderheit" auf Seite
des STM32 ist, denn es gibt mehrere Foren, die das "ACK Polling" Problem
betreffen, und da geht es immer um STM32 Controller, nie um andere (ist
natürlich ein Indiz, kein Beweis).
Wie gesagt: meine aktueller Workaround ist, einfach 10ms zu warten und
dann die nächste Page zu schreiben. Funktioniert einwandfrei,
reproduzierbar und beliebig oft. Sollte aber dennoch mal ein EEPROM
länger als 10ms schreiben (warum auch immer!), dann haben wir ein Gerät
im Feld, das blockiert- nur als Hintergrund: wir gehen in einigen
Monaten in Serie mit einigen 10.000 Geräten. Jedes Gerät hat eine
Lebensdauer von 6 Jahren. Damit will ich sagen: jeder Fehler, der
irgendwann auftreten könnte- der TRITT auch auf irgendwann. Daher liegt
mir dieses Thema am Herzen.
Dennoch mal einen schönen Dank an alle Mit - Teilnehmer zu diesem Thema.
Die I2C-Peripherie des STM32 ist gelinde gesagt eine Katastrophe.
Benutze am besten die CPAL-Library, darin sind die meisten Fehler schon
abgefangen. Dann gibts nur noch ab und zu Probleme damit, 1-Byte-Befehle
zu senden (also Start-Adresse-Byte-Stop), das sollte man tunlichst
vermeiden.
Ich habe damit leider jeden Tag zu tun und seit ich alles auf CPAL
umgerüstet habe, ist die Sache deutlich stabiler, wenn auch nicht immer
alles perfekt läuft.
Peter D. schrieb:> Er wollte ja auf das ACK warten und das geht nicht.
Das geht prizipiell nicht. Ich zitier mich selber:
Klaus schrieb:> Der Master taktet das ACK selbst, da kann es kein Timeout geben.Joey4711 schrieb:> as mich irritiert ist, dass alle andere I2C Aktionen einwandfrei> funktionieren; mein Verdacht ist, dass es eine "Besonderheit" auf Seite> des STM32 ist, denn es gibt mehrere Foren, die das "ACK Polling" Problem> betreffen, und da geht es immer um STM32 Controller, nie um andere (ist> natürlich ein Indiz, kein Beweis).
Wenn eine gelieferte Library im Spiel ist, könnte es daran liegen. Da
die meisten Programme, die ich hier gesehen habe, das ACK bzw NAK
grundsätzlich nicht auswerten (andere Fehlerzustände natürlich auch
nicht), würde ein SW-Fehler da lange unentdeckt bleiben.
MfG Klaus
Frank B. schrieb:> Die I2C-Peripherie des STM32 ist gelinde gesagt eine Katastrophe.
Da ich keinen I2C-Interrupt verwende, mache ich einfach das I2C in
Software. Das funktioniert immer und auf Anhieb. Und mehr Code ist es
auch nicht.
Anbei mal meine EEPROM-Lib.
Peter D. schrieb:> mache ich einfach das I2C in> Software.
Das ist geschummelt! Du drückst Dich um das Tal der Tränen, das jeder,
der die STM32-Peripherie nutzen will, durchschreiten muß. Und das
Schlimme ist: Ich habe Deine I2C-Bitbang-Schummel-Routinen auch schon
genutzt. Nämlich dann, wenn ich nicht sicher war, ob ein merkwürdiges
Verhalten von der I2C-Peripherie auf der MCU oder vom angesprochenen
Device kommt.
Walter T. schrieb:> Das ist geschummelt! Du drückst Dich um das Tal der Tränen
Warum soll man durch das steinige Tal gehen, wenn der bequeme Weg genau
gleich lang dauert?
Das HW-I2C hat erst dann Vorteile, wenn man es als Interrupt im
Hintergrund laufen läßt bzw. einen I2C-Slave benötigt.
Peter D. schrieb:> Frank B. schrieb:>> Die I2C-Peripherie des STM32 ist gelinde gesagt eine Katastrophe.>> Da ich keinen I2C-Interrupt verwende, mache ich einfach das I2C in> Software. Das funktioniert immer und auf Anhieb. Und mehr Code ist es> auch nicht.>> Anbei mal meine EEPROM-Lib.
Interessant und traurig zugleich, dass man heute auf einem
hochgezüchteten Controller mit so viel Peripherie lieber Bitbanging
benutzt.
Ich bin in meinen Programmen leider auf Interrupts angewiesen, sonst
dreht der CAN-Bus durch, wenns mal wieder länger dauert.
Frank B. schrieb:> Ich bin in meinen Programmen leider auf Interrupts angewiesen, sonst> dreht der CAN-Bus durch, wenns mal wieder länger dauert.
Ich mache CAN generell immer als Interrupt, da kann sich das Main soviel
Zeit lassen, wie es lustig ist.
Auch kann man das I2C leicht in Scheibchen schneiden, da es keine
Maximalzeiten kennt (ein Byte oder nur ein Bit je Maindurchlauf).
Walter T. schrieb:> DMA
Sag ich doch, nur im Hintergrund hat das HW-I2C Vorteile.
Allerdings lohnt sich der Aufwand nur, wenn man austesten will, nach
wieviel Mio Schreibzyklen der EEPROM die Grätsche macht.
Nur um 0..3 mal am Tag ne neue Konfiguration abzuspeichern, aber eher
nicht.
I2C belegt nur selten ein merkbare CPU-Last, daher wird es auch kaum als
Interrupt implementiert.
was der TO am Anfang beschreibt ist mir auch beim Arduino passiert, kann
also nix mit dem STM oder der Lib zu tun haben.
Ich hatte vorher ja nur im AVR Studio gearbeitet und wusste wann ich
eine ACK oder NACK Sequenz brauchte und konnte das manuell einpflegen.
Am Arduno Fehlanzeige, solange ich "nur" einen PCF85574(A) befrage oder
nur ein DS3231 Register abhole kein Problem.
Am Arduino wurde das I2C EEPROM in allen Listings immer mit delay(5)
gelöst, für mich unhaltbar auf jede Zelle 5ms zu warten was bei Block
write auch schiefgehen kann wenn das EEPROM 6ms braucht.
Ich überlegte doch glatt für 10µs mit einem anderen Port den Zustand
abzufragen nach einer write Sequenz und fand dann aber das
"Prüfkommando", einfach neues Read nach write in einer Schleife zu
starten und wenn das fehlerfrei klappte ohne ERROR war das I2C EEPROM
wieder bereit. Beim purren EEPROM hatte ich früher ja das busy Bit
befragen können, nun eben wenn das EEPROM sich wieder meldet.
Klaus schrieb:> Wenn eine gelieferte Library im Spiel ist, könnte es daran liegen. Da> die meisten Programme, die ich hier gesehen habe, das ACK bzw NAK> grundsätzlich nicht auswerten
das hat doch nix mit auswerten zu tun, oder verstehe ich was falsch?
Ich will 2 Bytes empfangen und das erste wird mit ACK quittiert, das 2te
und letzte mit NACK
genauso bei einer Kette von 10 Byte, 9x ACK das letzte mit NACK
Wie soll man das machen wenn man einen Block per LIB schickt, dort
müsste das letzte Byte ja in der LIB per NACK verarbeitet werden, aber
wenn I2C stretching auftritt weiss ich nie wann, ergo delay oder Port
beobachten oder prüfen wann das IC wieder mit mir redet.
1
// P. Fleury war so nett eine LIB zu bauen
2
// Auschnitt:
3
i2c_start_wait(DS3231+I2C_WRITE);// set device address and write mode
4
i2c_write(DS3231_ControlReg);
5
i2c_rep_start(DS3231+I2C_READ);// set device address and read mode
Joachim B. schrieb:> Klaus schrieb:>> Wenn eine gelieferte Library im Spiel ist, könnte es daran liegen. Da>> die meisten Programme, die ich hier gesehen habe, das ACK bzw NAK>> grundsätzlich nicht auswerten>> das hat doch nix mit auswerten zu tun, oder verstehe ich was falsch?
Wenn die Lib buggy ist und sich nie jemand um ACK bzw NAK kümmert, merkt
das kein Mensch. Das war gemeint.
Auch die Funktionen der P. Fleury Lib haben Returnwerte und auch in
deinem Code sehe ich nichts, was sie auswertet. Obwohl ich es da für
unwahrscheinlich halte, das die Lib buggy ist.
Joachim B. schrieb:> Wie soll man das machen wenn man einen Block per LIB schickt, dort> müsste das letzte Byte ja in der LIB per NACK verarbeitet werden,
Eine Blockfunktion sollte einen brauchbaren Returnwert haben so z.B.
- cannot set START, Bus not idle
- no ACK at address Byte, operation with STOP aborted
- no ACK at data Byte ...
.
.
Joachim B. schrieb:> fand dann aber das> "Prüfkommando", einfach neues Read nach write in einer Schleife zu> starten und wenn das fehlerfrei klappte
Damit hast du gerade das "ACK polling" erfunden. Wobei es geschickter
ist, mit R/W = 0 zu pollen und danach mit STOP abzubrechen. Ganz ganz
dumme Slaves erwarten nach einem Read mindestens 9 Clockpulse, bevor sie
den Bus wieder frei geben.
MfG Klaus
Klaus schrieb:> Damit hast du gerade das "ACK polling" erfunden.
ich war es nicht, aber danke für diesen Hinweis:
Klaus schrieb:> mit R/W = 0 zu pollen
Mich wunderte nur das dies so schwer zu finden war und warum fast alle
ein delay nach I2C EEPROM write setzen, klar es geht aber elegant ist
anders.
Klaus schrieb:> Wobei es geschickter> ist danach mit STOP abzubrechen.
macht das nicht?
Wire.endTransmission();
Klaus schrieb:> Auch die Funktionen der P. Fleury Lib haben Returnwerte und auch in> deinem Code sehe ich nichts, was sie auswertet. Obwohl ich es da für> unwahrscheinlich halte, das die Lib buggy ist.
ich weiss, da kürze ich Schlamper gerne ab, mal aus Bequemlichkeit, mal
aus Platznot, rate mal warum ich den Arduino mighty atmega1284p so mag?
buggy ist P.Fleurys LIB definitiv nicht, sie sogar sauber und leicht
verständlich.
Peter D. schrieb:> Frank B. schrieb:>> Ich bin in meinen Programmen leider auf Interrupts angewiesen, sonst>> dreht der CAN-Bus durch, wenns mal wieder länger dauert.>> Ich mache CAN generell immer als Interrupt, da kann sich das Main soviel> Zeit lassen, wie es lustig ist.
Schon klar, ich habe noch ein CANopen-Protokoll zeitnah auszuwerten,
denn der HBC ärgert sich, wenn die Antwortzeiten zu lang werden...
Frank B. schrieb:> Die I2C-Peripherie des STM32 ist gelinde gesagt eine Katastrophe.
Ich bin auch nicht mit dem I2C der AVRs zufrieden, das hängt sich als
Multimaster ständig auf, man braucht einen Timeouthandler, der es
rücksetzt. Das gleiche auch bei den Atmel 8051.
Richtig zuverlässig hat bei mir nur das I2C der original Philips P80C652
funktioniert, das braucht keine Überwachung mit Timeout. Einmal enablen
und es läuft und läuft und ...
Walter T. schrieb:> Funktioniert das "acknoledge polling" jetzt eigentlich mit den> bitbanging-Routinen?
Irgendwie scheinst du noch nicht verstanden zu haben, worum es beim "ACK
polling" wirklich geht.
Ein I2C Slave muß auf seine Adresse nach START mit ACK reagieren. Ein
EEPROM stellt sich aber tot, wenn es mit Schreiben beschäftigt ist. Es
antwortet nicht, das heißt der Master liest ein NAK vom Bus. Ein sauber
programmierter Master beendet dann die Übertragung mit einem STOP. Erst
wenn es mit Schreiben fertig ist, liefert das EEPROM wieder ein ACK auf
seine Adresse. Die Funktionen START anlegen, Adresse senden und dabei
ACK/NAK einlesen, STOP erzeugen etc sind die Grundfuktionen von I2C. Ob
diese von einer HW oder einer SW erzeugt werden, ist unerheblich.
MfG Klaus
Klaus schrieb:> Irgendwie scheinst du noch nicht verstanden zu haben, worum es beim "ACK> polling" wirklich geht.
Ich hol das mal wieder hoch, weil ich JETZT GERADE vor dem genau
gleichen Problem stehe bei einem 64k E2PROM das ACK zu pollen, während
das E2PROM gerade ein Byte wegschreibt. Das muss doch irgendwie gehen,
meine Routinen funktionieren auch.
Bloss das hier nicht, was ich mir aus den Finger gesogen habe, wie es
gehen könnte. Tut es aber nicht :-(
1
// Polling, bis E2PROM das Byte weggeschrieben hat
Christian J. schrieb:> Bloss das hier nicht, was ich mir aus den Finger gesogen habe, wie es> gehen könnte. Tut es aber nicht :-(
Kein Wunder, Du ignorierst ja standhaft die Beispiele, bzw. die
I2C-Beschreibung im Datenblatt des EEPROM.
ACK-Polling heißt, Du sendest Start+Adresse+Stop in einer Schleife und
prüfst das ACK auf die Adresse.
Diese Schleife hast Du nicht, also kanns nicht gehen.
Peter D. schrieb:> Kein Wunder, Du ignorierst ja standhaft die Beispiele, bzw. die> I2C-Beschreibung im Datenblatt des EEPROM.>> ACK-Polling heißt, Du sendest Start+Adresse+Stop in einer Schleife und> prüfst das ACK auf die Adresse.> Diese Schleife hast Du nicht, also kanns nicht gehen.Christian J. schrieb:> das ACK zu pollen, während> das E2PROM gerade ein Byte wegschreibt. Das muss doch irgendwie gehen,> meine Routinen funktionieren auch.
ich hatte ja hier beschrieben wie es geht:
Beitrag "Re: I2C Problem mit Acknowledge Polling"
das sollte auch anderswo klappen:
Joachim B. schrieb:> also so nach write und nach write block> do {> Wire.beginTransmission(_address); Wire.requestFrom(_address, 1);> _data = readIIC();> _error = Wire.endTransmission();> }while(_error);
Joachim B. schrieb:> ich hatte ja hier beschrieben wie es geht:> Beitrag "Re: I2C Problem mit Acknowledge Polling"
Arduino hat aber auch nichts mit dem STM32 zu tun. es geht mir nicht um
die Vorgehensweise sondern um die Coderierung. Das I2C Modul des STM32
ist um Längen komplexer als das eines AVR.
Christian J. schrieb:> Das I2C Modul des STM32> ist um Längen komplexer als das eines AVR.
Trotzdem muß man aber den gleichen Ablauf verwenden, wie beim AVR, 8051
oder SW-IWC und kann sich nicht was anderes aus den Fingern saugen.
Peter D. schrieb:> Trotzdem muß man aber den gleichen Ablauf verwenden, wie beim AVR
danke, sehe ich als Einäugiger genauso, es ist doch egal unter welcher
Plattform, ich speche den Chip solange an bis er sich wieder meldet,
solange ist er eben "busy" und wer Hosenträger und Gürtel mag der nimmt
zusätzlich einen timeout.
Ok,
trotzdem wäre es nett, wenn jemand eine fertige Routine hätte, welches
Bit da wo geprüft wird, welches Eventflag zuständig ist usw.
>> bis er sich wieder meldet,
Dazu müsste ich erstmal wissen, welche Funktion der StdPeriphLib mir
mitteilt, dass er sich gemeldet hat.... das I2C Modul hat mehr als
hundert Config und Flag Bits. Das Prinzip ist mir klar, es geht nur um
die Codierung für diespen speziellen Prozessor mit einer speziellen
HAL.
Der Code oben ist komplett, er sendet Start und Schreibadresse, wartet
bis diese raus sind. Ok, vielleicht fehlt noch ein Stop.
I2C_CheckEvent(I2C3, I2C_EVENT_SLAVE_ACK_FAILURE)); ???
@peda
Wenn ich mir ein IC aussuche, dann achte ich darauf, dass es keines mit
I2C-Interface ist. Mit anderen Worten: I2C ist nicht so mein Gebiet.
Bei Deinem Kod ist mir aber aufgefallen, dass Du nirgends
Clock-Stretching in Betracht gezogen hast. Habe ich in Deinem Kod etwas
übersehen? Oder ist das nicht so wichtig?
Mehmet K. schrieb:> Bei Deinem Kod ist mir aber aufgefallen, dass Du nirgends> Clock-Stretching in Betracht gezogen hast.
Bei EEPROM, IO-Expander usw. ist SCL nur ein Eingang.
Ist der Slave aber ein weiterer MC, muß man das Clock-Stretching
natürlich noch implementieren.
Christian J. schrieb:> I2C_CheckEvent(I2C3, I2C_EVENT_SLAVE_ACK_FAILURE)); ???
Das alles sollte aber doch im Manual zu Deiner Lib umfassend beschrieben
sein.
Wenn nicht, dann hilft nur die Lib wegschmeißen und die Register/Bits
selber setzen/auswerten.
Peter D. schrieb:> Das alles sollte aber doch im Manual zu Deiner Lib umfassend beschrieben> sein.
Peter, diese Lib schreibe ich gerade. Alle bisher gefundenen Libs haben
E2Proms nicht auf dem Radar oder da steht einfach Delay(5ms) hinter
jedem Byte was ja nicht Sinn der Sache sein kann. Und ACK Polling ist in
keinem Beispiel zu finden bzw. sehe ich es wohl nicht. Das braucht man
auch beim Page Write, es sei denn man will 10ms warten, obwohl es
vielleicht auch nur 5ms sind.
Christian J. schrieb:> Alle bisher gefundenen Libs haben> E2Proms nicht auf dem Radar
Darum geht es nicht, sondern um die Lib für die I2C Basisfunktionen.
Und die I2C-Write Funktion muß zurückliefern, ob sie vom Slave ACK oder
NACK empfangen hat.
Erst dann kann man sich aus den Basisfunktionen eine EEPROM-Lib bauen.
Schau Dir mal mein Beispiel an:
Beitrag "Re: I2C Problem mit Acknowledge Polling"
Christian J. schrieb:> Und ACK Polling ist in> keinem Beispiel zu finden bzw. sehe ich es wohl nicht. Das braucht man> auch beim Page Write, es sei denn man will 10ms warten, obwohl es> vielleicht auch nur 5ms sind.
deswegen habe ich ja die Arduino Routine erweitert, alle I2C EEPROM LIB
die ich fand wartete immer 5-10ms, das kann nicht sinnvoll sein, mit dem
polling ist es viel schneller.
Christian J. schrieb:> Tja, siehst Du da was, was so ausschaut?
Weil Du das ACK-Polling nicht verstanden hast. Nirgends wird auf ACK
geprüft und das ist zwingend notwendig!
Wie das ACK/NACK vom I2C_CheckEvent() geliefert werden kann weißt nur Du
nach dem Lesen der Doku zu Deiner I2C-Lib. Ich kenne Deine Lib ja nicht.
Hier nochmal das ACK-Polling Pseudocode:
Joachim B. schrieb:> muss man nich auch auf NACK abfragen wenn nur ein Byte gelesen werden> soll?
Beim Lesen dreht sich die Datenrichtung um, d.h. der Master liest das
Byte und sendet das ACK.
Das ACK zeigt dem Slave an, daß der Master noch weitere Bytes lesen
will.
Nach dem letzten Byte muß daher der Master ein NACK senden, ansonsten
kann das STOP fehlschlagen.
In meiner EEPROM-Lib ist das entsprechend implementiert:
Peter D. schrieb:> Wie das ACK/NACK vom I2C_CheckEvent() geliefert werden kann weißt nur Du> nach dem Lesen der Doku zu Deiner I2C-Lib. Ich kenne Deine Lib ja nicht.
Peter..... nochmal: Es gibt keine Lib! Ich schreibe die Funktionen
gerade. Weil ich mich in vieles eingelesen habe und feststelle, dass die
allermeisten Libs aus dem Netz, die halbwegs lesbar sind und nicht nur
aus einem Wust Registerzugriffen bestehen sehr "dürftig" sind. Nämlich
meist überhaupt keine Fehlerbehandlung haben, auch kein ACK des Slaves
prüfen bei Schreiben usw. Ok, was soll man auch machen, wenn was
schiefgeht? Reparieren kann es die CPU ja nicht.
Ich habe jedenfalls aufgegeben sowas simples wie das ACK zu ckecken für
die StdPeriphLibs des STM32. Ohne deren genaue Funktion zu kennen hat
das keinen Sinn und die .chm Datei die es nur noch als Hilfe gibt funzt
bei mir nicht.
Christian J. schrieb:> Peter..... nochmal: Es gibt keine Lib!
...
> Ich habe jedenfalls aufgegeben sowas simples wie das ACK zu ckecken
Warum?
Da Du den konkreten Typ nicht nennst, habe ich mal ins STM32F303
Reference Manual geschaut:
1
28.7.7 Interrupt and status register (I2C_ISR)
2
3
Bit 4 NACKF: Not Acknowledge received flag
4
This flag is set by hardware when a NACK is received after a byte transmission. It is cleared by
Christian J. schrieb:> Peter..... nochmal: Es gibt keine Lib!
Wo kommen denn dann diese Funktionen her?
> I2C_GenerateSTART(I2C1, ENABLE)
oder
> I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT)
MfG Klaus
Peter D. schrieb:> This flag is set by hardware when a NACK is received after a byte> transmission.
Ja, das gilt aber nur für den Slave Betrieb. Die zugehörige Lib Funktion
heisst I2C_Event(I2Cx, I2C_EVENT_SLAVE_ACK_FAILS), die aber nicht
funktioniert da ich damit schon alle Variationen ausprobiert habe.
Der Master sendet ja NAK und danach STOP, wenn er keine weiteren Bytes
lesen will, damit der Slave weiss, dass Ende ist.
Leider ist das Ganze schwer zu debuggen, da zeitkritisch.
Ich lass das erstmal ruhen, bis ich mich besser in die StdPeriphLib
eingearbeitet habe.
Evtl ist das beim 407 anders, der hat dieses Bit nicht aber
Acknowledge failure (AF)
This error occurs when the interface detects a nonacknowledge bit. In
this case:
• the AF bit is set and an interrupt is generated if the ITERREN bit is
set
• a transmitter which receives a NACK must reset the communication:
– If Slave: lines are released by hardware
– If Master: a Stop or repeated Start condition must be generated by
software
Kurz die Auflösung für nachfolgende Generationen:
Ob ein EEPROM seinen Schreibzyklus beendet hat findet man mit folgender
Sequenz bei einem STM32F4xx heraus (Timeout noch nicht drin). Nach ca
3-4 Durchläufen kommt das ACK, alles drüber ist Timeout.
1
// Warte bis Byte weggeschrieben wurde (Slave sendet solange kein ACK)
weil ich endlich im Header diesen Abschnitt fand.
Address Acknowledge
*
* After checking on EV5 (start condition correctly released on the
bus), the
* master sends the address of the slave(s) with which it will
communicate
* (I2C_Send7bitAddress() function, it also determines the direction of
the communication:
* Master transmitter or Receiver). Then the master has to wait that a
slave acknowledges
* his address. If an acknowledge is sent on the bus, one of the
following events will
* be set:
*
* 1) In case of Master Receiver (7-bit addressing): the
I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED
* event is set.
*
* 2) In case of Master Transmitter (7-bit addressing): the
I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED
* is set
Christian J. schrieb:> Nach ca> 3-4 Durchläufen kommt das ACK, alles drüber ist Timeout.
So wenige? Dann hast Du aber den Timeout sehr hoch gesetzt.
Da der EEPROM kein Clock-Stretching macht, sollte ein Timeout = 0
reichen.
Christian J. schrieb:> weil ich endlich im Header diesen Abschnitt fand.
Also benutzt Du doch eine fertige Lib. Und zu dieser gibt es wirklich
keine Doku?