Forum: Mikrocontroller und Digitale Elektronik STM32 I2C Slave (N)ACK nach Empfang entscheiden


von Tilo (Gast)


Lesenswert?

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.

von Ali K. (teddy50)


Lesenswert?

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.

von Steve van de Grens (roehrmond)


Lesenswert?

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
von Peter D. (peda)


Lesenswert?

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.

von Tilo (Gast)


Lesenswert?

@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.

von Steve van de Grens (roehrmond)


Lesenswert?

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
Noch kein Account? Hier anmelden.