diff --git a/drivers/sensors/Kconfig b/drivers/sensors/Kconfig index f58b810be7..a560a19c6c 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 a92d9f90cb..530d20a1be 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 59addb345c..15be14e13d 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 #include +#ifdef CONFIG_MPU60X0_SPI #include +#else +#include +#endif #include #include @@ -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 = ®_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]; - return -EINVAL; + msg[0].frequency = CONFIG_MPU60X0_I2C_FREQ; + msg[0].addr = dev->config.addr; + msg[0].flags = I2C_M_NOSTOP; + msg[0].buffer = ®_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 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 49531033a1..0c0ae79da7 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 /**************************************************************************** * 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 };