2025-09-13 6:58 AM
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))
{
}
}
}
2025-09-15 3:29 AM
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.
2025-09-21 1:48 PM
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.
2025-09-22 8:49 AM
Is the slave acknowledging the address? Can you show a plot of SDA/SCL that confirms this?
2025-09-22 12:44 PM
Hi, ACK fault seems to happen with my library but not with HAL.
2025-09-22 1:29 PM - edited 2025-09-22 1:31 PM
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.
2025-09-22 3:50 PM - edited 2025-09-22 3:55 PM
Isnt the way HAL reads the register same? Creating a temp var and assigning it. For example to clear the ADDR flag it uses this. Also doing what you did didnt work.
#define __HAL_I2C_CLEAR_ADDRFLAG(__HANDLE__) \
do{ \
__IO uint32_t tmpreg = 0x00U; \
tmpreg = (__HANDLE__)->Instance->SR1; \
tmpreg = (__HANDLE__)->Instance->SR2; \
UNUSED(tmpreg); \
} while(0)