Gast
#57960
Folgendes steckt in meiner main Funktion:
TWAR = (SLAVEADDR << 1);
TWCR = _BV(TWEN) | _BV(TWEA);
for (;;) {
while ((TWCR & _BV(TWINT)) == 0);
TWCR = _BV(TWINT) | _BV(TWEN) | _BV(TWEA);
}
Jetzt habe ich das Problem, daß jedesmal wenn ein Zugriff SLA+R erfolgt
anschließend der Slave die SDA Leitung dauerhaft auf 0 zieht.
Bei einem SLA+W Zugriff ist alles OK und ich bekomme einen sauberen Ack
auf Zugriff und der Bus ist danach wieder verfügbar.
Ein langwieriger Vergleich mit einer Software, die funktioniert, ergab,
daß das Problem durch den Wert von SLAVEADDR ausgelöst wird.
Ein Wert <=63 ist OK ein Wert >=64 zeigt das beschriebene Problem.
Im Disassembler sieht das so aus:
Wert = 64:
62: 80 e8 ldi r24, 0x80 ; 128
64: 82 b9 out 0x02, r24 ; 2
Wert = 63:
62: 8e e7 ldi r24, 0x7E ; 126
64: 82 b9 out 0x02, r24 ; 2
Also so wie es sein sollte und der Slave fühlt sich ja auch erst ab der
richtigen Adresse angesprochen - verhält sich danach nur falsch.
Getestet habe ich mit folgenden Programmen auf FreeBSD:
http://www.cosmo-project.de/~bernd/iic_probe
http://www.cosmo-project.de/~bernd/smb_probe
Im Prinzip passiert Clientseitig folgendes:
start, SLA+R, stop wenn Ack.
Falls jemand eine Erklärung dafür hat - ich bin jedenfalls ratlos.