You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by bt...@apache.org on 2021/01/17 21:39:40 UTC

[incubator-nuttx] branch master updated: nrf52_i2c: add support for I2C_M_NOSTART flags

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

btashton 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 0f1c026  nrf52_i2c: add support for I2C_M_NOSTART flags
0f1c026 is described below

commit 0f1c026a1696d42be8dc496f4e941f8cd9f6adc9
Author: raiden00pl <ra...@railab.me>
AuthorDate: Wed Jan 13 07:47:51 2021 +0100

    nrf52_i2c: add support for I2C_M_NOSTART flags
---
 arch/arm/src/nrf52/Kconfig     |  8 ++++++
 arch/arm/src/nrf52/nrf52_i2c.c | 61 ++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 69 insertions(+)

diff --git a/arch/arm/src/nrf52/Kconfig b/arch/arm/src/nrf52/Kconfig
index 3cdb768..6a4fc9a 100644
--- a/arch/arm/src/nrf52/Kconfig
+++ b/arch/arm/src/nrf52/Kconfig
@@ -626,3 +626,11 @@ config NRF52_SPI_MASTER_WORKAROUND_1BYTE_TRANSFER
 		Enable the workaround to fix SPI Master 1 byte transfer bug
 		which occurs in NRF52832 revision 1 and revision 2.
 endmenu
+
+menu "I2C Master Configuration"
+
+config NRF52_I2C_MASTER_DISABLE_NOSTART
+	bool "Disable the I2C Master NOSTART flag support"
+	default n
+
+endmenu
diff --git a/arch/arm/src/nrf52/nrf52_i2c.c b/arch/arm/src/nrf52/nrf52_i2c.c
index eb55b8b..6dcc579 100644
--- a/arch/arm/src/nrf52/nrf52_i2c.c
+++ b/arch/arm/src/nrf52/nrf52_i2c.c
@@ -30,6 +30,7 @@
 #include <nuttx/irq.h>
 #include <nuttx/arch.h>
 #include <nuttx/semaphore.h>
+#include <nuttx/kmalloc.h>
 #include <arch/board/board.h>
 
 #include "arm_arch.h"
@@ -207,6 +208,9 @@ static int nrf52_i2c_transfer(FAR struct i2c_master_s *dev,
   FAR struct nrf52_i2c_priv_s *priv = (FAR struct nrf52_i2c_priv_s *)dev;
   uint32_t regval = 0;
   int      ret = OK;
+#ifndef CONFIG_NRF52_I2C_MASTER_DISABLE_NOSTART
+  uint8_t *pack_buf = NULL;
+#endif
 
   ret = nxsem_wait(&priv->sem_excl);
   if (ret < 0)
@@ -291,6 +295,56 @@ static int nrf52_i2c_transfer(FAR struct i2c_master_s *dev,
 
       if ((priv->flags & I2C_M_READ) == 0)
         {
+#ifndef CONFIG_NRF52_I2C_MASTER_DISABLE_NOSTART
+          /* Check if we need to combine messages */
+
+          if (priv->msgc > 1)
+            {
+              if (priv->msgv[1].flags & I2C_M_NOSTART)
+                {
+                  /* More than 2 messages not supported */
+
+                  DEBUGASSERT(priv->msgc < 3);
+
+                  /* Combine buffers */
+
+                  pack_buf = kmm_malloc(priv->msgv[0].length +
+                                        priv->msgv[1].length);
+                  if (pack_buf == NULL)
+                    {
+                      return -1;
+                    }
+
+                  /* Combine messages */
+
+                  memcpy(pack_buf, priv->msgv[0].buffer,
+                         priv->msgv[0].length);
+                  memcpy(pack_buf + priv->msgv[0].length,
+                         priv->msgv[1].buffer, priv->msgv[1].length);
+
+                  /* Use new buffer to transmit data */
+
+                  priv->ptr  = pack_buf;
+                  priv->dcnt = priv->msgv[0].length + priv->msgv[1].length;
+
+                  /* Next message */
+
+                  priv->msgc -= 1;
+                  priv->msgv += 1;
+                }
+            }
+#else
+          if (priv->msgc > 1)
+            {
+              if (priv->msgv[1].flags & I2C_M_NOSTART)
+                {
+                  /* Not supported */
+
+                  DEBUGASSERT(0);
+                }
+            }
+#endif
+
           /* Write TXD data pointer */
 
           regval = (uint32_t)priv->ptr;
@@ -441,6 +495,13 @@ static int nrf52_i2c_transfer(FAR struct i2c_master_s *dev,
 #endif
 
 errout:
+#ifndef CONFIG_NRF52_I2C_MASTER_DISABLE_NOSTART
+  if (pack_buf != NULL)
+    {
+      kmm_free(pack_buf);
+    }
+#endif
+
   nxsem_post(&priv->sem_excl);
   return ret;
 }