cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F407 I2C ADDR bit clearing itself and interrupt problems

Defensive
Associate II

Hi, Im new to STM32 and writing a bare metal interrupt based i2c library. For some reason addr bit clears itself automatically even though im not reading sr1 and sr2. I also have problems with debug mode, if i decide to step over the function that sets up the interrupt for I2C1_EV_IRQ it sometimes causes debugger to skip the interrupt, it happens randomly. I had some problems with the built in debugger.

 

void I2C_ReceiveData(I2C_Com* i2c, uint8_t address, uint8_t deviceRegister, uint8_t* data, uint8_t length)
{
	if(!i2c->isBusy)
	{
		i2c->i2cReg->I2C_CR1 |= (1 << 10);

		i2c->deviceAddress = address;
		i2c->deviceAddress <<= 1;

		i2c->deviceRegister = deviceRegister;
		i2c->registerNotSent = 1;

		i2c->txLength = 0;

		i2c->rxBuffer = data;
		i2c->rxLength = length;

		i2c->isBusy = 1;
		i2c->repeatedStart = 1;

		i2c->i2cReg->I2C_CR2 |= (1 << 9);
		i2c->i2cReg->I2C_CR2 |= (1 << 10);

		SetNVIC(I2C1_EV_IRQ_NUM, 1);

		//Start condition
		i2c->i2cReg->I2C_CR1 |= (1 << 8);
	}
}

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
                //ADDR BIT CLEARS ITSELF CANT GET INTO THIS IF STATEMENT
		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))
		{

		}
	}

}

void I2C1_EV_IRQHandler()
{
	I2C_EventInterruptHandler(&i2c1Com);
}

 

2 REPLIES 2
TDK
Super User

What leads you to believe the bit is clearing itself?

Reading registers with the debugger has the same consequences as reading them with the program. Namely, reading SR1 and SR2 will clear the ADDR bit.

TDK_0-1756042640498.png

 

If you feel a post has answered your question, please click "Accept as Solution".

I was checking the SR1 register for the addr bit in the SFR. Is that what causes the addr bit to clear itself?