mirror of
https://gitee.com/mirrors_PX4/PX4-Autopilot.git
synced 2026-07-17 04:40:35 +08:00
c967cade47
backport 3cd66af889b42b036d6c9d88e067fc3b8abbdb2a and pr 258 Applies to STM32F4 and STM32F7 STM32, STM32 F7, and STM32 L4: Clone Freddie Chopin's I2C change to similar STM32 I2C drivers. Save 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.
326 lines
9.8 KiB
Diff
326 lines
9.8 KiB
Diff
diff --git NuttX/nuttx/arch/arm/src/stm32/stm32_i2c.c NuttX/nuttx/arch/arm/src/stm32/stm32_i2c.c
|
|
index 631ba66..669e0db 100644
|
|
--- NuttX/nuttx/arch/arm/src/stm32/stm32_i2c.c
|
|
+++ NuttX/nuttx/arch/arm/src/stm32/stm32_i2c.c
|
|
@@ -7,7 +7,7 @@
|
|
*
|
|
* With extensions, modifications by:
|
|
*
|
|
- * Copyright (C) 2011-2014, 2016 Gregory Nutt. All rights reserved.
|
|
+ * Copyright (C) 2011-2014, 2016-2017 Gregory Nutt. All rights reserved.
|
|
* Author: Gregory Nutt <gnutt@nuttx.org>
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
@@ -670,15 +670,15 @@ static inline int stm32_i2c_sem_waitdone(FAR struct stm32_i2c_priv_s *priv)
|
|
|
|
do
|
|
{
|
|
+ /* Calculate the elapsed time */
|
|
+
|
|
+ elapsed = clock_systimer() - start;
|
|
+
|
|
/* Poll by simply calling the timer interrupt handler until it
|
|
* reports that it is done.
|
|
*/
|
|
|
|
stm32_i2c_isr(priv);
|
|
-
|
|
- /* Calculate the elapsed time */
|
|
-
|
|
- elapsed = clock_systimer() - start;
|
|
}
|
|
|
|
/* Loop until the transfer is complete. */
|
|
@@ -729,6 +729,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);
|
|
@@ -744,10 +748,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. */
|
|
diff --git NuttX/nuttx/arch/arm/src/stm32/stm32_i2c_alt.c NuttX/nuttx/arch/arm/src/stm32/stm32_i2c_alt.c
|
|
index 545a647..981edb6 100644
|
|
--- NuttX/nuttx/arch/arm/src/stm32/stm32_i2c_alt.c
|
|
+++ NuttX/nuttx/arch/arm/src/stm32/stm32_i2c_alt.c
|
|
@@ -7,7 +7,7 @@
|
|
*
|
|
* With extensions, modifications by:
|
|
*
|
|
- * Copyright (C) 2011-2014, 2016 Gregory Nutt. All rights reserved.
|
|
+ * Copyright (C) 2011-2014, 2016-2017 Gregory Nutt. All rights reserved.
|
|
* Author: Gregory Nutt <gnutt@nuttx.org>
|
|
*
|
|
* Copyright( C) 2014 Patrizio Simona. All rights reserved.
|
|
@@ -678,15 +678,15 @@ static int stm32_i2c_sem_waitdone(FAR struct stm32_i2c_priv_s *priv)
|
|
|
|
do
|
|
{
|
|
+ /* Calculate the elapsed time */
|
|
+
|
|
+ elapsed = clock_systimer() - start;
|
|
+
|
|
/* Poll by simply calling the timer interrupt handler until it
|
|
* reports that it is done.
|
|
*/
|
|
|
|
stm32_i2c_isr(priv);
|
|
-
|
|
- /* Calculate the elapsed time */
|
|
-
|
|
- elapsed = clock_systimer() - start;
|
|
}
|
|
|
|
/* Loop until the transfer is complete. */
|
|
@@ -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);
|
|
@@ -753,9 +757,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. */
|
|
diff --git NuttX/nuttx/arch/arm/src/stm32/stm32f30xxx_i2c.c NuttX/nuttx/arch/arm/src/stm32/stm32f30xxx_i2c.c
|
|
index 312e0b4..b2da861 100644
|
|
--- NuttX/nuttx/arch/arm/src/stm32/stm32f30xxx_i2c.c
|
|
+++ NuttX/nuttx/arch/arm/src/stm32/stm32f30xxx_i2c.c
|
|
@@ -7,7 +7,7 @@
|
|
*
|
|
* With extensions and modifications for the F1, F2, and F4 by:
|
|
*
|
|
- * Copyright (C) 2011-2013, 2016 Gregory Nutt. All rights reserved.
|
|
+ * Copyright (C) 2011-2013, 2016-2017 Gregory Nutt. All rights reserved.
|
|
* Author: Gregroy Nutt <gnutt@nuttx.org>
|
|
*
|
|
* And this version for the STM32 F3 by
|
|
@@ -704,15 +704,15 @@ static inline int stm32_i2c_sem_waitdone(FAR struct stm32_i2c_priv_s *priv)
|
|
|
|
do
|
|
{
|
|
+ /* Calculate the elapsed time */
|
|
+
|
|
+ elapsed = clock_systimer() - start;
|
|
+
|
|
/* Poll by simply calling the timer interrupt handler until it
|
|
* reports that it is done.
|
|
*/
|
|
|
|
stm32_i2c_isr(priv);
|
|
-
|
|
- /* Calculate the elapsed time */
|
|
-
|
|
- elapsed = clock_systimer() - start;
|
|
}
|
|
|
|
/* Loop until the transfer is complete. */
|
|
@@ -844,6 +844,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 */
|
|
|
|
cr = stm32_i2c_getreg32(priv, STM32_I2C_CR2_OFFSET);
|
|
@@ -860,9 +864,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. */
|
|
diff --git NuttX/nuttx/arch/arm/src/stm32/stm32f40xxx_i2c.c NuttX/nuttx/arch/arm/src/stm32/stm32f40xxx_i2c.c
|
|
index 2bb715c..e91058a 100644
|
|
--- NuttX/nuttx/arch/arm/src/stm32/stm32f40xxx_i2c.c
|
|
+++ NuttX/nuttx/arch/arm/src/stm32/stm32f40xxx_i2c.c
|
|
@@ -7,7 +7,7 @@
|
|
*
|
|
* With extensions, modifications by:
|
|
*
|
|
- * Copyright (C) 2011-2014, 2016 Gregory Nutt. All rights reserved.
|
|
+ * Copyright (C) 2011-2014, 2016-2017 Gregory Nutt. All rights reserved.
|
|
* Author: Gregory Nutt <gnutt@nuttx.org>
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
@@ -672,15 +672,15 @@ static inline int stm32_i2c_sem_waitdone(FAR struct stm32_i2c_priv_s *priv)
|
|
|
|
do
|
|
{
|
|
+ /* Calculate the elapsed time */
|
|
+
|
|
+ elapsed = clock_systimer() - start;
|
|
+
|
|
/* Poll by simply calling the timer interrupt handler until it
|
|
* reports that it is done.
|
|
*/
|
|
|
|
stm32_i2c_isr(priv);
|
|
-
|
|
- /* Calculate the elapsed time */
|
|
-
|
|
- elapsed = clock_systimer() - start;
|
|
}
|
|
|
|
/* Loop until the transfer is complete. */
|
|
@@ -731,6 +731,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);
|
|
@@ -747,9 +751,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. */
|
|
diff --git NuttX/nuttx/arch/arm/src/stm32f7/stm32_i2c.c NuttX/nuttx/arch/arm/src/stm32f7/stm32_i2c.c
|
|
index d089db9..fd73457 100644
|
|
--- NuttX/nuttx/arch/arm/src/stm32f7/stm32_i2c.c
|
|
+++ NuttX/nuttx/arch/arm/src/stm32f7/stm32_i2c.c
|
|
@@ -7,7 +7,7 @@
|
|
*
|
|
* With extensions and modifications for the F1, F2, and F4 by:
|
|
*
|
|
- * Copyright (C) 2016 Gregory Nutt. All rights reserved.
|
|
+ * Copyright (C) 2016-2017 Gregory Nutt. All rights reserved.
|
|
* Authors: Gregroy Nutt <gnutt@nuttx.org>
|
|
* John Wharington
|
|
* David Sidrane <david_s5@nscdg.com>
|
|
@@ -897,15 +897,15 @@ static inline int stm32_i2c_sem_waitdone(FAR struct stm32_i2c_priv_s *priv)
|
|
|
|
do
|
|
{
|
|
+ /* Calculate the elapsed time */
|
|
+
|
|
+ elapsed = clock_systimer() - start;
|
|
+
|
|
/* Poll by simply calling the timer interrupt handler until it
|
|
* reports that it is done.
|
|
*/
|
|
|
|
stm32_i2c_isr(priv);
|
|
-
|
|
- /* Calculate the elapsed time */
|
|
-
|
|
- elapsed = clock_systimer() - start;
|
|
}
|
|
|
|
/* Loop until the transfer is complete. */
|
|
@@ -1034,6 +1034,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 */
|
|
|
|
cr = stm32_i2c_getreg32(priv, STM32_I2C_CR2_OFFSET);
|
|
@@ -1050,9 +1054,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. */
|
|
diff --git NuttX/nuttx/arch/arm/src/stm32l4/stm32l4_i2c.c NuttX/nuttx/arch/arm/src/stm32l4/stm32l4_i2c.c
|
|
index eed199f..be46524 100644
|
|
--- NuttX/nuttx/arch/arm/src/stm32l4/stm32l4_i2c.c
|
|
+++ NuttX/nuttx/arch/arm/src/stm32l4/stm32l4_i2c.c
|
|
@@ -4,7 +4,7 @@
|
|
*
|
|
* Copyright (C) 2011 Uros Platise. All rights reserved.
|
|
* Author: Uros Platise <uros.platise@isotel.eu>
|
|
- * Copyright (C) 2011-2013, 2016 Gregory Nutt. All rights reserved.
|
|
+ * Copyright (C) 2011-2013, 2016-2017 Gregory Nutt. All rights reserved.
|
|
* Author: Gregroy Nutt <gnutt@nuttx.org>
|
|
* Author: John Wharington
|
|
* Author: Sebastien Lorquet
|
|
@@ -648,15 +648,15 @@ static inline int stm32l4_i2c_sem_waitdone(FAR struct stm32l4_i2c_priv_s *priv)
|
|
|
|
do
|
|
{
|
|
+ /* Calculate the elapsed time */
|
|
+
|
|
+ elapsed = clock_systimer() - start;
|
|
+
|
|
/* Poll by simply calling the timer interrupt handler until it
|
|
* reports that it is done.
|
|
*/
|
|
|
|
stm32l4_i2c_isr(priv);
|
|
-
|
|
- /* Calculate the elapsed time */
|
|
-
|
|
- elapsed = clock_systimer() - start;
|
|
}
|
|
|
|
/* Loop until the transfer is complete. */
|
|
@@ -788,6 +788,10 @@ static inline void stm32l4_i2c_sem_waitstop(FAR struct stm32l4_i2c_priv_s *priv)
|
|
start = clock_systimer();
|
|
do
|
|
{
|
|
+ /* Calculate the elapsed time */
|
|
+
|
|
+ elapsed = clock_systimer() - start;
|
|
+
|
|
/* Check for STOP condition */
|
|
|
|
cr = stm32l4_i2c_getreg32(priv, STM32L4_I2C_CR2_OFFSET);
|
|
@@ -804,9 +808,6 @@ static inline void stm32l4_i2c_sem_waitstop(FAR struct stm32l4_i2c_priv_s *priv)
|
|
return;
|
|
}
|
|
|
|
- /* Calculate the elapsed time */
|
|
-
|
|
- elapsed = clock_systimer() - start;
|
|
}
|
|
|
|
/* Loop until the stop is complete or a timeout occurs. */
|