Forum: Mikrocontroller und Digitale Elektronik AVR TWI I²C MultiMaster Problem


von Martin (Gast)


Lesenswert?

Hallo zusammen,

ich versuche schon seit einiger Zeit das mit dem MultiMaster 
hinzubekommen. Ich nutze Teile aus der Fleury-Biblothek und den Org-Bib. 
von AVR. Das senden zwischen Master und Slave klappt, aber ich habe 
Probleme zwischen Master und Slave umzuschalten. Soll bedeuten 
IC1=Master IC2=Slave funzt, IC2=Master IC1=Slave funzt auch(Nach einem 
Reset).
Egal welcher AVR zuerst Master ist, wenn der Slave zum Master werden 
soll bzw umgekehrt der Master zum Slave, tritt ein Bus-Fehler auf(Der 
Master(der vorher Slave war) sendet das Start-Signal, sonst tut sich 
jedoch auf dem Bus garnichts).
Ich habe das schon mit dem Dragon getestet, komme aber trotzdem nicht 
weiter.
Ich nutze nur die Modis MasterTransmitter und SlaveReceiver, 
MasterReceiver und SlaveTransmitter ist noch nicht implementiert, wäre 
aber net, wenn das schon jemand hätte.

Wo das Prob genau liegt, kann ich in meiner recht einfachen Umgebung 
nicht testen, da müsste ich wohl mal 3 Avr ranhängen. Es scheint jedoch 
(sehr wahrscheinlich, da der Master nach dem StartSignal hängen bleibt) 
daran zu liegen, das der vorher adressierte Slave, der ja dann Master 
werden soll, damit nicht klarkommt.

Wenn der Dragon drann ist, dann funzt es manchmal, ich vermute dass dann 
wenn die Zeit zu kurz ist die Umschaltung von Slave auf Master nicht 
funzt, und wenn das ganze zu lange dauert eben ein TimeOut auftritt. 
Wenn das ganze dazwischen liegt dann gehts eben abundzu mal ;-(((

Ich habe auch schon versucht mit Warteschleifen zu arbeiten, und nach 
einem Slave-Modus den Tranceiver abzuschalten, aber auch das funzt net.

Am einfachsten wäre es wenn jemand sowas schon mal gemacht hat. (Hab 
schon gegoogelt wie verrückt, finde aber nix :-)))), außer Atmel-Org und 
Fleury

Ansonsten für alle Ideen offen,


CU

Martin

von Peter D. (peda)


Lesenswert?

Ohne Deinen Quelltext und den Quelltext der Bibliothek ist das Stochern 
im Nebel.


Wenn die Bibliothek nicht ausdrücklich für Multimasterbetrieb 
spezifiziert ist, dann ist sie nutzlos.
Dann mußt Du I2C selber programmieren.

Es ist ohnehin zu empfehlen, die I2C-Spezifikation zu verstehen, ehe man 
sowas komplexes macht. Sonst kann es nur in die Hose gehen.

Z.B. wenn ein Start nicht gesendet werden kann, liegt das daran, daß 
vorher kein Stop auf dem Bus erkannt wurde.

Auch kann man nicht zwischen Master und Slave umschalten, man ist immer 
beides gleichzeitig.

Eine explizite Umschaltung erfolgt nur dann, wenn einer die Arbitration 
verliert.


Peter

von Martin (Gast)


Lesenswert?

Hallo Peter,


ich versuch das mal....

Jeder AVR ist Standardmässig im SlaveBetrieb. SlaveBetrieb bedeutet TWI 
enabled und TWEA(TW enable ACK). TWEA und TWINT sind nat. auch noch 
gesetzt. Da Unbhängig von Slave und Master der Zustand  des TWSR(TW 
StatusRegister) gleich ist, nutze ich wie bei Atmel eine Variable um den 
Zustand des AVR zu ermitteln

i2c_mode == i2c_slave
i2c_mode == i2c_master
i2c_mode == i2c_none

Wie gesagt, jeder AVR ist Standardmässig im SlaveBetrieb. Wenn jetzt ein 
AVR über den BUS was mitzuteilen hat, wechselt er einfach in den 
Master-Betrieb.
Soll heissen,

i2c_mode == i2c_master,

TWEA=0 ; kein ACK

und dann eben

TWSTA=1; StartCond senden.

Das ganze funzt auch ganz gut, soll heissen, der AVR ist im 
Slave-Betrieb, wenn er was melden soll, dann geht er eben in den 
MasterBetrieb (wie oben beschrieben), sendet über den BUS und geht 
wieder in den Slave-Betrieb. Mehrfaches senden, also wechseln funzt 
auch. Das Prob besteht eben dann, sobald ein AVR einmal als Slave 
addressiert wurde, dann kann er anscheinend nicht mehr zum Master 
umschalten und läuft auf einen BUS-Error.


Ich habe mal die Org-Datei von Atmel angehängt, in der header-Datei 
steht weiter nix besonderes drin.

Vielleicht kennt ja auch jemand einen Artikel darüber, ich habe jedoch 
nix brauchbares gefunden.

CU

Martin

von Peter D. (peda)


Lesenswert?

Martin wrote:

> i2c_mode == i2c_slave
> i2c_mode == i2c_master
> i2c_mode == i2c_none

Und wozu soll das nütze sein ?

Was ist "i2c_mode" ?


> TWEA=0 ; kein ACK

Das sollte man nur machen als Master-Receiver beim letzten Byte, sonst 
nie.

Kann gut sein, daß sich das TWI total verschluckt, wenn Dich gerade ein 
anderer Master adressiert und Du ziehst ihm das ACK weg.


> TWSTA=1; StartCond senden.

Das ist genau das einzige, was Du machen mußt, um Master zu werden und 
nichts weiter.


> Ich habe mal die Org-Datei von Atmel angehängt, in der header-Datei
> steht weiter nix besonderes drin.

Wo ?

Peter

von Martin (Gast)


Angehängte Dateien:

Lesenswert?

Hallo Peter,

das mit dem anhängen hat wohl wegen der vorschau net gefunzt, probiere 
es etz nochmal :-)))

Ich habe das mit dem Mode nochmal geprüft, und es macht anscheinend 
tatsächlich keinen Sinn, da die Codes nur bei MT und MR bzw. ST und SR 
gleich sind. Keine Ahnung warum Atmel das gemacht hat. Ich werfe das mal 
raus!

Aber um auf Deine Frage zurückzukommen, Atmel nutzt den i2c_mode um 
feststustellen ob der AVR im Master- oder Slave- Mode ist.

Was ich nicht so ganz verstehe, ist die Sache mit dem Ack.
Ich nutze, um das ganze vorerst mal nicht zu kompliziert zu machen, und 
mir nicht noch mehr Fehlerquellen einzubauen, lediglich MT und SR Modes.

Wenn der AVR im Master-Modus ist, darf er kein ACK geben, also sollte 
man das meiner Meinung nach abschalten. Wenn der AVR Slave ist, aber 
nicht adressiert ist, dann kann meiner Meinung nach das ACK an sein, das 
TWI dürfte aber trotzdem kein ACK geben, weil der SLave ja nicht 
adressiert ist.

Wenn nun der Slave addressiert ist, dann muss er ja ACK geben damit der 
MT weiss, das der Slave adressiert wurde.

Ein Zustand das 2 Master sind (gleichzeitig) dürfte ja nicht auftreten 
da ja laut Protokoll nur 1 Master zur gleichen Zeit zulässig ist.

Wenn 2 ICs versuchen Master zu werden, kommt ja ARB Lost zum tragen.

Wie dem auch sei, ich hänge etz nochmal die I2C.c Datei an, dann kannst 
Du Dir das mal anschauen.


CU

Martin

von Martin (Gast)


Lesenswert?

Das TWI benötigt ne gewisse Zeit um die Stop-Condition durchzubekommen.

Man kann also die Atmel-Bibi verwenden und muss lediglich

while(TWCR & (1<<TWSTO));

einfügen, nachdem Stop gesendet wurde!!

Cu

Martin





Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.