Das Problem ist offensichtlich gelöst - nach der Methode "Auch ein blindes Huhn ...". Eine Erklärung, warum die Verzögerung nötig ist habe ich nämlich nicht. Vielleicht werde ich mit einem DSO noch Messungen am I²C-Bus machen, aber das hat erstmal Zeit.
Was geschah?
Die kritische Stelle der I²C-Leserei hatte ich im obigen Posting wohl recht gut getroffen. Da die konstanten wait-Vorgaben doch unbefriedigend sind, hatte ich mal versucht die Stati des Busses abzufragen. Das klappte nicht wirklich, ist auch eine etwas seltsame Lösung.
Mittlerweile habe ich den Code geändert, der Befehl "..rep_start.." steht in einer while-Schleife. Und nun tuckerts klaglos, aktuell mit 800 kHz, das ist ein TWBR von 4 (eigentlich 4,5), PFleury nennt ein Minumum von 10 für stabilen I²C-Lauf.
Anmerkung: der "..rep_start.." in der PFleury-Bibliothek ist nur ein 1:1 umgeleiteter "... i2c_start ...", der ja mit dem Ergebnis einer Bus-Statusprüfung zurückkommt ;.-.)
Anmerkung2: Das Datenblatt des m1284 nennt als TWI-Frequenz eine obere Grenze von Slavetakt / 16. Diesen kann ich nicht erreichen. Mit TWBR 2 gehts nämlich schon nicht mehr ! . . .
Code:
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Lesen (read back) vom Slave ... mit der Routine aus fleury´s lib
i2c_start_wait(SLAVE_MoCo+I2C_WRITE); // set device address and write mode
i2c_write( laddr ); // write address = laddr, das angepeilte Byte
i2c_stop(); //
while ((i2c_rep_start(SLAVE_MoCo+I2C_READ))) {}// Slave bereit zum Lesen?
//i2c_rep_start(SLAVE_MoCo+I2C_READ); // set device address and read mode
ipwm12 = i2c_readAck(); // Bytes lesen... ab laddr = 0x33/51
soll12 = i2c_readAck(); //
ipwm34 = i2c_readAck(); //
soll34 = i2c_readNak(); // letztes Byte lesen, NAK
i2c_stop(); //
Ärgerlich für mich ist nur, dass diese Änderung wieder mal ne experimentelle Softwareentwicklung ist, weil mir der tatsächliche Grund für die Notwendigkeit dieser Verzögerung nicht klar ist.
Getestet wurde in diesem Zusammenhang in meinem aktuellen Archie-Aufbau mit Master (m1284/20MHz), drei Slaves: 2x1284/20MHz und 1x328/20MHz und einer rund 1,5 m langen I²C-Leitung mit zwei Zwischensteckern. Master und Slaves sind durch mehrere Interrupts "verseucht", der Motorcontroller z.B. durch Regelungsroutine ( > 2 x 100 Hz ), Encoder (2 Stk, bis > 500 Hz), Heartbeat+Boardtimer 20 kHz und UART-115kBd. Ähnlich auch der Master durch Heartbeat+Boardtimer, RC-5-Decoder, UART 1 x mit 115kBd und 1 x mit 57kBd. . .
Lesezeichen