AnsweredAssumed Answered

Problem with I2Cx_EV_IRQHandler called way too frequent

Question asked by fog.kenneth_blaabjer on Jun 18, 2014
Latest reply on Jun 18, 2014 by fog.kenneth_blaabjer
Hi, I am new to this forum and to using the STM32 processors, so please forgive me if this topic has already been discussed. 

I am using a Discovery board with a STM32L152RC micro-processor on. I am trying to implement the I2C2 as a slave for a GUI I am using. The I2C interface itself is working, but it seems to stop the main loop from running. 

By debugging I can see that the SB bit is set over and over, thus calling the I2C2_EV_IRQHandler again and again even though my I2C port should be a slave and not a master. 

The SB bit should only be set when I create a Start condition, so why is it set again and again when the I2C is in slave mode? The interrupt should only be called if the I2C interface detects an address match. 

void MX_I2C_Init(void)
{     


     GPIO_InitTypeDef GPIO_InitStruct;
     I2C_InitTypeDef  I2C_InitStructure;
     
  /** I2C1 GPIO Configuration (Master) 
  PB8   ------> I2C1_SCL
  PB9   ------> I2C1_SDA     
     ** I2C2 GPIO Configuration (Slave)
  PB10   ------> I2C2_SCL
  PB11   ------> I2C2_SDA
  */
     
  /*Enable or disable the AHB peripheral clock */
  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);                    // Enable GPIO peripheral clock
     
  /*Configure GPIO pin : PB */
  GPIO_InitStruct.GPIO_Pin = GPIO_Pin_8|GPIO_Pin_9|GPIO_Pin_10|GPIO_Pin_11;
     GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;                                             // set pins to alternative function
  GPIO_InitStruct.GPIO_OType = GPIO_OType_OD;                                        // Setup as open-drain if used as output
  GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;                                   // No internal pull-up/down resistor
  GPIO_InitStruct.GPIO_Speed = GPIO_Speed_10MHz;                              // For fast mode, use 10MHz
  GPIO_Init(GPIOB, &GPIO_InitStruct);


  /*Configure GPIO pin alternate function */
  GPIO_PinAFConfig(GPIOB, GPIO_PinSource8, GPIO_AF_I2C1);          // Alternative function I2C1


  /*Configure GPIO pin alternate function */
  GPIO_PinAFConfig(GPIOB, GPIO_PinSource9, GPIO_AF_I2C1);          // Alternative function I2C1
     
     /*Configure GPIO pin alternate function */
  GPIO_PinAFConfig(GPIOB, GPIO_PinSource10, GPIO_AF_I2C2);          // Alternative function I2C2


  /*Configure GPIO pin alternate function */
  GPIO_PinAFConfig(GPIOB, GPIO_PinSource11, GPIO_AF_I2C2);          // Alternative function I2C2
     
  // I2C1 clock enable
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);               // Enable peripheral clock I2C1
  RCC_AHBPeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);                    // Enable peripheral clock I2C1


     // I2C2 clock enable
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C2, ENABLE);               // Enable peripheral clock I2C2
  RCC_AHBPeriphClockCmd(RCC_APB1Periph_I2C2, ENABLE);                    // Enable peripheral clock I2C2
     
     I2C_DeInit(I2C1);                                                                                                                                                           // Important to reset I2C after clock enabled
     I2C_DeInit(I2C2);                                                                                                                                                           // Important to reset I2C after clock enabled
     
  I2C_InitStructure.I2C_ClockSpeed = 200000;                                                                                          // I2C clockspeed 200 kHz                                                                                
     I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;                                                                                          // Alternative function I2C mode
  I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;                                                                      // Duty Cycle 50%
  I2C_InitStructure.I2C_OwnAddress1 = 0x00;                                                                                               // Own address, not relevant in Master mode
  I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;                                                                                          // Acknoledge enabled
  I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;               // 7 bit address     
     I2C_Init(I2C1, &I2C_InitStructure);                                                                                                              // Init I2C1
     
     I2C_InitStructure.I2C_OwnAddress1 = TIA_Address;                                                                           // Address 0x60, (remember to shift address left by one bit = 0xC0)
     I2C_Init(I2C2, &I2C_InitStructure);                                                                                                              // Init I2C2
     
     I2C_StretchClockCmd(I2C1,ENABLE);                                                                                                                   // Enable clock streching
     I2C_StretchClockCmd(I2C2,ENABLE);                                                                                                                   // Enable clock streching
     
     I2C_OwnAddress2Config(I2C2,Driver_Address);                                                                                          // Set I2C2 address2 to 0x68, (remember to shift address left by one bit = 0xD0)
     
     I2C_Cmd(I2C1, ENABLE);                                                                                                                                            // Enable I2C1 peripheral
     I2C_Cmd(I2C2, ENABLE);                                                                                                                                            // Enable I2C2 peripheral
     
}

int main(void)
{


  MX_GPIO_Init();
     MX_I2C_Init();     
     MX_Timer_Init();
     
  SystemCoreClockUpdate();                                          // Get Core Clock Frequency   
  if (SysTick_Configuration(SystemCoreClock / 1000)) {      // SysTick 1 msec interrupts  
    while (1);                                                      // Capture error              
  }     
     
     I2C_ITConfig(I2C2, (I2C_IT_ERR | I2C_IT_EVT | I2C_IT_BUF ), ENABLE);     
     NVIC_EnableIRQ(I2C2_EV_IRQn);
     NVIC_EnableIRQ(I2C2_ER_IRQn);
     
  while (1)
  {          
          GPIO_SetBits(GPIOB,GPIO_Pin_6);  
          Delay(100);
          GPIO_ResetBits(GPIOB,GPIO_Pin_6);          
          Delay(100);     
  }
     
}

The code runs until I enable the NVIC_EnableIRQ(I2C2_EV_IRQn), then it seems to jump instantly to the interrupt and just go around and around in the I2C2_EV_IRQHandler, never to continue to the while(1) loop in the main().

Any suggestions would be greatly appreciated. 

Outcomes