i2c hört auf zu funktionieren

Gast #6909672
Lesenswert?

hi,
ich verwende die i2c Funktionen von mss

https://github.com/CalPlug/Microsemi_SmartFusion2_TrainingProjects/blob/master/UCI_Demo2/firmware/drivers/mss_i2c/mss_i2c.h

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.
Gast #6909677
Lesenswert?

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
Gast #6909679
Lesenswert?

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.
Gast #6909683
Lesenswert?

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).
Gast #6909696
Lesenswert?

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.
..
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.
Gast #6909724
Lesenswert?

Mike schrieb:
> Sendest Du nach dem Lesen vom Slave und vor dem Rückschreiben eine Stop-
> condition (RELEASE BUS)?
pseudocode:
1
library_lese_manipuliere_schreibe(){
2
data=MSS_I2C_write_read (SLAVE_ADR,MSS_I2C_RELEASE_BUS);
3
data_man=manipuliere(data)
4
MSS_I2C_write( SLAVE_ADR,data_man,MSS_I2C_RELEASE_BUS);
5

6
}
Gast #6909731
Lesenswert?

es schien (bin mir sehr sicher!) aber zu funktionieren als ich die 
Funktion kopiert habe.

1
mycopy_lese_manipuliere_schreibe(){
2

3
data=MSS_I2C_write_read (SLAVE_ADR,MSS_I2C_RELEASE_BUS);
4

5
data_man=manipuliere(data)
6

7
MSS_I2C_write( SLAVE_ADR,data_man,MSS_I2C_RELEASE_BUS);
1
mycopy_lese_manipuliere_schreibe();//ok
2
mycopy_lese_manipuliere_schreibe();//ok
3
mycopy_lese_manipuliere_schreibe();//ok
4
library_lese_manipuliere_schreibe();//ok - erste gehen noch
5
library_lese_manipuliere_schreibe();//ok -erste gehen noch
6
library_lese_manipuliere_schreibe();//nok - dann auf einmal nicht mehr
7
.
8
.
9
.
10
library_lese_manipuliere_schreibe();//nok
11
mycopy_lese_manipuliere_schreibe();//nok
12
starte_i2c_neu(); // einfach mal neu starten ( sofern ich das richtig gemacht habe..)
13
library_lese_manipuliere_schreibe();//nok
14
mycopy_lese_manipuliere_schreibe();//nok
Gast #6909737
Lesenswert?

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?
Gast #6909741
Lesenswert?

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:
1
   MSS_I2C_write_read( &g_mss_i2c0, target_slave_addr, tx_buffer,
2
                            write_length, rx_buffer, read_length,
3
                            MSS_I2C_RELEASE_BUS );

Das Ergebnis kommt dann auch in den rx_buffer.
Gast #6909760
Lesenswert?

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.
Gast #6909820
Lesenswert?

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...
Gast #6909890
Lesenswert?

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.
Gast #6909913
Lesenswert?

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 ;-)
Gast #6910755
Lesenswert?

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:
1
super_schreiben(){
2
hole_daten()
3
verarbeite_gelesene_daten()
4
sende_zu_slave()
5
}

Details:

*"schreibe-lese":*
1
hole_daten(){
2
counter =0;
3
MSS_I2C_write_read(argumente)
4
do {
5
counter++;
6

7
status=MSS_I2C_get_status(selected_i2c);
8
if counter > 250 
9
return 1;
10
while(status==MSS_I2C_IN_PROGRESS)
11
// FAIL FÜR IMMER MSS_I2C_IN_PROGRESS
12
// ich gehe hier schon raus mit einem counter
13

14
}

*Verarbeite Daten (nicht relevant):*
1
verarbeite_gelesene_daten()

*"Sende daten"*
1
sende_zu_slave(buffer){
2
MSS_I2C_write(i2c, SLAVEADRESSE, buffer, BUFFER_SIZE, MSS_I2C_RELEASE_BUS);
3
} // end of write..
Moderator (Firma: Titel) Persönliche Seite #6911046
Lesenswert?

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...
Gast #6911091
Lesenswert?

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
Gast #6911092
Lesenswert?

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.
Gast #6911111
Lesenswert?

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.)
Gast #6911141
Lesenswert?

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.
#6911312
Lesenswert?

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)
#6911376
Lesenswert?

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...
3
data_man=manipuliere(data)
4
MSS_I2C_write( SLAVE_ADR,data_man,MSS_I2C_RELEASE_BUS);
5
}

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...
Gast #6911726
Lesenswert?

*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...
3
data_man=manipuliere(data)
4
MSS_I2C_write( SLAVE_ADR,data_man,MSS_I2C_RELEASE_BUS);
5
}

mss lib
(https://github.com/CalPlug/Microsemi_SmartFusion2_TrainingProjects/blob/master/UCI_Demo2/firmware/drivers/mss_i2c/mss_i2c.h)
Gast #6911765
Lesenswert?

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.
Gast #6912826
Lesenswert?

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.
#6912848
Lesenswert?

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
Gast #6912891
Lesenswert?

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
Gast #6912925
Lesenswert?

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
Angehängte Dateien:
#6912985
Lesenswert?

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
Gast #6912986
Lesenswert?

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)
#6912989
Lesenswert?

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
Beitrag #6912994 wurde von einem Moderator gelöscht.
Gast #6913087
Lesenswert?

Kohlenstopfer schrieb:
> biild

I²C sieht normalerweise anders aus. Eigentlich müsste man sehen, wie ein 
Kondensator durch den Pull-Up Widerstand aufgeladen wird. Ungefähr so: 
https://www.tek.com/-/media/images/video-images/4-series-mso-user-interface-tour.jpg

Dergute W. schrieb:
> ie 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?

Überprüfe das
#6913091
Lesenswert?

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
Gast #6948359
Lesenswert?

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.
1
MSS_I2C_write( &g_mss_i2c0, target_slave_addr, tx_buffer, write_length,
2
                       MSS_I2C_RELEASE_BUS );
1
This parameter is a pointer to a buffer holding the data to be written to
2
the target I2C device. Care must be taken not to release the memory used by this buffer before the write transaction completes.
Angehängte Dateien:
Gast #6948391
Lesenswert?

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.
Angehängte Dateien:
Gast #6948429
Lesenswert?

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
Gast #6948471
Lesenswert?

Kohlenstopfer schrieb:
> Es sollen z.B. 0x48888924 gesendet werden:
> und dann: 0x48 9C A7 03

Kohlenstopfer 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.
Gast #6948494
Lesenswert?

**Erster Test**

Habe das gerade nochmal "direkt" getestet (einfach in der main() 
aufgerufen) ...

also 16 Bit werden wie gewünscht gesendet
1
uint8_t write_bufferxy[] = {0x01, 0xF1, 0x12, 0x00, 0x00, 0x11, 0x11}; // das soll geschrieben werden
2
  // sende ax, bx,cx,d3..0
3
  // Achtung buffer_size muss 7 Bytes entsprechen...
4
  MSS_I2C_write(gewaehltesi2c, 0x40, write_bufferxy, 7, MSS_I2C_RELEASE_BUS);

 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
1
uint8_t write_bufferxy[] = {0x01, 0xF1, 0x12, 0x00,  0x3D, 0xF8, 0x28};
2
MSS_I2C_write(gewaehltesi2c, 0x40, write_bufferxy, 7, MSS_I2C_RELEASE_BUS);

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
Angehängte Dateien:
Gast #6948500
Lesenswert?

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.
Gast #6948512
Lesenswert?

Also was noch nicht klappt ist einfach ausgedrückt:
1
//pseudocode
2
main(){
3
 
4
 
5
 uint8_t write_bufferxy[] = {0x01, 0xF1, 0x12, 0x00,  0x3D, 0xF8, 0x28}; //das funktioniert..
6
 MSS_I2C_write(gewaehltesi2c, 0x40, write_bufferxy, 7, MSS_I2C_RELEASE_BUS);
7
 // 
8
 meineTestfunktion();
9

10
}
11

12

13

14
/*
15
Eine Testfunktion in der ich Lesen/ Schreiben Teste
16
*/
17

18
meineTestfunktion()
19
{
20
easyWriteToI2C("0x1",0x3DF128); // geht nicht
21

22
 //folgendes geht:
23
 uint8_t write_bufferxy[] = {0x01, 0xF1, 0x12, 0x00,  0x3D, 0xF8, 0x28};
24
 MSS_I2C_write(gewaehltesi2c, 0x40, write_bufferxy, 7, MSS_I2C_RELEASE_BUS);
25

26
}
27
/**
28
Eine write Funktion um weniger Parameter angeben zu müssen..
29
*/
30
easyWriteToI2C(par a, par b){
31
 changesomestuff();
32
 // sogar der hart gecodete Buffer geht nicht:
33
 uint8_t write_bufferxy[] = {0x01, 0xF1, 0x12, 0x00,  0x3D, 0xF8, 0x28};
34
 MSS_I2C_write(gewaehltesi2c, 0x40, write_bufferxy, 7, MSS_I2C_RELEASE_BUS);
35

36
}



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.
Gast #6948531
Lesenswert?

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.
Gast #6949166
Lesenswert?

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.
Gast #6949262
Lesenswert?

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.
#6949309
Lesenswert?

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
Gast #6949616
Lesenswert?

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

1
  uint8_t write_buffer[] = {v, v2, v3, v4, v5, v6, v7}; 
2
  MSS_I2C_write(ausgewöltesI2C, 0x40, write_buffer, 7, MSS_I2C_RELEASE_BUS);
3
  MSLEEP(1000);

Jetzt nochmal alten Code-Stand drauf machen und gleiches versuchen..
Beitrag #6949638 wurde von einem Moderator gelöscht.
Gast #6950787
Lesenswert?

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
#6950878
Lesenswert?

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
Beitrag #6950879 wurde von einem Moderator gelöscht.
Gast #6953389
Lesenswert?

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.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren