2023-04-26 05:03 AM
Hi,
We're using the STM32 HAL layer(STM32G0xx_HAL_Driver v1.6.1) for I2C and see that when re-enabling the I2C listen interrupt, the HAL_I2C_ListenCpltCallback is called twice. This results in that the first I2C read cmd works but the second after that fails.
Our callback:
void HAL_I2C_ListenCpltCallback(I2C_HandleTypeDef *i2c_handle)
{
if (my_i2c.state == MY_I2C_STATE_DONE) {
my_i2c.state = MY_I2C_STATE_RX_ADDR;
HAL_I2C_EnableListen_IT(i2c_handle);
}
}
The reason for this seems to be that we're calling HAL_I2C_EnableListen_IT from interrupt/HAL context.
What seems to happen in I2C_Slave_ISR_IT are these calls:
1. I2C_ITSlaveCplt(5036) -> HAL_I2C_ListenCpltCallback(6173) -> our function above
2. our function above -> HAL_I2C_EnableListen_IT
3. I2C_ITListenCplt(5053) -> HAL_I2C_ListenCpltCallback(6256) -> our function above
What happens is that function in 2 above changes the HAL internal state to:
hi2c->State = HAL_I2C_STATE_LISTEN
while in 3 the HAL driver checks that state and erroneously(I think) calls the HAL_I2C_ListenCpltCallback again.
This means that we can't really do calls from the HAL_I2C_ListenCpltCallback down to HAL again or we use the driver wrongly. It could be fixed by keeping track of the old state in I2C_Slave_ISR_IT and check that instead of the current state. Not sure if this is the preferred solution though.
When looking at some old code e.g. HAL v1.2.0 this does not seem to be a problem since I2C_ITSlaveCplt is never called.
Solved! Go to Solution.
2023-04-28 09:36 AM
Hi Andrka,
Your question has been routed to the online support team. A case has been created and you'll be contacted shortly.
Kind Regards
STMicro Support
Joe WILLIAMS
2023-04-27 01:10 PM
Hi, open issue here
https://github.com/STMicroelectronics/STM32Cubeg0
2023-04-28 09:36 AM
Hi Andrka,
Your question has been routed to the online support team. A case has been created and you'll be contacted shortly.
Kind Regards
STMicro Support
Joe WILLIAMS
2024-04-16 04:56 AM
Just wondering if this was resolved. I'm having what I think is the same issue.
I can move the HAL_I2C_EnableListen_IT call to main, but I'm concerned about the window where my device won't be listening to i2c messages.
If there is a way to enable listen from the cplt callback then at least the window would be shorter. Even better might be to never disable listen mode, but I haven't found a way to do that.
Thanks.