Mehr Informationen sind nötig. Hardwareaufbau (Schaltplan + Aufbau),
welche Hardware ist konkret im Einsatz (wer ist Master, wer Slave, was
ist sonst noch da). Und der Code, der das Problem zeigt. Auch dein
selbst programmierter Code ist sicher nicht verkehrt.
Kohlenstopfer schrieb:> Das ist sehr seltsam.
Du hast irgend einen Code aus irgend einer Quelle irgendwie irgendwo
laufen gelassen, es funktioniert nicht, und du findest das seltsam?
Seltsam...
Wenn dein eigener COde doch funktioniert, was ist dann die Frage?
Oliver
Kohlenstopfer schrieb:> ich habe eine library mit einem Slave-Zugriff-Befehl. Er soll dabei> einen Wert vom Slave lesen und dann etwas zum Slave senden.> I2C scheint bei diesem Befehl aber aufzuhören zu funktionieren.> Wenn ich das gleiche selber nach programmiere scheint es allerdings zu> funktionieren!> Das ist sehr seltsam.
Danke für die Mitteilung
aha schrieb:> Danke für die Mitteilung
Er hatte schlechte Laune, und musste das an jemanden auslassen. Da
bietet sich ein Neuling natürlich an, insbesonders wenn die Fragen
ungeschickt gestellt werden, wie hier.
Ist halt so bei Boomern: Sie merken dass sie obsolet sind und
gesellschaftlich zu einer immer größeren Belastung werden, das macht
grantig.
Name: schrieb:> aha schrieb:>> Danke für die Mitteilung>> Er hatte schlechte Laune, und musste das an jemanden auslassen. Da> bietet sich ein Neuling natürlich an, insbesonders wenn die Fragen> ungeschickt gestellt werden, wie hier.>> Ist halt so bei Boomern: Sie merken dass sie obsolet sind und> gesellschaftlich zu einer immer größeren Belastung werden, das macht> grantig.
Habe gute Laune, sehe aber die Frage nicht (falls es eine Frage sein
sollte).
aha schrieb:> Habe gute Laune, sehe aber die Frage nicht (falls es eine Frage sein> sollte)
ja es ist eine Frage. Aber eine relativ schwierige ohne zusätzliche
Informationen xD
Kohlenstopfer schrieb:> I2C scheint bei diesem Befehl aber aufzuhören zu funktionieren
Beim ersten? Also geht I2C gar nicht? Dann dürfte eine Konfiguration
falsch sein.
Hast Du ein oszi oder Logic State analyzer?
Wenn clock und Daten zappeln, evt nur die Adresse falsch?
A. S. schrieb:> Beim ersten? Also geht I2C gar nicht? Dann dürfte eine Konfiguration> falsch sein.
Also ich habe drei unterschiedliche Anwendungsfälle für den Master(ARM
M3):
1. Nur Lesen von Slave: MSS_I2C_write_read :MSS_I2C_RELEASE_BUS
2. Nur Schreiben auf Slave: MSS_I2C_write: MSS_I2C_RELEASE_BUS
3. Lesen von Slave ->Daten manipulieren-> wieder reinschreiben auf
Slave: MSS_I2C_write_read dann MSS_I2C_write
Bei 3. hört das ganze auf zu funktionieren, wenn ich die Funktion aus
der Library verwende, die die MSS Library verwendet,bleibt
MSS_I2C_get_status() in MSS_I2C_IN_PROGRESS.
Eine Kopie dieser Funktion funktioniert allerdings. Außerdem fiel mir
auf, dass wenn ich im Programm zuerst meine Kopie aufrufe und danach
eine Befehl der Library verwende sogar der Library-Befehl einige male
korrekt ausließt.
..
Wenn ich über den I2C Controller "neu starte"/ initialisiere
funktioniert er trotzdem nicht. Erst nach Neustart des Controllers.
..
A. S. schrieb:> Hast Du ein oszi oder Logic State analyzer?
Ich habe ein Oszilloskop.
Gute Idee übrigens einfach mal die Slave-Adresse zu prüfen im Debugger.
Das ganze ist aber so seltsam, dass ich das bisher ignoriert habe.
Kohlenstopfer schrieb:> 3. Lesen von Slave ->Daten manipulieren-> wieder reinschreiben auf> Slave: MSS_I2C_write_read dann MSS_I2C_write
Sendest Du nach dem Lesen vom Slave und vor dem Rückschreiben eine Stop-
condition (RELEASE BUS)?
Kohlenstopfer schrieb:> data=MSS_I2C_write_read (SLAVE_ADR,MSS_I2C_RELEASE_BUS);
Ich kenne die Library zwar nicht, vermute aber, dass es sich hier um ein
kombiniertes Schreiben und Lesen handelt (mit Repeated Start condition).
Das wird gerne bei I2C-Speicherbausteinen genutzt, wo zunächst die
Byteadresse (nicht Slaveaddresse) gesendet und dann der Speicher
ausgelesen wird. Dann müßte die Funktion aber ein weiteres Argument für
die zu sendenden Daten haben. Wäre hier vielleicht …I2C_read_data()
besser?
Mike schrieb:> Dann müßte die Funktion aber ein weiteres Argument für> die zu sendenden Daten haben
Ah das war gerade nur Pseudocode.
Die Funktion in der MSS Library sieht wie folgt aus und wird auch so von
mir verwendet:
Kohlenstopfer schrieb:> 1 Master Operations> 2 The application can use the MSS_I2C_write(), MSS_I2C_read() and> 3 MSS_I2C_write_read() functions to initiate an I2C bus transaction.> The> 4 application can then wait for the transaction to complete using the> 5 MSS_I2C_wait_complete() function or poll the status of the I2C> transaction> 6 using the MSS_I2C_get_status() function until it returns a value> different> 7 from MSS_I2C_IN_PROGRESS.
Wartest Du denn nach dem initialen Lesevorgang auf das Ende der
Transaktion? Ich kann das im Pseudocode nicht finden. Ich nehme an, dass
die Library asynchron ist, d.h. im Hintergrund noch weiter arbeitet,
wenn der Funktionsaufruf zurückkehrt. Rufst Du gleich wieder eine
I2C-Funktion auf, kommt das Protokoll durcheinander.
Moin,
Ich wuerd' erstmal das scope nehmen und stumpf gucken, ob die start- und
stop-conditions alle so sind, wie sie sein sollen. Hoert sich fuer mich
ganz stark nach sowas an...
Gruss
WK
Dergute W. schrieb:> Ich wuerd' erstmal das scope nehmen und stumpf gucken, ob die start- und> stop-conditions alle so sind, wie sie sein sollen. Hoert sich fuer mich> ganz stark nach sowas an...
Interessant :)
Wenn ich den Debugger nach so einem BUG neu starte und einmal von 0 bis
255 alle Teilnehmer anspreche bekomme ich keine Antwort...
Wenn ich den Controller dann neu starte bekomme ich meine 4 Slave
antworten...
Kohlenstopfer schrieb:> 1. Nur Lesen von Slave: MSS_I2C_write_read :MSS_I2C_RELEASE_BUS> 2. Nur Schreiben auf Slave: MSS_I2C_write: MSS_I2C_RELEASE_BUS> 3. Lesen von Slave ->Daten manipulieren-> wieder reinschreiben auf> Slave: MSS_I2C_write_read dann MSS_I2C_write>
Anscheinend ein Neuling...
Seit 30 Jahren weiss man doch, dass alles, was mit MS beginnt,
eigentlich immer Probleme macht. Verzichte auf MS und alles wird besser.
Hallo,
ich könnte wetten, dass zumindest SCL auf Low liegt - das würde auch
erklären, warum nach einem Fehler keine Devices mehr gescannt werden
können.
Mach mal einen Reset des I2C (HW-Reset der Peripherie), das beseitigt
zwar nicht die Ursache, würde aber evtl. Licht ins Dunkel bringen.
Möglicherweise werden von der Library nicht alle möglichen Zustände der
I2C Statemachine erkannt und behandelt. Ich hatte sowas vor Jahren
schonmal mit der originalen ST-Library, seitdem schreibe ich mir sowas
selbst ;-)
Kohlenstopfer schrieb:> do{> ergebnis =MSS_I2C_get_status(i2c)> }while(ergebnis == MSS_I2C_IN_PROGRESS)>> naja das ist das einzige was ich mache
Nach jeder Transaktion oder nur am Ende nach dem Schreiben? Wenn ja,
hängt der Bus nach write_read oder nach dem write?
Mike schrieb:> Kohlenstopfer schrieb:>> do{>> ergebnis =MSS_I2C_get_status(i2c)>> }while(ergebnis == MSS_I2C_IN_PROGRESS)>>>> naja das ist das einzige was ich mache>> Nach jeder Transaktion oder nur am Ende nach dem Schreiben? Wenn ja,> hängt der Bus nach write_read oder nach dem write?
bin gerade wieder zu dieser Stelle gekommen.
Und genau da wo er lesen, Daten ändern , schreiben soll kommt dieser
Bug.
...
Hmm wenn ich schreibe, warte ich gar nicht auf den Status. Ich geh mal
mit dem Debugger dort hin.
(Das komische ist, dass es wie gesagt, mit einer Kopie der Funktion
klappt.)
Hier nochmal der Ablauf:
Stefan ⛄ F. schrieb:> Während der Entwicklungsphase mache ich immer LEDs an SCL und SDA. Dann> sieht man sofort wenn es klemmt.
ah dann sieht man wenn etwas z.B. konstant leuchtet. Ist auf jeden Fall
ne gute Sache :D
Marvin M. schrieb:> Möglicherweise werden von der Library nicht alle möglichen Zustände der> I2C Statemachine erkannt und behandelt
das wäre sehr schön :D
Weil ich dann meinen PC aus dem Fenster schmeiße und jemand einen neuen
PC bekommt.
Kohlenstopfer schrieb:> (Das komische ist, dass es wie gesagt, mit einer Kopie der Funktion> klappt.)
Gerade aber leider nicht mehr :D
Vlt. zieht der Slave nachdem gelesen wurde eine Leitung dauerhaft auf
high oder low.
Ich versuche es mal zu messen.
Kohlenstopfer schrieb:> Ich versuche es mal zu messen.
Mich wundert immer wieder, wie lange man sich vor dem Messen drücken
kann.
Kohlenstopfer schrieb:> Stefan ⛄ F. schrieb:>> Während der Entwicklungsphase mache ich immer LEDs an SCL und SDA. Dann>> sieht man sofort wenn es klemmt.> ah dann sieht man wenn etwas z.B. konstant leuchtet.
Ein Tipp dazu: weil der IDLE Zustand bei SDA und SCL jeweils H ist,
sollten die LEDs von Vcc her versorgt werden und einfach mit ihrem
Vorwiderstand parallel zu den I²C-Pullups liegen. Dann blitzt es bei
jeder Übertragung nur kurz auf. Aber wenn es dauernd leuchtet, dann hat
sich der Bus festgefressen...
Lothar M. schrieb:> Mich wundert immer wieder, wie lange man sich vor dem Messen drücken> kann.
Geringe Dokumentation im Code. Vtl. soll das Programm gar nicht an diese
Stelle kommen.
Ok habe gerade das erste Mal gemessen:
SDA, SCL sind auf ca. 2,5 V.
senden /lesen: kurzer "Burst".
Gerade eine Funktion ausgeführt mit mehreren R/W Befehlen: Mehrere
Bursts.
Wenn man zur fehlerhaften Funktion kommt, kommen sehr viele Bursts
hintereinander es sieht aus wie ein Rauschen.
Es hört nicht auf.
Ich steppe mal weiter und messe
Kohlenstopfer schrieb:> kommen sehr viele Bursts> hintereinander es sieht aus wie ein Rauschen.> Es hört nicht auf.
Also hört die Kommunikation nicht auf, sondern läuft im Gegenteil
wahrscheinlich in einer Endlosschleife.
Jetzt sind wir an dem Punkt angekommen, wo die strukturierte Fehlersuche
erst beginnt.
Kohlenstopfer schrieb:> scl ist dabei low
Dauernd?
Dann fuhrwerkt irgendwer unzulässigerweise auf dem SDA herum. Denn mit
SCL=low wäre Clock-Stretching angesagt.
Stefan ⛄ F. schrieb:> Jetzt sind wir an dem Punkt angekommen, wo die strukturierte Fehlersuche> erst beginnt.
hört sich gut an :)
ich dachte das wäre mein/das Ende
>Dauernd?>Dann fuhrwerkt irgendwer unzulässigerweise auf dem SDA herum. Denn mit>SCL=low wäre Clock-Stretching angesagt.
Ja dauernd, als ob unendlich viele Daten geschrieben werden sollen auf
SDA.
Allerdings SCL = low.
Nur wenn ich den Controllern neu starte ist wieder SDA=SCL=high
...
Das geschieht wenn ich diesen Befehl ausführe. Es ist seltsam, da es wie
ein Fehlverhalten aussieht.
(Werde jetzt einen alten Code testen, bei dem es mit Kopien dieser
Befehle geklappt hat.)
Dort scheint aber der erste Befehl geklappt zu haben. Erst beim zweiten
(lese-datenverändern-schreiben) kommt ein Fehler
.. vlt. aber auch nur einfach Zufall
Was du jetzt brauchst ist ein Oszilloskop um die Signalpegel und Flanken
zu prüfen. Wenn du knapp bei Kasse bist, genügt schon ein DSO150.
https://de.aliexpress.com/item/33040555028.html
Und du brauchst einen Logic Analyzer um die digitale Information im
Signal zu protokollieren, dafür muss weniger als 10 Euro ausgeben.
https://de.aliexpress.com/item/4000364877295.html
Als Software empfehle ich PulseView
https://sigrok.org/wiki/Downloads
, das kann die I²C Kommunikation sogar dekodieren. Sieht dann etwa so
aus:
http://stefanfrings.de/stm32/pulseview_i2c.png
Wenn du ein Oszilloskop hast, dass beide Funktionen abdeckt: Umso
besser, dann nimm das.
Zeige uns damit mal, wie das Signal auf den beiden Leitungen im
Fehlerfall aussieht.
Wenn eine LED ständig leuchtet oder flackert, verbinde des Reset Eingang
des Mikrocontrollers mit GND (dauerhaft, nicht tastend). Er gibt den Bus
dann frei, so dass beide Leitungen auf High gehen sollten. Wenn sie
nicht auf High gehen, spinnt einer deiner Slaves. Du kannst einen Slave
nach dem anderen abtrennen, um heraus zu finden, welcher der Übeltäter
ist.
Allerdings kann die Fehlerursache trotzdem im Master liegen. Es kann ja
sein, dass fehlerhafte Daten/Kommunikation den Slave erst dazu bringen,
sich aufzuhängen. Dennoch ist es hilfreich herauszufinden, ob der Master
oder welcher Slave den Bus blockiert.
Kohlenstopfer schrieb:> ok da geht es auch nicht mehr .> wie kann das sein.> Ich weiß doch, dass das mal ging.
wenn Parameter mal grenzwertig waren Widerstände oder Datenblattwerte
dann kann sich durch Alterung oder nur durch "run in" diese Werte
verändern!
Bedenke im Datenblatt stehen meinst Werte von bis und wenn ein Wert eben
hart an der Grenze funktionierte dann kann der auch mal wegdriften!
Widerstände können sich vergrößern an Steckkontakte!
high/low Erkennung (Vih/Vil) kann wegdriften!
VCC kann wegdriften (somit verändert sich auch VCC * 0,7 für high)
Stefan ⛄ F. schrieb:> Was du jetzt brauchst ist ein Oszilloskop
Das ist hier ja das Tragi(komi)sche, denn
Kohlenstopfer schrieb:>>>> Ich habe ein Oszilloskop.
Deshalb meine Anmerkung zum Thema "Messen"...
Lothar M. schrieb:> Das ist hier ja das Tragi(komi)sche, denn> Kohlenstopfer schrieb:>>>>> Ich habe ein Oszilloskop.>> Deshalb meine Anmerkung zum Thema "Messen"...
na dann kann er doch Vi high / Vi low immer messen gemäß der
Datenblätter
Leider wurde bisher immer noch nicht gesagt, um was für einen Slave es
sich handelt und mit welchem (nicht-pseudo-sondern-realen) Code der
Slave angesprochen wird.
Bei dem Problem vermute ich auch stark, dass nach dem ersten
Schreibzugriff der Bus mit einer Stop-Condition geschlossen wird. Die
nachfolgende Start-Condition beim Lesevorgang bring dann den Slave
durcheinander (dessen State-Machine hängt sich auf). Hier darf nur der
Repeated Start stehen, vorher darf keine Stop-Condition auf dem Bus
sein.
1
library_lese_manipuliere_schreibe(){
2
data=MSS_I2C_write_read(SLAVE_ADR,MSS_I2C_RELEASE_BUS);//<<<<<=== hier was anderes als MSS_I2C_RELEASE_BUS reinschreiben...
Es gibt aber auch Slaves (z.B. der HMC5883), der intern die
Registeradressen weiterzählt. Der hängt sich auch auf, wenn man nicht
alle 6 Bytes der gemessenen Werte ausliest...
*The MSS_I2C_RELEASE_BUS constant is used to specify the options
parameter to functions MSS_I2C_read(), MSS_I2C_write() and
MSS_I2C_write_read() to indicate that a STOP bit must be generated at
the end of the I2C transaction to release the bus.*
Bernhard S. schrieb:> Bei dem Problem vermute ich auch stark, dass nach dem ersten> Schreibzugriff der Bus mit einer Stop-Condition geschlossen wird.
Nach dem ersten Schreibzugriff? Oder einfach nach MSS_I2C_write_read
(wie du auch kommentiert hast)
> Die nachfolgende Start-Condition beim Lesevorgang bring dann den Slave> durcheinander
Es kommt doch zuerst ein MSS_I2C_write
*I2C master write-read This function initiates an I2C write-read
transaction where data is first written to the target device before
issuing a restart condition and changing
the direction of the I2C transaction in order to read from the target
device.*
1
library_lese_manipuliere_schreibe(){
2
data=MSS_I2C_write_read(SLAVE_ADR,MSS_I2C_RELEASE_BUS);//<<<<<=== hier was anderes als MSS_I2C_RELEASE_BUS reinschreiben...
Mist habe das gerade mit MSS_I2C_HOLD_BUS bei MSS_I2C_write_read()
Aber nein.
Beim nächsten MSS_I2C_write_read() hängt er wieder :D
.
Auch wenn ich nach MSS_I2C_write ein MSS_I2C_HOLD_BUS einfüge
funktioniert das nicht.
Stefan ⛄ F. schrieb:> Wenn eine LED ständig leuchtet oder flackert, verbinde des Reset Eingang> des Mikrocontrollers mit GND (dauerhaft, nicht tastend). Er gibt den Bus> dann frei, so dass beide Leitungen auf High gehen sollten. Wenn sie> nicht auf High gehen, spinnt einer deiner Slaves. Du kannst einen Slave> nach dem anderen abtrennen, um heraus zu finden, welcher der Übeltäter> ist.
Stimmt, d. Bus wird dann frei von dem Controller. Der Controller ist in
einem SoC System. Müsste das SoC resetten. Bin da noch vorsichtig^^
Slaves könnte ich dann ebenfalls nach und nach resetten.
Lothar M. schrieb:> Mich wundert immer wieder, wie lange man sich vor dem Messen drücken> kann.
Wir sind einfach zu alt, Lothar. Wir haben noch gelernt nachzusehen
warum etwas nicht wie erwartet funktioniert statt erstmal wild
rumzuvermuten. ;)
Moin,
Kohlenstopfer schrieb:>> Stefan ⛄ F. schrieb:>> Du kannst einen Slave>> nach dem anderen abtrennen, um heraus zu finden, welcher der Übeltäter>> ist.
Schlaue Entwickler bauen, um rauskriegen zu koennen (und auch aus
anderen Gruenden), wer hier grad' am Bus zieht, gerne auch mal
niederohmige Serienwiderstaende in die beiden Leitungen ein. Dann kann
man bei klemmendem Bus gucken, auf welcher Seite des Serien-R das Low
lower ist.
Aber: Iiiih - Hardware....
Und "hinterher" kann sowas etwas tricky sein, in ein bestehendes Design
reinzupopeln. Vorher im Schaltbild 2x 0R sind deutlich schneller
gezeichnet und geroutet :-)
> Stimmt, d. Bus wird dann frei von dem Controller. Der Controller ist in> einem SoC System. Müsste das SoC resetten. Bin da noch vorsichtig^^> Slaves könnte ich dann ebenfalls nach und nach resetten.
Wenn du das kannst - nicht jeder Slave hat eine Resetleitung. Und nicht
an jeder Resetleitung kannst du beliebig ziehen, ohne ggf. weiter Teile
in den Reset zu bringen.
Gruss
WK
Dergute W. schrieb:> Dann kann> man bei klemmendem Bus gucken, auf welcher Seite des Serien-R das Low> lower ist.
Interessant werde den Schaltplan prüfen!
...
Müsste mal das Oszilloskop anschauen, ob das die Daten digitalisieren
kann. Dann würde ich es am PC anylisieren.... Es ist von Rohde&Schwarz
Rtb2004
Moin,
Kohlenstopfer schrieb:> Müsste mal das Oszilloskop anschauen,
Jaaa!!eins!elf!!
> ob das die Daten digitalisieren> kann.
Nein. Selber draufglotzen. Wie sehen die Flanken aus?
Ueber/Unterschwinger? Sind Start- und Stopconditions an den Stellen wo
sie nach Datenblatt des geheimen I2C Slaves sein muessen?
Gruss
WK
Dergute W. schrieb:> Nein. Selber draufglotzen. Wie sehen die Flanken aus?
Die Bilder im Anhang zeigen SDA. Das ist was durchgehend auf dem Bus
passiert.
Kohlenstopfer schrieb:>> Dann kann>> man bei klemmendem Bus gucken, auf welcher Seite des Serien-R das Low
scheint bei meinem Slave vorhanden zu sein. werde mal messen
Dergute W. schrieb:> Dann kann> man bei klemmendem Bus gucken, auf welcher Seite des Serien-R das Low> lower ist.
sah nach dem gleichem Spannungswert bei SCL aus.
Kohlenstopfer schrieb:> Die Bilder im Anhang zeigen SDA
Ziehen deine Pull-Up Widerstände den Bus wirklich auf 2,4 Volt? Und ist
das für alle Teilnehmer ein gültiger HIGH Pegel?
Moin,
Zu den Bildern faellt mir spontan ein:
1x Triggern im Bild ist besser.
Gehoert der Highpegel so? Also 2.x Volt? Ist das der Pegel, den du da
erwartest? Oder ist das evtl. ein 3.3V Bus, wo ein Teilnehmer mit eher
nur 1.8V rechnet und alles drueber verzweifelt ueber'ne interne Diode
nach 1.8V ableitet?
Die Flanken, insbesondere die steigende kommt mir verdaechtig schnell
vor. Sind die I2C Pins am Master wirklich open Collector/Drain/Anode?
Oder versehentlich auf doch Push/Pull?
Gruss
WK
Stefan ⛄ F. schrieb:> Ziehen deine Pull-Up Widerstände den Bus wirklich auf 2,4 Volt
oh der Grund liegt daran, dass dort noch ein
I2C Voltage Level Translator vorhanden ist, der das auf 2,5 bringen
soll.
Stefan ⛄ F. schrieb:> das für alle Teilnehmer ein gültiger HIGH Pegel?
Das ist nur für einen Slave gedacht. Der Rest bekommt 3,3 V ( denke
ich... müsste ich noch mal schauen)
Moin,
Kohlenstopfer schrieb:> oh der Grund liegt daran, dass dort noch ein> I2C Voltage Level Translator vorhanden ist, der das auf 2,5 bringen> soll.
Oha - vielleicht nicht ganz unerhebliches Detail :-/
Auf deinen Bildern sieht man immer bei der steigenden Flanke im unteren
Drittel eine leichte Verbreiterung des "Strahls".
Wie sieht'n das in "viel breiter" aus?
Gruss
WK
Moin,
Kohlenstopfer schrieb:> biild
OK, mit einem geheimen I2C Translator koennte das schon so aussehen.
Also anhand der Infos, die ich mir hier aus dem Thread ziehen kann, kann
ich nur sagen: Irgendwas scheint nicht immer zu gehen, aber ich bin
derzeit zu dumm, um ueberhaupt sagen zu koennen, ob's an der HW oder der
SW liegt...
Vielleicht schaffts ja wer anders, oder der 2.Post dieses Threads wird
nochmal gruendlich durchgearbeitet.
Gruss
WK
Jetzt habe ich den logic analyzer.
Lesebefehle waren bis jetzt ok.
Beim Schreiben ist es seltsam:
Es sollen z.B. 0x48888924 gesendet werden:
slave adr
spezielle adresse
und dann: 0x48 9C A7 03
Das passt aber nicht mit was man aufnimmt.
Siehe Anhang
(Danach mache ich wieder ein I2C Read)
Ich bin mit dem Debugger eine Zeile vor write gegangen. Im Buffer stand
die passende Zahl als Array.
Trotzdem wird etwas anderes abgeschickt.
Auch bei einem write Befehle davor sehe ich das jetzt:
Anstatt 0x3DF828 schickt er 0x9C A7 03
Also sollte der Master denn nicht einfach etwas schicken können, was ihm
gegeben wird?
Ich werde diesen Funktion mal versuchen so direkt wie möglich
aufzurufen.
Also ohne Umwege.
Stell deine Fragen kuenftig bei Facebook oder Tiktok.
Das waere deinem Niveau angemessen.
Wenn die "Kopie" der Funktion funktioniert, dann nimm die
und gut ist.
Boomer schrieb:> Wenn die "Kopie" der Funktion funktioniert, dann nimm die> und gut ist.
Ich meinte nur, dass die mss-Funktion durch andere Funktionen aufgerufen
wird.
Vielleicht gibt es einen Unterschied wenn ich die mss-Funktion direkt
aufrufe. Mit dem Debugger habe ich auch schon den zu sendenden Buffer
kurz vor der Funktion betrachtet.
Welche Kopie meinst du?
Es sollte doch der Buffer geschrieben werden.
Stattdessen wird ein anderer unbekannter Wert gesendet..
Ich finde es seltsam, weil bei einem anderen Bufferwert funktioniert das
Senden. Zum Beispiel mit 0x7A E0
Moin,
Kohlenstopfer schrieb:> Care must be taken not to release the memory used by this buffer before> the write transaction completes.
Und? Takest du care? Steht das wirklich im Sendepuffer, oder glaubst du
das nur? Stehts noch z.b. 1sec nach dem Senden so im Sendepuffer?
Gruss
WK
Kohlenstopfer schrieb:> Es sollen z.B. 0x48888924 gesendet werden:> und dann: 0x48 9C A7 03Kohlenstopfer schrieb:> Anstatt 0x3DF828 schickt er 0x9C A7 03
Mit fällt auf, dass er in beiden Fällen die letzen 3 Bytes verändert
sind, sogar auf die selben Werte.
Kohlenstopfer schrieb:> bei einem anderen Bufferwert funktioniert das> Senden. Zum Beispiel mit 0x7A E0
Vielleicht, weil das kürzer ist und schneller gesendet wird.
Kohlenstopfer schrieb:> Care must be taken not to release the memory used by this buffer before> the write transaction completes.
Hast du das beachtet? Überschreibst du den Buffer zu früh oder liegt er
gar auf dem Stack und die besitzende Funktion endet bevor die I²C
Kommunikation abgeschlossen ist?
Kann ich mal deinen Quelltext sehen?
Dergute W. schrieb:> Stehts noch z.b. 1sec nach dem Senden so im Sendepuffer?
Gute Frage.
0x11 11 11 11 und 0x3DF828 werden auch "korrekt" gesendet.
Also auch diese 32 Bit werden gesendet
**Zweiter Test**
uint8_t write_bufferxy[] = {0x01, 0xF1, 0x12, 0x00, 0x3D, 0xF8, 0x28};
habe ich gerade direkt vor das MSS_I2C_write geschrieben.
Beim Schreiben soll er das jetzt immer das machen.
Macht er aber nicht:
Habe eine Testfuntkion.
Dort werden Schreibbefehle durchgeführt.
Diese unterscheiden sich vom MSS_I2
Vom Logicanalyzer wird etwas anderes aufgezeichnet!
**Dritter Test**
Jetzt habe ich folgendes auch mal direkt in meine Testfunktion
geschrieben.
Damit hat es geklappt.
Also der Wert 3DF828 erscheint auch beim Logic Analyzer
Dergute W. schrieb:> Und? Takest du care? Steht das wirklich im Sendepuffer, oder glaubst du> das nur? Stehts noch z.b. 1sec nach dem Senden so im Sendepuffer?
Wusste bisher noch nicht wie.
Stefan ⛄ F. schrieb:> Hast du das beachtet? Überschreibst du den Buffer zu früh oder liegt er> gar auf dem Stack und die besitzende Funktion endet bevor die I²C> Kommunikation abgeschlossen ist?
Das mit dem Stack ist sehr interessant.
> Kann ich mal deinen Quelltext sehen?
Geht nicht :,(
> Dergute W. schrieb:>> Stehts noch z.b. 1sec nach dem Senden so im Sendepuffer?>> Gute Frage.
Ja es sieht danach aus als müsste ich mir das anschauen, wenn mir nichts
anderes einfällt.
Hatte glaube ich eh schon Stack Probleme
Füge mal direkt hinter MSS_I2C_write() eine delay_ms(1000) ein und teste
dann nochmal.
Wenn das Senden dann geht, überschreibst du den Buffer zu früh bzw. die
Funktion ende zu früh.
Wenn es dann immer noch nicht geht, hast du vielleicht eine ISR die den
Puffer überschreibt, oder einen Stack Überlauf.
Füge außerdem Code ein, der den Buffer nach dem Delay kontrolliert und
ggf. irgendwie einen Alarm absetzt.
Stefan ⛄ F. schrieb:> Wenn es dann immer noch nicht geht, hast du vielleicht eine ISR die den> Puffer überschreibt, oder einen Stack Überlauf.> Füge außerdem Code ein, der den Buffer nach dem Delay kontrolliert und> ggf. irgendwie einen Alarm absetzt.
ok :D
Werde mal schauen ob ich die Stellen finden kann.
Lokale Variablen innerhalb von Funktionen liegen auf dem Stack. In dem
Moment wo die Funktion verlassen wird, verliere sie ihre Gültigkeit. Wie
lange es bis zum Datenverlust dauert, ist reiner Zufall.
Bevor du die Funktion verlässt musst du warten, bis die Daten gesendet
wurden. Oder du benutzt globale Variablen. Oder du erzeugt Puffer auf
dem Heap. Dann musst du dich aber auch um das "Aufräumen" kümmern.
Moin,
Kohlenstopfer schrieb:> uint8_t write_bufferxy[] = {0x01, 0xF1, 0x12, 0x00, 0x3D, 0xF8, 0x28};
Da trau' ich mich doch wetten, dass wenn du mal spasshalber testweise
statt "uint8_t" "static uint8_t" schreibst, dass es dann besser
funktioniert...
Immer dieser Kellerspeicher...
Gruss
WK
Boomer schrieb:> Arrays auf dem Stack sind doch immer fuer einen Schenkelklopfer> gutt!
sag das doch gleich!
Früher hatten wir noch keine Stacks, da haben wir die Bits einzeln
angefertigt, belackt und dann sorgsam auf den Schreibtisch gelegt zum
Trocknen. Meistens vier bis fünf Wochen hat da eine Bitlegung gedauert.
Keller schrieb:> CLK Frequenz ???
Also die I2C SCL Frequenz wird angezeigt als ca : f=380 kHz, T = 2*1,3
us = 2,6 us
Dergute W. schrieb:> Da trau' ich mich doch wetten, dass wenn du mal spasshalber testweise> statt "uint8_t" "static uint8_t
bin grade dabei
(vielen Dank für den Tipp)
genau jetzt klappen alle Arten von Schreibbefehlen...
...
dabei wollte ich genau jetzt schauen ob es einen Unterschied macht wenn
ich static schreibe.
Jetzt schreibt der mir 0x003DF828 und 0x007DF820 korrekt in die Register
wenn ich das auslese kommt das auch wieder..
werde einfach mal 32 Bits senden anstatt 24
und noch mehr Testfunktionen betrachten.
Moin,
Kohlenstopfer schrieb:> dabei wollte ich genau jetzt schauen ob es einen Unterschied macht wenn> ich static schreibe.
Es macht auf jeden Fall den Unterschied, wo dein oller Buffer angelegt
wird: Entweder aufm Stack oder in 'nem Extra Stueckchen RAM.
Aufm Stack kann er (muss aber nicht) sofort ueberschrieben werden, sowie
die Funktion beendet ist. Als static wird er erst ueberschrieben, wenn
du explizit das naechste mal was reinschreibst.
Gruss
WK
Denke immer dran, dass das Senden (bei der verwendeten Bibliothek)
asynchron im Hintergrund abläuft. Während deine Funktion schon beendet
ist, sendet er immer noch.
Stefan ⛄ F. schrieb:> Während deine Funktion schon beendet> ist, sendet er immer noch.
Es mag sein, dass es nicht die Ursache ist. Aber mein Programm lief noch
nie so weit wie jetzt mit dem Sleep am Ende...
Kohlenstopfer schrieb:> Es mag sein, dass es nicht die Ursache ist. Aber mein Programm lief noch> nie so weit wie jetzt mit dem Sleep am Ende...
Logisch, denn dadurch verzögerst du die Programmausführung. Innerhalb
der 1000ms wird wohl alle gesendet sein. Danach darf der Puffer ungültig
werden.
Kohlenstopfer schrieb:> Jetzt nochmal alten Code-Stand drauf machen und gleiches versuchen..
ja, nur durch das Hinzufügen von sleep geht es jetzt weiter...
Dergute W. schrieb im Beitrag #6949638:
> main() {> meineTestfunktion();> bufferoverwrite();> }
wie meinst du das?
---
Bitte Admin zensiert mal diese Stelle bei 20.01.2022 15:39
Kohlenstopfer schrieb:> wie meinst du das?
So wie's da steht.
In deiner Testfunktion startest du den i2c transfer; und unmittelbar
danach rufst du eine andere Funktion auf, die auf dem Stack evtl. an der
gleichen Stelle, wo aus deinem Sendepuffer vielleicht grad noch fleissig
gesendet wird, was anderes hinschreibt (was dann ggf. statt deinem
Originalpufferinhalt aufm i2c rumflakt)
>> ---> Bitte Admin zensiert mal diese Stelle bei 20.01.2022 15:39
Ernsthaft?
Guck niemals Kentucky Fried Movie.
Gruss
WK
Dergute W. schrieb:> Ernsthaft?
Schwierige Frage. Könnte auf manche abwertend wirken.
Toll jetzt wurde dadurch dein Code gelöscht xD.
aber du hast irgendwie sowas gemacht:
1
sendeI2c()
2
strcpy (variable,"test");
und dann könnte "test" per i2c übermittelt werden, falls der Stack
überschrieben wird meinst du.
Auf jeden Fall vielen Dank :D
Die 1000 ms waren schon mal ein guter Schritt.