You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by xi...@apache.org on 2021/06/17 02:22:34 UTC

[incubator-nuttx] branch master updated: risc-v/esp32c3: Adds I2C RESET support via hardware.

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

xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git


The following commit(s) were added to refs/heads/master by this push:
     new 8f59054  risc-v/esp32c3: Adds I2C RESET support via hardware.
8f59054 is described below

commit 8f59054ef211411d40175cda98e8c3edf5aba804
Author: Sara Souza <sa...@espressif.com>
AuthorDate: Tue Jun 15 18:25:24 2021 -0300

    risc-v/esp32c3: Adds I2C RESET support via hardware.
---
 arch/risc-v/src/esp32c3/esp32c3_i2c.c | 89 ++++-------------------------------
 1 file changed, 9 insertions(+), 80 deletions(-)

diff --git a/arch/risc-v/src/esp32c3/esp32c3_i2c.c b/arch/risc-v/src/esp32c3/esp32c3_i2c.c
index a993b0c..8807703 100644
--- a/arch/risc-v/src/esp32c3/esp32c3_i2c.c
+++ b/arch/risc-v/src/esp32c3/esp32c3_i2c.c
@@ -772,9 +772,9 @@ static void esp32c3_i2c_deinit(struct esp32c3_i2c_priv_s *priv)
 
 static void esp32c3_i2c_reset_fsmc(struct esp32c3_i2c_priv_s *priv)
 {
-  esp32c3_i2c_deinit(priv);
+  /* Reset FSM machine */
 
-  esp32c3_i2c_init(priv);
+  modifyreg32(I2C_CTR_REG(priv->id), 0, I2C_FSM_RST_M);
 }
 
 /****************************************************************************
@@ -1140,83 +1140,12 @@ static int esp32c3_i2c_transfer(struct i2c_master_s *dev,
 #ifdef CONFIG_I2C_RESET
 static void esp32c3_i2c_clear_bus(struct esp32c3_i2c_priv_s *priv)
 {
-  uint32_t clock_count;
-  uint32_t stretch_count;
-  int ret;
-
-  const struct esp32c3_i2c_config_s *config = priv->config;
-
-  /* Use GPIO configuration to un-wedge the bus */
-
-  esp32c3_configgpio(config->scl_pin, INPUT_PULLUP | OUTPUT_OPEN_DRAIN);
-  esp32c3_gpio_matrix_out(config->scl_pin, SIG_GPIO_OUT_IDX, 0, 0);
-  esp32c3_configgpio(config->sda_pin, INPUT_PULLUP | OUTPUT_OPEN_DRAIN);
-  esp32c3_gpio_matrix_out(config->sda_pin, SIG_GPIO_OUT_IDX, 0, 0);
-
-  /* Let SDA go high */
-
-  esp32c3_gpiowrite(config->sda_pin, 1);
-
-  /* Clock the bus until any slaves currently driving it let it go. */
-
-  clock_count = 0;
-  while (!esp32c3_gpioread(config->sda_pin))
-    {
-      /* Give up if we have tried too hard */
-
-      if (clock_count++ >= I2C_SCL_CYC_NUM_DEF)
-        {
-          ret = -EIO;
-          goto out;
-        }
-
-      /* Sniff to make sure that clock stretching has finished.
-       *
-       * If the bus never relaxes, the reset has failed.
-       */
-
-      stretch_count = 0;
-      while (!esp32c3_gpioread(config->scl_pin))
-        {
-          /* Give up if we have tried too hard */
+  uint32_t value = VALUE_TO_FIELD(I2C_SCL_CYC_NUM_DEF, I2C_SCL_RST_SLV_NUM);
+  modifyreg32(I2C_SCL_SP_CONF_REG(priv->id), I2C_SCL_RST_SLV_NUM_M, value);
 
-          if (stretch_count++ > 10)
-            {
-              ret = -EIO;
-              goto out;
-            }
-
-          up_udelay(10);
-        }
-
-      /* Drive SCL low */
-
-      esp32c3_gpiowrite(config->scl_pin, 0);
-      up_udelay(10);
-
-      /* Drive SCL high again */
-
-      esp32c3_gpiowrite(config->scl_pin, 1);
-      up_udelay(10);
-    }
-
-  /* Generate a start followed by a stop to reset slave
-   * state machines.
-   */
-
-  esp32c3_gpiowrite(config->sda_pin, 0);
-  up_udelay(10);
-  esp32c3_gpiowrite(config->scl_pin, 0);
-  up_udelay(10);
-  esp32c3_gpiowrite(config->scl_pin, 1);
-  up_udelay(10);
-  esp32c3_gpiowrite(config->sda_pin, 1);
-  up_udelay(10);
-
-  ret = OK;
+  modifyreg32(I2C_SCL_SP_CONF_REG(priv->id), 0, I2C_SCL_RST_SLV_EN_M);
 
-out:
-  return ret;
+  modifyreg32(I2C_CTR_REG(priv->id), 0, I2C_CONF_UPGATE_M);
 }
 #endif
 
@@ -1247,11 +1176,11 @@ static int esp32c3_i2c_reset(struct i2c_master_s *dev)
 
   flags = enter_critical_section();
 
-  esp32c3_i2c_deinit(priv);
+  esp32c3_i2c_reset_fsmc(priv);
 
-  esp32c3_i2c_clear_bus(priv);
+  /* Clear bus */
 
-  esp32c3_i2c_init(priv);
+  esp32c3_i2c_clear_bus(priv);
 
   priv->i2cstate   = I2CSTATE_IDLE;
   priv->msgid      = 0;