Hallo zusammen,
ich muss ein Intersil X9119 über I2C ansprechen.
Dafür verwende ich einen Atmega48 und die I2C Lib von Peter Fleury.
I2C/TWI an sich funktioniert, ich kann einen anderen Chip der am selben
Bus hängt problemlos ansprechen. Aber der X9119 ist etwas seltsam.
Wie im Datanblatt auf Seite 8 zu sehen ist, erwartet er dass man ihm zum
lesen eines Registers die Slave Address mit Read bit schickt, dann den
Befehl zum lesen und dann 2 Bytes liest.
Normalerweise nutzt man ja den Master Transmit Mode um den Befehl zu
schicken, dann wechselt man in den Master Reciever Mode um die Antwort
zu lesen. Aber das funktioniert hier nicht (wie laut Datenblatt auch zu
erwarten war).
Mein Problem ist nun, dass mein Atmega nichts auf SDA schreiben will
während er im Master Reciver Mode ist. Und er geht automatisch in diesen
wenn ich das Read bit in der Slave Adresse setze...
Gibt es irgendeine Möglichkeit trotz Master Reciver Mode etwas auf SDA
zu schreiben?
Meine Funktion zum lesen sieht zur Zeit folgendermaßen aus:
1
uint16_treadValue(uint8_tdev){
2
uint16_tret;
3
// Read WCR
4
i2c_start_wait((X9119|(dev<<1))+I2C_READ);
5
i2c_write(0b10000000);
6
ret=((i2c_readAck()&0x3)<<8);
7
ret|=i2c_readNak();
8
i2c_stop();
9
returnret;
10
}
Und das was raus kommt ist auf dem angehängten Screenshot zu sehen
(X9119-1.png).
Danke,
Thomas
Entweder ist ein grober Fehler im Datenblatt, oder die Kommunikation
weicht extrem vom Standard ab.
Wie du richtig bemerkt hast, steuert das RW-Bit den modus. Sobald du
SLA+R sendest, ist der AVR im Receiver Mode, und da kannst du nicht
senden.
Wenn das Datenblatt korrekt ist, entweder Chip wegwerfen und was
standardkonformes nehmen, oder "zu Fuß" die Bits schubsen...
Der Chip hat laut Datenblatt kein I²C, sondern ein "2-Wire Serial
Interface".
Das ist zwar irgendwie ähnlich, aber ist augenscheinlich doch ein
eigenes Protokoll von Intersil. Da hilft nichts, das wirst du zu Fuß in
reiner Software implementieren müssen.
Oliver
Sieht so aus, als hat Intersil das I2C-Protokoll nicht verstanden.
Um auf Lesen umzuschalten, ist der erlaubte Weg ein repeat Start +
SLA+R.
Verzichte doch aufs Rücklesen und merke Dir den Wert im EEPROM des MC,
wenn Du ihn unbedingt brauchst.
Das wäre möglich, aber ich würde gerne erst einmal wissen, ob das
schreiben überhaupt geklappt hat.
Ok, das könnte ich herausbekommen in dem ich den Widerstand messe.
Mal sehen wie ich es jetzt umsetzt, ich werde erst mal eine bit banging
Library bauen und dann mal sehen.
Danke für eure Antworten.
Thomas Z. schrieb:> ich werde erst mal eine bit banging> Library bauen und dann mal sehen.
Ich hab sowas ähnliches mal gebaut für den "E2-Bus", das ist auch so
eine inkompatible Sondergeschichte von E+E, hab ich für einen CO2-Sensor
von denen gebraucht. Allerdings nicht ganz so sonderbar :-)
kannst brauchen?
Ich habe jetzt die i2csw.c von hier als Grundlage genommen:
http://www.procyonengineering.com/embedded/avr/avrlib/
Aber besonders schön ist sie nicht und getestet habe ich es auch noch
nicht.
Eine schönere Alternative wäre willkommen :-)
Danke für eure Hilfe,
ich habe meinen Code jetzt mal angehängt.
Er basiert noch auf dem von
http://www.procyonengineering.com/embedded/avr/avrlib/
und steht deshalb unter GPL.
Falls noch einmal jemand mit diesem Intersil X9119 reden muss, hilft ihm
dieser Code vielleicht.
Er ist nicht der schönste aber die Funktionen die ich verwende gehen
jetzt :-)
Getestet sind:
x9119_read_wcr
x9119_read_dr
x9119_write_dr
x9119_xfr_dr_to_wcr
Hi
>Er ist nicht der schönste aber die Funktionen die ich verwende gehen>jetzt :-)
Möglich, aber keineswegs I2C-Konform.
>#define X9119_SDL_LO X9119_SDAPORT &= ~(1<<X9119_SDA)>#define X9119_SDL_HI X9119_SDAPORT |= (1<<X9119_SDA)>#define X9119_SCL_LO X9119_SCLPORT &= ~(1<<X9119_SCL)>#define X9119_SCL_HI X9119_SCLPORT |= (1<<X9119_SCL)
SDA und SCL können kein aktives H sondern nur ein aktives L erzeugen.
Das H auf den Busleitungen wird durch die Pull-Up-Widerstände erzeugt.
Praktisch wird das gemacht indem man die Port-Bits von SCL und SDA auf L
setzt und die Datenrichtung für ein L auf Ausgang und für ein H auf
Eingang setzt. Du hast deine Routinen leider von jemanden abgeschrieben,
der I2C/TWI nicht richtig verstanden hat.
MfG Spess
Hi Spess,
das ist in diesem Fall aber kein Problem, da sich ja herausgestellt hat
dass der Chip nicht I2C kompatibel ist, sondern ein anderes Protokoll
verwendet dass nur Ähnlichkeiten mit I2C hat.
Und da im Datenblatt keine Pull-Up Widerstände erwähnt werden müssen
diese nicht unbedingt vorhanden sein.
So etwas wie clock streching unterstützt der Chip auch nicht, weshalb
ich vor jedem Befehl erst mal ACK polling betreiben muss um zu warten,
bis der Chip den vorherigen Befehl abgearbeitet hat (was bis zu 5ms
dauern kann).
Weshalb der Chip die Clock Leitung auch gar nicht anfasst.
lg
Thomas
Thomas Z. schrieb:> Und da im Datenblatt keine Pull-Up Widerstände erwähnt werden müssen> diese nicht unbedingt vorhanden sein.
Äh, doch...
"It is an open drain output and may be wire-ORed with any
number of open drain or open collector outputs. An open
drain output requires the use of a pull-up resistor."
Und nach Datenblatt aknowledged der Chip als Slave. Das geht nicht ohne
pull-ups und high-Z-high.
Oliver