Forum: Mikrocontroller und Digitale Elektronik STM32 I2C Slave Endless clock stretch


von Ruediger N. (butze72)


Angehängte Dateien:

Lesenswert?

Hallo,
habe einen STM32F072 den ich als I2C Slave betreiben möchte. 
Konfiguriert habe ich die Sache mit CubeMX, Slaveadresse eingestellt auf 
$32. Lasse mein Programm bis nach der Initialisierung des I2C laufen und 
feuere mit einem anderen STM32 einen Write Frame auf den Slave:
1
buf[0] = 0x55;
2
HAL_I2C_Master_Transmit(&hi2c1, 0x64, buf, 1, HAL_MAX_DELAY);

Das Ergebnis sieht man auf dem Bild, der Master generiert 8 Takte und 
legt die Adresse 0x32 auf den Bus, danach klemmt der Slave den Takt und 
nichts geht mehr. Habe mir das I2C ISR Register im Slave angeschaut, 
ADDCODE hat die 0x32, BUSY und ADDR sind gesetzt. Aber es klemmt!

Wenn ich nun auf dem Slave "Clock no Strech Mode" aktiviere wird der 
Frame ordentlich acknowledged, der Content von Buf[0] wird sauber 
aufgelegt und der Frame beendet. Das Problem ist dass ich "no Strech 
Mode" nicht aktivieren möchte aber vor allem mal wissen möchte was da 
schief geht.

: Bearbeitet durch User
von (prx) A. K. (prx)


Lesenswert?

Das kann bedeuten, dass beim Slave zwar die Hardware sauber reagiert, 
aber die Software die Schnittstelle nicht bedient.

von Falk B. (falk)


Lesenswert?

Ruediger N. schrieb:
> Das Problem ist dass ich "no Strech
> Mode" nicht aktivieren möchte aber vor allem mal wissen möchte was da
> schief geht.

Vermutlich muss deine Software das clock stretching bestätigen und damit 
beenden. Denn das ist ja der Zweck. Dem Slave Zeit zu geben, die Daten 
zu verdauen.

von Peter D. (peda)


Lesenswert?

Der Slave muß in den Interrupthandler springen und das Flag löschen, 
welches das Clock Stretching bewirkt.

von Planloser (Gast)


Lesenswert?

Ruediger N. schrieb:
> Hallo,
> habe einen STM32F072 den ich als I2C Slave betreiben möchte.
> Konfiguriert habe ich die Sache mit CubeMX, Slaveadresse eingestellt auf
> $32. Lasse mein Programm bis nach der Initialisierung des I2C laufen und
> feuere mit einem anderen STM32 einen Write Frame auf den Slave:buf[0] =
> 0x55;
> HAL_I2C_Master_Transmit(&hi2c1, 0x64, buf, 1, HAL_MAX_DELAY);
>
> Das Ergebnis sieht man auf dem Bild, der Master generiert 8 Takte und
> legt die Adresse 0x32 auf den Bus, danach klemmt der Slave den Takt und
> nichts geht mehr. Habe mir das I2C ISR Register im Slave angeschaut,
> ADDCODE hat die 0x32, BUSY und ADDR sind gesetzt. Aber es klemmt!


Hast Du das ADDR-Bit gelöscht?

"When the ADDR flag is set: the received address matches with one of the 
enabled
slave addresses. This stretch is released when the ADDR flag is cleared 
by softwaresetting the ADDRCF bit."

von Ruediger N. (butze72)


Lesenswert?

Super! Ich danke euch vielmals! Es bewahrheitet sich doch immer wieder, 
wer lesen kann ist klar im Vorteil. War felsenfest davon ausgegangen 
dass die HW bis zu dem Zeitpunkt als dass der RxBuffer belegt ist den 
Empfang einfach durchlaufen lässt ohne dass ich eingreifen muss.

Ich wünsche euch ein sonniges Wochenende!

von Martin M (Gast)


Lesenswert?

Hallo,

bei mir ist das gleiche Problem, dass der Slave im 'Clock Stretch Mode' 
die Clock-Leitung nicht wieder freigibt.

Das Addr-Bit versuche ich über das Kommando :
hi2c1.Instance->ICR = I2C_FLAG_ADDR;
zu löschen.
Scheint zu funktionieren, jedenfalls ist es danach 0 :
temp1 = (hi2c1.Instance->ISR & I2C_FLAG_ADDR) == I2C_FLAG_ADDR;

Nützt aber nichts.
An welcher Stelle muss das Addr-Bit denn gelöscht werden ?

von Peter D. (peda)


Lesenswert?

Steht doch alles im Manual. Es gibt 4 Möglichkeiten fürs Clock 
Stretching:
Slave clock stretching (NOSTRETCH = 0)
In default mode, the I2C slave stretches the SCL clock in the following 
situations:
•When the ADDR flag is set: the received address matches with one of the 
enabled slave addresses. This stretch is released when the ADDR flag is 
cleared by software setting the ADDRCF bit.
•In transmission, if the previous data transmission is completed and no 
new data is written in I2C_TXDR register, or if the first data byte is 
not written when the ADDR flag is cleared (TXE=1). This stretch is 
released when the data is written to the I2C_TXDR register.
•In reception when the I2C_RXDR register is not read yet and a new data 
reception is completed. This stretch is released when I2C_RXDR is read.
•When TCR = 1 in Slave Byte Control mode, reload mode (SBC=1 and 
RELOAD=1), meaning that the last data byte has been transferred. This 
stretch is released when then TCR is cleared by writing a non-zero value 
in the NBYTES[7:0] field

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.