AnsweredAssumed Answered

STM32F103 - I2C Slave - Polled works, Int fails

Question asked by MWP on Apr 23, 2013
Latest reply on May 2, 2013 by MWP
Hi all,

Im taking my first steps in trying to get a STM32F103 I2C slave working...
Not easy considering what seems to be the complete lack of simple known working examples :(

Polling for I2C events/data works perfectly.

Using the interrupt has issues though.
The int will get the first start/data-byte/stop sequence OK, but after that it fails to work.
The int gets fired, but I2C_GetLastEvent() returns an odd code that doesnt match anything in stm32f10x_i2c.h.
So far i haven't been able to find out where the flags are listed??

Below is the polled & int-driven code...

void I2C_SlaveTest(void)
    GPIO_InitTypeDef    GPIO_InitStructure;
    I2C_InitTypeDef     I2C_InitStructure;
    NVIC_InitTypeDef    NVIC_InitStructure;
    lBYTE               Data;
    //enable clocks
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);
    // I2C1 SDA and SCL configuration
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;
    GPIO_Init(GPIOB, &GPIO_InitStructure);
    I2C_Cmd(I2C1, ENABLE);
    I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
    I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;
    I2C_InitStructure.I2C_OwnAddress1 = I2C_SLAVE;
    I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
    I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
    I2C_InitStructure.I2C_ClockSpeed = 10000;
    I2C_Init(I2C1, &I2C_InitStructure);
#ifndef POLLED
    // I2C1 interrupts
    NVIC_InitStructure.NVIC_IRQChannel = I2C1_EV_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    I2C_ITConfig(I2C1, I2C_IT_EVT /*| I2C_IT_ERR*/, ENABLE);
    while (1)
#ifdef POLLED      
        Data = I2C_ReceiveData(I2C1);
        GPIO_WriteBit(LED4_GRN_PIN, 1);
        GPIO_WriteBit(LED4_GRN_PIN, 0);
#ifndef POLLED
void I2C_Interrupt(void)
    lBYTE           Data;
    switch (Last = I2C_GetLastEvent(I2C1))
            GPIO_WriteBit(LED2_RED_PIN, 1);
            GPIO_WriteBit(LED3_RED_PIN, 1);
            Data = I2C_ReceiveData(I2C1);
            GPIO_WriteBit(LED4_RED_PIN, 1);