4
\$\begingroup\$

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. I am using the stm32f4 standard peripheral library.

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:

STM32F415 Logic Analyzer

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:

STM32F407-DISCO Logic Analyzer

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.

P.S: I have tried with and without additional pullups and the I2C Slave Address is fine, because it works with STM32F0, STM32F4-DISCO and Atmel Mcus.

Best Regards and Thanks in advance!

\$\endgroup\$
  • \$\begingroup\$ gpioInit.GPIO_PuPd = GPIO_PuPd_UP; should be gpioInit.GPIO_PuPd = GPIO_OType_OD; with pull-ups. \$\endgroup\$ – Abel Tom Mar 14 '18 at 12:13
  • \$\begingroup\$ yes indeed, but unfortunately I dit it, I don't know why it slipped while copying the code from Eclipse to here. Sorry for the confusion \$\endgroup\$ – Dustin Lehmann Mar 14 '18 at 15:21
  • \$\begingroup\$ I would say the slave address is not correct, if the 7 bit slave address is 0xE0 then you need to pass the eight bit address to the API I2C_Send7bitAddress(I2C1, uint8_t(0xE0<<1), I2C_Direction_Transmitter); but im strongly guessing it is 0x70 and you already shifted it \$\endgroup\$ – Abel Tom Mar 15 '18 at 7:03
  • 1
    \$\begingroup\$ Do you have an oscilloscope you can try instead of the Saleae? When I've had problems with I2C, it was because my pullup was too weak and the waveform was very sloppy. The Saleae wouldn't show that but a scope would. \$\endgroup\$ – Glenn Willen Mar 15 '18 at 7:33
  • \$\begingroup\$ @AbelTom the I2C Send7Bit function converts it 8bit format. \$\endgroup\$ – ammar.cma Mar 15 '18 at 7:41
2
\$\begingroup\$

thanks for all the suggestions. I found the solution and it's kind of weird. It works correctly on both boards, but on the STM32F415 it does not work with the logic analyzer capturing the data. On the F407 it does not matter. It's kind of a heisenbug, it does not happen if I don't look, but I had to look to know if it is working.

\$\endgroup\$
  • 3
    \$\begingroup\$ This likely means that your pullup resistors are too weak. It's part of why looking with a scope is useful to see the character of the signal, even if the logic analyzer is better at decoding the protocol (at least once you get a non-trivial amount of data that challenges the speed and UI of a typical modern scope's built-in I2C decoder). \$\endgroup\$ – Chris Stratton Mar 15 '18 at 15:21
  • 1
    \$\begingroup\$ And when your company buys a scope, but doesnt buy the licence for the I2C decoder \$\endgroup\$ – BeB00 Mar 16 '18 at 0:11

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.