2019-12-10 05:47 AM
Hello,
I'm working on a project, where the Master (STM32F107) have to communicate with a few slaves (ATxmega) via I2C. Most of the time it works fine. But sometimes the SCL line is going low and stays low. First i thought it's a Slave issue (because of clock stretching), but its a Master problem.
I tested different thinks, when the error occurs. For example I make a hardwarereset on a slave. Then it's rebooting, but SCL is still low. The Master and Slave are on different PCBs, so I can cut the connection between them. When I'm doing this, the SCL line on the Slave side goes up, on the Master stays low. I'm using HAL and reset the I2C configuration and reinitialize it. I already tried direct register access and reset the I2C periphery on this way. But it doesn't help. Only a reboot of the master fixes the problem (hard- or software reset, both works).
I activated the I2C error interrupt, but the interrupt never occurs. The I2C registers are also unremarkable:
I2C_SR1: BTF and TxE are set
I2C_SR2: MSL, BUSY and TRA are set.
I'm using fast mode (400 kHz) with 2k2 pullups.
I already checked the erata, there are a few known issues with the I2C periphery, but no one fit with mine.
Any ideas?
Solved! Go to Solution.
2019-12-10 06:41 AM
> With RCC you mean, I should reboot the device?
No, I mean reset the I2C module using RCC_APB1RSTR.I2CxRST
> Even when i reconfigure the SDA Pin as GPIO output pushpull, I'm not able to get it high.
You mean SCL?
Are you sure you changed it to GPIO Output? Or try it to change to GPIO Input. That should release the pin, even if the I2C module holds it low...
I don't use the 'F1, and certainly not Cube.
JW
2019-12-10 06:00 AM
Try lower ("stronger") pullups, to defeat any noise, especially when pulling the lines accross several boards; also review grounding arrangement.
On software side, add a timeout mechanism, upon timeout reset the I2C in RCC and perform the 9-pulse recovery.
(Similar issues were discussed many times, recently e.g. here https://community.st.com/s/question/0D50X0000Bh5EqdSQE/i2c-device-locking-up )
JW
2019-12-10 06:08 AM
I already tried 1k pullups, but it didn't change anything.
With RCC you mean, I should reboot the device? When yes, this works, but it took really long until everything is rebooted and initalized again, so I want to avoid this. The 9-pulse recovery doesn't affect me, because this is used when the SDA line stays low... and i already tried. Even when i reconfigure the SDA Pin as GPIO output pushpull, I'm not able to get it high.
2019-12-10 06:41 AM
> With RCC you mean, I should reboot the device?
No, I mean reset the I2C module using RCC_APB1RSTR.I2CxRST
> Even when i reconfigure the SDA Pin as GPIO output pushpull, I'm not able to get it high.
You mean SCL?
Are you sure you changed it to GPIO Output? Or try it to change to GPIO Input. That should release the pin, even if the I2C module holds it low...
I don't use the 'F1, and certainly not Cube.
JW
2019-12-11 01:04 AM
> No, I mean reset the I2C module using RCC_APB1RSTR.I2CxRST
This works! Immediately after setting the bit the SCL line is released. After reinitializing the I2C periphery everything works fine again.
> You mean SCL?
Yeah, I mean SCL.
> Are you sure you changed it to GPIO Output?
Yes, i double checked the GPIO register.
> Or try it to change to GPIO Input. That should release the pin, even if the I2C module holds it low...
I tried this, but this is not working. It seemed that I have to work with the RCC reset.
Thank you for your suggestions.