Question
I2C busy flag
Posted on August 05, 2013 at 12:10
Hello,
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){
while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
}
else if(direction == I2C_Direction_Receiver){
while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));
}
}