2026-03-03 4:48 AM
Hello,
While working with STM32F446RET6, I encountered a problem with I2C1. When using HAL_I2C_Mem_Read_IT(), an error occasionally occurs in the form of sending 0x00 instead of the address with the read bit after Repeated Start. The error seems to only occur with O3 optimization.
I2C Configuration:
NVIC Configuration:
Only TIM1 update interrupt (TIM10 not used), DMA1 stream2 (SPI3_RX) and DMA1 stream5 (SPI3_TX) have higher priority than I2C1.
Here is an example of a correct signal:
The signal with error and I2C_Flush_DR() looks like this:
static void I2C_Flush_DR(I2C_HandleTypeDef *hi2c)
{
/* Write a dummy data in DR to clear TXE flag */
if (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_TXE) != RESET)
{
hi2c->Instance->DR = 0x00U;
}
} The signal and I2C_Flush_DR() looks like this:
static void I2C_Flush_DR(I2C_HandleTypeDef *hi2c)
{
/* Write a dummy data in DR to clear TXE flag */
if (__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_TXE) != RESET)
{
hi2c->Instance->DR = 0xF4U;
}
} As you can see, this happens because I2C_Flush_DR() is called at the wrong time, but I don't know why. The slave address should be written to the DR register, but the value from I2C_Flush_DR() is written instead.
Can anybody help?
Thanks,
Arek
Solved! Go to Solution.
2026-03-04 6:08 AM - edited 2026-03-04 6:09 AM
The specific guideline (my words, not ST) is to handle I2C flags immediately. If your other interrupts are fast enough, it won't matter, but that appears not to be the case here.
2026-03-03 6:29 AM
The I2C peripheral on the STM32F4 has some unfortunate race conditions that must be met to succeed. It would not surprise me if one of these was failing due to the presence of other code.
Can you set the I2C interrupt priority to above all others and retest?
If that doesn't work, depending on your interest and ability level, you may need to instrument HAL to find out what specifically is failing and why. How repeatable is this?
I don't see why it would only happen on O3. All the relevant fields in I2C_HandleTypeDef are volatile.
2026-03-04 1:25 AM
The error appeared irregularly, every few minutes, sometimes more often. I ran test with a higher priority (~6 hours) and the error did not occur, but I don't know if it's gone or if it hasn't appeared yet. So it's possible that this is the solution.
I also ran tests with Og and O2 (each for 2-3 hours) and did not encounter such an error there, so I assumed that the error most likely occurs with O3.
For the future, are there any specific guidelines regarding event handling time? Or just be aware of the time dependencies and ensure them, e.g., through higher interrupt priority and no preemption?
2026-03-04 6:08 AM - edited 2026-03-04 6:09 AM
The specific guideline (my words, not ST) is to handle I2C flags immediately. If your other interrupts are fast enough, it won't matter, but that appears not to be the case here.