2025-08-23 7:01 PM
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);
}
2025-08-24 6:37 AM
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.
2025-08-24 11:29 AM
I was checking the SR1 register for the addr bit in the SFR. Is that what causes the addr bit to clear itself?