diff options
author | Lorenz Meier <lm@qgroundcontrol.org> | 2014-10-28 11:09:00 +0100 |
---|---|---|
committer | Lorenz Meier <lm@qgroundcontrol.org> | 2014-10-28 11:09:00 +0100 |
commit | b492c8ac9ea659e4421554ab4a343357f35bafaa (patch) | |
tree | f1c6b9c35d8b40e97819005232d4f9087a256645 | |
parent | cb862233badf378aff6c2fe9b55774401b5a79d4 (diff) | |
parent | 43089519ddfad745cb27fe702d035253bf6e7bb4 (diff) | |
download | px4-nuttx-b492c8ac9ea659e4421554ab4a343357f35bafaa.tar.gz px4-nuttx-b492c8ac9ea659e4421554ab4a343357f35bafaa.tar.bz2 px4-nuttx-b492c8ac9ea659e4421554ab4a343357f35bafaa.zip |
Merge pull request #23 from tridge/pullrequest-i2c-lockup-fix
stm32_i2c: handle more error conditions on I2C bus
-rw-r--r-- | nuttx/arch/arm/src/stm32/stm32_i2c.c | 28 |
1 files changed, 28 insertions, 0 deletions
diff --git a/nuttx/arch/arm/src/stm32/stm32_i2c.c b/nuttx/arch/arm/src/stm32/stm32_i2c.c index 44978862d..fb8718316 100644 --- a/nuttx/arch/arm/src/stm32/stm32_i2c.c +++ b/nuttx/arch/arm/src/stm32/stm32_i2c.c @@ -93,6 +93,9 @@ #include "stm32_i2c.h" #include "stm32_waste.h" +// useful when debugging +// #pragma GCC optimize("O0") + /* At least one I2C peripheral must be enabled */ #if defined(CONFIG_STM32_I2C1) || defined(CONFIG_STM32_I2C2) || defined(CONFIG_STM32_I2C3) @@ -316,6 +319,8 @@ static inline uint32_t stm32_i2c_disablefsmc(FAR struct stm32_i2c_priv_s *priv); static inline void stm32_i2c_enablefsmc(uint32_t ahbenr); #endif /* I2C1_FSMC_CONFLICT */ static int stm32_i2c_isr(struct stm32_i2c_priv_s * priv); +// useful when debugging +// static int stm32_i2c_isr(struct stm32_i2c_priv_s *priv) __attribute__((optimize("O0"))); #ifndef CONFIG_I2C_POLLED #ifdef CONFIG_STM32_I2C1 static int stm32_i2c1_isr(int irq, void *context); @@ -1262,6 +1267,29 @@ static int stm32_i2c_isr(struct stm32_i2c_priv_s *priv) // throw away the unexpected byte stm32_i2c_getreg(priv, STM32_I2C_DR_OFFSET); } + } else if (status & I2C_SR1_TXE) { + /* this should never happen, but it does happen + occasionally with lots of noise on the bus. It means the + peripheral is expecting more data bytes, but we don't have + any to give. + This has been seen with status=0x70084, reproduced with + noise generated by a Jabra wireless headset in close + proximity to the I2C lines + */ + stm32_i2c_putreg(priv, STM32_I2C_DR_OFFSET, 0); + } else if (status & I2C_SR1_BTF) { + /* + we should have handled all cases where this could happen + above, but just to ensure it gets acked, lets clear it here + */ + stm32_i2c_getreg(priv, STM32_I2C_DR_OFFSET); + } else if (status & I2C_SR1_STOPF) { + /* + we should never get this, as we are a master not a + slave. Write CR1 with its current value to clear the + error + */ + stm32_i2c_modifyreg(priv, STM32_I2C_CR1_OFFSET, 0, 0); } /* Do we have more bytes to send, enable/disable buffer interrupts |