Skip to main content
Visitor II
September 13, 2025
Question

STM32F407 I2C ADDR bit not being set

  • September 13, 2025
  • 2 replies
  • 543 views

Hi, Im using my own I2C library but after i write the device adress when i receive SB interrupt the adress bit never seems to be set to 1. I have tried testing it with HAL and it seems to work fine. I would be happy if someone could help

void I2C_EventInterruptHandler(I2C_Com* i2c)
{
	uint8_t temp;

	//Check if event interrupt bit is set
	if(I2C_CheckBitStatus(&i2c->i2cReg->I2C_CR2, 9))
	{
		//Start condition
		if(I2C_CheckBitStatus(&i2c->i2cReg->I2C_SR1, 0))
		{
			temp = i2c->i2cReg->I2C_SR1;

			i2c->i2cReg->I2C_DR = i2c->deviceAddress;
		}

		//Check for address sent
		if(I2C_CheckBitStatus(&i2c->i2cReg->I2C_SR1, 1))
		{
			//Check if its in read mode and if rxLegth is 1
			if(i2c->deviceAddress & 1 && i2c->rxLength == 1)
			{
				//Disable ack
				i2c->i2cReg->I2C_CR1 &= ~(1 << 10);
				i2c->i2cReg->I2C_CR1 |= (1 << 9);
			}

			temp = i2c->i2cReg->I2C_SR1;
			temp = i2c->i2cReg->I2C_SR2;
		}

		//Check for tx/rx interrupt bit
		else if(I2C_CheckBitStatus(&i2c->i2cReg->I2C_CR2, 10))
		{
			//tx interrupt
			if(I2C_CheckBitStatus(&i2c->i2cReg->I2C_SR1, 7))
			{
				I2C_TxInterruptHandler(i2c);
			}

			//rx interrupt
			if(I2C_CheckBitStatus(&i2c->i2cReg->I2C_SR1, 6))
			{
				I2C_RxInterruptHandler(i2c);
			}
		}

		//Check for BFT bit
		else if(I2C_CheckBitStatus(&i2c->i2cReg->I2C_SR1, 2))
		{
			I2C_BFTInterruptHandler(i2c);
		}


		//Check for Stop bit
		else if(I2C_CheckBitStatus(&i2c->i2cReg->I2C_SR1, 4))
		{

		}
	}

}

 

    This topic has been closed for replies.

    2 replies

    Technical Moderator
    September 15, 2025

    Hello @Defensive ,

    Check the SR1 and SR2 registers for the ADDR bit, as mentioned in the RM0090: this bit is cleared by software reading SR1 register followed reading SR2, or by hardware when PE=0. 

    Reading I2C_SR2 after reading I2C_SR1 clears the ADDR flag, even if the ADDR flag was set after reading I2C_SR1. Consequently, I2C_SR2 must be read only when ADDR is found set in I2C_SR1 or when the STOPF bit is cleared.

    DefensiveAuthor
    Visitor II
    September 21, 2025

    Hi, sorry for the late response. The problem is that the ADDR bit is not being sent, which should happen after EV5 (Reading SR1 and writing to DR) the solution you are proposing is for clearing the ADDR bit.

    Super User
    September 22, 2025

    Is the slave acknowledging the address? Can you show a plot of SDA/SCL that confirms this?

    • If slave does not respond, ADDR should not be set.
    • If slave does respond, ADDR gets set. Reading SR1 from code or from the debugger will clear it.
    DefensiveAuthor
    Visitor II
    September 22, 2025

    Hi, ACK fault seems to happen with my library but not with HAL.

    Super User
    September 22, 2025

    Read SR1 once at the start of the handler and process each bit in there that is set. Look at HAL library for how it's done correctly. Don't read it and set it to a variable ad hoc. That has consequences.