You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mynewt.apache.org by je...@apache.org on 2020/11/24 18:21:18 UTC

[mynewt-core] branch master updated: Add busy I2C state recovery on STMF1/F4/L1

This is an automated email from the ASF dual-hosted git repository.

jerzy pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/mynewt-core.git


The following commit(s) were added to refs/heads/master by this push:
     new ea9dff5  Add busy I2C state recovery on STMF1/F4/L1
ea9dff5 is described below

commit ea9dff58e9428ba61dc09e42ed0a1261f5336708
Author: J. Ipanienko <j....@mexicomail.com>
AuthorDate: Tue Jul 21 15:17:16 2020 -0500

    Add busy I2C state recovery on STMF1/F4/L1
    
    Sometime glitche on SDA SCL lines cause I2c to enter
    busy state that never end.
    All calls to read or write will fail later because of BUSY flag.
    Datasheet recommens software reset in that case.
    Workaround applied to transmit only, it could be on receive
    but that should do.
---
 hw/mcu/stm/stm32_common/src/stm32_driver_mod_i2c_v1.c | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/hw/mcu/stm/stm32_common/src/stm32_driver_mod_i2c_v1.c b/hw/mcu/stm/stm32_common/src/stm32_driver_mod_i2c_v1.c
index dcc359e..32053da 100644
--- a/hw/mcu/stm/stm32_common/src/stm32_driver_mod_i2c_v1.c
+++ b/hw/mcu/stm/stm32_common/src/stm32_driver_mod_i2c_v1.c
@@ -373,7 +373,16 @@ HAL_StatusTypeDef HAL_I2C_Master_Transmit_Custom(I2C_HandleTypeDef *hi2c,
       /* Wait until BUSY flag is reset */
       if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BUSY, SET, I2C_TIMEOUT_BUSY_FLAG, tickstart) != HAL_OK)
       {
-        return HAL_BUSY;
+        /* Stuck in busy state, datasheet recommends software reset */
+        HAL_I2C_DeInit(hi2c);
+        hi2c->Instance->CR1 |= I2C_CR1_SWRST;
+        hi2c->Instance->CR1 &= ~I2C_CR1_SWRST;
+        HAL_I2C_Init(hi2c);
+        /* If still busy give up */
+        if(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) == SET)
+        {
+          return HAL_BUSY;
+        }
       }
     }