cancel
Showing results for 
Search instead for 
Did you mean: 

I2C1 interrupts setup

occam25
Associate II
Posted on March 04, 2013 at 11:31

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;
}
}

#i2c-interrupts-stm32
1 REPLY 1
occam25
Associate II
Posted on March 04, 2013 at 12:29

Sorry, I forgot to configure the NVIC... now it works :)

The i2c setup code is the following:

void init_I2C1(void){
GPIO_InitTypeDef GPIO_InitStruct;
I2C_InitTypeDef I2C_InitStruct;
NVIC_InitTypeDef NVIC_InitStructure;
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); 
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;
I2C_InitStruct.I2C_Ack = I2C_Ack_Enable; //I2C_Ack_Disable;
I2C_InitStruct.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
I2C_Init(I2C1, &I2C_InitStruct);
I2C_Cmd(I2C1, ENABLE);
// I2C1 interrupts
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
NVIC_InitStructure.NVIC_IRQChannel = I2C1_EV_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = I2C1_ER_IRQn;
NVIC_Init(&NVIC_InitStructure);
I2C_ITConfig(I2C1, I2C_IT_EVT | I2C_IT_ERR, ENABLE);
}