2026-02-04 1:36 PM
Hello,
I am using the HAL for multi-master SMBUS operations on an STM32H753. I ran into a scenario in which the event handler interrupt function (I2C4_EV_IRQHandler() in my case) was repeatedly firing such that there was no CPU available for other code to run.
It seems that the logic within HAL_SMBUS_EV_IRQHandler(), which the above function calls, may not be correctly identifying the source of the interrupt, and not clearing it.
This code:
/* SMBUS in mode Transmitter ---------------------------------------------------*/
if ((SMBUS_CHECK_IT_SOURCE(tmpcr1value, (SMBUS_IT_TCI | SMBUS_IT_STOPI |
SMBUS_IT_NACKI | SMBUS_IT_TXI)) != RESET) &&
((SMBUS_CHECK_FLAG(tmpisrvalue, SMBUS_FLAG_TXIS) != RESET) ||
(SMBUS_CHECK_FLAG(tmpisrvalue, SMBUS_FLAG_TCR) != RESET) ||
(SMBUS_CHECK_FLAG(tmpisrvalue, SMBUS_FLAG_TC) != RESET) ||
(SMBUS_CHECK_FLAG(tmpisrvalue, SMBUS_FLAG_STOPF) != RESET) ||
(SMBUS_CHECK_FLAG(tmpisrvalue, SMBUS_FLAG_AF) != RESET)))
{calls SMBUS_CHECK_IT_SOURCE() to see if certain interrupts are enabled in the control register, before checking the associated statuses in the status register. However, looking at the definition of this macro, this code is not checking whether ANY of the four interrupts are enabled - it is instead checking if ALL of the four interrupts are enabled:
#define SMBUS_CHECK_IT_SOURCE(__CR1__, __IT__) ((((__CR1__) & (__IT__)) == (__IT__)) ? SET : RESET)I believe the intent was probably to check whether ANY of these interrupts are enabled (?).
The same possibly-incorrect pattern is repeated again below under "SMBUS in mode Receiver", but is done correctly under "SMBUS in mode Listener Only".
E.g., in my particular case, only the SMBUS_IT_TCI/TCIE interrupt enable bit was set in CR1 (the other three were clear). And the TC bit was set in the ISR register, needing to be cleared, but the if condition above was not passing and not allowing SMBUS_Master_ISR() to execute and potentially clear the interrupt.
I compared this SMBUS HAL code to the general I2C HAL code, and saw that the I2C HAL code does not follow this pattern - it checks only one bit at a time with I2C_CHECK_IT_SOURCE().
Similar HAL SMBUS code seems to also appear for processors other than the H7 that I am using.
Thanks,
Brian