cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F415 weird I2C behaviour

Dustin Lehmann
Associate II
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
1 ACCEPTED SOLUTION

Accepted Solutions
Dustin Lehmann
Associate II
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!

View solution in original post

12 REPLIES 12
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

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

AvaTar
Lead
Posted on March 14, 2018 at 12:16

Proper pull-ups ?

Dustin Lehmann
Associate II
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;

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.

Posted on March 14, 2018 at 12:13

Hi thanks for the reply. Unfortunately I do not get the BERR to 1, but the AF. And it is 0 if I send the Start Condition and as soon as I send the Adress or any kind of data, it is set to 1

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.

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).

Posted on March 14, 2018 at 13:13

Yes I know, but currently I'm on a university internship and my scope is standing at home, if all else fails, I will have to wait until next month until I can debug it electrically. What could be different between the F415 on the 1Bitsy board and the F407 on the discovery board in terms of I2C? This is what bothers me, that my approach cannot be totally wrong