ave elapsed time before handling I2C in stm32_i2c_sem_waitstop()
This patch follows the same logic as in previous fix to stm32_i2c_sem_waitdone(). It is possible that a context switch occurs after I2C registers are read but before elapsed time is saved in stm32_i2c_sem_waitstop(). It is then possible that the registers were read only once with "elapsed time" equal 0. When scheduler resumes this thread it is quite possible that now "elapsed time" will be well above timeout threshold. In that case the function returns and reports a timeout, even though the registers were not read "recently". Fix this by inverting the order of operations in the loop - save elapsed time before reading registers. This way a context switch anywhere in the loop will not cause an erroneous "timeout" error.
This commit is contained in:
parent
d391f9d7d3
commit
3cd66af889
@ -737,6 +737,10 @@ static inline void stm32_i2c_sem_waitstop(FAR struct stm32_i2c_priv_s *priv)
|
||||
start = clock_systimer();
|
||||
do
|
||||
{
|
||||
/* Calculate the elapsed time */
|
||||
|
||||
elapsed = clock_systimer() - start;
|
||||
|
||||
/* Check for STOP condition */
|
||||
|
||||
cr1 = stm32_i2c_getreg(priv, STM32_I2C_CR1_OFFSET);
|
||||
@ -752,10 +756,6 @@ static inline void stm32_i2c_sem_waitstop(FAR struct stm32_i2c_priv_s *priv)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/* Calculate the elapsed time */
|
||||
|
||||
elapsed = clock_systimer() - start;
|
||||
}
|
||||
|
||||
/* Loop until the stop is complete or a timeout occurs. */
|
||||
|
Loading…
Reference in New Issue
Block a user