2021-09-25 02:30 PM
stm32f103cbt6, i2c1 in slave receiver mode. CubeIDE, stm32f1 pack ver 1.8.4. I use HAL_I2C_Slave_Receive_IT to receive 1(adr)+2 bytes. I2C standard mode. Both err and evt interrupts enabled. I2C stucks into bus error (BERR flag). Jumping over HAL code figured out that ADDR, RXNE, STOPF events happen and handled and looks like correct data arrived but is not passed to application because of BERR. What was taken into consideration: 1. Pullup resistors 10K replaced to 1K, 2.SCL freq 3KHz-100KHz, 3.All configurations made in CubeIDE device configuration tool. 4. ADDR in the tool must be set divided by 2 to make i2c receive correctly.
What are exact reasons of BERR flag? Does it just detect SDA changes on SCL=1 or something else?
2021-09-26 07:21 AM
BERR signifies an unexpected start or stop condition, per the reference manual.
Can you use a logic analyzer to show what's happening on the line? How do you know it's incorrect behavior?
2021-09-27 03:15 AM
2021-09-27 03:16 AM
2021-09-27 03:17 AM
2021-09-27 06:29 AM
I can't see anything that would explain BERR in the scope plots. The NACK on the last byte makes sense as you're only receiving 2 bytes. It will NACK the last byte in order to stop the transaction.
2021-09-27 08:31 AM
That sequence anyway should not lead to BERR in this case. Actualy i found out what is going on. The logic that drives BERR flag in uC is really sensitive to SDA to SCL hold time which can be 0 as per specification. In my case I can't exactly say wether this was violated to negative value (if so, definitely not more than -20 ns) but this was enough to catch wrong START or STOP condition. As soon as my I2C master is FPGA project I increased this hold time to approx less than 50 ns and that was enough to make it work stable. Many thanx for Your help.
2021-09-27 08:38 AM
Thanks for reporting back with the answer.
After looking back at the plots, I can see now that SDA changes state very close to the SCL falling edge. Probably SDA changes state before SCL on one or more of them which is in fact a misplaced start or stop condition. The logic analyzer should catch this, but if the edges are close or overlapping, perhaps the correct logic isn't in the analyzer software.