cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F302K8 I2C weirdness

psusi
Associate II

I have noticed some very strange behavior with the I2C controller. It appears that when it has a slave address match, it sets the ADDR ISR flag and raises an interrupt ( if enabled ). If I have a breakpoint in the interrupt handler, the ISR BUSY flag remains set and it appears to be locking up the bus with an indefinate clock stretch. As I step through the ISR, as soon as it clears the ADDR flag, it stops blocking the bus and transfers the byte, clearing the BUSY flag, and setting STOPF and RXNE to indicate that there is a byte in the receive register. Why is the controller waiting for the ADDR flag to be cleared ( you may not even be interested in it and not enable its interrupt! ) before accepting the data byte? Then it gets even stranger. If I step to the next line of the ISR, the RXNE flag self clears before the ISR has a chance to recognize it and read from the RXDR. This definitely should not happen right?

3 REPLIES 3
TDK
Guru

Here's what the reference manual has to say about the BUSY bit:

Bit 15 BUSY: Bus busy

This flag indicates that a communication is in progress on the bus. It is set by hardware when a

START condition is detected. It is cleared by hardware when a Stop condition is detected, or

when PE=0.

Sounds like the behavior you see is expected, at least that part of it.

> If I step to the next line of the ISR, the RXNE flag self clears before the ISR has a chance to recognize it and read from the RXDR. This definitely should not happen right?

It sounds like you are viewing the peripheral registers. Viewing the I2C->RXDR register will clear the RXNE flag.

If you feel a post has answered your question, please click "Accept as Solution".
psusi
Associate II

I wasn't questioning the meaning of the BUSY bit; that was merely for context. I was questioning the fact that the controller seems to require you to clear the ADDR bit before it will allow the first data byte to be transferred. It should not be doing that and the manual does not give any indication that it does or that clearing it is required. I thought I had accounted for the possibility that it was the debugger reading that cleared RXNE but now that I try it again, that does seem to be the case.

TDK
Guru

I think the RM does explain it. With NOSTRETCH=0, you get the behavior you described, where SCL is stretched to let the user code decide how it wants to proceed. If you don't want this, set NOSTRETCH=1. It even has flowcharts for these two scenarios. Doesn't that describe exactly what's happening?

0693W000001qW5kQAE.png

If you feel a post has answered your question, please click "Accept as Solution".