cancel
Showing results for 
Search instead for 
Did you mean: 

Working demonstration of I2C2 on STM32F412ZG - Busy flag errata?

MShaw.1072
Associate

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.

1 ACCEPTED SOLUTION

Accepted Solutions
MShaw.1072
Associate

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();

View solution in original post

5 REPLIES 5
Amel NASRI
ST Employee

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.

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

MShaw.1072
Associate

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();

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.

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.