Probleme mit I2C-Verbindung

Hallo,

ich habe ein Problem mit einer I2C-Verbindung. Manchmal funktioniert die =DCbertragung, dann wiederum nicht. Irgendwer zieht die Datenleitung dauerhaft auf Masse, der Sender bekommt dann nat=FCrlich sofort einen Arbitration Loss.

Folgende beide Evaluation Boards von Fujitsu sind miteinander gekoppelt: "Host-Board":

formatting link
(Prozessor:
formatting link
tm )

Grafik-Board:

formatting link

6-lime.html

Auf dem Grafik-Board sitzt wieder ein Video Input Processor der =FCber I2C konfiguriert werden soll. Selbst die Beispielprogramme von Fujitsu funktionieren nur ab und zu.

Kann ich davon ausgehen, dass das Problem hardwaretechnischen Ursprungs ist?

So sieht das aus auf dem Oszi aus, wenn die Datenleitung auf Masse gezogen bleibt:

formatting link

Das Grafikboard l=E4sst sich unabh=E4ngig vom Host-Board resetten, dabei geht die Datenleitung dann wieder auf High. Es steckt kein Schema beim Auftreten des Fehlers dahinter, ich kann vor dem Debugging die Boards resetten -> meistens tritt der Fehler auf, manchmal nicht, ohne Resets dazwischen genau dasselbe...

Vielleicht hat ja jemand von euch einen Rat, was ich noch testen k=F6nnte oder sogar wie ich das Problem beheben k=F6nnte, denn es ist schon nervig wenn man gerade andere Codeteile debuggt und sich dabei jedesmal auf sein Gl=FCck bei diesem Abschnitt verlassen muss.

Reply to
cheyrich
Loading thread data ...

snipped-for-privacy@googlemail.com:

Sieht mir nach fehlerhafter I2C Routine aus:

Wenn der Slave nicht alle Takte für ein Byte bekommt, dann bleibt er eben mal mittendrin mit gezogener Datenleitung stehen. Am Ende zähl ich ich nur 6 Takte sonst sind es 9 dann mal 10, schon seltsam, das sollten doch immer genausoviele Bits sein? Inklusive Start- und Stopbit würde ich da 10 Takte ansetzen. Eventuell wird I2C auch durch einen Interrupt zu lange unterbrochen und irgendwo kommt ein Timeout (normalerweise ist I2C statisch und es gibt keine Timeouts, manchmal wird es aber doch implementiert). Wie ist denn I2C implementiert? Per Bitbang (also die Software wackelt selbst mit den Pins) oder macht das ne Hardware (SIO)?

M.

--
Bitte auf mwnews2@pentax.boerde.de antworten.
Reply to
Matthias Weingart

Hallo Matthias,

softwaretechnisch sieht das ganze so aus, dass ich ein Array habe, in dem sequentiell die Subadressen und Parameter hinterlegt sieht. Der =E4u=DFere Aufbau sieht dann so aus:

for (i=3D0; i < sizeof(videoinput_params); i +=3D 2) { do { i2c_error =3D 0; i2c_error =3D i2c_start(I2C_VIDEOINPUT_ADDR | I2C_WRITE); // Send slave address if( i2c_error =3D=3D 0) { i2c_error =3D i2c_write(videoinput_params[i]); // Send sub address

if( i2c_error =3D=3D 0) { i2c_error =3D i2c_write(videoinput_params[i+1]); // Send value

if( i2c_error =3D=3D 0) { i2c_error =3D i2c_stop(); } } } i2c_error_sum +=3D i2c_error; // DEBUG__ } while(i2c_error !=3D 0); }

Jede einzelne Subadressen/Parameter-Kombination wird also solange wiederholt bis sie fehlerfrei war.

Die Kommunikation =FCbernimmt der im =B5C eingebaute Hardware-Controller. Die Routinen sehen wie folgt aus:

####### INIT void i2c_init(void) { PFR22_D4 =3D 1; // Set port function register for I2C SDA0 PFR22_D5 =3D 1; // Set port function register for I2C SCL0

ICCR0_EN =3D 0; // Disable I2C, clears all flags but BER and BEIE in IBCR0 and IBSR0

#if (I2C_BAUDRATE =3D=3D 400) ICCR0_CS4 =3D 0; // CS4..0 : Set prescaler (~400kbit/s) ICCR0_CS3 =3D 0; ICCR0_CS2 =3D 0; ICCR0_CS1 =3D 1; ICCR0_CS0 =3D 0; ICCR0_NSF =3D 1; // Enable noise filter (should be enabled for

400kbit/s) #elif (I2C_BAUDRATE !=3D 400) ICCR0_CS4 =3D 0; // CS4..0 : Set prescaler (~98kbit/s) ICCR0_CS3 =3D 1; ICCR0_CS2 =3D 1; ICCR0_CS1 =3D 0; ICCR0_CS0 =3D 0; ICCR0_NSF =3D 0; // Disable noise filter (should be enabled for 400kbit/s) #endif // I2C_BAUDRATE

IDAR0 =3D 0; // Clear data register

IBCR0_BER =3D 0; // Clear bus error interrupt flag IBCR0_BEIE =3D 0; // Bus error interrupt disabled IBCR0_ACK =3D 0; // No acknowledge generated IBCR0_GCAA =3D 0; // No general call acknowledge is generated IBCR0_INTE =3D 0; // Disable interrupt IBCR0_INT =3D 0; // Clear transfer interrupt request flag

ICCR0_EN =3D 1; // Enable I2C }

######## Start

UINT8 i2c_start(UINT8 slave_address) { ICCR0_EN =3D 0; // Disable I2C, clears all flags but BER and BEIE in IBCR0 and IBSR0 IBCR0_BER =3D 0; // Clear bus error flag IDAR0 =3D slave_address; // Set slave_address to data register ICCR0_EN =3D 1; // Enable I2C IBCR0_MSS =3D 1; // Sets master mode, generates start condition and begins transfer return i2c_check(); // Check for errors and timeouts }

####### WRITE

UINT8 i2c_write(UINT8 value) { IDAR0 =3D value; // Load data into register

if(IBCR0_MSS !=3D 1) // Check if still master return I2C_ERROR;

IBCR0_INT =3D 0; // Starts next transfer (without start condition) return i2c_check(); // Check for errors and timeouts }

###### STOP

UINT8 i2c_stop(void) {

UINT16 timeout =3D 0;

while (IBCR0_INT =3D=3D 0) // Wait for last transfer finished { CLEAR_WD(); timeout++; if (timeout >=3D I2C_TIMEOUT_VALUE) return I2C_ERROR; }

IBCR0_MSS =3D 0; // Changes to slave mode and generates stop condition

timeout =3D 0; while (IBSR2_BB =3D=3D 1) // Wait until bus is idle (or timeout detected) { CLEAR_WD(); timeout++; if (timeout >=3D I2C_TIMEOUT_VALUE) return I2C_ERROR; }

ICCR0_EN =3D 0; // Disable I2C return I2C_OKAY;

}

######## CHECK

UINT8 i2c_check() { UINT16 timeout =3D 0;

while(IBCR0_INT =3D=3D 0) { // Waiting for answer from slave CLEAR_WD(); timeout++; // Timeout mechanism if (timeout >=3D I2C_TIMEOUT_VALUE) return I2C_ERROR; // Returns error }

if((IBCR0_BER !=3D 0) || (IBSR0_AL !=3D 0) || (IBSR0_LRB !=3D 0)) return I2C_ERROR;

return I2C_OKAY; }

###########################

Was allerdings f=FCr einen Softwarefehler sprechen w=FCrde, w=E4re dass das ganze im Einzelschrittbetrieb funktionst=FCchtig ist. Aber es kann doch nicht sein, dass irgendwer die Datenleitung dauerhaft auf Masse h=E4lt.

Achja der Slave ist ein SAA7113 von Philipps (Datenblatt: http://www.ortodoxism.ro/datasheets/philips/SAA7113H_1.pdf )

Danke schonmal, sollte ich derweil was neues herausfinden, schreib ich hier den aktuellen Stand hin

Achja hier ist noch ein Screenshot von einem funktionierenden Sendezyklus von Adresse/Subadresse/Parameter (wegen deiner 9/10 Taktfrage?!):

formatting link

Reply to
cheyrich

Ich kenne die Boards nicht, aber nach einem Blick auf den Trace stellt sich mir die eventuell dumme Frage: Die I2C Pull-up Widerstaende sind vorhanden/aktiviert?

Gruss Klaus

Reply to
Klaus Bahner

schrieb

Hallo Frau Googlemail

Den kann es nur geben wenn ein zweiter Master auf den Bus zugreift. Sind zwei Master vorhanden? Wohl nicht...

Mit kurzer, verdrillter Leitung nehme ich mal an? Wenn ich mir das Schirmbild so angucke, befürchte ich aber...

Kann sein, muss nicht.

Die steigenden Flanken sehen gaaanz übel aus --> die pull-ups mal etwas verkleinern oder die Verbindung kapazitätsärmer gestalten.

(Das ganze Schirmbild sieht irgendwie sch...aus, verrauscht und komische spikes in SDA)

Die Spec. meint:

6.1 Data validity

The data on the SDA line must be stable during the HIGH period of the clock. The HIGH or LOW state of the data line can only change when the clock signal on the SCL line is LOW..

(Start- und Stopbedingung sind dann die Ausnahme)

Ich habe deinen Schirmplot mal mit nem Graphikekitor angeguckt, senkrechte Hilfslinie und copy/paste zeigt, dass die zit. Bed. für Datenübernahme auch immer (manchmal, gerade bei den steigenden Flanken "gerade so, knapp") erfüllt ist bis auf den letzten Wechsel von SDA auf low, da liegen die Flanken von SDA und SCL zeitgleich, verletzen also die zit. Bedingung.

Also durchaus verständlich, wenn der master dann sauer wird und beleidigt mittendrin aufhört zu clocken... :)

(Fallend SDA *während* SCL=high ist die gültige Stopbedingung!)

Reply to
Ruediger Klenner

Hallo Klaus,

laut Handbuch sollte es gen=FCgen, das Port Function Register auf die entsprechende Funktion zu stellen.

Auweia, ich glaube das wars. Jetzt aber mal ehrlich

PFR22.5 0 - Port is in general purpose port mode.

1 - Port is in resource function mode: Resource function is SCL0 open drain PFR22.4 0 - Port is in general purpose port mode. 1 - Port is in resource function mode: Resource function is SDA0 open drain, and INT14 input
Reply to
cheyrich

hoppla, bin vorzeitig auf Absenden gekommen

Hallo Klaus

Auweia, ich glaube das wars. Aber jetzt mal ehrlich, das Handbuch versteh ich dahingehend, dass es gen=FCgen m=FCsste, das Port Function register richtig einzustellen und nicht noch zus=E4tzlich die PullUp/ Down Register, und da das auch im Beispielprogramm so nicht eingestellt war, hab ich mir nichts dabei gedacht.

Im Handbuch steht:

PFR22.5 0 - Port is in general purpose port mode. 1 - Port is in resource function mode: Resource function is SCL0 open drain

PFR22.4 0 - Port is in general purpose port mode. 1 - Port is in resource function mode: Resource function is SDA0 open drain, and INT14 input

F=FCr mich liest das so, als ob der zus=E4tzlich die pull-ups setzen w=FCrde.

Naja jetzt sieht das in der Initialisierung so aus und scheint zu funktionieren:

PFR22_D4 =3D 1; // Set port function register for I2C SDA0 PFR22_D5 =3D 1; // Set port function register for I2C SCL0 PPER22_D4 =3D 1; // Enable Pull-Up/Down PPER22_D5 =3D 1; // Enable Pull-Up/Down PPCR22_D4 =3D 1; // Set Pull-Up PPCR22_D5 =3D 1; // Set Pull-Up

Danke nochmal f=FCr den Tipp

Reply to
cheyrich

schrieb:

klasse :)

Kann man auch anders sehen. Vergleiche mal steigende Flanken und fallende Flanken auf deinem Schirmbild!

Kann sehr wohl!

Nach Spec. 8.3 " Use of the clock synchronizing mechanism as a handshake", was aber nix mit bus arbitration zu tun hat. Gedacht für langsame slaves (a la uC).

Lies einfach mal die Spec:

formatting link

Philips, nur zwei pehs! Ich denke mal, daß die wissen wie eine I2C SM auszusehen hat :)

ja, sieht schrecklich aus!

Reply to
Ruediger Klenner

snipped-for-privacy@googlemail.com:

Yup, das ist schon richtig "Repeated Start". Er braucht bei den Folgezyklen dann nur 9 Takte.

Um es nochmal zu wiederholen: Dein Slave zieht das auf "L" (oder H, jenachdem welches Bit das Letzte ist). Weil er nur 6 Takte gekriegt hat. Nun krieg mal raus, warum der Master manchmal nur 6 Takte schickt. Vielleicht weil du das per timeout abbrichst? Disable erstmal mal den Timeoutkram.

M.

--
Bitte auf mwnews2@pentax.boerde.de antworten.
Reply to
Matthias Weingart

Hallo R=FCdiger,

Nein, die Boards sind =FCber einen 96- und 48-poligen Steckverbinder, der auch die Busse usw. f=FChrt, miteinander verbunden

Reply to
cheyrich

Open Drain impliziert nicht automatisch das Vorhandensein von Pull-Ups.

Gruß Henning

Reply to
Henning Paul

Muss mich revidieren, damit gings jetzt ein paar Mal, jetzt gehts wieder nicht :/

Reply to
cheyrich

Und das Einschalten von Port-Pullups kann das Problem auch nur seltener gemacht haben. I2C will Pullups im Bereich von 2k, sowas ist für typische Ports schon recht wenig. Da müsste man im Datenblatt nachschauen, was das wirklich ist. Notfalls muss man die noch dazulöten.

--
         Georg Acher, acher@in.tum.de
         http://www.lrr.in.tum.de/~acher
         "Oh no, not again !" The bowl of petunias
Reply to
Georg Acher

=C4h, der Slave kann die Taktleitung auf Masse halten wenn er langsamer l=E4uft. Von der Datenleitung hab ich nichts in der Spec gefunden

Huch ein guter Freund von mir hei=DFt Philip'p' ;). Ne, aber deshalb hab ich das extra dazugeschrieben, ich denke auch nicht dass die Erfinder vom I2C da Mist gebaut haben :D

Da stimme ich dir zu

Reply to
cheyrich

schrieb:

Wenn die Leitung hinreichend kurz ist... (Es ist ein Inter-IC-Bus, nie als Inter-boards-bus gedacht).

Die Signale auf deinem Bus sind definitiv nicht ok, schrecklich! Sieh mal zu dass da bessere Trapeze auftauchen mit weniger Gekräusel drumrum.

pull-ups checken ob sie überhaupt da sind, 2k2 oder so, evtll. verkleinern. Oszi hast du ja, das sollte besser aussehen.

Und fallend SDA bei *gleichzeitig* fallendem SCL ist jedenfalla eine violation, wo auch immer die herkommt.

Reply to
Ruediger Klenner

"Ruediger Klenner" schrieb:

Wie sieht denn die Verbindung GND zwischen den beiden boards aus?

Eines der dünnen Drähtchen im langen Flachkabel, an jedem Ende über einen Connectorpin kontaktiert...?

Massekabel an einem Rand des breiten Flachbandkabels, data und clock am anderen Rand, passend durchflutete Fläche dazwischen?

Miss mal die Spannungen zwischen GND board1 und GND board2, nur mal so als Idee... :)

Reply to
Ruediger Klenner

Die Boards sind ohne Kabel, direkt zusammengesteckt. Schema:

formatting link
(zusammengesteckt vorstellen)

Reply to
cheyrich

schrieb:

apropos:

Ich sehe I2C_BAUDRATE nirgendwo initialisiert, aber haste ja sicherlich gemacht.

Ändert sich was wenn du es langsamer laufen lässt? 100kbit/s?
Reply to
Ruediger Klenner

Habe jetzt mal an den Timeoutwerten herumgespielt. Jetzt l=E4uft das ganze besser.

Jetzt gibts nur noch ein Problem. Nach jedem Zyklus, wenn eine neue Start Condition gesendet werden soll gibts ne Violation:

formatting link

Wie man hier sieht, geht die Datenleitung auf Masse, obwohl die Taktleitung noch low ist. Der entsprechende Code-Abschnitt sieht so aus:

UINT8 i2c_start(UINT8 slave_address) { ICCR0_EN =3D 0; // Disable I2C, clears all flags but BER and BEIE in IBCR0 and IBSR0 IBCR0_BER =3D 0; // Clear bus error flag IDAR0 =3D slave_address; // Set slave_address to data register ICCR0_EN =3D 1; // Enable I2C IBCR0_MSS =3D 1; // Sets master mode, generates start condition and begins transfer return i2c_check(); // Check for errors and timeouts } Der Arbitration Loss tritt sofort nach Setzen des MSS-Bit auf. Habe testweise mal vorher ne Abfrage auf Bus Busy eingef=FCgt, auch die hat nichts gebracht.

Hier noch ein paar andere Oszi-Screenshots (hab endlich herausgefunden, wie man gescheite Bilder damit macht :)

Start:

formatting link
Zyklus:
formatting link
Komplette =DCbertragung:
formatting link

Reply to
cheyrich

Ja die Definition hab ich nicht mit kopiert. Ich lass das Ding "sicherheitshalber" eh mit 100 laufen. Bei 400 bricht er im 12. Zyklus (reproduzierbar) so ab:

formatting link

Reply to
cheyrich

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.