Hi,
hat jemand schon einmal folgendes Phänomen erlebt:
Beim Versuch eine I2C2 Kommunikation mittels eines Cortex Stm32f103 auf
zu bauen liegen SCL und SDA beide auf +3,3V, innerhalb eines bruchteils
einer Sekunde (aber für das auge noch schön sichtbar) zieht der Cortex
die Clockleitung auf Masse.
Elektrotechnisch hat die SCl Leitung keine Verbindung zur Masse, beide
Leitungen (SCA und SDL) sind über einen 10 k Ohm Widerstand auf +3,3V
gelegt.
Hier meine Initialisierung:
Ich arbeite mich grad in die NxP LPC11xx/13xx/17xx Reihe ein, dort ist
es so, dass wenn das I2C-Interface für Multimaster konfiguriert ist die
Clockleitung solange auf Masse zieht wie das SI-Flag
(I2C-Interrupt-Flag) aktiv ist. Ich würde also mal im Datenblatt zu
deinem Controller schauen, ob er das sog. Clock-Stretching ebenfalls auf
diese Weise macht und entsprechend untersuchen, ob er ungewolltes
Clock-Stretching macht.
Ralf
Verstehe Dein Problem nicht ganz, denn :
- der I2C Bus des STM hat natürlich Massebezug oder wie schliesst Du
einen Slave Baustein an ?
Die Intialiserung über die Firmawarecalls scheint in Ordnung zu sein.
Ich benutze den I2C Bus allerdings im DMA/Interruptbetrieb.
Gruss
Thomas schrieb:> - der I2C Bus des STM hat natürlich Massebezug oder wie schliesst Du> einen Slave Baustein an ?
ich wollt ausdrücken, das meine SCL Leitung kein Kurzschluss auf Masse
hat.
Ich habe versuchsweise die Pin Initialisierung mal hinter die I2C
Structure Initialisierung gesetzt, jetzt bleibt SCL auf +3,3 V, dafür
wird aber nichts mehr gesendet.......
Sylvia H. schrieb:> Beim Versuch eine I2C2 Kommunikation mittels eines Cortex Stm32f103 auf> zu bauen liegen SCL und SDA beide auf +3,3V, innerhalb eines bruchteils> einer Sekunde (aber für das auge noch schön sichtbar) zieht der Cortex> die Clockleitung auf Masse.
Nicht grad für das was man ein Sekundenbruchteil nennt, sondern eher im
Mikrosekundenbereich, aber erlebt habe ich das schon. Nämlich denn, wenn
zuerst die SCL/SDA-Pins als AF-OD konfiguriert werden und danach die
I2C-Unit initialisiert wird. Dann sind in der Zwischenzeit die Pins auf
"low".
Abhilfe: Erst I2C Initialisieren, dann die Pins konfigurieren. Hat bei
mir funktioniert.
also die GPIO Init wieder an den Anfang setzen, nun sendet der Master
wieder.
Aber danach ist der Clock auf 0.
Soll das clock Streching sein? Laut Datenblatt verstehe ich das so, dass
der Master BEVOR einer Schreibaktion mit SCL auf low auf ein event
wartet.
Bei mir ist der Clock aber NACH der Schreibaktion auf low, der Master
wird aber von mir nicht in den receiver mode gesetzt....
SDA/SCL line control
● If clock stretching is enabled:
– Transmitter mode: If TxE=1 and BTF=1: the interface holds the clock
line low
before transmission to wait for the microcontroller to read SR1 and then
write the
byte in the Data Register (both buffer and shift register are empty).
– Receiver mode: If RxNE=1 and BTF=1: the interface holds the clock line
low after
reception to wait for the microcontroller to read SR1 and then read the
byte in the
Data Register (both buffer and shift register are full).
A. K. schrieb:> Abhilfe: Erst I2C Initialisieren, dann die Pins konfigurieren. Hat bei> mir funktioniert.
upps, zu spät gelesen...
hab ich versucht, aber dann hat der Master gar nichts mehr gesendet
(siehe oben).....
Sylvia H. schrieb:> Bei mir ist der Clock aber NACH der Schreibaktion auf low, der Master> wird aber von mir nicht in den receiver mode gesetzt....
Das passiert ab ehesten, wenn du Kommunikation nicht korrekt abläuft
(Slave antwortet nicht oder die Programmierung des Masters stimmt
nicht).
Hast du ein Scope und kannst SDA und SCL mal aufnehmen? Ansonsten wird
SCL auch auf Masse gezogen wenn du den Bus nur initialisierst und nichts
sendest?
Mike
Mike S. schrieb:> Hast du ein Scope und kannst SDA und SCL mal aufnehmen? Ansonsten wird> SCL auch auf Masse gezogen wenn du den Bus nur initialisierst und nichts> sendest?
wenn nur inititalisiert wird bleiben SDA und SCL auf 3,3V
Wenn ich etwas sende, dann erscheinen die Bytes auf auf dem Bus (kann
ich mit dem Advaark sehen), danach zeigt mir mein OSZI das SDA auf 3,3V
und SCL auf Masse liegt...
ich bleibe auch nicht in irgendeiner Methode hängen, weil mein
partnerbord nicht sein ACK schickt,
das Senden wird abgeschlossen.
Danach ist der Bus tot, weil SCL auf Masse liegt.
Aus den verfügbaren Informationen ist Dein Phänomen nicht erklärbar. Ich
rate Dir, wenn Du schnell zu einem Ergebnis kommen willst, den I2c Bus
Treiber von STM (siehe Application) zu verwenden.
Vorher solltest Du aber sicherstellen, ob nicht Dein Slave
möglicherweise durch Clockstretching diesen Effekt erzeugt.
Das dein Programm hängen bleibt sagt ja auch keiner, aber ich hab die
Erfahrung gemacht, das die I2C Hardware von ST gerne mal hängen bleibt
wenn sie nicht korrekt angesprochen wird. Und das ist zum Teil nicht
einfach :)
Thomas schrieb:> Aus den verfügbaren Informationen ist Dein Phänomen nicht erklärbar. Ich> rate Dir, wenn Du schnell zu einem Ergebnis kommen willst, den I2c Bus> Treiber von STM (siehe Application) zu verwenden.
die benutze ich schon..
> Vorher solltest Du aber sicherstellen, ob nicht Dein Slave> möglicherweise durch Clockstretching diesen Effekt erzeugt.
das habe ich mir auch schon gedacht, das es dem Slave vielleicht zu
schnell geht. Das Slave Board arbeitet mit einem ATXMEGA16D4 drauf.
Daher habe ich mal die Pingeschwindigkeit von GPIO_Speed_50MHz auf
GPIO_Speed_10MHz geändert, und die I2C geschwindigkeit auf 100 kHz
eingestellt.
Hat aber leider nichts gebracht :(
es ist eindeutig der ATXMEGA16 Slave, der die CLK Leitung auf Masse
zieht.
Ich habe das herausgefunden, indem ich einmal nur den Advaark auf dem
I2C bus habe mitlauschen lassen, da wurde SCL nach dem Master senden
nicht auf Masse gezogen.
Gibt es da Erfahrungswerte, hat jemand schon einmal ähnliche Probleme
bei der I2c Kommunikation zwischen einem ATXMEGA und einem Cortex
gehabt?
Sylvia H. schrieb:> Daher habe ich mal die Pingeschwindigkeit von GPIO_Speed_50MHz auf> GPIO_Speed_10MHz geändert
Das verändert nur die Stärke der Ausgangstreiber und damit die
Flankensteilheit. Für I2C sollte das langsamste eingestellt werden.
Grüße
Sven
Ok, hab noch mal in meinem Code gestöbert. Das bisher war leicht
verfälscht aus dem Gedächnis. Die bei mir implementierten Reihenfolge
ist:
-1- I2C Takt einschalten, dies muss vor den Pins kommen.
-2- Pins konfigurieren
-3- I2C konfigurieren.
I2C Reset ist bei mir nur als Software-Reset über CR1 drin.
die Initialisierungsreihenfolge ist egal, das Problem bleibt jedes Mal
das gleiche. Da auf dieser Seite keine Antwort mehr kam, habe ich das
problem auf einer neuen Seite noch mal mit OSZI Bildern geschildert:
Cortex I2C zu kurze Impulsdauer
bitte A.K. schau doch dort mal vorbei, du hast doch immer so gute Ideen
:)
Wenn Du einen uC als Slave hast, dann kannst Du damit rechnen, dass er
das Clockstretching bei Uebertragungsraten von 100kHz oder mehr benutzt.
Setzt Deinen I2C Clock mal spasseshalber auf 1kHz und schau was
passiert.
Thomas schrieb:> Setzt Deinen I2C Clock mal spasseshalber auf 1kHz und schau was> passiert.
der Cortex macht irgendwie nichts langsameres als 10 khz, auch wenn ich
ihn 1kHz initialisiere, sendet er mit 10 Khz. seltsam....
Aber am Problem ändert sich auch nichts, der ATXMEGA zieht trotzdem SCL
auf Masse
A. K. schrieb:> Sämtliche Errata-Sheets schon durchforstet?
jop, da findet man nur Erratas bezügl. der Empfangsfunktion und einer
repeated Start condition, aber nichts, was man machen kann, wenn das
Partnerboard aus der Kommunikation aussteigt...
Das Problem liegt meiner Meinung nach darin, das der Cortex eine zu
kurze Startbedingung sendet:
Während der ATXMEGA seine Startbedinugn 6us auf dem Bus stehen hat,
liefert der Cortex nur 840 ns lang ein Startsignal.
Ausserdem steht zwischen den einzelnen Bytes SDL beim Cortex auch zu
kurz an. (nur 440 ns, während der ATXMEGA 7,8us SDL auf High hält.
Wie kann ich den Cortex dazu bewegen, die Startbedinung länger zu
senden, und SDL länger auf High zu halten?
Ich habe es schon mit einem delay nach dem senden der Startbedinung und
vor dem senden der Slaveadresse versucht, aber das nützt nichts. Da wird
nur etwas später die Adresse versendet, aber die Startbedingung bleibt
so kurz.
Hat jemand eine Idee?
I2C Spec. 2.1 verlangt für SDL=>SCL in der Start Condition bei 400KHz
für t(HD,STA) mindestens 600ns. Wenn das diese 440ns sind, dann ist das
offiziell etwas zu wenig. Auf dem Bild ist dies jedoch nicht eindeutig
erkennbar. Dass der AVRX scheint sich hier an die 4µs des 100KHz Betrieb
zu halten.
Im oben gezeigte Code wird der Standard-Mode (<= 100KHz) spezifiziert:
I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;
Die Screenshots sind aber von 400KHz. Welcher Code passt zu den Bildern?
es ist auf jeden fall ein 400 kHz Modus erwünscht, die Bilder zeigen
diesen Mode auch
A. K. schrieb:> Im oben gezeigte Code wird der Standard-Mode (<= 100KHz) spezifiziert:> I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
ist das nicht die Einstellung für 400 Khz? Ansonsten gibt es doch nur
noch die Einstellung für den SMBus mit seinen 100 kHz....
A. K. schrieb:> I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;
dies sagt, dass das Verhältnis von Impulsdauer/Impulspause des SCK
Signales 1/2 sei soll, ansosnten gibt es nur noch die Einstellung 9/16,
aber das bezieht sich doch auch alles auf den 400kHz fast Mode?
Sylvia H. schrieb:>> Im oben gezeigte Code wird der Standard-Mode (<= 100KHz) spezifiziert:>> I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;>> ist das nicht die Einstellung für 400 Khz? Ansonsten gibt es doch nur> noch die Einstellung für den SMBus mit seinen 100 kHz....
Die Lib ist nicht mein Fall, aber ich könnte mir vorstellen, dass sich
dies in Bit 15 vom CCR übersetzt, das zusammen mit Bit 14 zwischen
Standard (100Khz) und Fast Mode (400KHz) differenziert.
Bit 15 F/S: I2C master mode selection
0: Standard Mode I2C
1: Fast Mode I2C
I2C jedenfalls kennt diese Modi:
Standard Mode 100 kHz
Fast Mode 400 kHz
Fast Mode Plus 1 MHz
High Speed Mode 3,4 MHz
A. K. schrieb:> I2C Spec. 2.1 verlangt für SDL=>SCL in der Start Condition bei 400KHz> für t(HD,STA) mindestens 600ns.
woher hast du diese Info? Ich finde in der I2C Spec 2.1 von Phillips
Semiconductors auf den Tabellen S.31ff nur Informationen über die
minimale Länge einer repeated start condition....
Sylvia H. schrieb:> woher hast du diese Info? Ich finde in der I2C Spec 2.1 von Phillips> Semiconductors auf den Tabellen S.31ff nur Informationen über die> minimale Länge einer repeated start condition....
Kreative Interpretation. Das "(repeated)" in Klammern habe ich so
verstanden, dass dieser Wert sowohl für die Start Condition als auch für
die Repeated Start Condition gilt.
PS: Ich bin kein Freund der Lib und habe oft keine Doku davon parat. Was
immer die tut - der Controller interessiert sich einen Dreck für die
Lib, der kümmert sich nur um seine Steuerregister und nur die sind in
dessen Doku aufgeführt.
Wenn man solche Problem hat, dann sollte man immer einen Blick auf die
Register werfen und deren Inhalt mit der Controller-Referenz überprüfen.
ok, neuer Versuch:
nachdem ich festgestellt habe, das sich der Cortex laut I2C
Spezifikation normgerecht verhält, und ich der Meinung bin, wenn alles
normgerecht ist, dann sollte doch auch ein ATXMEGA der Cortex
verstehen.....
habe ich einen neuen Test gestartet:
Zwei Cortexe bekommen fast das gleiche Programm. Sie werden so
programmiert, das sie beim Einschalten ein paar byte Infos auf den I2c
bus werfen, und danach einer alle 2s, un der andere alle 5s ein paar
bytes auf den General Call bus legen.
Meine Beobachtung:
Ein Board alleine hat keine Probleme seine Daten zu senden. Stecke ich
das andere Board an den Bus gibt es entweder eine totenstille mit SDA
und SCL beide auf High, und manchmal eine totenstille mit SDA auf High
und SCL auf Low. Welche beide Möglichkeiten auftreten ist
zufallsbedingt.
Ziehe ich dann wieder ein Board ab, sendet das andere Board entweder
gleich wieder seine Daten, oder muss kurz resetet werden, und wirft dann
wieder alle gewünschten bytes auf den Bus.
Nun meine Frage:
kann es sein, das der Cortex nicht mit Multimaster zurechtkommt? Laut
Datenblatt müsste er es eigentlich können....
ich korrigire:
wenn ein zweites Board an den Bus angeschlossen wird ist totenstille,
wird es wieder abgezogen, muss das verbleibende Board auf jeden Fall
resettet werden, damit es wieder annfängt zu senden
Ich habe das grad nicht genau drauf, aber heisst Multimaster mit general
call nicht auch, dass jeder Master auch als Slave reagieren muss?
Jedenfalls wäre hier wohl interessant, in welchen Zustand im Falle eines
Falles nicht nur der Bus ist, sondern insbesondere auch die beteiligten
I2C-Controller.
Auf welche Adressen reagiert dein Code denn? Wenn die I2C-Unit einer
Node sich als Slave angesprochen fühlt, egal ob per GC oder explizit
adressiert, und ihre Software darauf nicht passend reagiert, dann
landest du beim STM32 per default im clock stretching und bleibst darin
hängen, weil die Hardware darauf wartet, dass die Software entsprechend
reagiert.
Wenn diese Software nicht per Interrupt arbeitet, dann könnte eine
Kollision zwischen dem Sendeversuch als Master und einer zeitlich
passend einlaufenden start condition einer anderen Node leicht einen
deadlock hervorrufen.
Auch hier ist es wichtig, zu erfahren welcher Zustand beiderseits
vorliegt, in dem Fall auch der Zustand der Software. Allein über die
beiden Busleitungen wirst du das nicht erfahren.
A. K. schrieb:> Ich habe das grad nicht genau drauf, aber heisst Multimaster mit general> call nicht auch, dass jeder Master auch als Slave reagieren muss?
jop, so ist es
A. K. schrieb:> Auf welche Adressen reagiert dein Code denn? Wenn die I2C-Unit einer> Node sich als Slave angesprochen fühlt, egal ob per GC oder explizit> adressiert, und ihre software state machine darauf nicht reagiert, dann> landest du beim STM32 per default im clock stretching und bleibst darin> hängen, weil die Hardware darauf wartet, dass die Software entsprechend> reagiert.
Meine Boards haben das eine die Adresse 0xa1 und das andere 0xa2. Aber
die werden nicht angesprochen, die ganze Kommunikation muss über den
General Call 0x00 laufen.
Was eine software state machine ist kann ich mir im Moment nicht
vorstellen, hab den ganzen Tag angestrengt nachgedacht und gearbeitet,
die Luft ist raus.......
Aber morgen früh bin ich wieder voll da!!!!
A. K. schrieb:> Wenn diese state machine nicht per Interrupt arbeitet, dann könnte eine> Kollision zwischen dem Sendeversuch als Master und einer zeitlich> passend einlaufenden start condition einer anderen Node einen deadlock> hervorrufen.
noch ne NVIC zum programmieren? was anderes als
1
NVIC_SetPriority(I2C1_EV_IRQn,0x00);
2
NVIC_EnableIRQ(I2C1_EV_IRQn);
3
4
NVIC_SetPriority(I2C1_ER_IRQn,0x01);
5
NVIC_EnableIRQ(I2C1_ER_IRQn);
6
7
NVIC_SetPriority(I2C2_EV_IRQn,0x02);
8
NVIC_EnableIRQ(I2C2_EV_IRQn);
9
10
NVIC_SetPriority(I2C2_ER_IRQn,0x03);
11
NVIC_EnableIRQ(I2C2_ER_IRQn);
Wahrscheinlich hängen die Problem irgendwie mit diesem General Call
zusammen.....
Sylvia H. schrieb:> Wahrscheinlich hängen die Problem irgendwie mit diesem General Call> zusammen.....
Nur ist der eigentlich ab Reset abgeschaltet und die Nodes müssten es
ignorieren, es sei denn du (oder die Lib) schaltet es irgendwo ein.
Den Begriff software state machine hatte ich nicht sehr glücklich
gewählt und auch korrigiert, weils eher eine hardware state machine mit
softwareseitiger Reaktion darauf ist.
Jedenfalls gerät es angesichts des homöopathisch dosierten Codes oben
zum Kaffeesatzlesen. Du solltest jetzt mal die Möglichkeit schaffen,
heraus zu bekommen, in welchem Zustand sich die I2C-Units und deine
Software zum Zeitpunkt der Hänger befinden. Sowas ist zentraler Punkt
beim Debugging.
Sylvia H. schrieb:> Meine Boards haben das eine die Adresse 0xa1 und das andere 0xa2.
Ich lese nur interessiert mit: sind Deine Adressen richtig gewählt? 0xa1
ist nicht in Ordnung, da das Bit0 das RW-Signal widerspiegelt.
Sylvia H. schrieb:> ATXMEGA hat ein kurzes Erratasheet, da steht nur " no known errata"> drinn.....
Alles muss man selber machen. Hätte mich auch gewundert - so simpel sind
die Xmegas denn doch nicht, als dass man das bugfrei zustande bekäme:
Das Datasheet vom erwähnten ATXMEGA16D4 in der Version 12/10 erwähnt 28,
und allein 5 davon betreffen das TWI.
A. K. schrieb:> Das Datasheet vom erwähnten ATXMEGA16D4 in der Version 12/10 erwähnt 28,> und allein 5 davon betreffen das TWI.
Sorry, ich hatte wohl vergessen zu erwähnen, das es ein ATXMEGA16A4 ist,
dort steht nichts im Errata....
A. K. schrieb:> Nur ist der eigentlich ab Reset abgeschaltet und die Nodes müssten es> ignorieren, es sei denn du (oder die Lib) schaltet es irgendwo ein.
Ich schalte den General Call bei der Initialisierung ein.
A. K. schrieb:> Jedenfalls gerät es angesichts des homöopathisch dosierten Codes oben> zum Kaffeesatzlesen.
Ich benutze die Angehängte Lib, der Rest ist ein wüster Code, da ich
Libs von Kollegen, die den Code für ATXMEGA geschrieben hatten in
Cortexsprache umsetzen musste....
Ich rufe in meiner main zuerst die Methode TWI_Init() twi_bus.c auf,
dort befinden sich auch die IRQ Händler.
Danach wird die TWI_Main() Methode aus twi_main.c aufgerufen, dort wird
ein Timer initialisiert, und eigendlich wird hier auch eine dynamische
Adressvergabe gestartet, wenns dann endlich mal geht.....
danach wird in der Main mit
nochmal ein paar bytes auf per General Call auf den Bus geschickt
(TWI_Send() steht in twi_bus.c
Das wars, jetzt kommt die endlos while(1){} Schleife, ab hier wird nur
noch per Timer Interrupt jede 1,8s etwas an die Adresse 0x00 gesendet.
Ich weis, der Code ist chaotisch und absolut nicht sortiert, geschweige
denn gekapselt. (deshalb habe ich bisher nur Auszüge gepostet, weil das
extrem peinlich für mich ist)
Aber das ist nicht mein Werk, so würde ich nie einen Code schreiben. Ich
muss mit dem Code eines Kollegen zurechtkommen. Wenn alles ordentlich
funktioniert, werde ich als aller erstes mal den Code in einen logischen
Zusammenhang bringen.
A. K. schrieb:> Du solltest jetzt mal die Möglichkeit schaffen,> heraus zu bekommen, in welchem Zustand sich die I2C-Units und deine> Software zum Zeitpunkt der Hänger befinden. Sowas ist zentraler Punkt> beim Debugging.
Bisher ist das Programm immer mal wieder beim Senden an der Stelle
hängen geblieben, wo auf das Event 8_2, also das ACK des Slave auf ein
Datum gewartet wird.
Meistens aber hängt das Programm dann in der while(1) Schleife, ohne
irgendwelche Reaktionen zu zeigen. Es geht dann noch nicht einmal mehr
in den Timer Interupt. Es hängt sich so gesehen einfach alles auf.....
Willi schrieb:> Ich lese nur interessiert mit: sind Deine Adressen richtig gewählt? 0xa1> ist nicht in Ordnung, da das Bit0 das RW-Signal widerspiegelt.
Das habe ich noch nicht berücksichtigt, muss das Thema mal nachlesen....
Sylvia H. schrieb:> Ich benutze die Angehängte Lib, der Rest ist ein wüster Code, da ich> Libs von Kollegen, die den Code für ATXMEGA geschrieben hatten in> Cortexsprache umsetzen musste....
Mein Beileid für jeden, der diesen Code lesen muss.
Aber eines sehe ich trotzdem, nicht zuletzt weil ich das oben ja schon
ähnlich befürchtet hatte: Der Code geht offenbar davon aus, dass er nur
als I2C-Master verwendet wird. Wenn aber eine Node zusätzlich als Slave
genutzt wird, sei es weil sie direkt adressiert wird, sei es weil sie
auf GCs reagiert, dann muss das in der Software auch vorgesehen werden.
Dieser Code ist in einer Multimaster-Situation also nur einsetzbar, wenn
grantiert werden kann, dass ein solcher Master nie als Slave
angesprochen wird.
Sylvia H. schrieb:> Bisher ist das Programm immer mal wieder beim Senden an der Stelle> hängen geblieben, wo auf das Event 8_2, also das ACK des Slave auf ein> Datum gewartet wird.
Ich werde es jetzt noch ein einziges Mal versuchen, dann ist Schluss:
In welchem Zustand sind die I2C-Units wenn es hängt? Was du dazu
benötigst ist zum gegebenen Zeitpunkt ein Register-Dump der I2C-Units.
Obacht aber bei Registern, die beim Auslesen was auslösen.
Ebenso ist ein Trace der Statusregister der I2C-Units nützlich. Und wenn
du diese Rohdaten hast, dann dekodierst du sie anhand der Reference und
dann kannst nachvollziehen, was da abgeht und wo es schlussendlich
hängt.
Das bedeutet natürlich auch, dass du Information aus dem Int Handler
benötigst, denn da fällt das ja an. Lass dir was einfallen, wie du da
rankommst.
A. K. schrieb:> Mein Beileid für jeden, der diesen Code lesen muss.
ich weis, ich weis, ist mir auch peinlich genug......
A. K. schrieb:> Aber eines sehe ich trotzdem, nicht zuletzt weil ich das oben ja schon> ähnlich befürchtet hatte: Der Code geht offenbar davon aus, dass er nur> als I2C-Master verwendet wird. Wenn aber eine Node zusätzlich als Slave> genutzt wird, sei es weil sie direkt adressiert wird, sei es weil sie> auf GCs reagiert, dann muss das in der Software auch vorgesehen werden.
Beim Cortex ist es so, dass im default Zustand der Slave Mode
eingeschaltet ist. Möchte man als Master etwas machen, sendet man eine
START condition, und danach ob man Master-Transmitter oder
Master-Receiver sein möchte. Nach der Aktion schaltet das Interfache
automatisch wieder in den Slave Mode.
Das heist, das man den Cortex weder als Master noch als Slave
initialisiert, wie beim ATXMEGA oder bei all den anderen Controllern so
üblich, sondern nur die standart Initialisierung braucht (Welcher TWI
Kanal, welche TWI Geschwindigkeit, welche Adresse als Slave usw)
Der Rest wird von den Interruptroutinen erledigt.
Meine Slave Interruptroutine schreibt z.B. alle Bytes die Empfangen
werden in den twi_buf[]. Dieser kann dann ausgewertet werden. Somit ist
gewährleistet, das der Cortex, wenn er im Multi-Master Mode die Slave
Rolle annimmt, auch mitbekommt, was auf dem Bus los ist.
Aber moment mal:
ist man als Empfänger im Multi-Master Mode eigentlich ein Slave-Receiver
oder ein Master-Receiver?
Normalerweise müsste man doch dann ein Slave-Receiver sein, da ja der
andere die Master Rolle übernommen hat, und etwas aktiv auf den Bus
schickt....
Sylvia H. schrieb:> ist man als Empfänger im Multi-Master Mode eigentlich ein Slave-Receiver> oder ein Master-Receiver?
Wenn von einer anderen Node angesprochen, dann Slave. Ob Receiver oder
nicht hängt von der Adresse ab, von Bit 0.
In diesem Multimaster müssen also im Handler alle möglichen Zustände
berücksichtigt werden. Nicht bloss die paar, die ich gesehen habe.
Hallo Leute,
hab mich jett auch mal mit meienm STM32 Discovery hingesetzt und
versucht i2c Master mit i2c Slae zu verbinden - beides auf der Platine.
Zumindest der Master-Code funktioniert- hab ich mit einem xMEga als
Slave getestet.
Jetzt hängt aber immer mal meine slave Implementierung. Die Leitungen
werden ziehmlich lange auf Low gezogen.
Eine Frage hab ich (sicher noch weitere): Im Manual steht bei Slave
receiver wenn der eine Stop-Condition bekommt: EV4: STOPF=1, cleared by
reading SR1 register followed by writing to the CR1 register
Aber was soll man denn ins Command register schreiben ohne irgend
welchen Unsinn zu machen?
Habt ihr eine Master / Slave Bibliothek, die Ihr benutzt?
Die CMSIS Library ist ja wohl mit den Aufrufen standardisiert aber wohl
nicht z.B in den Event Flags von I2C_GetLastEvent.
Danke schon mal.
Adib.
der Adib schrieb:> Habt ihr eine Master / Slave Bibliothek, die Ihr benutzt?
Die Angehängten Dateien stammen von STM "optimizedI2CExamples" Projekt,
diese habe ich benutzt.
Aber ob sie funktionieren steht in den Sternen, bei mir gibts nur
Probleme....
der Adib schrieb:> Eine Frage hab ich (sicher noch weitere): Im Manual steht bei Slave> receiver wenn der eine Stop-Condition bekommt: EV4: STOPF=1, cleared by> reading SR1 register followed by writing to the CR1 register> Aber was soll man denn ins Command register schreiben ohne irgend> welchen Unsinn zu machen?
das steht in der angehängten stm32f10x_it.c in den Interruptroutinen
A. K. schrieb:> In diesem Multimaster müssen also im Handler alle möglichen Zustände> berücksichtigt werden. Nicht bloss die paar, die ich gesehen habe.
Meiner Meinung nach wurde in den Interruptroutinen alle Fälle
berücksichtigt:
Master- und Slave-Receiver schreiben beide die ankommenden Bytes in
twi_buf[], alle anderen Fälle sind nicht relevant, da ich gepollt auf
den Bus schreiben
A. K. schrieb:> Das bedeutet natürlich auch, dass du Information aus dem Int Handler> benötigst, denn da fällt das ja an. Lass dir was einfallen, wie du da> rankommst.
mach ich.......
Sylvia H. schrieb:> Meiner Meinung nach wurde in den Interruptroutinen alle Fälle> berücksichtigt:
Kann gut sein, dass ich den falschen Handler erwischt habe. Der gestern
gepostetete Code ist ja ein ziemliches Durcheinander an auskommentieren
und teilweise unlesbar formatiertem Code. Da wühl ich mich jetzt nicht
durch.
> alle anderen Fälle sind nicht relevant, da ich gepollt auf> den Bus schreiben
Und genau das kann zum Problem werden, weil Polling eine bestimmte
Abfolge von Ereignissen voraussetzt, die die in einer
Multimaster-Umgebung u.U. nicht gegeben ist.
Ich möchte mit Eqlipse gerne die Register des Cortex auslesen. Dazu gehe
ich in den Debugmodus und sehe die Register r0-r9 wie im Anhang zu
sehen.
Nun weis ich, das die Register Boundary Adress für I2C2 laut Datenblatt
0x4000 5800 - 0x4000 5BFF beträgt.
Die Passenden I2C2 Register liegen dann auf entsprechenden Offsetts
höher.
Doch wie kann ich nun über diese Adressen herausfinden, was Eqlipse mir
mit r0-r9 anzeigt? Nirgendwo finde ich eine Option heraus zu finden, auf
welchen Adressen die Register r0-r9 anfangen.
Weis jemand, wie man die Adressen den Registern zuorden kann?
Ansonsten kann ich nur sehen, das mein cortex wie schon vorher erwähnt,
bei der Abfrage nach Event 8_2 hängen bleibt...
hab was rausgefunden, falls es irgend jemand interessiert:
- In Eqlipse Debug Configurations anklicken
- Im Reiter Debugger das Kästchen Verbose console mode aktivieren
- eine Text Datei erstellen, in der folgendes geschrieben wird:
set $I2C_CR1=(char *)0x40005800
display $I2C_CR1
- Auf diese Datei als GDB command file verweisen
danach erscheint beim Debuggen im Konsolenfenster folgender ausdruck:
~"1: $I2C_CR1 = 0x40005800 \"A\\004\""
1: $I2C_CR1 = 0x40005800 "A\004"~"\n"
So und nun fängt mein Problem an:
wenn ich den Wert "A\004"~"\n" aus dem ASCII Code in Hex Code umwandele,
kommen ziemlich bescheuerte Daten für das Register raus....
Weis jemand, wie man die Zeile
1: $I2C_CR1 = 0x40005800 "A\004"~"\n"
Interpretiert?
Also ich habe zZ eine Atollic Pro Testversion am Start. damit kann man
alle Peripherie register ganz gut sehen.
Es sollte aber auch mit dem Eclipse Plugin: embsysregview funktionieren.
Was für eine Eclipse Version / Plugins verwendest du?
Das ARM-plugin funktioniert ja nicht mit dem neuen 3.7.
Adib.
für die interessieten Mitleser :)
mit der angehängten Textdate als GDB Comand File kann man sich im
Debugmode die Werte seiner Register anzeigen lassen.
Es steht ein dann in der Console der Registerwert in Dezimalform da.
soweit so gut,
nun habe ich alle Registerwerte, die ich im Falle des Aufhängens mir
anschauen konnte.
Noch mal kurz zur Problemstellung:
Mein einzelner Master (A) sendet lustig alle 2s 3 Bytes auf den Bus: F1
30 29
gehen als General Call an die Adresse 0x00 auf die Reise.
Sobald ein anderer Master(B) an den Bus angeschlossen wird, springt
(meistens) SCL auf low und erholt sich nicht mehr. Das „meistens“
bezieht sich darauf, dass wenn der Master B sofort etwas sendet SCL auf
low geht, und wenn nicht, SCL auf High bleibt, aber dann trotzdem tote
Hose auf dem Bus ist
hier nun die Registerwerte meines armen Sende-Masters A:
CR1: 0441 => Periphal enable =1, General Call enable = 1,ACK enable = 1
Alles klar
CR2: 0124 => Interrupt enable = 1, Periphal Frequenz = 36 Mhz
Da im 400 kHz Mode die Periphal Frequenz auf mindestens 4MHz
gestellt werden soll => Alles klar
OAR1: 4030 => Adressmode = 0 (=7 Bit Adresse), Adrese = 30 (hab mich mal
in das Thema Adressen eingelesen, A1 ist Quatsch…..)
Alles klar
OAR2:0, Alles Klar
Nun tauchen 2 Unterschiedliche Hängermöglichkeiten auf:
1. SCL wird nicht auf Low gezogen, aber trotzdem bleibt der Cortex
Hängen
Registeranzeigen:
DR: 41 => Das zweite Byte wurde versucht ins Datenregister zu laden,
danach blieb der Cortex hängen
SR2: 2=> Sr2 sagt, der Bus ist Busy
SR1 bleibt immer 0 das heißt dass TxE auf 0 immer sagt, das Data
Register ist nicht leer, was auch wahr ist.
Wenn ich nun mit dem Debugger weitersteppe lande in meiner Timer
Interruptroutine, aus der ich nicht wieder herauskomme.
2. SCL wird auf Low gezogen
Registeranzeigen:
DR: 255 => Wo kommt auf einmal 0xff her, die Zahl hab ich nie
gesendet????
SR2:18 => General Call received = 1, OK, aber das reservierte Bit 3
sollte eigentlich von der Hardware auf 0 gesetzt sein, ist es aber nicht
Auch hier lande ich beim weitersteppen in der Timer Interruptroutine und
komme nicht wieder heraus
Soweit die Registerwerte…..
Ich stolpere über SR2 im 2. Fall. Warum zieht die Hardware nicht das Bit
3 auf 0?
Könnte das der Grund für die Abstürze sein?
Aber im 1.Fall zeigt SR2 ja nur Busy an, da zieht die Hardware das Bit 3
ja auch auf 0……
Seltsam,seltsam……
noch etwas:
nach dem Register CR2 ist nur das Error Interrupt enable Bit aktiviert.
Ich habe den Master ein Nachricht per Polling schicken lassen, dabei ist
er ja hängengeblieben.
nach dem Verlust einer Arbitration schaltet die Hardware den CORTEX ja
automatisch in den Slave-modus um. Müsste dann aber nicht auch das Event
Interrupt Bit gesetzt sein?
ich dacht immer, wenn ich die NVIC so schreibe:
Hi Leute,
nachdem ich tagelange Tests durchgeführt, ungefähr 1000000 mal alle
Register des Cortex kontrolliert, die I2C Spezifikation und das Cortex
Datasheet (sammt Errata) auswendig kann ;=) ....
Hier die Lösung des Problemes:
Die Von STM bereitgestellte Library für "Optimized I2C Exmples" (an2824)
weist folgende ausschlaggebende Fehler auf:
I2C2_ER_IRQHandler :
- Es fehlte die Behandlung folgender Error-Flags:
PECERR,TIMEOUT,SMBALERT
- ARLO: Das Flag wurde zum Zurücksetzen mit einer falschen Maske
verundet
- BERR: obwohl im Errata steht, es müsste nur in einer „noisy
environment“ folgendes programmiert werden, hat es sich herausgestellt,
dass man dies auch in einer ganz normalen Umgebung machen muss:
(übrigens, das Errata hat hier auch einen Fehler, man bräuchte wohl auch
noch ein Errata zum Errata…..)
Wenn ein BERR auftritt, und das START Bit ist gesetzt, muss I2C resettet
werden indem man in CR1 das SWRST Bit setzt. Aber Achtung, nicht
vergessen I2C2 danach wieder zu Initialisieren! Sonst läuft I2C2 weiter,
hat aber alle Register auf den Wert 0 gesetzt!!!!
Danach noch E2C Event Interrupts einschalten, und alles ist wieder ok:
1
/* If BERR = 1 */
2
if((SR1Register&0x0100)==0x0100){
3
4
I2C2->SR1&=0xFEFF;
5
6
if((I2C2->CR1&0x0100)==0x0100){//is START bit set?
7
/* Peripheral under reset */
8
I2C2->CR1|=CR1_SWRST_Set;//Errata S. 25
9
I2C_LowLevelInit(I2C2);
10
/* Enable the selected I2C interrupts */
11
I2C2->CR2|=I2C_IT_EVT;
12
}
13
14
SR1Register=0;
15
}
I2C_Master_BufferWrite:
Wenn der Master etwas auf den Bus schreiben möchte und die
Startbedingung gesetzt hat, dann wartet er auf Event 5.
Sollte in dieser Wartezeit ein BERR auftreten, wartet er endlos, deshalb
muss ein Timeout gesetzt werden. Kommt er in den Timeout, muss man hier
auch wieder I2C2 reseten, neu Initialisieren und den Event Interrupt
einschalten, genauso wie oben in der BERR = 1 Routine.
Dies sind die Fehler, die ich in der Firmaware gefunden habe. Was lerne
wir daraus? Mann kann echt auf nichts mehr verlassen, noch nicht mal auf
den Hersteller.....
Des Weiteren ist ein 10 kOhm pullup Widerstand wesentlich zu hoch.
Nun läufts auf dem I2C2 Bus !
Grüße von
Sylvia
Ich habe zwei Boards die miteiander über I2C Kommunizieren müssen:
Ein Board hat einen ATXMEGA16D4 drauf, an dem kann ich nichts ändern.
Das Andere läuft mit einem Cortex Stm32f103, den habe ich mit den
geposteten Libs programmiert.
Hallo leo,
Beide sind Master. Der ATXMEGA sendet all 10 sekunden ein 16 Byte
grosses Datenpaket auf den Bus, welches der CORTEX per Interrupt
empfangen, auswerten und weiterverarbeitet muss. Gleichzeitig soll es
aber auch möglich sein, das der CORTEX dem ATXMEGA von sich aus ein
Datenpaket zuschickt. Daher das Multimaster-System.
Hallo Sylvia,
warum die XMEGA-Applikation separat?
Warum nicht die XMEGA-Applikation auch auf einem ARM?
Oder umgekehrt: Warum nicht die ARM-Applikation auf auch auf einem
ATXMEGA?
Vielen Dank und Gruß
Leo
Hallo leo,
Das ist meine Bachelorarbeit:
Ein Rauchmeldermodul sendet alle 10 sekunden Daten auf den I2C Bus.
Dieses Rauchmeldermodul ist bereits entwickelt und schon fest
vorgegeben.
Ein von mir zu entwickelndes Modul soll diese Daten aufnehmen, und über
Ethernet an einen Rechner zur weiteren Auswertung schicken.
Der Cortex arbeitet auf meinem Ethernet-Modul. Dieses Modul soll auch in
der Lage sein, SPI und CAN Nachrichten ins Ethernet zu pusten. Des
Weiteren braucht der Steuerungscontroller 2 x I2C Schnittstellen
(Firmeninterne Gründe).
Daher der große Cortex für die Ansteuerung eines kleinen
Ethernet-Controller.
Beide Module müssen in ein 19 Zoll Gehäuse eingpasst werden, und auch
unabhängig voneinander arbeiten können. Daher müssen beide Aplikationen
auf getrennten Boards laufen.
Gruß
Sylvia