Hallo zusammen, wenn ich den Controller mitte einer Kommunikation mit dem (I2C) Eeprom unterbreche und resete (z.B. während dem Debuggen, oder auch mit einem schnellen spanungsreset), antwortet der Eeprom nicht mehr und bekomme nur Buskollisionen! Erst wenn ich die ganze platine von der Versorgung trenne und kurz warte dann ist alles wieder ok. Ich glaube der EEprom bleibt mitte in der Kommunikation, ignoriert die neuen Start-Befehle udn bekomme die Buskollisionen,kann das stimmen?
> Ich glaube der EEprom bleibt mitte in der Kommunikation, ignoriert die > neuen Start-Befehle udn bekomme die Buskollisionen,kann das stimmen? Ja das kann stimmen. Wackel bei deine I2C-Initialisierung mal mit SCL. Kann sein das die Statemachine im EEPROM dann wieder aufsetzt. Olaf
Normalerweise müßte das Ganze mit einem STOP zu beheben sein. Wenn ein Device ein STOP erkennt, sollte es den aktuellen Vorgang abbrechen. Gruß TK
Ich erinnere mich dunkel an eine Diskussion zum selben Thema, die bei der I2C Treiberentwicklung für Linux geführt wurde. Wenn ich mich richtig erinnere war das so: Wenn ein Lesevorgang durchgeführt wird, darf man nicht mitten im Datenwort aufhören die Taktleitung SCL zu takten, da das Byte noch halb im Ausgangsregister drinsteckt. Dieses Byte muß in jedem Fall erstmal fertig ausgegeben werden bevor eine Stop-Condition kommen kann. Das EEPROM selber hat ja keinen Reset-Pin. Da kommt nur irgendwann mal ein Timeout zustande. Wenn Du also mitten im Lesevorgang abbrichst kannst Du: 1. Eine Zeitlang warten (-> Datasheet) oder 2. Power-Reset machen oder 3. nach der Unterbrechung die SCL-Leitung noch eine Zeitlang takten um die restlichen Bits noch rauszuschütteln.
PS.: Mit dem Timeout bin ich mir am wenigsten sicher...
das mit dem Timeout finde ich nirgendwo im Datenblatt!
Nach dem Reset weiß Dein AVR-TWI ja nicht, daß der EEPROM noch Daten sendet und in welchen Takt er gerade ist. Das TWI kann die Blockierung daher nicht aufheben und wird ständig Fehler melden. Du mußt Dir daher eine Software-I2C Funktion schreiben, die solange versucht STOP zu senden, bis es klappt. Wenn es nicht klappt, ne SCL-Flanke und weiter versuchen. Im Worst Case braucht es 9 Versuche. Ich hab gerade leider nur ne 8051-Assembler Funktion gefunden:
1 | ;---------------------- send stop --------------------------------------- |
2 | ;Input: CY = 0: no previous error |
3 | ;Output: CY = CY OR 1: Error, SDA or SCL still low |
4 | ;SDA: X -> 1 |
5 | ;SCL: 0 -> 1 |
6 | SI2CSTO: |
7 | clr ssda |
8 | mi2cdelay cycle_4us - 1 |
9 | setb sscl |
10 | mi2cdelay cycle_4_7us - 3 |
11 | orl c, /sscl ;test sscl |
12 | setb ssda |
13 | nop ;time to go high |
14 | orl c, /ssda ;test ssda |
15 | ret |
16 | ;---------------------- reset the I2C bus ------------------------------- |
17 | ;Output: CY = 1 Error, reset failed |
18 | ;SDA: X -> 1 |
19 | ;SCL: X -> 1 |
20 | SI2CRES: |
21 | mov r2, #9 ;try it 9 times |
22 | ?si2crs1: |
23 | clr c |
24 | clr sscl ;generate clock pulse |
25 | call si2csto ;try sending stop |
26 | jnc ?si2crs2 |
27 | djnz r2, ?si2crs1 |
28 | ?si2crs2: |
29 | ret |
Das Prinzip sollte aber daraus ersichtlich sein. Peter
> das mit dem Timeout finde ich nirgendwo im Datenblatt!
Ich glaub auch nicht das es einen Timeout gibt. Zwei Gruende:
1. Wo soll das zeitbestimmende Glied sein? Es gibt weder einen
Kondensator, noch einen Takt der gezaehlt werden koennte.
2. Wie lang sollte die Zeit sein? Egal was man darauf antworten
wuerde, es gibt immer eine Zeit die fuer eine Anwendung zu
lang und fuer eine Andere zu kurz ist.
Ich denke daher in den Teile wird lediglich eine Statemachine drin sein
die als Basis die SCL-Takte zaehlt. Von daher erscheint es mir am
vernuenftigsten einfach ein paar Takte rauzuschicken wenn es ein Problem
gibt.
Olaf
In der Regel steht in den Datenblätter was von SCL Clock Min:0Hz Max:400kHz D.h. ein 0Hz Clock ist auch noch erlaubt, Ergo: Kein Timeout.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.