After the I2C start, the interrupt handler is called in a loop with I2C_EVENT_MASTER_MODE_SELECT event
Hello everybody,
First I have to say that I never implemented I2C with interruptions. I searched on this forum and on the ST libraries a functional and simple send/receive I2C code working with interruptions and I don't find something interesting, maybe I'm wrong. If you have a good example, do not hesitate :) I have already a working code for I2C communications (including I2C1_Start,I2C1_Repeated_Start,I2C1_Stop,I2C1_Wr,I2C1_Read_Ack,I2C1_Read) but without interruptions: my code is not real-time. For the moment I just coded an interruption handler to check if thisIRQHandleris called each time an I2C message is received by the STM32:void
I2C_Config(
void)
{ RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE); RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE); GPIO_InitTypeDef GPIO_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; /////////////////////// /// INIT GPIO I2C /// /////////////////////// // SDA and SCL Pins declaration GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_6; // SDA, SCLGPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType = GPIO_OType_OD; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; GPIO_Init(GPIOB, &GPIO_InitStructure); // READY pin GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8; // INTGPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; GPIO_Init(GPIOB, &GPIO_InitStructure); // Connect I2C1 pins to AF GPIO_PinAFConfig(GPIOB, GPIO_PinSource6, GPIO_AF_I2C1); // SCLGPIO_PinAFConfig(GPIOB, GPIO_PinSource9, GPIO_AF_I2C1);
// SDAI2C_DeInit(I2C1);
I2C_InitTypeDef I2C_InitStruct; I2C_InitStruct.I2C_ClockSpeed = 400000; // 400kHzI2C_InitStruct.I2C_Mode = I2C_Mode_I2C;
// I2C modeI2C_InitStruct.I2C_DutyCycle = I2C_DutyCycle_2;
// 50% duty cycle --> standardI2C_InitStruct.I2C_OwnAddress1 = 0x00;
// own address, not relevant in master modeI2C_InitStruct.I2C_Ack = I2C_Ack_Enable;
// enable acknowledge when reading (can be changed later on)I2C_InitStruct.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
// set address length to 7 bit addressesI2C_Init(I2C1, &I2C_InitStruct);
// init I2C1I2C_Cmd(I2C1, ENABLE);
// I2C NVIC NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4); NVIC_InitStructure.NVIC_IRQChannel = I2C1_EV_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = PREAMPTION_PRIORITY_LOW; 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,ENABLE); // enable event IRQ}
void
I2C1_EV_IRQHandler(
void)
{ uint32_t LastI2Cevent = I2C_GetLastEvent(I2C1); switch(LastI2Cevent)
{ caseI2C_EVENT_SLAVE_RECEIVER_ADDRESS_MATCHED:
break;
caseI2C_EVENT_SLAVE_BYTE_RECEIVED:
break;
caseI2C_EVENT_SLAVE_TRANSMITTER_ADDRESS_MATCHED:
break;
caseI2C_EVENT_SLAVE_STOP_DETECTED:
break;
caseI2C_EVENT_SLAVE_BYTE_TRANSMITTED:
break;
caseI2C_EVENT_SLAVE_ACK_FAILURE:
break;
caseI2C_EVENT_MASTER_MODE_SELECT:
break;
default:
break;
} } After the first time I execute my I2C1_Start() function ,the code stays at the commandwhile
(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));
... and this interrupt handler is called in a loop, withLastI2Cevent =
I2C_EVENT_MASTER_MODE_SELECT
event. Do you have any idea why? Thanks a lot!