Hallo Ich habe einen STM32G0B1CBT6. Ich möchte damit einen "man in the middle" bei einer I2C Kommunikation realisieren: (Source, Master) <------> (STM32, Slave) (STM32, Master) <------> (Sink, Slave) Sobald Source auf dem STM schreiben will, wird die Kommunikation per Clock stretch pausiert. Das von Source geschriebene Byte wird an Sink weiter geschickt. Der Slave verarbeitet dann die Daten. Wenn Source lesen will, wird nach Adressübertragung per Clock Stretch gewartet, die Daten von Slave gelesen und dann an Source übertragen. Mein Problem ist, dass wenn der STM vom Master ein Byte empfängt ich noch nicht weiß, ob mit ACK oder NACK geantwortet werden soll. Diese Information ist erst vorhanden, wenn der STM das Byte an Sink weitergeleitet und ACK/NACK von Sink erhalten hat. Auszug aus der Registerbeschreibung von CR2: Bit 15 NACK: NACK generation (slave mode) The bit is set by software, cleared by hardware when the NACK is sent, or when a STOP condition or an Address matched is received, or when PE=0. 0: an ACK is sent after current received byte. 1: a NACK is sent after current received byte. Das Verhalten ist genau wie beschrieben. Abhänging von dem Bit wird ein ACK oder NACK erzeugt. Das Problem ist nun, dass während des Transfers noch gar nicht bekannt ist, ob ACK oder NACK richtig ist. Nach den 8Bits müsste ein Clock Stretch für die Verarbeitung erfolgen und abhängig davon soll dann (N)ACK gesetzt werden. Übersehe ich etwas oder ist es tatsächlich nicht möglich erst die Daten zu empfangen und dann zu entscheiden, ob ACK oder NACK gesetzt werden soll? Vielen Dank.
Wieso kommuniziert du mit dem Sink nicht, nachdem du mit dem Master abgeschlossen hast? Dann musst du kein Clockstretching machen und kannst dich voll und ganz auf einen Device Konzentrieren.
Das ACK/NACK wird gesendet in dem Moment gesendet, wenn du das gerade empfangene byte aus dem I2C_RXDR Register ausliest. Tust du das verzögert, findet Clock-Stretching statt. Leider ist nach meinem Kenntnisstand es nicht möglich, das I2C_RXDR zuerst zu lesen und danach die Entscheidung zu treffen, ob dieses Byte mit ACK oder NACK bestätigt werden soll.
:
Bearbeitet durch User
Die meisten I2C-Controller machen einen kompletten 9 Bit Transfer, d.h. es muß vor dem Empfang eines Bytes entschieden werden, ob mit ACK oder NACK geantwortet wird. Eine Ausnahme sind I2C-Controller mit reduzierter Implementation, z.B. die ATtiny mit USI.
@Ali: Das funktioniert leider nicht, da es sich zu erst um: Write, Repeated Start und Read handelt. Wären die Transfers völlig unabhängig, würde das gehen. @Steve und Peter: Danke für eure Rückmeldung, das habe ich befürchtet. Anscheinend scheint sich der Master nicht daran zu stören, dass ich manchmal ein ACK zurück gebe, wo ein NACK hingehören würde. Daher habe ich Glück. Die I2C Hardware scheint so ihre Eigenarten zu haben. Ebensie wie ACK/NACK scheint ein STOP im Master Mode nur dann generierbar zu sein, wenn man die Entscheidung vor oder während einem (Read) Transfer trifft. Es scheint jedoch so zu sein, dass ein Transfer dann zu Ende ist, wenn die 8Bits empfangen wurde. Bei mir haben sich Timings ergeben, in denen ich erst dann wusste das ein STOP gesendet werden soll, wenn ACK gesetzt wird. Damit dann noch ein STOP generiert wird, hätte ein Byte mehr gelesen werden müssen. Das hat Source durcheinander gebracht. Ich hab es jetzt so gelöst, dass in diesem Fall I2C abgeschaltet wird und STOP durch GPIO Wackeln erzeugt wird. Leider nicht schön aber es geht.
Tilo schrieb: > Ich hab es jetzt so gelöst, dass in diesem Fall I2C abgeschaltet wird > und STOP durch GPIO Wackeln erzeugt wird. > Leider nicht schön aber es geht. Gute Idee!
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.