AnsweredAssumed Answered

I2C1 interrupts setup

Question asked by jap.javi on Mar 4, 2013
Latest reply on Mar 4, 2013 by jap.javi
Hi,
I am trying to make the I2C work in slave mode in a STM3241G-EVAL.
I want to comunicate the stm32f417 with a mother board that is running Linux (that will be the master).
I am in the very begining and I am doing something wrong because interrupts don't work. I have searched for examples but all I have found is for master mode. Can anyone tell me what I am missing in the I2C1 setup code?

Hardware connections are ok. In linux I am using the i2c-tools and the i2cdetect detects the address configured in the code, among others (althought it shifts it, the 0x0A is seen as 0x05). Also, if I put the code of the interrupt in the main loop it receives the address.
Another doubt I have is how to configure the i2c-tools frequency.

// INITIALIZATION (in main.c)
void init_I2C1(void){
    
  GPIO_InitTypeDef GPIO_InitStruct;
  I2C_InitTypeDef I2C_InitStruct;
    
   // GPIO setup
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
  GPIO_InitStruct.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_9;
  GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;
  GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStruct.GPIO_OType = GPIO_OType_OD;
  GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP;
  GPIO_Init(GPIOB, &GPIO_InitStruct);
  // Connect I2C1 pins to AF
  GPIO_PinAFConfig(GPIOB, GPIO_PinSource6, GPIO_AF_I2C1);
  GPIO_PinAFConfig(GPIOB, GPIO_PinSource9, GPIO_AF_I2C1);
    
  // I2C1 setup
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);
  I2C_InitStruct.I2C_ClockSpeed = 400000; //10000; // 10KHz
  I2C_InitStruct.I2C_Mode = I2C_Mode_I2C;
  I2C_InitStruct.I2C_DutyCycle = I2C_DutyCycle_2;
  I2C_InitStruct.I2C_OwnAddress1 = OWN_ADDRESS;  // 0x0A
  I2C_InitStruct.I2C_Ack = I2C_Ack_Enable;
  I2C_InitStruct.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
  I2C_Init(I2C1, &I2C_InitStruct);
  I2C_Cmd(I2C1, ENABLE);
  
  // I2C1 interrupts
  I2C_ITConfig(I2C1, I2C_IT_EVT | I2C_IT_ERR, ENABLE);  // Enable EVENT and ERROR interrupts
}
  
// In stm32f4xx_it.c
void I2C1_EV_IRQHandler(){
  
     volatile uint32_t temp;
      
     switch (I2C_GetLastEvent(I2C1)){
     case I2C_EVENT_SLAVE_RECEIVER_ADDRESS_MATCHED:
        STM_EVAL_LEDOn(LED3);
        break;
  
     case I2C_EVENT_SLAVE_BYTE_RECEIVED:
        STM_EVAL_LEDToggle(LED4);
        //I2C_InputBuffer[I2C_InputBufferIndex++] = I2C_ReceiveData(I2C1);
        break;
  
     case I2C_EVENT_SLAVE_STOP_DETECTED:
        STM_EVAL_LEDOff(LED3);
        break;
     }
  
    // ADDR & STOPF cleaning
    while ((I2C1->SR1 & I2C_SR1_ADDR) == I2C_SR1_ADDR)
    {
        temp=I2C1->SR1;
        temp=I2C1->SR2;
      }
      while ((I2C1->SR1&I2C_SR1_STOPF) == I2C_SR1_STOPF)
      {
        temp=I2C1->SR1;
        I2C1->CR1 |= 0x1;
      }
}

Outcomes