AnsweredAssumed Answered

I2C busy flag

Question asked by epifanio.edgar on Aug 5, 2013
Latest reply on Aug 8, 2013 by epifanio.edgar

I am trying to connect two boards using I2C. I have already configured one as master but whenever I send the start condition the I2C bus is busy. Maybe I am wrong in the initialization of the GPIO pins.

Find the initialization code below.
Thanks in advance!

void init_I2C2(void){
    GPIO_InitTypeDef GPIO_InitStruct;
    I2C_InitTypeDef I2C_InitStruct;
    // enable APB1 peripheral clock for I2C2
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C2, ENABLE);
    // enable clock for SCL and SDA pins
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOH, ENABLE);
    /* setup SCL and SDA pins
     * SCL on PH5 and SDA on PH4
    GPIO_InitStruct.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_5; // we are going to use PH4 and PH5
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;           // set pins to alternate function
    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;      // set GPIO speed
    GPIO_InitStruct.GPIO_OType = GPIO_OType_OD;         // set output to open drain --> the line has to be only pulled low, not driven high
    GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;
    GPIO_Init(GPIOH, &GPIO_InitStruct);                 // init GPIOH
    // Connect I2C2 pins to AF
    GPIO_PinAFConfig(GPIOH, GPIO_PinSource4, GPIO_AF_I2C2); // SCL
    GPIO_PinAFConfig(GPIOH, GPIO_PinSource5, GPIO_AF_I2C2); // SDA
    // configure I2C2
    I2C_InitStruct.I2C_ClockSpeed = 100000;         // 100kHz
    I2C_InitStruct.I2C_Mode = I2C_Mode_I2C;         // I2C mode
    I2C_InitStruct.I2C_DutyCycle = I2C_DutyCycle_2; // 50% duty cycle --> standard
    I2C_InitStruct.I2C_OwnAddress1 = 0x00;          // own address, not relevant in master mode
    I2C_InitStruct.I2C_Ack = I2C_Ack_Enable;        // disable acknowledge when reading (can be changed later on)
    I2C_InitStruct.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit; // set address length to 7 bit addresses
    I2C_Init(I2C2, &I2C_InitStruct);                // init I2C2
    // enable I2C2
    I2C_Cmd(I2C2, ENABLE);
/* This function issues a start condition and
 * transmits the slave address + R/W bit
 * Parameters:
 *      I2Cx --> the I2C peripheral e.g. I2C1
 *      address --> the 7 bit slave address
 *      direction --> the tranmission direction can be:
 *                      I2C_Direction_Transmitter for Master transmitter mode
 *                      I2C_Direction_Receiver for Master receiver
void I2C_start(I2C_TypeDef* I2Cx, uint8_t address, uint8_t direction){
    // wait until I2C2 is not busy anymore
    while(I2C_GetFlagStatus(I2Cx, I2C_FLAG_BUSY));
    // Send I2C1 START condition
    I2C_GenerateSTART(I2Cx, ENABLE);
    // wait for I2C1 EV5 --> Slave has acknowledged start condition
    while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_MODE_SELECT));
    // Send slave Address for write
    I2C_Send7bitAddress(I2Cx, address, direction);
    /* wait for I2C1 EV6, check if
     * either Slave has acknowledged Master transmitter or
     * Master receiver mode, depending on the transmission
     * direction
    if(direction == I2C_Direction_Transmitter){
    else if(direction == I2C_Direction_Receiver){
        while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));