2019-11-07 04:02 AM
I am currently bringing up a board with an STM32F412ZG.
We are using the I2C2 peripheral on PF0 and PF1 and not having much luck.
We can drive I2C1 and I2C3 without issue, but when trying to use I2C2 the busy flag remains asserted - even after forcing resets. A search turned up an older errata on the F103 with a similar fingerprint: https://electronics.stackexchange.com/questions/272427/stm32-busy-flag-is-set-after-i2c-initialization
Is I2C2 known to work? Is there an example demonstrating it's usage?
My next step is to try running the mitigation from the linked issue.
Solved! Go to Solution.
2019-11-12 06:10 AM
Thanks for the help all! @Amel NASRI it would be interesting to know if ordering things as you suggest fixes our issue too.
The issue was interesting because we could initialise I2C2 with the following code on PB10/PB11:
__HAL_RCC_GPIOB_CLK_ENABLE();
__HAL_RCC_I2C2_CLK_ENABLE();
HAL_GPIO_INIT(USS_HAL_GPIO_PORT_B, USS_HAL_GPIO_PIN_10, USS_HAL_GPIO_MODE_AF_OD,
USS_HAL_GPIO_SPEED_VERY_HIGH, USS_HAL_GPIO_PULLUP_UP, GPIO_AF4_I2C2);
HAL_GPIO_INIT(USS_HAL_GPIO_PORT_B, USS_HAL_GPIO_PIN_11, USS_HAL_GPIO_MODE_AF_OD,
USS_HAL_GPIO_SPEED_VERY_HIGH, USS_HAL_GPIO_PULLUP_UP, GPIO_AF4_I2C2);
To get it working on PF0/PF1 we needed to reset the peripheral after configuring the GPIOs:
__HAL_RCC_GPIOF_CLK_ENABLE();
__HAL_RCC_I2C2_CLK_ENABLE();
HAL_GPIO_INIT(USS_HAL_GPIO_PORT_F, USS_HAL_GPIO_PIN_0, USS_HAL_GPIO_MODE_AF_OD,
USS_HAL_GPIO_SPEED_VERY_HIGH, USS_HAL_GPIO_PULLUP_UP, GPIO_AF4_I2C2);
HAL_GPIO_INIT(USS_HAL_GPIO_PORT_F, USS_HAL_GPIO_PIN_1, USS_HAL_GPIO_MODE_AF_OD,
USS_HAL_GPIO_SPEED_VERY_HIGH, USS_HAL_GPIO_PULLUP_UP, GPIO_AF4_I2C2);
__HAL_RCC_I2C2_FORCE_RESET();
__HAL_RCC_I2C2_RELEASE_RESET();
2019-11-12 01:58 AM
Hello,
There is no limitation on I2C2 of STM32F412.
Make sure that you configure the I2C pins and enable alternate function before enable I2C2 clock.
-Amel
PS: Please update your nickname to get rid of this generic "Userxxxxx".
To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.
2019-11-12 04:56 AM
What other status bits are set when BUSY? In which phase does it occur? Did you observe the SCK/SDA using oscilloscope? Do you use the I2C2 as master or as slave? Are there proper pullups on the bus?
JW
2019-11-12 06:10 AM
Thanks for the help all! @Amel NASRI it would be interesting to know if ordering things as you suggest fixes our issue too.
The issue was interesting because we could initialise I2C2 with the following code on PB10/PB11:
__HAL_RCC_GPIOB_CLK_ENABLE();
__HAL_RCC_I2C2_CLK_ENABLE();
HAL_GPIO_INIT(USS_HAL_GPIO_PORT_B, USS_HAL_GPIO_PIN_10, USS_HAL_GPIO_MODE_AF_OD,
USS_HAL_GPIO_SPEED_VERY_HIGH, USS_HAL_GPIO_PULLUP_UP, GPIO_AF4_I2C2);
HAL_GPIO_INIT(USS_HAL_GPIO_PORT_B, USS_HAL_GPIO_PIN_11, USS_HAL_GPIO_MODE_AF_OD,
USS_HAL_GPIO_SPEED_VERY_HIGH, USS_HAL_GPIO_PULLUP_UP, GPIO_AF4_I2C2);
To get it working on PF0/PF1 we needed to reset the peripheral after configuring the GPIOs:
__HAL_RCC_GPIOF_CLK_ENABLE();
__HAL_RCC_I2C2_CLK_ENABLE();
HAL_GPIO_INIT(USS_HAL_GPIO_PORT_F, USS_HAL_GPIO_PIN_0, USS_HAL_GPIO_MODE_AF_OD,
USS_HAL_GPIO_SPEED_VERY_HIGH, USS_HAL_GPIO_PULLUP_UP, GPIO_AF4_I2C2);
HAL_GPIO_INIT(USS_HAL_GPIO_PORT_F, USS_HAL_GPIO_PIN_1, USS_HAL_GPIO_MODE_AF_OD,
USS_HAL_GPIO_SPEED_VERY_HIGH, USS_HAL_GPIO_PULLUP_UP, GPIO_AF4_I2C2);
__HAL_RCC_I2C2_FORCE_RESET();
__HAL_RCC_I2C2_RELEASE_RESET();
2019-11-12 09:03 AM
Try to swap the two pins' initialization in the latter case - as it is now, the former one assigns the pins in SCL-SDA order, while the latter in SDA-SCL order. The former creates a STOP condition, and I wouldn't be surprised if that is needed to properly reset the internal logic of I2C.
Nonetheless, reset (either as you've written, in RCC; or using I2C_CR1.SWRST) is always a good idea to start with.
JW
PS. Change your username to a normal nick.
2019-11-13 01:49 AM
Hi Jan,
Yes, using SWRST should be a solution.
For I2C peripheral where there is no SWRST bit in CR1 register, it is required to reset the I2C peripheral like it is done here:
__HAL_RCC_I2C2_FORCE_RESET();
__HAL_RCC_I2C2_RELEASE_RESET();
-Amel
To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.