AnsweredAssumed Answered

I2C on STM32F4 gets stuck while checking EV6 flag

Question asked by schilling.robert on May 26, 2012
Latest reply on Sep 1, 2013 by moshiri.ramin
Hi guys,

I'm working on a STM32F4 Discovery board and trying send over I2C. Therefore I'm using the functions from the Standard Peripheral Library. Unfortunately the device stucks after sending the address while checking the I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED

Here is my initialization:
#define IMU_I2C                          I2C1
#define IMU_I2C_CLK                      RCC_APB1Periph_I2C1
#define IMU_I2C_SCL_PIN                  GPIO_Pin_6         
#define IMU_I2C_SCL_GPIO_PORT            GPIOB                 
#define IMU_I2C_SCL_GPIO_CLK             RCC_AHB1Periph_GPIOB
#define IMU_I2C_SCL_SOURCE               GPIO_PinSource6
#define IMU_I2C_SCL_AF                   GPIO_AF_I2C1
#define IMU_I2C_SDA_PIN                  GPIO_Pin_9                 
#define IMU_I2C_SDA_GPIO_PORT            GPIOB                      
#define IMU_I2C_SDA_GPIO_CLK             RCC_AHB1Periph_GPIOB
#define IMU_I2C_SDA_SOURCE               GPIO_PinSource9
#define IMU_I2C_SDA_AF                   GPIO_AF_I2C1
 
void i2c_init(void)
{
  GPIO_InitTypeDef GPIO_InitStructure;
  I2C_InitTypeDef I2C_InitStructure;
   
  // Enable Clk
  RCC_APB1PeriphClockCmd(IMU_I2C_CLK, ENABLE);
  RCC_AHB1PeriphClockCmd(IMU_I2C_SCL_GPIO_CLK | IMU_I2C_SDA_GPIO_CLK, ENABLE);
 
  // Performing a Reset
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
  RCC_APB1PeriphResetCmd(IMU_I2C_CLK, ENABLE);
  RCC_APB1PeriphResetCmd(IMU_I2C_CLK, DISABLE);
     
  // Remap Pins
  GPIO_PinAFConfig(IMU_I2C_SCL_GPIO_PORT, IMU_I2C_SCL_SOURCE, IMU_I2C_SCL_AF);
  GPIO_PinAFConfig(IMU_I2C_SDA_GPIO_PORT, IMU_I2C_SDA_SOURCE, IMU_I2C_SDA_AF); 
   
  // Initialize SCL
  GPIO_InitStructure.GPIO_Pin = IMU_I2C_SCL_PIN;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;
  GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_NOPULL;
  GPIO_Init(IMU_I2C_SCL_GPIO_PORT, &GPIO_InitStructure);
 
  // Initialize SDA
  GPIO_InitStructure.GPIO_Pin = IMU_I2C_SDA_PIN;
  GPIO_Init(IMU_I2C_SDA_GPIO_PORT, &GPIO_InitStructure);
       
  // I2C configuration
  I2C_InitStructure.I2C_Mode        = I2C_Mode_I2C;
  I2C_InitStructure.I2C_DutyCycle   = I2C_DutyCycle_2;
  I2C_InitStructure.I2C_OwnAddress1 = 0;
  I2C_InitStructure.I2C_Ack         = I2C_Ack_Enable;
  I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
  I2C_InitStructure.I2C_ClockSpeed = 100000;
   
  I2C_Cmd(IMU_I2C, ENABLE);
  I2C_Init(IMU_I2C, &I2C_InitStructure);
}


My sending function is like the examples from ST but it stucks after sending the address while checking the EV6 flag.

void i2c_write_buf(uint8_t address, uint8_t* buf, int32_t len)
{
  while(I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY));
   
  /* Send I2C1 START condition */
  I2C_GenerateSTART(I2C1, ENABLE);
   
  /* Test on I2C1 EV5 and clear it */
  while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));
     
  /* Send slave Address for write */
  I2C_Send7bitAddress(I2C1, address, I2C_Direction_Transmitter);
   
  /* Test on I2C1 EV6 and clear it */
  while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)); //I2C stucks here!!!
   
  while(len--)
  {
    /* Send I2C1 slave register address */
    I2C_SendData(I2C1, *buf++);
     
    /* Test on I2C1 EV8_2 and clear it */
    while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
  }
   
  /* Send I2C1 STOP Condition */
  I2C_GenerateSTOP(I2C1, ENABLE); 
}

For initialization and sending I followed the examples from ST. On the I2C pins the is a magnetometer with external pullups. 

Does anyone know where there is a mistake??

Thanks, Robert

Outcomes