drivers/sensors/mpu60x0: Add I2C support.
This commit is contained in:
parent
807c1df498
commit
701100f6f9
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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 = ®_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;
|
||||
|
||||
|
@ -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
|
||||
};
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user