I wanted to create a simple library for i2c, but I stucked in start generation. my code is this:
void i2c_init()
{
gpio_init(GPIOB, 6, GPIO_AFOUT_OPENDRAIN); // Initialize PortB-Pin6 for OpenDrain Alternate Function
gpio_init(GPIOB, 7, GPIO_AFOUT_OPENDRAIN); // Initialize PortB-Pin7 for OpenDrain Alternate Function
RCC -> APB2ENR |= (1<<0); // Enable Clock for AFIO
RCC -> APB1ENR |= (1<<21); // Enable Clock for I2C1
I2C1 -> CR1 |= (1<<15); // Reset I2C1
delay_ms(1);
I2C1 -> CR1 &= ~(1<<15); // Undo Reset I2C1
I2C1 -> CR2 = 8; // Set Freq of I2C1 (8)
I2C1 -> CCR = 40; // Set CCR Value of I2C1 (40)
I2C1 -> TRISE = 9; // Set Max Rise Time for I2C1 (9)
//I2C1 -> OAR1 = 0x4000;
I2C1 -> CR1 |= (1<<0); // Enable I2C1
}
unsigned char i2c_write(unsigned char SlaveAdr, unsigned int RegAdr, unsigned char Data)
{
unsigned int RegAdrH = ((RegAdr & 0xFF00) >> 8);
unsigned int RegAdrL = (RegAdr & 0x00FF);
// Start COM
I2C1 -> CR1 |= (1<8); // Start Conversation
while(!(I2C1 -> SR1 & (1<<0))); // Wait for SB (Start Bit) to set (takes Forever!)
...
}
But this loop never ends and SB bit never sets. I'm working on this for a week but failed every time! Does anybody know how to resolve the issue?
i found the problem thanks to real.
I2C1 -> CR1 |= (1<8) // Missed < sign
I2C1 -> CR1 |= (1<<8) This one do the work.