Hallo zusammen,
ich habe mich in den letzten Wochen mit dem MSP430G2553 Launchpad
vertraut gemacht und mich nun an I2C herangetastet. Dazu verwende ich
zunächst TI Beispiele und spreche einen Sensor über I2C an.
Das funktioniert.
Aber, der MSP430 hängt sich willkürlich auf und beim Debuggen ist mir
aufgefallen, dass er sich an folgender Stelle aufhängt, bzw. stehen
bleibt.
1
while(UCB0CTL1&UCTXSTP);// Ensure stop condition got sent
Ist das Problem anderen MSP430 Usern auch schon aufgefallen?
Beste Grüße,
Greenhorn
Greenhorn schrieb:> Hallo zusammen,>> ich habe mich in den letzten Wochen mit dem MSP430G2553 Launchpad> vertraut gemacht und mich nun an I2C herangetastet. Dazu verwende ich> zunächst TI Beispiele und spreche einen Sensor über I2C an.>> Das funktioniert.>> Aber, der MSP430 hängt sich willkürlich auf ....
Mit welcher Taktfrequenz arbeitest Du am I2C-Bus?
Welche Leitungslänge?
Vielleicht ist Dein Sensor nicht so flot und versucht ein
Clockstreching.
Verringere mal den I2C Takt auf die Hälfte.
mfg klaus
Ohne jetzt die Signale auf deinem I2C Bus auf meinem Scope gesehen zu
haben, vermute ich, daß der Slave SDA oder SCL oder beide auf low hält.
Damit kommt kein gültiges Stop zustande.
Typische Gründe dafür sind nicht sauber zuende geführte Nachrichten:
beim Lesen das letzte Byte nicht mit NACK quitiert oder beim Debuggen
wurde ein Zyklus abgebrochen. Häufig liegt die Ursache eine Weile zurück
und wird nicht erkannt, da das ACK vom Slave nie ausgewertet wird, und
erstmal einen Weile in den klemmenden Bus gesendet wird.
MfG Klaus
Seh gerade, Clockfrequenz runtersetzen. Fehlt noch der Ratschlag mit
kleiner Pullups. Beides kommt immer, hat aber bei 99% der Threads, die
ich in Erinnerung habe, nicht geholfen.
I2C bei MSP430 lasse ich grundsätzlich nach dem start in der main mal
die bits toggeln so 1000mal, ich hab das gefühl die hängen sich manchmal
willkürlich auf und kommen nicht mehr zurück, hatte ich glaube auch so
mal im e2e forum gelesen, bei mir hilft das sehr oft.
Dann ist natürlich wichtig was für einen I2C slave du dran hast und ob
dort alles passt, ob die angesprochenen pullups an SDA und SCL sind und
ich fange immer mit langsamen Taktfrequenzen an, falls ich Probleme
habe, os hab ichs bisher immer irgendwann :) rausfinden können.
Hallo zusammen,
danke für die hilfreichen Tipps. Ich habe eine Lösung gefunden. Nach der
Initialisierung des I2C Moduls habe ich nun ein:
1
__delay_cycles(10000);
eingefügt.
Ich habe in einem anderen Forum gelesen, dass nach der Abarbeitung der
Initialisierungsbefehle das Modul erst noch eine Zeit X benötigt um sich
richtig zu initialisieren, während dessen das Programm aber schon den
nächsten Befehl abarbeitet.
Lange Rede kurzer Sinn, das Problem ist seit dem nicht mehr aufgetaucht.
Zumindest bis jetzt.
Beste Grüße,
Greenhorn
sdg schrieb:> I2C bei MSP430 lasse ich grundsätzlich nach dem start in der main mal> die bits toggeln so 1000mal, ich hab das gefühl die hängen sich manchmal> willkürlich auf und kommen nicht mehr zurück, hatte ich glaube auch so> mal im e2e forum gelesen, bei mir hilft das sehr oft.
Hat mit MSPxx nichts zu tun. 8 mal mit SCL wackeln und dann prüfen, ob
SCL und SDA high sind, ist die gängige Prozedur einen verklemmten I2C
Bus zu reseten.
MfG Klaus
Klaus schrieb:> sdg schrieb:>> I2C bei MSP430 lasse ich grundsätzlich nach dem start in der main mal>> die bits toggeln so 1000mal, ich hab das gefühl die hängen sich manchmal>> willkürlich auf und kommen nicht mehr zurück, hatte ich glaube auch so>> mal im e2e forum gelesen, bei mir hilft das sehr oft.>> Hat mit MSPxx nichts zu tun. 8 mal mit SCL wackeln und dann prüfen, ob> SCL und SDA high sind, ist die gängige Prozedur einen verklemmten I2C> Bus zu reseten.>
Ich muss sagen, das klingt alles nach Voodoo. Ich habe vier I2C-Busse
gesteuert über MSP430F2013 seit über 7 Jahren im Einsatz. So ein
I2C-Slave ist ein ganz blöder Baustein, der wie eine Schaltuhr einer
alten Waschmaschine arbeitet. Dementsprechend arbeiten auch die MSP430
als I2C-Master. Die Signale des Slave werden über Interrupts erkannt und
in einem Register festgehalten, wieder so ähnlich wie bei einer
Schaltuhr einer alten Waschmaschine.
Also, man muss nicht erst "8 mal mit SCL wackeln und dann prüfen, ob SCL
und SDA high sind", sondern ein I2C-Init (Start) und schon geht es los.
So sollte es sein.
Nicht von ungefähr habe ich nach der Taktfrequenz des I2C-Busses
gefragt. Auch nach der Leitungslänge. Der nächste Parameter wäre, sind
mehrere I2C-Clients am Bus? Es geht hier um die Übertragungsparameter
des I2C-Busses für die gewisse Grenzen, in der Hauptsache Leitungs- und
Anschlusskapazitäten, einzuhalten sind. Hierzu siehe die "philips i2c
specification".
http://www.nxp.com/documents/user_manual/UM10204.pdf
....
So, ich habe die aktuelle Spezifikation überflogen und bin auf die
Kapitel "3.1.15 START byte" und "3.1.16 Bus clear" gestossen. In der
Tat wird inzwischen empfohlen einen speziellen Start durchzuführen der
dem "SCL wackeln" nahe kommt.
Ich muss sagen, diesen speziellen Start habe ich bisher noch nicht
benötigt. Dabei arbeite ich mit bis zu 10m I2C-Bus-Länge, aber nur bei
ca. 8 kHz. Am 5V I2C-Bus habe ich 2,2 kOhm Pullups. Es ist auch ein
Unterschied ob man einen PCF8574 oder einen DS1631 ansteuert. Letzterer
ist etwas empfindlich. Einen PCF8574 habe ich mal dagegen über 50m
Telefonleitung 4x0,6mm noch mit 100 kHz ansteuern können und das ohne
Repeater/Hub/Extender.
Ein am I2C-Slave seriell geschalteter Widerstand von ca. 300 Ohm (330
Ohm) am 5V Bus vor dem Clk und DTA Eingang verbessert das
Übertragungsverhalten.
Seite 37:
"Optional series resistors Rs protect the I/O stages of the I2C-bus
devices from high-voltage spikes on the bus lines and minimize ringing
and interference."
Weiteres siehe hierzu auf Seite 58 "7.3 Series protection resistors".
Noch ein Rat, Firmen wie TI wollen natürlich gut dastehen und setzen in
ihren Demos die höchsten Taktraten ein. Wenn es nicht unbedingt sein
muss, gehe mit der Frequenz herunter.
mfg klaus
Überprüfe Deinen Code mal dahingehend ob vielleicht bei irgendeinem
Lesezugriff vor der STOP Condition fälschlicherweise ein ACK gesendet
wird. Dieses ACK (an Stelle eines NACK) hat mich letzte Woche gut 5
Abende meiner Freizeit gekostet.
> So ein I2C-Slave ist ein ganz blöder Baustein, der wie> eine Schaltuhr einer alten Waschmaschine arbeitet.
Das ist nicht immer so. Manche I2C Bausteine machen eher Probleme wie
andere, manche Layouts sind schlechter und manche Umgebungen haben mehr
Störungen. Es ist keine Frage das I2C in 99.9% der Faelle gut
funktioniert, aber nicht in 100%.
Und deshalb ist sowas hier:
> while (UCB0CTL1 & UCTXSTP);
Der ganz grosse Mist! Da gehört immer auch ein Zaehler rein und bei
Ablauf wird der Bus mit Dummytakten resettet und die I2C-Maschine im
Controller neu initialisiert.
Alles andere fuehrt zu diesen Scheissgeraeten wo man alle paar
Monate/Jahre mal den Stecker ziehen muss damit sie wieder laufen.
Olaf
Ein Tip:
Wenn Du eine laufende Kommunikation unkontrolliert unterbrichst (z.B.
durch Reset des µC durch den Debugger), kann es sein, dass der Slave
"hängen bleibt", weil er auf die Beendigung dieser Kommunikation wartet.
Folgendes Szenario hab ich mal erlebt:
1. Power on, µC + Slave okay
2. µC kommuniziert erfolgreich mit Slave
3. Reset an µC, Kommunikation wird mitten in Telegram unterbrochen
4. µC fährt wieder hoch und will mit Slave reden
5. Slave antwortet nicht, weil er noch mitten im alten Telegram steckt
6. Power off/on hilft
Vielleicht hast Du etwas ähnliches?
Klaus Ra. schrieb:> Ich muss sagen, das klingt alles nach Voodoo.Klaus Ra. schrieb:> So ein> I2C-Slave ist ein ganz blöder Baustein, der wie eine Schaltuhr einer> alten Waschmaschine arbeitet.
Und da passt doch alles zusammen. Wenn deine Waschmaschine nicht genug
Takte für die Übertragung eines Bytes zusammenkriegt, steht sie da, hält
SDA low (denn das ist der aktuelle Bitwert) und wartet auf den nächsten
Takt. In dem Zustand kann auf dem Bus weder ein START noch ein STOP
erzeugt werden (SDA ist immer low). Jetzt kann entweder die Waschfrau
den Stecker ziehen oder sie dreht den Programmschalter von Hand auf
"fertig".
MfG Klaus
Klaus schrieb:> Klaus Ra. schrieb:>> Ich muss sagen, das klingt alles nach Voodoo.>> Klaus Ra. schrieb:>> So ein>> I2C-Slave ist ein ganz blöder Baustein, der wie eine Schaltuhr einer>> alten Waschmaschine arbeitet.>> Und da passt doch alles zusammen. Wenn deine Waschmaschine nicht genug> Takte für die Übertragung eines Bytes zusammenkriegt, steht sie da, hält> SDA low (denn das ist der aktuelle Bitwert) und wartet auf den nächsten> Takt. In dem Zustand kann auf dem Bus weder ein START noch ein STOP> erzeugt werden (SDA ist immer low). Jetzt kann entweder die Waschfrau> den Stecker ziehen oder sie dreht den Programmschalter von Hand auf> "fertig".>
Ich hatte mich ja schon selber berichtigt. Die I2C-Spezifikationen sind
wohl wegen noch höherer Taktraten angepasst und erweitert worden. Das
die "I2C-Schaltuhr" auch schon mal stehen bleibt, habe ich bei mir so
gelöst, dass ich für eine I2C-Aktion ein Timeout vorgebe. Letztlich wird
sogar nach einigen Minuten der I2C-Master samt Bus kurz stromlos
gemacht. Ich muss sagen, die reinen I2C-Fehler sind eher sehr, sehr
selten.
Allerdings werde ich meine Protokolle auf reine I2C-Fehler überprüfen
und überlegen ob und wie man auf I2C-Blockaden reagieren kann. Dazu
werde ich mir mal die TI - I2C-LIB für CC6 anschauen.
...
So wie ich das in der Lib-Source sehe haben die da ein
USCI_B_I2C_masterSendSingleByteWithTimeout und auch ein
USCI_B_I2C_masterSendSingleByteWithTimeout, aber keine besondere
Funktion für einen hängenden Slave. Ich werde mir mal die Doku
vornehmen.
mfg klaus.
Klaus Ra. schrieb:> Ich hatte mich ja schon selber berichtigt. Die I2C-Spezifikationen sind> wohl wegen noch höherer Taktraten angepasst und erweitert worden.
Mit der Geschwindigkeit sollte das nichts zu tun haben. Ich denke, daß
selbst ein Uralt-EEPROM ala 24Cxx den Bus verklemmt, wenn man ein Read
in der Mitte abwürgt. Ich kann das aber im Moment nicht überprüfen.
Ich bin zum ersten mal auf einen hängenden Bus gestoßen, als ich das
letzte zu lesende Byte nicht mit NAK quitiert habe. Ist zwar eigentlich
gängig, aber nicht jeder Slave braucht das. Die nächsten Fälle kamen mit
besseren Debuggern. Nicht mehr Print und durchlaufen lassen, sondern:
Breakpoint, Step, achja.., Restart. Trotz init hing dann der Bus. Ein
Power Cycle, d.h. HW-Reset für den Slave, brachte das in Ordnung. Jetzt
mach ich das 8 mal Takt auf SCL als Teil des I2C init, bevor ich den HW
I2C einschalte. Kostet kaum Zeit und funktioniert dann auch beim
Debuggen.
Das kann auch zur Laufzeit helfen. wenn vor dem Anlegen vom Start der
Bus nicht idle ist (Single Master) noch mal init laufen lassen. Klappts
dann noch nicht, ist die HW defekt.
Der Timeout ist IMHO mit dem SMBUS gekommen. Das betrift aber die Slaves
eigentlich nicht. Auf den RAM-Riegeln sind die Standard-24Cxx.
MfG Klaus