From a3364b5bd94009119a64c0e178d22bfa0aced902 Mon Sep 17 00:00:00 2001 From: David Sidrane Date: Thu, 21 Sep 2017 20:02:05 +0000 Subject: [PATCH] Merged in david_s5/nuttx/master_stm32_f4_i2c (pull request #490) stm32:stm32f40xxx I2C ensure proper isr handling Injecting data errors that causes a STOP to be perceived by the driver, will continually re-enter the isr with SB not set and BTF and RxNE set. This changes allows the interrupts to be cleared and propagates a I2C_SR1_TIMEOUT to the waiting task. Approved-by: Gregory Nutt --- arch/arm/src/stm32/stm32f40xxx_i2c.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/arch/arm/src/stm32/stm32f40xxx_i2c.c b/arch/arm/src/stm32/stm32f40xxx_i2c.c index 9492ebc65ef..ec5bc02d1ed 100644 --- a/arch/arm/src/stm32/stm32f40xxx_i2c.c +++ b/arch/arm/src/stm32/stm32f40xxx_i2c.c @@ -1250,12 +1250,24 @@ static int stm32_i2c_isr_process(struct stm32_i2c_priv_s *priv) priv->status = status; /* Any new message should begin with "Start" condition - * Situation priv->msgc == 0 came from DMA RX handler and should be managed + * However there were 2 situations where that was not true + * Situation 1: priv->msgc == 0 came from DMA RX handler and should + * be managed + * + * Situation 2: If an error is injected that looks like a STOP the + * interrupt will be reentered with some status that will be incorrect. This + * will ensure that the error handler will clear the interrupt enables and + * return the error to the waiting task. */ if (priv->dcnt == -1 && priv->msgc != 0 && (status & I2C_SR1_SB) == 0) { +#ifdef CONFIG_STM32_I2C_DMA return OK; +#else + priv->status |= I2C_SR1_TIMEOUT; + goto state_error; +#endif } /* Check if this is a new transmission so to set up the @@ -2026,6 +2038,9 @@ static int stm32_i2c_isr_process(struct stm32_i2c_priv_s *priv) /* Clear interrupt flags */ +#ifndef CONFIG_STM32_I2C_DMA +state_error: +#endif stm32_i2c_putreg(priv, STM32_I2C_SR1_OFFSET, 0); priv->dcnt = -1;