From 61ff3c6b8424b24eade7bbd522ad3b96ea0b7797 Mon Sep 17 00:00:00 2001 From: Alexander Oryshchenko Date: Fri, 24 Mar 2017 06:43:40 -0600 Subject: [PATCH] =?UTF-8?q?I=20needed=20to=20use=20DS3231,=C2=A0I=20rememb?= =?UTF-8?q?er=C2=A0that=C2=A0in=20past=20it=20worked=20ok,=20but=20now=20f?= =?UTF-8?q?or=20stm32f4xx=20is=20used=20another=20driver=20(chip=20specifi?= =?UTF-8?q?c,=C2=A0stm32f40xxx=5Fi2c.c)=20and=20DS3231=20driver=20doesn't?= =?UTF-8?q?=20work.=20After=20investigating=20a=20problem=20I=20found=20th?= =?UTF-8?q?at=20I2C=20driver=20(isr=20routine)=20has=20a=20few=20places=20?= =?UTF-8?q?there=20it=20sends=20stop=20bit=20even=20if=20not=20all=20messa?= =?UTF-8?q?ges=20are=20managed.=20So,=20e.g.,=20removing=20stm32=5Fi2c=5Fs?= =?UTF-8?q?endstop=20(#1744)=20and=20adding=20stm32=5Fi2c=5Fsendstart=20af?= =?UTF-8?q?ter=20data=20reading=20helps=20to=20make=20DS3231=20working.=20?= =?UTF-8?q?=20Verified=20by=20David=20Sidrane.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- arch/arm/src/stm32/stm32f40xxx_i2c.c | 56 +++++++++++++++++++++++----- 1 file changed, 46 insertions(+), 10 deletions(-) diff --git a/arch/arm/src/stm32/stm32f40xxx_i2c.c b/arch/arm/src/stm32/stm32f40xxx_i2c.c index 8d3a9fa84d..12080928c2 100644 --- a/arch/arm/src/stm32/stm32f40xxx_i2c.c +++ b/arch/arm/src/stm32/stm32f40xxx_i2c.c @@ -1261,6 +1261,15 @@ static int stm32_i2c_isr(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 + */ + + if (priv->dcnt == -1 && priv->msgc != 0 && (status & I2C_SR1_SB) == 0) + { + return OK; + } + /* Check if this is a new transmission so to set up the * trace table accordingly. */ @@ -1516,9 +1525,16 @@ static int stm32_i2c_isr(struct stm32_i2c_priv_s *priv) status |= (stm32_i2c_getreg(priv, STM32_I2C_SR2_OFFSET) << 16); - /* Send Stop */ + /* Send Stop/Restart */ - stm32_i2c_sendstop(priv); + if (priv->msgc > 0) + { + stm32_i2c_sendstart(priv); + } + else + { + stm32_i2c_sendstop(priv); + } i2cinfo("Address ACKed beginning data reception\n"); i2cinfo("short read N=1: programming stop bit\n"); @@ -1828,7 +1844,17 @@ static int stm32_i2c_isr(struct stm32_i2c_priv_s *priv) { i2cinfo("short read N=2: DR and SR full setting stop bit and reading twice\n"); - stm32_i2c_sendstop(priv); + /* Send Stop/Restart */ + + if (priv->msgc > 0) + { + stm32_i2c_sendstart(priv); + } + else + { + stm32_i2c_sendstop(priv); + } + *priv->ptr++ = stm32_i2c_getreg(priv, STM32_I2C_DR_OFFSET); priv->dcnt--; *priv->ptr++ = stm32_i2c_getreg(priv, STM32_I2C_DR_OFFSET); @@ -1905,9 +1931,16 @@ static int stm32_i2c_isr(struct stm32_i2c_priv_s *priv) stm32_i2c_traceevent(priv, I2CEVENT_READ_3, priv->dcnt); - /* Program stop */ + /* Program Stop/Restart */ - stm32_i2c_sendstop(priv); + if (priv->msgc > 0) + { + stm32_i2c_sendstart(priv); + } + else + { + stm32_i2c_sendstop(priv); + } /* read dcnt = 2 */ @@ -2061,7 +2094,14 @@ static void stm32_i2c_dmarxcallback(DMA_HANDLE handle, uint8_t status, void *arg * interrupt routine if enabled. */ - stm32_i2c_sendstop(priv); + if (priv->msgc > 0) + { + stm32_i2c_sendstart(priv); + } + else + { + stm32_i2c_sendstop(priv); + } /* Let the I2C periph know to stop DMA transfers, also is used by ISR to check * if DMA is done. @@ -2115,10 +2155,6 @@ static void stm32_i2c_dmatxcallback(DMA_HANDLE handle, uint8_t status, void *arg regval |= (I2C_CR2_ITERREN | I2C_CR2_ITEVFEN); stm32_i2c_putreg(priv, STM32_I2C_CR2_OFFSET, regval); #endif - - /* let the ISR routine take care of shutting down or switching to next msg */ - - stm32_i2c_isr(priv); } #endif /* ifdef CONFIG_STM32_I2C_DMA */