cancel
Showing results for 
Search instead for 
Did you mean: 

STM32L1 I2C2->SR2 busy flag set after reset

guillem2
Associate II
Posted on June 09, 2014 at 17:26

Hello all,

I am working with an STM32L1 and a I2C interface (Concretely I2C2, Pins PB10 and PB11). I tried different things but I am still not able to overcome the following issue: after intialising the I2C interface (including RCC and GPIO) I am not able to clear the busy flag in the SR2 but both signals (SCL and SDA are at high level 3.3.V pulled up by a Pull up resistor compliant with the I2C specs).

I checked that the pins are not used by any other AF peripheral, I tried with slave and without slave (just having a look with the scope on the SCL and SDA pins) but no success, signals are as expected (high) but the busy flag doesn't disappear. I also tried different microprocessor boards to discard a hardware fault.

I tried to restart the IC2 before using it and in other points during the initalisation with no luck, it clears the busy flag on reset but it is set back to 1 again just after enabling it.

   RCC->APB1RSTR |= RCC_APB1RSTR_I2C2RST; // Reset i2c peripheral

    uint32_t count_down = 1000000;

    while (count_down > 0)

    {

       count_down--;

    };

    RCC->APB1RSTR &= ~RCC_APB1RSTR_I2C2RST;

I know that this issue has been found for several people before, and I have read carefully other post, but I haven't success on make it work.

Here is how my code looks:

//START CODE

  GPIO_InitTypeDef  GPIO_InitStructure;

  I2C_InitTypeDef  I2C_InitStructure;

  RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C2, ENABLE);

  GPIO_PinAFConfig(I2C_SCL_GPIO_PORT, I2C_SCL_GPIO_PIN_SOURCE, GPIO_AF_I2C2);

  GPIO_PinAFConfig(I2C_SDA_GPIO_PORT, I2C_SDA_GPIO_PIN

_SOURCE

, GPIO_AF_I2C2);

  GPIO_InitStructure.GPIO_Pin = I2C_SCL_GPIO_PIN;

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;

  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_40MHz;

  GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;

  GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_NOPULL;

  GPIO_Init(I2C_SCL_GPIO_PORT, &GPIO_InitStructure);

  GPIO_InitStructure.GPIO_Pin = I2C_SDA_GPIO_PIN;

  GPIO_Init(I2C_SDA_GPIO_PORT, &GPIO_InitStructure);

   // I found out that initialising AHB clock where I am intialising RCC_APB1Periph_I2C2 cause SCL and SCA to go low,

   // but initialising just after initialise the GPIO both signals are at 3.3V.

   RCC_AHBPeriphClockCmd(I2C_SCL_GPIO_CLK | I2C_SDA_GPIO_CLK, ENABLE);

   I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;

   I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;

   I2C_InitStructure.I2C_OwnAddress1 = 0xA0;

   I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;

   I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;

   I2C_InitStructure.I2C_ClockSpeed = 100000;// I tried different speeds but no effect.

   I2C_Init(I2C2, &I2C_InitStructure);

   I2C_Cmd(I2C2, ENABLE);

//FINSIH CODE

It would be very useful if somebody has a clue how I can get through this busy state.

Thanks a lot lads.

#i2c-reset #stm32l1 #stm32 #i2c
3 REPLIES 3
stm322399
Senior
Posted on June 09, 2014 at 19:47

Whatever is the root cause of your problem, you *must* enable GPIO clock before programming AF and initializing pins.

Fix this, and try again with I2C2 reset and busy flag check.

jpeacock2399
Associate II
Posted on June 09, 2014 at 21:46

One of the problems with I2C is the behavior of some I2C peripherals after a reset, especially after an incomplete bus transaction.  Some of the ''dumber'' peripherals will not really reset but force a busy, still waiting for a completed transaction.

The trick to fixing this is to first set up the I2C bus as open collector GPIO pins.  Manually clock the SCK line until the busy condition clears, and then go on the initialize the pins as an I2C controller.
guillem2
Associate II
Posted on June 10, 2014 at 14:36

Hi all,

Yesterday reading on the forum I realised that I did the same silly mistake that an other guy posted before: feed the

GPIO_PinAFConfig

function with the GPIO_Pin_11 instead of GPIO_PinSource11. After fixing that the I2C still not working because, as Laurent pointed out, AHB clock must be initialised before GPIO initialisations.

In conclusion, from a fundamental error I started trying several positions on the peripherals and clock initialisations and I didn't put them back to the original place.

So now the I2C busy flag is cleared and I am able to send the start condition... not a huge step by the humanity but a good relieve for me 😉

So thanks Laurent and Jack (I keep the trick for the future).