You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by ac...@apache.org on 2020/06/25 02:30:45 UTC

[incubator-nuttx] branch master updated: drivers/sensors/mpu60x0: Add I2C support.

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

acassis 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 701100f  drivers/sensors/mpu60x0: Add I2C support.
701100f is described below

commit 701100f6f910161295a8672d73c20c41ac868755
Author: Ouss4 <ab...@gmail.com>
AuthorDate: Thu Jun 25 01:30:53 2020 +0100

    drivers/sensors/mpu60x0: Add I2C support.
---
 drivers/sensors/Kconfig         |  5 +++
 drivers/sensors/Make.defs       |  8 ++--
 drivers/sensors/mpu60x0.c       | 92 +++++++++++++++++++++++++++++++----------
 include/nuttx/sensors/mpu60x0.h | 24 ++++++-----
 4 files changed, 93 insertions(+), 36 deletions(-)

diff --git a/drivers/sensors/Kconfig b/drivers/sensors/Kconfig
index f58b810..a560a19 100644
--- a/drivers/sensors/Kconfig
+++ b/drivers/sensors/Kconfig
@@ -549,6 +549,11 @@ config MPU60X0_I2C
 
 endchoice
 
+config MPU60X0_I2C_FREQ
+	int "MPU60x0 I2C Frequency"
+	depends on MPU60X0_I2C
+	default 400000
+
 config MPU60X0_EXTI
 	bool "Enable interrupts"
 	default n
diff --git a/drivers/sensors/Make.defs b/drivers/sensors/Make.defs
index a92d9f9..530d20a 100644
--- a/drivers/sensors/Make.defs
+++ b/drivers/sensors/Make.defs
@@ -227,10 +227,6 @@ ifeq ($(CONFIG_LIS3DH),y)
   CSRCS += lis3dh.c
 endif
 
-ifeq ($(CONFIG_SENSORS_MPU60X0),y)
-  CSRCS += mpu60x0.c
-endif
-
 ifeq ($(CONFIG_SENSORS_MAX31855),y)
   CSRCS += max31855.c
 endif
@@ -261,6 +257,10 @@ endif
 
 endif # CONFIG_SPI
 
+ifeq ($(CONFIG_SENSORS_MPU60X0),y)
+  CSRCS += mpu60x0.c
+endif
+
 # Quadrature encoder upper half
 
 ifeq ($(CONFIG_SENSORS_QENCODER),y)
diff --git a/drivers/sensors/mpu60x0.c b/drivers/sensors/mpu60x0.c
index 59addb3..15be14e 100644
--- a/drivers/sensors/mpu60x0.c
+++ b/drivers/sensors/mpu60x0.c
@@ -34,7 +34,7 @@
  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  * POSSIBILITY OF SUCH DAMAGE.
  *
- *****************************************************************************/
+ ****************************************************************************/
 
 /****************************************************************************
  * TODO: Theory of Operation
@@ -54,7 +54,11 @@
 
 #include <nuttx/compiler.h>
 #include <nuttx/kmalloc.h>
+#ifdef CONFIG_MPU60X0_SPI
 #include <nuttx/spi/spi.h>
+#else
+#include <nuttx/i2c/i2c_master.h>
+#endif
 #include <nuttx/fs/fs.h>
 #include <nuttx/sensors/mpu60x0.h>
 
@@ -305,7 +309,7 @@ static const struct file_operations g_mpu_fops =
  * the chip and its associated data.
  */
 
-#ifdef CONFIG_SPI
+#ifdef CONFIG_MPU60X0_SPI
 /* __mpu_read_reg(), but for spi-connected devices. See that function
  * for documentation.
  */
@@ -403,9 +407,8 @@ static int __mpu_write_reg_spi(FAR struct mpu_dev_s *dev,
 
   return ret;
 }
-#endif
 
-#ifdef CONFIG_I2C
+#else
 
 /* __mpu_read_reg(), but for i2c-connected devices. */
 
@@ -413,20 +416,60 @@ static int __mpu_read_reg_i2c(FAR struct mpu_dev_s *dev,
                               enum mpu_regaddr_e reg_addr,
                               FAR uint8_t *buf, uint8_t len)
 {
-  /* We don't support i2c yet. */
+  int ret;
+  struct i2c_msg_s msg[2];
 
-  return -EINVAL;
+  msg[0].frequency = CONFIG_MPU60X0_I2C_FREQ;
+  msg[0].addr      = dev->config.addr;
+  msg[0].flags     = I2C_M_NOSTOP;
+  msg[0].buffer    = &reg_addr;
+  msg[0].length    = 1;
+
+  msg[1].frequency = CONFIG_MPU60X0_I2C_FREQ;
+  msg[1].addr      = dev->config.addr;
+  msg[1].flags     = I2C_M_READ;
+  msg[1].buffer    = buf;
+  msg[1].length    = len;
+
+  ret = I2C_TRANSFER(dev->config.i2c, msg, 2);
+  if (ret < 0)
+    {
+      snerr("ERROR: I2C_TRANSFER(read) failed: %d\n", ret);
+      return ret;
+    }
+
+  return OK;
 }
 
 static int __mpu_write_reg_i2c(FAR struct mpu_dev_s *dev,
                                enum mpu_regaddr_e reg_addr,
                                FAR const uint8_t *buf, uint8_t len)
 {
-  /* We don't support i2c yet. */
+  int ret;
+  struct i2c_msg_s msg[2];
+
+  msg[0].frequency = CONFIG_MPU60X0_I2C_FREQ;
+  msg[0].addr      = dev->config.addr;
+  msg[0].flags     = I2C_M_NOSTOP;
+  msg[0].buffer    = &reg_addr;
+  msg[0].length    = 1;
+
+  msg[1].frequency = CONFIG_MPU60X0_I2C_FREQ;
+  msg[1].addr      = dev->config.addr;
+  msg[1].flags     = I2C_M_NOSTART;
+  msg[1].buffer    = (FAR uint8_t *)buf;
+  msg[1].length    = len;
+
+  ret = I2C_TRANSFER(dev->config.i2c, msg, 2);
+  if (ret < 0)
+    {
+      snerr("ERROR: I2C_TRANSFER(write) failed: %d\n", ret);
+      return ret;
+    }
 
-  return -EINVAL;
+  return OK;
 }
-#endif
+#endif /* CONFIG_MPU60X0_SPI */
 
 /* __mpu_read_reg()
  *
@@ -443,16 +486,14 @@ static inline int __mpu_read_reg(FAR struct mpu_dev_s *dev,
                                  enum mpu_regaddr_e reg_addr,
                                  FAR uint8_t *buf, uint8_t len)
 {
-#ifdef CONFIG_SPI
+#ifdef CONFIG_MPU60X0_SPI
   /* If we're wired to SPI, use that function. */
 
   if (dev->config.spi != NULL)
     {
       return __mpu_read_reg_spi(dev, reg_addr, buf, len);
     }
-#endif
-
-#ifdef CONFIG_I2C
+#else
   /* If we're wired to I2C, use that function. */
 
   if (dev->config.i2c != NULL)
@@ -485,16 +526,14 @@ static inline int __mpu_write_reg(FAR struct mpu_dev_s *dev,
                                   enum mpu_regaddr_e reg_addr,
                                   FAR const uint8_t *buf, uint8_t len)
 {
-#ifdef CONFIG_SPI
+#ifdef CONFIG_MPU60X0_SPI
   /* If we're connected to SPI, use that function. */
 
   if (dev->config.spi != NULL)
     {
       return __mpu_write_reg_spi(dev, reg_addr, buf, len);
     }
-#endif
-
-#ifdef CONFIG_I2C
+#else
   if (dev->config.i2c != NULL)
     {
       return __mpu_write_reg_i2c(dev, reg_addr, buf, len);
@@ -657,10 +696,17 @@ static int mpu_reset(FAR struct mpu_dev_s *dev)
 {
   /* We support only SPI right now. */
 
+#ifdef CONFIG_MPU60X0_SPI
   if (dev->config.spi == NULL)
     {
       return -EINVAL;
     }
+#else
+  if (dev->config.i2c == NULL)
+    {
+      return -EINVAL;
+    }
+#endif
 
   mpu_lock(dev);
 
@@ -668,8 +714,8 @@ static int mpu_reset(FAR struct mpu_dev_s *dev)
 
   __mpu_write_pwr_mgmt_1(dev, PWR_MGMT_1__DEVICE_RESET);
 
-  /* Wait for reset cycle to finish (note: per the datasheet, we don't need to
-   * hold NSS for this)
+  /* Wait for reset cycle to finish (note: per the datasheet, we don't need
+   * to hold NSS for this)
    */
 
   do
@@ -690,10 +736,12 @@ static int mpu_reset(FAR struct mpu_dev_s *dev)
 
   /* Disable i2c if we're on spi. */
 
+#ifdef CONFIG_MPU60X0_SPI
   if (dev->config.spi)
     {
       __mpu_write_user_ctrl(dev, USER_CTRL__I2C_IF_DIS);
     }
+#endif
 
   /* Disable low-power mode, enable all gyros and accelerometers */
 
@@ -827,7 +875,7 @@ static ssize_t mpu_read(FAR struct file *filep, FAR char *buf, size_t len)
 
   if (send_len)
     {
-      memcpy(buf, ((uint8_t *) & dev->buf) + dev->bufpos, send_len);
+      memcpy(buf, ((uint8_t *)&dev->buf) + dev->bufpos, send_len);
     }
 
   /* Move the cursor, to mark them as sent. */
@@ -943,7 +991,9 @@ int mpu60x0_register(FAR const char *path, FAR struct mpu_config_s *config)
   memset(priv, 0, sizeof(*priv));
   nxmutex_init(&priv->lock);
 
-  /* Keep a copy of the config structure, in case the caller discards theirs. */
+  /* Keep a copy of the config structure, in case the caller discards
+   * theirs.
+   */
 
   priv->config = *config;
 
diff --git a/include/nuttx/sensors/mpu60x0.h b/include/nuttx/sensors/mpu60x0.h
index 4953103..0c0ae79 100644
--- a/include/nuttx/sensors/mpu60x0.h
+++ b/include/nuttx/sensors/mpu60x0.h
@@ -34,27 +34,30 @@
  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  * POSSIBILITY OF SUCH DAMAGE.
  *
- *****************************************************************************/
+ ****************************************************************************/
 
 #ifndef __INCLUDE_NUTTX_SENSORS_MPU60X0_H
 #define __INCLUDE_NUTTX_SENSORS_MPU60X0_H
 
 /****************************************************************************
  * Included Files
- *****************************************************************************/
+ ****************************************************************************/
 
 #include <nuttx/config.h>
 
 /****************************************************************************
  * Public Types
- *****************************************************************************/
+ ****************************************************************************/
 
-/* These structures are defined elsewhere, and we don't need their definitions
- * here.
+/* These structures are defined elsewhere, and we don't need their
+ * definitions here.
  */
 
+#ifdef CONFIG_MPU60X0_SPI
 struct spi_dev_s;
+#else
 struct i2c_master_s;
+#endif
 
 /* Specifies the initial chip configuration and location.
  *
@@ -93,7 +96,7 @@ struct i2c_master_s;
 
 struct mpu_config_s
 {
-#ifdef CONFIG_SPI
+#ifdef CONFIG_MPU60X0_SPI
   /* For users on SPI.
    *
    *  spi_devid : the SPI master's slave-select number
@@ -101,14 +104,13 @@ struct mpu_config_s
    *  spi       : the SPI master device, as used in SPI_SELECT(spi, ..., ...)
    */
 
-   FAR struct spi_dev_s *spi;
-   int spi_devid;
-#endif
-
-#ifdef CONFIG_I2C
+  FAR struct spi_dev_s *spi;
+  int spi_devid;
+#else
     /* For users on I2C. (Unimplemented.) */
 
     FAR struct i2c_master_s *i2c;
+    int addr;
 #endif
   };