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 2023/08/14 09:51:53 UTC

[nuttx] branch master updated: arch/{nrf52|nrf53|nrf91}: handle I2C errors in interrupt mode

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/nuttx.git


The following commit(s) were added to refs/heads/master by this push:
     new b73e1b9591 arch/{nrf52|nrf53|nrf91}: handle I2C errors in interrupt mode
b73e1b9591 is described below

commit b73e1b959110e89cf73e4e26e4884e806583b7f1
Author: raiden00pl <ra...@railab.me>
AuthorDate: Mon Aug 14 08:55:01 2023 +0200

    arch/{nrf52|nrf53|nrf91}: handle I2C errors in interrupt mode
---
 arch/arm/src/nrf52/nrf52_i2c.c | 36 ++++++++++++++++++++----------------
 arch/arm/src/nrf53/nrf53_i2c.c | 38 +++++++++++++++++++++-----------------
 arch/arm/src/nrf91/nrf91_i2c.c | 36 ++++++++++++++++++++----------------
 3 files changed, 61 insertions(+), 49 deletions(-)

diff --git a/arch/arm/src/nrf52/nrf52_i2c.c b/arch/arm/src/nrf52/nrf52_i2c.c
index c9c810ec4f..9e0310b426 100644
--- a/arch/arm/src/nrf52/nrf52_i2c.c
+++ b/arch/arm/src/nrf52/nrf52_i2c.c
@@ -41,14 +41,6 @@
 #include "hardware/nrf52_twi.h"
 #include "hardware/nrf52_utils.h"
 
-/****************************************************************************
- * Pre-processor Definitions
- ****************************************************************************/
-
-/* I2C errors not functional yet */
-
-#undef CONFIG_NRF52_I2C_ERRORS
-
 /****************************************************************************
  * Private Types
  ****************************************************************************/
@@ -412,6 +404,7 @@ static int nrf52_i2c_transfer(struct i2c_master_s *dev,
 
           if (priv->status < 0)
             {
+              ret = priv->status;
               goto errout;
             }
 #endif
@@ -464,6 +457,7 @@ static int nrf52_i2c_transfer(struct i2c_master_s *dev,
 
           if (priv->status < 0)
             {
+              ret = priv->status;
               goto errout;
             }
 #endif
@@ -511,6 +505,7 @@ static int nrf52_i2c_transfer(struct i2c_master_s *dev,
 
   if (priv->status < 0)
     {
+      ret = priv->status;
       goto errout;
     }
 #endif
@@ -560,6 +555,7 @@ static int nrf52_i2c_reset(struct i2c_master_s *dev)
 static int nrf52_i2c_isr(int irq, void *context, void *arg)
 {
   struct nrf52_i2c_priv_s *priv = (struct nrf52_i2c_priv_s *)arg;
+  uint32_t                 regval = 0;
 
   /* Reset I2C status */
 
@@ -613,14 +609,26 @@ static int nrf52_i2c_isr(int irq, void *context, void *arg)
       nrf52_i2c_putreg(priv, NRF52_TWIM_EVENTS_STOPPED_OFFSET, 0);
     }
 
-#ifdef CONFIG_NRF52_I2C_ERRORS
   if (nrf52_i2c_getreg(priv, NRF52_TWIM_EVENTS_ERROR_OFFSET) == 1)
     {
-      i2cerr("I2C ERROR\n");
+      regval = nrf52_i2c_getreg(priv, NRF52_TWIM_ERRORSRC_OFFSET) & 0x7;
+
+      i2cerr("Error SRC: 0x%08" PRIx32 "\n", regval);
 
       /* Set ERROR status */
 
-      priv->status = ERROR;
+      if (regval & TWIM_ERRORSRC_OVERRUN)
+        {
+          /* Overrun error */
+
+          priv->status = -EIO;
+        }
+      else
+        {
+          /* NACK */
+
+          priv->status = -ENXIO;
+        }
 
       /* ERROR event */
 
@@ -629,8 +637,8 @@ static int nrf52_i2c_isr(int irq, void *context, void *arg)
       /* Clear event */
 
       nrf52_i2c_putreg(priv, NRF52_TWIM_EVENTS_ERROR_OFFSET, 0);
+      nrf52_i2c_putreg(priv, NRF52_TWIM_ERRORSRC_OFFSET, 0x7);
     }
-#endif
 
   return OK;
 }
@@ -684,12 +692,8 @@ static int nrf52_i2c_init(struct nrf52_i2c_priv_s *priv)
 #ifndef CONFIG_I2C_POLLED
   /* Enable I2C interrupts */
 
-#ifdef CONFIG_NRF52_I2C_ERRORS
   regval = (TWIM_INT_LASTRX | TWIM_INT_LASTTX | TWIM_INT_STOPPED |
             TWIM_INT_ERROR);
-#else
-  regval = (TWIM_INT_LASTRX | TWIM_INT_LASTTX | TWIM_INT_STOPPED);
-#endif
   nrf52_i2c_putreg(priv, NRF52_TWIM_INTEN_OFFSET, regval);
 
   /* Attach error and event interrupts to the ISRs */
diff --git a/arch/arm/src/nrf53/nrf53_i2c.c b/arch/arm/src/nrf53/nrf53_i2c.c
index 6284372122..b000187f10 100644
--- a/arch/arm/src/nrf53/nrf53_i2c.c
+++ b/arch/arm/src/nrf53/nrf53_i2c.c
@@ -41,14 +41,6 @@
 #include "hardware/nrf53_twi.h"
 #include "hardware/nrf53_utils.h"
 
-/****************************************************************************
- * Pre-processor Definitions
- ****************************************************************************/
-
-/* I2C errors not functional yet */
-
-#undef CONFIG_NRF53_I2C_ERRORS
-
 /****************************************************************************
  * Private Types
  ****************************************************************************/
@@ -462,6 +454,7 @@ static int nrf53_i2c_transfer(struct i2c_master_s *dev,
 
           if (priv->status < 0)
             {
+              ret = priv->status;
               goto errout;
             }
 #endif
@@ -514,6 +507,7 @@ static int nrf53_i2c_transfer(struct i2c_master_s *dev,
 
           if (priv->status < 0)
             {
+              ret = priv->status;
               goto errout;
             }
 #endif
@@ -561,6 +555,7 @@ static int nrf53_i2c_transfer(struct i2c_master_s *dev,
 
   if (priv->status < 0)
     {
+      ret = priv->status;
       goto errout;
     }
 #endif
@@ -609,7 +604,8 @@ static int nrf53_i2c_reset(struct i2c_master_s *dev)
 #ifndef CONFIG_I2C_POLLED
 static int nrf53_i2c_isr(int irq, void *context, void *arg)
 {
-  struct nrf53_i2c_priv_s *priv = (struct nrf53_i2c_priv_s *)arg;
+  struct nrf53_i2c_priv_s *priv   = (struct nrf53_i2c_priv_s *)arg;
+  uint32_t                 regval = 0;
 
   /* Reset I2C status */
 
@@ -663,14 +659,26 @@ static int nrf53_i2c_isr(int irq, void *context, void *arg)
       nrf53_i2c_putreg(priv, NRF53_TWIM_EVENTS_STOPPED_OFFSET, 0);
     }
 
-#ifdef CONFIG_NRF53_I2C_ERRORS
   if (nrf53_i2c_getreg(priv, NRF53_TWIM_EVENTS_ERROR_OFFSET) == 1)
     {
-      i2cerr("I2C ERROR\n");
+      regval = nrf53_i2c_getreg(priv, NRF53_TWIM_ERRORSRC_OFFSET) & 0x7;
+
+      i2cerr("Error SRC: 0x%08" PRIx32 "\n", regval);
 
       /* Set ERROR status */
 
-      priv->status = ERROR;
+      if (regval & TWIM_ERRORSRC_OVERRUN)
+        {
+          /* Overrun error */
+
+          priv->status = -EIO;
+        }
+      else
+        {
+          /* NACK */
+
+          priv->status = -ENXIO;
+        }
 
       /* ERROR event */
 
@@ -679,8 +687,8 @@ static int nrf53_i2c_isr(int irq, void *context, void *arg)
       /* Clear event */
 
       nrf53_i2c_putreg(priv, NRF53_TWIM_EVENTS_ERROR_OFFSET, 0);
+      nrf53_i2c_putreg(priv, NRF53_TWIM_ERRORSRC_OFFSET, 0x7);
     }
-#endif
 
   return OK;
 }
@@ -734,12 +742,8 @@ static int nrf53_i2c_init(struct nrf53_i2c_priv_s *priv)
 #ifndef CONFIG_I2C_POLLED
   /* Enable I2C interrupts */
 
-#ifdef CONFIG_NRF53_I2C_ERRORS
   regval = (TWIM_INT_LASTRX | TWIM_INT_LASTTX | TWIM_INT_STOPPED |
             TWIM_INT_ERROR);
-#else
-  regval = (TWIM_INT_LASTRX | TWIM_INT_LASTTX | TWIM_INT_STOPPED);
-#endif
   nrf53_i2c_putreg(priv, NRF53_TWIM_INTEN_OFFSET, regval);
 
   /* Attach error and event interrupts to the ISRs */
diff --git a/arch/arm/src/nrf91/nrf91_i2c.c b/arch/arm/src/nrf91/nrf91_i2c.c
index a73eb68b69..c41e899dee 100644
--- a/arch/arm/src/nrf91/nrf91_i2c.c
+++ b/arch/arm/src/nrf91/nrf91_i2c.c
@@ -41,14 +41,6 @@
 #include "hardware/nrf91_twi.h"
 #include "hardware/nrf91_utils.h"
 
-/****************************************************************************
- * Pre-processor Definitions
- ****************************************************************************/
-
-/* I2C errors not functional yet */
-
-#undef CONFIG_NRF91_I2C_ERRORS
-
 /****************************************************************************
  * Private Types
  ****************************************************************************/
@@ -462,6 +454,7 @@ static int nrf91_i2c_transfer(struct i2c_master_s *dev,
 
           if (priv->status < 0)
             {
+              ret = priv->status;
               goto errout;
             }
 #endif
@@ -514,6 +507,7 @@ static int nrf91_i2c_transfer(struct i2c_master_s *dev,
 
           if (priv->status < 0)
             {
+              ret = priv->status;
               goto errout;
             }
 #endif
@@ -561,6 +555,7 @@ static int nrf91_i2c_transfer(struct i2c_master_s *dev,
 
   if (priv->status < 0)
     {
+      ret = priv->status;
       goto errout;
     }
 #endif
@@ -610,6 +605,7 @@ static int nrf91_i2c_reset(struct i2c_master_s *dev)
 static int nrf91_i2c_isr(int irq, void *context, void *arg)
 {
   struct nrf91_i2c_priv_s *priv = (struct nrf91_i2c_priv_s *)arg;
+  uint32_t                 regval = 0;
 
   /* Reset I2C status */
 
@@ -663,14 +659,26 @@ static int nrf91_i2c_isr(int irq, void *context, void *arg)
       nrf91_i2c_putreg(priv, NRF91_TWIM_EVENTS_STOPPED_OFFSET, 0);
     }
 
-#ifdef CONFIG_NRF91_I2C_ERRORS
   if (nrf91_i2c_getreg(priv, NRF91_TWIM_EVENTS_ERROR_OFFSET) == 1)
     {
-      i2cerr("I2C ERROR\n");
+      regval = nrf91_i2c_getreg(priv, NRF91_TWIM_ERRORSRC_OFFSET) & 0x7;
+
+      i2cerr("Error SRC: 0x%08" PRIx32 "\n", regval);
 
       /* Set ERROR status */
 
-      priv->status = ERROR;
+      if (regval & TWIM_ERRORSRC_OVERRUN)
+        {
+          /* Overrun error */
+
+          priv->status = -EIO;
+        }
+      else
+        {
+          /* NACK */
+
+          priv->status = -ENXIO;
+        }
 
       /* ERROR event */
 
@@ -679,8 +687,8 @@ static int nrf91_i2c_isr(int irq, void *context, void *arg)
       /* Clear event */
 
       nrf91_i2c_putreg(priv, NRF91_TWIM_EVENTS_ERROR_OFFSET, 0);
+      nrf91_i2c_putreg(priv, NRF91_TWIM_ERRORSRC_OFFSET, 0x7);
     }
-#endif
 
   return OK;
 }
@@ -734,12 +742,8 @@ static int nrf91_i2c_init(struct nrf91_i2c_priv_s *priv)
 #ifndef CONFIG_I2C_POLLED
   /* Enable I2C interrupts */
 
-#ifdef CONFIG_NRF91_I2C_ERRORS
   regval = (TWIM_INT_LASTRX | TWIM_INT_LASTTX | TWIM_INT_STOPPED |
             TWIM_INT_ERROR);
-#else
-  regval = (TWIM_INT_LASTRX | TWIM_INT_LASTTX | TWIM_INT_STOPPED);
-#endif
   nrf91_i2c_putreg(priv, NRF91_TWIM_INTEN_OFFSET, regval);
 
   /* Attach error and event interrupts to the ISRs */