LPC2378 sporadisches Problem mit I2C stop

Gast #3477741
Lesenswert?

Hallo Forum,

ich arbeite mit einem LPC2378 und am I2C0 (im master mode) ist ein 
EEPROM angeschlossen.
Sporadisch hat sich mein Programm komplett aufgehängt.
Anhand von Terminalausgaben habe ich die Stelle auf das Senden der Stop 
Condition eingegrenzt.
Dann habe ich in der i2c_stop() Funktion noch ein while() Schleife ohne 
Timeout gefunden.

Nun habe ich einen Timeout in der while() Schleife und bei Ablauf des 
Timeouts wird der I2C Bus neu initialisiert.
Damit scheint es zu laufen.

Ich frage mich aber, warum die Stop Condition manchmal fehlschlägt...
Momentan bombadiere ich den Controller mit Leseanfragen ans EEPROM. Und 
da sehe ich nun ab und zu, dass der Timeout abläuft.
Das Programm läuft aber jetzt weiter.

Beim Schreiben ins EEPROM wird mit der Stop Condition die interne 
Übernahme des EEPROM Buffers getriggert. Ob das jetzt so auch 
funktioniert, habe ich noch nicht getestet.

Ob die Stop Condition richtig auf dem Bus landet konnte ich mangels 
Triggermöglichkeit nicht richtig überprüfen.

Habt ihr eine Idee woran das liegen kann?

Unten meine i2c_stop() mit der besagten while() Schleife.
Das Datenblatt sagt zu STO:
1
STO is the STOP flag. Setting this bit causes the I2C interface to transmit a STOP
2
condition in master mode, or recover from an error condition in slave mode. When STO is
3
1 in master mode, a STOP condition is transmitted on the I2C bus. When the bus detects
4
the STOP condition, STO is cleared automatically.
1
//Send "STOP" condition
2
u08 i2c_stop(void) {
3
  u08 timeout = 40; //typically goes on after 5 loops
4

5
  I2C0CONCLR = SIC;     //  clear SI
6
  I2C0CONSET = STO;     //  set STO
7
  
8
  while(--timeout && (I2C0CONSET&STO)); //  check for STO cleared with timeout
9
  xprintf("i2c_stop(): timeout %d\n" ,timeout); //debug
10
  if (timeout==0) {
11
    i2c0_init();
12
    return 1;
13
  }
14
  return 0;
15
}
Gast #3477875
Lesenswert?

Ich habe mir nun einen Pin als Trigger gesetzt und mit einem 
Logicanalyzer gesehen, dass die Stop Condition nicht auf dem Bus zu 
sehen ist.

Kann es sein, dass diese Befehle zu nah hintereinander stehen?
1
I2C0CONCLR = SIC;     //  clear SI
2
I2C0CONSET = STO;     //  set STO
Gast #3478105
Lesenswert?

Ich habe jetzt die Vermutung, dass die Befehle in anderer Reihenfolge 
kommen müssen.
Zumindest scheint es bisher damit zu funktionieren und so habe ich es in 
anderem Beispielcode gesehen. Aber einen Beleg im Datenblatt habe ich 
nicht gefunden.

Also so:
1
I2C0CONSET = STO;     //  set STO
2
I2C0CONCLR = SIC;     //  clear SI

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