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_DeInit(I2C1);
    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_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);
    I2C_ITConfig(I2C1, I2C_IT_EVT /*| I2C_IT_ERR*/, ENABLE);
#endif 
 
    while (1)
    {
#ifdef POLLED      
        if (!I2C_CheckFlag(I2C_EVENT_SLAVE_RECEIVER_ADDRESS_MATCHED, LED1_RED_PIN))
            continue;
 
        if (!I2C_CheckFlag(I2C_EVENT_SLAVE_BYTE_RECEIVED, LED2_RED_PIN))
            continue;
        Data = I2C_ReceiveData(I2C1);
 
        if (!I2C_CheckFlag(I2C_EVENT_SLAVE_STOP_DETECTED, LED3_RED_PIN))
            continue;
 
        GPIO_WriteBit(LED4_GRN_PIN, 1);
        GPIO_Delay(100);
        GPIO_WriteBit(LED4_GRN_PIN, 0);
#endif     
    }
}
 
#ifndef POLLED
void I2C_Interrupt(void)
{
    lBYTE           Data;
 
    switch (Last = I2C_GetLastEvent(I2C1))
    {
        case I2C_EVENT_SLAVE_RECEIVER_ADDRESS_MATCHED:
            GPIO_WriteBit(LED2_RED_PIN, 1);
            break;
 
        case I2C_EVENT_SLAVE_BYTE_RECEIVED:
            GPIO_WriteBit(LED3_RED_PIN, 1);
            Data = I2C_ReceiveData(I2C1);
            break;
 
        case I2C_EVENT_SLAVE_STOP_DETECTED:
            GPIO_WriteBit(LED4_RED_PIN, 1);
            break;
             
        default:
            break;
    }
}
#endif

Outcomes