Skip to main content
Dustin Lehmann
Associate II
March 14, 2018
Solved

STM32F415 weird I2C behaviour

  • March 14, 2018
  • 12 replies
  • 5777 views
Posted on March 14, 2018 at 09:24

Hello,

I am using a STM32F415RGT6 embedded in the 1Bitsy Board. I want to set up the I2C Peripheral in order to read some data from a sensor.

My example code:

RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB,

ENABLE

);

GPIO_InitTypeDef

gpioInit;

GPIO_StructInit(&gpioInit);

gpioInit.

GPIO_Mode

=

GPIO_Mode_AF

;

gpioInit.

GPIO_Pin

= GPIO_Pin_6 | GPIO_Pin_7;

gpioInit.

GPIO_PuPd

=

GPIO_PuPd_UP

;

gpioInit.

GPIO_Speed

= GPIO_Speed_25MHz;

GPIO_PinAFConfig(GPIOB, GPIO_PinSource6, GPIO_AF_I2C1);

GPIO_PinAFConfig(GPIOB, GPIO_PinSource7, GPIO_AF_I2C1);

GPIO_Init(GPIOB, &gpioInit);

RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1,

ENABLE

);

I2C_DeInit(I2C1);

I2C_InitTypeDef

I2C_InitStructure;

I2C_StructInit(&I2C_InitStructure);

/* I2C configuration */

I2C_InitStructure.

I2C_Mode

= I2C_Mode_I2C;

I2C_InitStructure.

I2C_ClockSpeed

= 100000;

I2C_InitStructure.

I2C_DutyCycle

= I2C_DutyCycle_2;

I2C_InitStructure.

I2C_OwnAddress1

= 0x01;

I2C_InitStructure.

I2C_Ack

= I2C_Ack_Enable;

I2C_InitStructure.

I2C_AcknowledgedAddress

= I2C_AcknowledgedAddress_7bit;

I2C_Init(I2C1, &I2C_InitStructure);

I2C_Cmd(I2C1,

ENABLE

);

while

(I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY))

;

/* Generate Start, send the address and wait for ACK */

I2C_GenerateSTART(I2C1,

ENABLE

);

while

(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT))

;

I2C_Send7bitAddress(I2C1, 0xE0, I2C_Direction_Transmitter);

while

(!I2C_CheckEvent(I2C1,

I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))

;

After that I want to write a 0x00, but the code always hangs in the last line, apparently the Master never reads the acknowledge. The I2C status registers always read:

I2C1 -> SR1 = 1024

I2C1 -> SR2 = 3

which means that the Acknowledge Failure bit is always set. If I analyze it using my Saleae I get the following:

0690X0000060A7aQAE.png

The Slave sends the ACK, but the STM32F415 cannot read it.

The weird thing: If I try the same code on my F407 - Disco (only with clock set to 400khz, but it's the same behaviour on both MCUs regardless of Speed), it works flawlessly:

0690X0000060A7VQAU.png

All other peripherals work fine. I already tried several workarounds, but the AF bit is always set, regardless of method. I hope you can help me.

Best Regards

#i2c #acknowledge-byte #stm32f4 #i2c-setup #stm32f415 #i2c-bug
This topic has been closed for replies.
Best answer by Dustin Lehmann
Posted on March 14, 2018 at 21:55

Well, I found the problem. It just don't work with the F415 with the logic analyzer measuring SCL and SDA. If I remove the analyzer it works. With the F407 it does not matter if it is plugged in or not. Well, that were 8 wasted hours of debugging. Thanks to all who tried to help me!

12 replies

waclawek.jan
Super User
March 14, 2018
Posted on March 14, 2018 at 10:26

The I2C is a quirky peripheral.

Read out and compare all I2C registers between the working and non-working example.

JW

Dustin Lehmann
Associate II
March 14, 2018
Posted on March 14, 2018 at 10:32

All Control Registers are set the same after intialization. After the sending of the start condition, the SR1 and SR2 are also the same. Only after sending the address, the working example on the STM32F407 produces correct results in SR1, on the F415 the SR1 immediately jumps to 1024, which means only the AF bit is set

john doe
Senior III
March 14, 2018
Posted on March 14, 2018 at 12:07

I have a problem with F446 [and none of my other boards do with this slave] where it throws a bus error every time the controller resets.  Here's how I worked around it, in my function that does the low level reading:

    uint32_t tmpreg = 0;

    tmpreg = hi2c1.Instance->SR1;

    if ( tmpreg & I2C_SR1_BERR )        // bus error

    {

        HAL_I2C_MspDeInit(&hi2c1);

        HAL_I2C_MspInit(&hi2c1);

        MX_I2C1_Init();

    }

and then I continue on with my HAL_I2C_Master_Transmit.  I do think the I2C in F1/F4 series is buggy.  L4 and F7 just work.

AvaTar
Senior III
March 14, 2018
Posted on March 14, 2018 at 12:16

Proper pull-ups ?

Dustin Lehmann
Associate II
March 14, 2018
Posted on March 14, 2018 at 12:26

Yes. Tried the internal ones, and external 1.8kOhm/3.3kOhm/4.7 kOhm Resistors to 3.3V, same behaviour.

AvaTar
Senior III
March 14, 2018
Posted on March 14, 2018 at 13:08

At least the internal one's are proven to be totally inappropriate as I2C pull-ups.

And I totally agree with Jan, the I2C is a quirky peripheral.

Albeit, logic analyzers are not always a good substitute tool for scopes (like for the I2C bus at this speed).

Dustin Lehmann
Associate II
March 14, 2018
Posted on March 14, 2018 at 12:44

I forgot in the above code snippet the following line (which is included in the original one), I don't why it slipped while copying:

gpioInit.GPIO_OType = GPIO_OType_OD;

Dustin Lehmann
Dustin LehmannAuthorBest answer
Associate II
March 14, 2018
Posted on March 14, 2018 at 21:55

Well, I found the problem. It just don't work with the F415 with the logic analyzer measuring SCL and SDA. If I remove the analyzer it works. With the F407 it does not matter if it is plugged in or not. Well, that were 8 wasted hours of debugging. Thanks to all who tried to help me!

waclawek.jan
Super User
March 14, 2018
Posted on March 14, 2018 at 23:16

That sounds like marginal timing settings.

In the 'F4xx, the I2C has quite a couple of timing settings. Can you please post those read-out values?

JW