drivers/sensors/mpu60x0: Add I2C support.

This commit is contained in:
Ouss4 2020-06-25 01:30:53 +01:00 committed by Alan Carvalho de Assis
parent 807c1df498
commit 701100f6f9
4 changed files with 93 additions and 36 deletions

View File

@ -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

View File

@ -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)

View File

@ -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];
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_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;

View File

@ -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
@ -103,12 +106,11 @@ struct mpu_config_s
FAR struct spi_dev_s *spi;
int spi_devid;
#endif
#ifdef CONFIG_I2C
#else
/* For users on I2C. (Unimplemented.) */
FAR struct i2c_master_s *i2c;
int addr;
#endif
};