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);
}