forked from nuttx/nuttx-update
sensors: add uorb support for lsm9ds1
This commit is contained in:
parent
11efa29192
commit
79e8aa5e21
9 changed files with 2132 additions and 1128 deletions
|
@ -113,7 +113,12 @@ if(CONFIG_SENSORS)
|
|||
endif()
|
||||
|
||||
if(CONFIG_SENSORS_LSM9DS1)
|
||||
list(APPEND SRCS lsm9ds1.c)
|
||||
list(APPEND SRCS lsm9ds1_base.c)
|
||||
if(CONFIG_SENSORS_LSM9DS1_UORB)
|
||||
list(APPEND SRCS lsm9ds1_uorb.c)
|
||||
else()
|
||||
list(APPEND SRCS lsm9ds1.c)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(CONFIG_SENSORS_MSA301)
|
||||
|
|
|
@ -605,6 +605,36 @@ config SENSORS_LSM9DS1
|
|||
---help---
|
||||
Enable driver support for the STMicro LSM9DS1.
|
||||
|
||||
config SENSORS_LSM9DS1_UORB
|
||||
bool "LSM9DS1 UORB Interface"
|
||||
default n
|
||||
depends on SENSORS_LSM9DS1
|
||||
|
||||
if SENSORS_LSM9DS1_UORB
|
||||
|
||||
config SENSORS_LSM9DS1_POLL
|
||||
bool "Enables polling sensor data"
|
||||
default n
|
||||
---help---
|
||||
Enables polling of sensor.
|
||||
|
||||
config SENSORS_LSM9DS1_POLL_INTERVAL
|
||||
int "Polling interval in microseconds, default 1 sec"
|
||||
depends on SENSORS_LSM9DS1_POLL
|
||||
default 1000000
|
||||
range 0 4294967295
|
||||
---help---
|
||||
The interval until a new sensor measurement will be triggered.
|
||||
|
||||
config SENSORS_LSM9DS1_THREAD_STACKSIZE
|
||||
int "Worker thread stack size"
|
||||
depends on SENSORS_LSM9DS1_POLL
|
||||
default 1024
|
||||
---help---
|
||||
The stack size for the worker thread.
|
||||
|
||||
endif #SENSORS_LSM9DS1_UORB
|
||||
|
||||
config SENSORS_MSA301
|
||||
bool "MSA301 support"
|
||||
default n
|
||||
|
@ -616,7 +646,7 @@ config LSM9DS1_I2C_FREQUENCY
|
|||
int "LSM9DS1 I2C frequency"
|
||||
default 400000
|
||||
range 1 400000
|
||||
depends on SENSORS_LSM9DS1
|
||||
depends on SENSORS_LSM9DS1 || SENSORS_LSM9DS1_UORB
|
||||
|
||||
config SENSORS_LPS25H
|
||||
bool "STMicro LPS25H pressure sensor"
|
||||
|
|
|
@ -121,7 +121,12 @@ ifeq ($(CONFIG_SENSORS_LSM6DSL),y)
|
|||
endif
|
||||
|
||||
ifeq ($(CONFIG_SENSORS_LSM9DS1),y)
|
||||
CSRCS += lsm9ds1.c
|
||||
CSRCS += lsm9ds1_base.c
|
||||
ifeq ($(CONFIG_SENSORS_LSM9DS1_UORB),y)
|
||||
CSRCS += lsm9ds1_uorb.c
|
||||
else
|
||||
CSRCS += lsm9ds1.c
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_SENSORS_MSA301),y)
|
||||
|
|
File diff suppressed because it is too large
Load diff
717
drivers/sensors/lsm9ds1_base.c
Normal file
717
drivers/sensors/lsm9ds1_base.c
Normal file
|
@ -0,0 +1,717 @@
|
|||
/****************************************************************************
|
||||
* drivers/sensors/lsm9ds1_base.c
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership. The
|
||||
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include "lsm9ds1_base.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
/* Accelerometer Operations */
|
||||
|
||||
static int lsm9ds1accelgyro_config(FAR struct lsm9ds1_dev_s *priv);
|
||||
static int lsm9ds1accel_start(FAR struct lsm9ds1_dev_s *priv);
|
||||
static int lsm9ds1accel_stop(FAR struct lsm9ds1_dev_s *priv);
|
||||
static int lsm9ds1accelgyro_setsamplerate(FAR struct lsm9ds1_dev_s *priv,
|
||||
uint32_t samplerate);
|
||||
static int lsm9ds1accel_setfullscale(FAR struct lsm9ds1_dev_s *priv,
|
||||
uint32_t fullscale);
|
||||
|
||||
/* Gyroscope Operations */
|
||||
|
||||
static int lsm9ds1gyro_start(FAR struct lsm9ds1_dev_s *priv);
|
||||
static int lsm9ds1gyro_stop(FAR struct lsm9ds1_dev_s *priv);
|
||||
static int lsm9ds1gyro_setfullscale(FAR struct lsm9ds1_dev_s *priv,
|
||||
uint32_t fullscale);
|
||||
|
||||
/* Magnetometer Operations */
|
||||
|
||||
static int lsm9ds1mag_config(FAR struct lsm9ds1_dev_s *priv);
|
||||
static int lsm9ds1mag_start(FAR struct lsm9ds1_dev_s *priv);
|
||||
static int lsm9ds1mag_stop(FAR struct lsm9ds1_dev_s *priv);
|
||||
static int lsm9ds1mag_setfullscale(FAR struct lsm9ds1_dev_s *priv,
|
||||
uint32_t fullscale);
|
||||
static int lsm9ds1mag_setsamplerate(FAR struct lsm9ds1_dev_s *priv,
|
||||
uint32_t samplerate);
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
|
||||
const struct lsm9ds1_ops_s g_lsm9ds1accel_ops =
|
||||
{
|
||||
lsm9ds1accelgyro_config,
|
||||
lsm9ds1accel_start,
|
||||
lsm9ds1accel_stop,
|
||||
lsm9ds1accelgyro_setsamplerate,
|
||||
lsm9ds1accel_setfullscale,
|
||||
};
|
||||
|
||||
const struct lsm9ds1_ops_s g_lsm9ds1gyro_ops =
|
||||
{
|
||||
lsm9ds1accelgyro_config,
|
||||
lsm9ds1gyro_start,
|
||||
lsm9ds1gyro_stop,
|
||||
lsm9ds1accelgyro_setsamplerate,
|
||||
lsm9ds1gyro_setfullscale,
|
||||
};
|
||||
|
||||
const struct lsm9ds1_ops_s g_lsm9ds1mag_ops =
|
||||
{
|
||||
lsm9ds1mag_config,
|
||||
lsm9ds1mag_start,
|
||||
lsm9ds1mag_stop,
|
||||
lsm9ds1mag_setsamplerate,
|
||||
lsm9ds1mag_setfullscale,
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: lsm9ds1accelgyro_config
|
||||
*
|
||||
* Description:
|
||||
* Configure the accelerometer and gyroscope.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int lsm9ds1accelgyro_config(FAR struct lsm9ds1_dev_s *priv)
|
||||
{
|
||||
uint8_t regval;
|
||||
int ret;
|
||||
|
||||
/* Sanity check */
|
||||
|
||||
DEBUGASSERT(priv != NULL);
|
||||
|
||||
/* Get the device identification */
|
||||
|
||||
ret = lsm9ds1_readreg8(priv, LSM9DS1_WHO_AM_I, ®val);
|
||||
if (ret < 0)
|
||||
{
|
||||
snerr("ERROR: lsm9ds1_readreg8 failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (regval != LSM9DS1_WHO_AM_I_VALUE)
|
||||
{
|
||||
snerr("ERROR: Invalid device identification %02x\n", regval);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: lsm9ds1accel_start
|
||||
*
|
||||
* Description:
|
||||
* Start the accelerometer.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int lsm9ds1accel_start(FAR struct lsm9ds1_dev_s *priv)
|
||||
{
|
||||
uint8_t setbits;
|
||||
|
||||
/* Sanity check */
|
||||
|
||||
DEBUGASSERT(priv != NULL);
|
||||
|
||||
if (priv->samplerate < lsm9ds1_midpoint(10, 50))
|
||||
{
|
||||
setbits = LSM9DS1_CTRL_REG6_XL_ODR_XL_10HZ;
|
||||
}
|
||||
else if (priv->samplerate < lsm9ds1_midpoint(50, 119))
|
||||
{
|
||||
setbits = LSM9DS1_CTRL_REG6_XL_ODR_XL_50HZ;
|
||||
}
|
||||
else if (priv->samplerate < lsm9ds1_midpoint(119, 238))
|
||||
{
|
||||
setbits = LSM9DS1_CTRL_REG6_XL_ODR_XL_119HZ;
|
||||
}
|
||||
else if (priv->samplerate < lsm9ds1_midpoint(238, 476))
|
||||
{
|
||||
setbits = LSM9DS1_CTRL_REG6_XL_ODR_XL_238HZ;
|
||||
}
|
||||
else if (priv->samplerate < lsm9ds1_midpoint(476, 952))
|
||||
{
|
||||
setbits = LSM9DS1_CTRL_REG6_XL_ODR_XL_476HZ;
|
||||
}
|
||||
else
|
||||
{
|
||||
setbits = LSM9DS1_CTRL_REG6_XL_ODR_XL_952HZ;
|
||||
}
|
||||
|
||||
return lsm9ds1_modifyreg8(priv, LSM9DS1_CTRL_REG6_XL,
|
||||
LSM9DS1_CTRL_REG6_XL_ODR_XL_MASK, setbits);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: lsm9ds1accel_stop
|
||||
*
|
||||
* Description:
|
||||
* Stop the accelerometer.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int lsm9ds1accel_stop(FAR struct lsm9ds1_dev_s *priv)
|
||||
{
|
||||
/* Sanity check */
|
||||
|
||||
DEBUGASSERT(priv != NULL);
|
||||
|
||||
return lsm9ds1_modifyreg8(priv, LSM9DS1_CTRL_REG6_XL,
|
||||
LSM9DS1_CTRL_REG6_XL_ODR_XL_MASK,
|
||||
LSM9DS1_CTRL_REG6_XL_ODR_XL_POWERDOWN);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: lsm9ds1accelgyro_setsamplerate
|
||||
*
|
||||
* Description:
|
||||
* Set the accelerometer or gyroscope's sample rate.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int lsm9ds1accelgyro_setsamplerate(FAR struct lsm9ds1_dev_s *priv,
|
||||
uint32_t samplerate)
|
||||
{
|
||||
/* Sanity check */
|
||||
|
||||
DEBUGASSERT(priv != NULL);
|
||||
|
||||
priv->samplerate = samplerate;
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: lsm9ds1accel_setfullscale
|
||||
*
|
||||
* Description:
|
||||
* Set the accelerometer's full-scale range.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int lsm9ds1accel_setfullscale(FAR struct lsm9ds1_dev_s *priv,
|
||||
uint32_t fullscale)
|
||||
{
|
||||
uint8_t setbits;
|
||||
|
||||
/* Sanity check */
|
||||
|
||||
DEBUGASSERT(priv != NULL);
|
||||
|
||||
if (fullscale < lsm9ds1_midpoint(2, 4))
|
||||
{
|
||||
setbits = LSM9DS1_CTRL_REG6_XL_FS_XL_2G;
|
||||
}
|
||||
else if (fullscale < lsm9ds1_midpoint(4, 8))
|
||||
{
|
||||
setbits = LSM9DS1_CTRL_REG6_XL_FS_XL_4G;
|
||||
}
|
||||
else if (fullscale < lsm9ds1_midpoint(8, 16))
|
||||
{
|
||||
setbits = LSM9DS1_CTRL_REG6_XL_FS_XL_8G;
|
||||
}
|
||||
else
|
||||
{
|
||||
setbits = LSM9DS1_CTRL_REG6_XL_FS_XL_16G;
|
||||
}
|
||||
|
||||
return lsm9ds1_modifyreg8(priv, LSM9DS1_CTRL_REG6_XL,
|
||||
LSM9DS1_CTRL_REG6_XL_FS_XL_MASK, setbits);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: lsm9ds1gyro_start
|
||||
*
|
||||
* Description:
|
||||
* Start the gyroscope.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int lsm9ds1gyro_start(FAR struct lsm9ds1_dev_s *priv)
|
||||
{
|
||||
uint8_t setbits;
|
||||
|
||||
/* Sanity check */
|
||||
|
||||
DEBUGASSERT(priv != NULL);
|
||||
|
||||
if (priv->samplerate < lsm9ds1_midpoint(14, 59))
|
||||
{
|
||||
setbits = LSM9DS1_CTRL_REG1_G_ODR_G_14p9HZ;
|
||||
}
|
||||
else if (priv->samplerate < lsm9ds1_midpoint(59, 119))
|
||||
{
|
||||
setbits = LSM9DS1_CTRL_REG1_G_ODR_G_59p5HZ;
|
||||
}
|
||||
else if (priv->samplerate < lsm9ds1_midpoint(119, 238))
|
||||
{
|
||||
setbits = LSM9DS1_CTRL_REG1_G_ODR_G_119HZ;
|
||||
}
|
||||
else if (priv->samplerate < lsm9ds1_midpoint(238, 476))
|
||||
{
|
||||
setbits = LSM9DS1_CTRL_REG1_G_ODR_G_238HZ;
|
||||
}
|
||||
else if (priv->samplerate < lsm9ds1_midpoint(476, 952))
|
||||
{
|
||||
setbits = LSM9DS1_CTRL_REG1_G_ODR_G_476HZ;
|
||||
}
|
||||
else
|
||||
{
|
||||
setbits = LSM9DS1_CTRL_REG1_G_ODR_G_952HZ;
|
||||
}
|
||||
|
||||
return lsm9ds1_modifyreg8(priv, LSM9DS1_CTRL_REG1_G,
|
||||
LSM9DS1_CTRL_REG1_G_ODR_G_MASK, setbits);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: lsm9ds1gyro_stop
|
||||
*
|
||||
* Description:
|
||||
* Stop the gyroscope.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int lsm9ds1gyro_stop(FAR struct lsm9ds1_dev_s *priv)
|
||||
{
|
||||
/* Sanity check */
|
||||
|
||||
DEBUGASSERT(priv != NULL);
|
||||
|
||||
return lsm9ds1_modifyreg8(priv, LSM9DS1_CTRL_REG1_G,
|
||||
LSM9DS1_CTRL_REG1_G_ODR_G_MASK,
|
||||
LSM9DS1_CTRL_REG1_G_ODR_G_POWERDOWN);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: lsm9ds1gyro_setfullscale
|
||||
*
|
||||
* Description:
|
||||
* Set the gyroscope's full-scale range.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int lsm9ds1gyro_setfullscale(FAR struct lsm9ds1_dev_s *priv,
|
||||
uint32_t fullscale)
|
||||
{
|
||||
uint8_t setbits;
|
||||
|
||||
/* Sanity check */
|
||||
|
||||
DEBUGASSERT(priv != NULL);
|
||||
|
||||
if (fullscale < lsm9ds1_midpoint(245, 500))
|
||||
{
|
||||
setbits = LSM9DS1_CTRL_REG1_G_FS_G_245DPS;
|
||||
}
|
||||
else if (fullscale < lsm9ds1_midpoint(500, 2000))
|
||||
{
|
||||
setbits = LSM9DS1_CTRL_REG1_G_FS_G_500DPS;
|
||||
}
|
||||
else
|
||||
{
|
||||
setbits = LSM9DS1_CTRL_REG1_G_FS_G_2000DPS;
|
||||
}
|
||||
|
||||
return lsm9ds1_modifyreg8(priv, LSM9DS1_CTRL_REG1_G,
|
||||
LSM9DS1_CTRL_REG1_G_FS_G_MASK, setbits);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: lsm9ds1mag_config
|
||||
*
|
||||
* Description:
|
||||
* Configure the magnetometer.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int lsm9ds1mag_config(FAR struct lsm9ds1_dev_s *priv)
|
||||
{
|
||||
uint8_t regval;
|
||||
int ret;
|
||||
|
||||
/* Sanity check */
|
||||
|
||||
DEBUGASSERT(priv != NULL);
|
||||
|
||||
/* Get the device identification */
|
||||
|
||||
ret = lsm9ds1_readreg8(priv, LSM9DS1_WHO_AM_I_M, ®val);
|
||||
if (ret < 0)
|
||||
{
|
||||
snerr("ERROR: lsm9ds1_readreg8 failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (regval != LSM9DS1_WHO_AM_I_M_VALUE)
|
||||
{
|
||||
snerr("ERROR: Invalid device identification %02x\n", regval);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: lsm9ds1mag_start
|
||||
*
|
||||
* Description:
|
||||
* Start the magnetometer.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int lsm9ds1mag_start(FAR struct lsm9ds1_dev_s *priv)
|
||||
{
|
||||
/* Sanity check */
|
||||
|
||||
DEBUGASSERT(priv != NULL);
|
||||
|
||||
return lsm9ds1_modifyreg8(priv, LSM9DS1_CTRL_REG3_M,
|
||||
LSM9DS1_CTRL_REG3_M_MD_MASK,
|
||||
LSM9DS1_CTRL_REG3_M_MD_CONT);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: lsm9ds1mag_stop
|
||||
*
|
||||
* Description:
|
||||
* Stop the magnetometer.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int lsm9ds1mag_stop(FAR struct lsm9ds1_dev_s *priv)
|
||||
{
|
||||
/* Sanity check */
|
||||
|
||||
DEBUGASSERT(priv != NULL);
|
||||
|
||||
return lsm9ds1_modifyreg8(priv, LSM9DS1_CTRL_REG3_M,
|
||||
LSM9DS1_CTRL_REG3_M_MD_MASK,
|
||||
LSM9DS1_CTRL_REG3_M_MD_POWERDOWN2);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: lsm9ds1mag_setfullscale
|
||||
*
|
||||
* Description:
|
||||
* Set the magnetometer's full-scale range.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int lsm9ds1mag_setfullscale(FAR struct lsm9ds1_dev_s *priv,
|
||||
uint32_t fullscale)
|
||||
{
|
||||
uint8_t setbits;
|
||||
|
||||
/* Sanity check */
|
||||
|
||||
DEBUGASSERT(priv != NULL);
|
||||
|
||||
if (fullscale < lsm9ds1_midpoint(4, 8))
|
||||
{
|
||||
setbits = LSM9DS1_CTRL_REG2_M_FS_4GAUSS;
|
||||
}
|
||||
else if (fullscale < lsm9ds1_midpoint(8, 12))
|
||||
{
|
||||
setbits = LSM9DS1_CTRL_REG2_M_FS_8GAUSS;
|
||||
}
|
||||
else if (fullscale < lsm9ds1_midpoint(12, 16))
|
||||
{
|
||||
setbits = LSM9DS1_CTRL_REG2_M_FS_12GAUSS;
|
||||
}
|
||||
else
|
||||
{
|
||||
setbits = LSM9DS1_CTRL_REG2_M_FS_16GAUSS;
|
||||
}
|
||||
|
||||
return lsm9ds1_modifyreg8(priv, LSM9DS1_CTRL_REG2_M,
|
||||
LSM9DS1_CTRL_REG2_M_FS_MASK, setbits);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: lsm9ds1mag_setsamplerate
|
||||
*
|
||||
* Description:
|
||||
* Set the magnetometer's sample rate.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int lsm9ds1mag_setsamplerate(FAR struct lsm9ds1_dev_s *priv,
|
||||
uint32_t samplerate)
|
||||
{
|
||||
uint8_t setbits;
|
||||
|
||||
/* Sanity check */
|
||||
|
||||
DEBUGASSERT(priv != NULL);
|
||||
|
||||
/* The magnetometer can change its sample rate without exiting
|
||||
* power-down mode, so we don't need to save the value for later,
|
||||
* unlike the accelerometer and gyroscope.
|
||||
*/
|
||||
|
||||
if (samplerate < lsm9ds1_midpoint(0, 1))
|
||||
{
|
||||
setbits = LSM9DS1_CTRL_REG1_M_DO_0p625HZ;
|
||||
}
|
||||
else if (samplerate < lsm9ds1_midpoint(1, 2))
|
||||
{
|
||||
setbits = LSM9DS1_CTRL_REG1_M_DO_1p25HZ;
|
||||
}
|
||||
else if (samplerate < lsm9ds1_midpoint(2, 5))
|
||||
{
|
||||
setbits = LSM9DS1_CTRL_REG1_M_DO_2p5HZ;
|
||||
}
|
||||
else if (samplerate < lsm9ds1_midpoint(5, 10))
|
||||
{
|
||||
setbits = LSM9DS1_CTRL_REG1_M_DO_5HZ;
|
||||
}
|
||||
else if (samplerate < lsm9ds1_midpoint(10, 20))
|
||||
{
|
||||
setbits = LSM9DS1_CTRL_REG1_M_DO_10HZ;
|
||||
}
|
||||
else if (samplerate < lsm9ds1_midpoint(20, 40))
|
||||
{
|
||||
setbits = LSM9DS1_CTRL_REG1_M_DO_20HZ;
|
||||
}
|
||||
else if (samplerate < lsm9ds1_midpoint(40, 80))
|
||||
{
|
||||
setbits = LSM9DS1_CTRL_REG1_M_DO_40HZ;
|
||||
}
|
||||
else
|
||||
{
|
||||
setbits = LSM9DS1_CTRL_REG1_M_DO_80HZ;
|
||||
}
|
||||
|
||||
return lsm9ds1_modifyreg8(priv, LSM9DS1_CTRL_REG1_M,
|
||||
LSM9DS1_CTRL_REG1_M_DO_MASK, setbits);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: lsm9ds1_readreg8
|
||||
*
|
||||
* Description:
|
||||
* Read from an 8-bit register.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int lsm9ds1_readreg8(FAR struct lsm9ds1_dev_s *priv,
|
||||
uint8_t regaddr, FAR uint8_t *regval)
|
||||
{
|
||||
struct i2c_config_s config;
|
||||
int ret;
|
||||
|
||||
/* Sanity check */
|
||||
|
||||
DEBUGASSERT(priv != NULL);
|
||||
DEBUGASSERT(regval != NULL);
|
||||
|
||||
/* Set up the I2C configuration */
|
||||
|
||||
config.frequency = CONFIG_LSM9DS1_I2C_FREQUENCY;
|
||||
config.address = priv->addr;
|
||||
config.addrlen = 7;
|
||||
|
||||
/* Write the register address */
|
||||
|
||||
ret = i2c_write(priv->i2c, &config, ®addr, sizeof(regaddr));
|
||||
if (ret < 0)
|
||||
{
|
||||
snerr("ERROR: i2c_write failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Restart and read 8 bits from the register */
|
||||
|
||||
ret = i2c_read(priv->i2c, &config, regval, sizeof(*regval));
|
||||
if (ret < 0)
|
||||
{
|
||||
snerr("ERROR: i2c_read failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
sninfo("addr: %02x value: %02x\n", regaddr, *regval);
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: lsm9ds1_readreg
|
||||
*
|
||||
* Description:
|
||||
* Read bytes from registers
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int lsm9ds1_readreg(FAR struct lsm9ds1_dev_s *priv,
|
||||
uint8_t regaddr, FAR uint8_t *regval, uint8_t len)
|
||||
{
|
||||
struct i2c_config_s config;
|
||||
int ret;
|
||||
|
||||
/* Sanity check */
|
||||
|
||||
DEBUGASSERT(priv != NULL);
|
||||
DEBUGASSERT(regval != NULL);
|
||||
|
||||
/* Set up the I2C configuration */
|
||||
|
||||
config.frequency = CONFIG_LSM9DS1_I2C_FREQUENCY;
|
||||
config.address = priv->addr;
|
||||
config.addrlen = 7;
|
||||
|
||||
/* Write the register address */
|
||||
|
||||
ret = i2c_write(priv->i2c, &config, ®addr, sizeof(regaddr));
|
||||
if (ret < 0)
|
||||
{
|
||||
snerr("ERROR: i2c_write failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Restart and read 8 bits from the register */
|
||||
|
||||
ret = i2c_read(priv->i2c, &config, regval, sizeof(*regval) * len);
|
||||
if (ret < 0)
|
||||
{
|
||||
snerr("ERROR: i2c_read failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: lsm9ds1_writereg8
|
||||
*
|
||||
* Description:
|
||||
* Write to an 8-bit register.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int lsm9ds1_writereg8(FAR struct lsm9ds1_dev_s *priv,
|
||||
uint8_t regaddr, uint8_t regval)
|
||||
{
|
||||
struct i2c_config_s config;
|
||||
uint8_t buffer[2];
|
||||
int ret;
|
||||
|
||||
/* Sanity check */
|
||||
|
||||
DEBUGASSERT(priv != NULL);
|
||||
|
||||
/* Set up a 2-byte message to send */
|
||||
|
||||
buffer[0] = regaddr;
|
||||
buffer[1] = regval;
|
||||
|
||||
/* Set up the I2C configuration */
|
||||
|
||||
config.frequency = CONFIG_LSM9DS1_I2C_FREQUENCY;
|
||||
config.address = priv->addr;
|
||||
config.addrlen = 7;
|
||||
|
||||
/* Write the register address followed by the data (no RESTART) */
|
||||
|
||||
ret = i2c_write(priv->i2c, &config, buffer, sizeof(buffer));
|
||||
if (ret < 0)
|
||||
{
|
||||
snerr("ERROR: i2c_write failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
sninfo("addr: %02x value: %02x\n", regaddr, regval);
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: lsm9ds1_modifyreg8
|
||||
*
|
||||
* Description:
|
||||
* Modify an 8-bit register.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int lsm9ds1_modifyreg8(FAR struct lsm9ds1_dev_s *priv,
|
||||
uint8_t regaddr, uint8_t clearbits,
|
||||
uint8_t setbits)
|
||||
{
|
||||
uint8_t regval;
|
||||
int ret;
|
||||
|
||||
/* Sanity check */
|
||||
|
||||
DEBUGASSERT(priv != NULL);
|
||||
|
||||
ret = lsm9ds1_readreg8(priv, regaddr, ®val);
|
||||
if (ret < 0)
|
||||
{
|
||||
snerr("ERROR: lsm9ds1_readreg8 failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
regval &= ~clearbits;
|
||||
regval |= setbits;
|
||||
|
||||
ret = lsm9ds1_writereg8(priv, regaddr, regval);
|
||||
if (ret < 0)
|
||||
{
|
||||
snerr("ERROR: lsm9ds1_writereg8 failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: lsm9ds1_midpoint
|
||||
*
|
||||
* Description:
|
||||
* Find the midpoint between two numbers.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
uint32_t lsm9ds1_midpoint(uint32_t a, uint32_t b)
|
||||
{
|
||||
return (uint32_t)(((uint64_t)a +
|
||||
(uint64_t)b + (uint64_t)1) / (uint64_t)2);
|
||||
}
|
||||
|
537
drivers/sensors/lsm9ds1_base.h
Normal file
537
drivers/sensors/lsm9ds1_base.h
Normal file
|
@ -0,0 +1,537 @@
|
|||
/****************************************************************************
|
||||
* drivers/sensors/lsm9ds1_base.h
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership. The
|
||||
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef __INCLUDE_NUTTX_SENSORS_LSM9DS1_COMMOM_H
|
||||
#define __INCLUDE_NUTTX_SENSORS_LSM9DS1_COMMOM_H
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <debug.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <nuttx/kmalloc.h>
|
||||
#include <nuttx/random.h>
|
||||
#include <nuttx/fs/fs.h>
|
||||
|
||||
#include <nuttx/i2c/i2c_master.h>
|
||||
#include <nuttx/sensors/lsm9ds1.h>
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/* Register Addresses *******************************************************/
|
||||
|
||||
/* Accelerometer and gyroscope registers */
|
||||
|
||||
#define LSM9DS1_ACT_THS 0x04 /* Inactivity threshold */
|
||||
#define LSM9DS1_ACT_DUR 0x05 /* Inactivity duration */
|
||||
#define LSM9DS1_INT_GEN_CFG_XL 0x06 /* Accelerometer interrupt configuration */
|
||||
#define LSM9DS1_INT_GEN_THS_X_XL 0x07 /* Accelerometer X interrupt threshold */
|
||||
#define LSM9DS1_INT_GEN_THS_Y_XL 0x08 /* Accelerometer Y interrupt threshold */
|
||||
#define LSM9DS1_INT_GEN_THS_Z_XL 0x09 /* Accelerometer Z interrupt threshold */
|
||||
#define LSM9DS1_INT_GEN_DUR_XL 0x0a /* Accelerometer interrupt duration */
|
||||
#define LSM9DS1_REFERENCE_G 0x0b /* Gyroscope reference value for high-pass filter */
|
||||
#define LSM9DS1_INT1_CTRL 0x0c /* INT1_A/G pin control */
|
||||
#define LSM9DS1_INT2_CTRL 0x0d /* INT2_A/G pin control */
|
||||
#define LSM9DS1_WHO_AM_I 0x0f /* Accelerometer and gyroscope device identification */
|
||||
#define LSM9DS1_CTRL_REG1_G 0x10 /* Gyroscope control register 1 */
|
||||
#define LSM9DS1_CTRL_REG2_G 0x11 /* Gyroscope control register 2 */
|
||||
#define LSM9DS1_CTRL_REG3_G 0x12 /* Gyroscope control register 3 */
|
||||
#define LSM9DS1_ORIENT_CFG_G 0x13 /* Gyroscope sign and orientation */
|
||||
#define LSM9DS1_INT_GEN_SRC_G 0x14 /* Gyroscope interrupt source */
|
||||
#define LSM9DS1_OUT_TEMP_L 0x15 /* Temperature low byte */
|
||||
#define LSM9DS1_OUT_TEMP_H 0x16 /* Temperature high byte */
|
||||
#define LSM9DS1_STATUS_REG 0x17 /* Status register */
|
||||
#define LSM9DS1_OUT_X_L_G 0x18 /* Gyroscope pitch (X) low byte */
|
||||
#define LSM9DS1_OUT_X_H_G 0x19 /* Gyroscope pitch (X) high byte */
|
||||
#define LSM9DS1_OUT_Y_L_G 0x1a /* Gyroscope roll (Y) low byte */
|
||||
#define LSM9DS1_OUT_Y_H_G 0x1b /* Gyroscope roll (Y) high byte */
|
||||
#define LSM9DS1_OUT_Z_L_G 0x1c /* Gyroscope yaw (Z) low byte */
|
||||
#define LSM9DS1_OUT_Z_H_G 0x1d /* Gyroscope yaw (Z) high byte */
|
||||
#define LSM9DS1_CTRL_REG4 0x1e /* Control register 4 */
|
||||
#define LSM9DS1_CTRL_REG5_XL 0x1f /* Accelerometer control register 5 */
|
||||
#define LSM9DS1_CTRL_REG6_XL 0x20 /* Accelerometer control register 6 */
|
||||
#define LSM9DS1_CTRL_REG7_XL 0x21 /* Accelerometer control register 7 */
|
||||
#define LSM9DS1_CTRL_REG8 0x22 /* Control register 8 */
|
||||
#define LSM9DS1_CTRL_REG9 0x23 /* Control register 9 */
|
||||
#define LSM9DS1_CTRL_REG10 0x24 /* Control register 10 */
|
||||
#define LSM9DS1_INT_GEN_SRC_XL 0x26 /* Accelerometer interrupt source */
|
||||
#define LSM9DS1_STATUS_REG2 0x27 /* Status register 2 */
|
||||
#define LSM9DS1_OUT_X_L_XL 0x28 /* Accelerometer X low byte */
|
||||
#define LSM9DS1_OUT_X_H_XL 0x29 /* Accelerometer X high byte */
|
||||
#define LSM9DS1_OUT_Y_L_XL 0x2a /* Accelerometer Y low byte */
|
||||
#define LSM9DS1_OUT_Y_H_XL 0x2b /* Accelerometer Y high byte */
|
||||
#define LSM9DS1_OUT_Z_L_XL 0x2c /* Accelerometer Z low byte */
|
||||
#define LSM9DS1_OUT_Z_H_XL 0x2d /* Accelerometer Z high byte */
|
||||
#define LSM9DS1_FIFO_CTRL 0x2e /* FIFO control register */
|
||||
#define LSM9DS1_FIFO_SRC 0x2f /* FIFO status control register */
|
||||
#define LSM9DS1_INT_GEN_CFG_G 0x30 /* Gyroscope interrupt configuration */
|
||||
#define LSM9DS1_INT_GEN_THS_XH_G 0x31 /* Gyroscope pitch (X) interrupt threshold high byte */
|
||||
#define LSM9DS1_INT_GEN_THS_XL_G 0x32 /* Gyroscope pitch (X) interrupt threshold low byte */
|
||||
#define LSM9DS1_INT_GEN_THS_YH_G 0x33 /* Gyroscope roll (Y) interrupt threshold high byte */
|
||||
#define LSM9DS1_INT_GEN_THS_YL_G 0x34 /* Gyroscope roll (Y) interrupt threshold low byte */
|
||||
#define LSM9DS1_INT_GEN_THS_ZH_G 0x35 /* Gyroscope yaw (Z) interrupt threshold high byte */
|
||||
#define LSM9DS1_INT_GEN_THS_ZL_G 0x36 /* Gyroscope yaw (Z) interrupt threshold low byte */
|
||||
#define LSM9DS1_INT_GEN_DUR_G 0x37 /* Gyroscope interrupt duration */
|
||||
|
||||
/* Magnetometer registers */
|
||||
|
||||
#define LSM9DS1_OFFSET_X_REG_L_M 0x05 /* X low byte offset */
|
||||
#define LSM9DS1_OFFSET_X_REG_H_M 0x06 /* X high byte offset */
|
||||
#define LSM9DS1_OFFSET_Y_REG_L_M 0x07 /* Y low byte offset */
|
||||
#define LSM9DS1_OFFSET_Y_REG_H_M 0x08 /* Y high byte offset */
|
||||
#define LSM9DS1_OFFSET_Z_REG_L_M 0x09 /* Z low byte offset */
|
||||
#define LSM9DS1_OFFSET_Z_REG_H_M 0x0a /* Z high byte offset */
|
||||
#define LSM9DS1_WHO_AM_I_M 0x0f /* Device identification */
|
||||
#define LSM9DS1_CTRL_REG1_M 0x20 /* Control register 1 */
|
||||
#define LSM9DS1_CTRL_REG2_M 0x21 /* Control register 2 */
|
||||
#define LSM9DS1_CTRL_REG3_M 0x22 /* Control register 3 */
|
||||
#define LSM9DS1_CTRL_REG4_M 0x23 /* Control register 4 */
|
||||
#define LSM9DS1_CTRL_REG5_M 0x24 /* Control register 5 */
|
||||
#define LSM9DS1_STATUS_REG_M 0x27 /* Status register */
|
||||
#define LSM9DS1_OUT_X_L_M 0x28 /* X low byte */
|
||||
#define LSM9DS1_OUT_X_H_M 0x29 /* X high byte */
|
||||
#define LSM9DS1_OUT_Y_L_M 0x2a /* Y low byte */
|
||||
#define LSM9DS1_OUT_Y_H_M 0x2b /* Y high byte */
|
||||
#define LSM9DS1_OUT_Z_L_M 0x2c /* Z low byte */
|
||||
#define LSM9DS1_OUT_Z_H_M 0x2d /* Z high byte */
|
||||
#define LSM9DS1_INT_CFG_M 0x30 /* Interrupt configuration */
|
||||
#define LSM9DS1_INT_SRC_M 0x31 /* Interrupt source */
|
||||
#define LSM9DS1_INT_THS_L_M 0x32 /* Interrupt threshold low byte */
|
||||
#define LSM9DS1_INT_THS_H_M 0x33 /* Interrupt threshold high byte */
|
||||
|
||||
/* Register Bit Definitions *************************************************/
|
||||
|
||||
/* Inactivity threshold register */
|
||||
|
||||
#define LSM9DS1_ACT_THS_ACT_THS_SHIFT 0 /* Inactivity threshold */
|
||||
#define LSM9DS1_ACT_THS_ACT_THS_MASK (127 << LSM9DS1_ACT_THS_ACT_THS_SHIFT)
|
||||
#define LSM9DS1_ACT_THS_SLEEP_ON_INACT_EN (1 << 7) /* Gyroscope operating mode during inactivity */
|
||||
|
||||
/* Accelerometer interrupt configuration register */
|
||||
|
||||
#define LSM9DS1_INT_GEN_CFG_XL_XLIE_XL (1 << 0) /* X-axis low byte interrupt enable */
|
||||
#define LSM9DS1_INT_GEN_CFG_XL_XHIE_XL (1 << 1) /* X-axis high byte interrupt enable */
|
||||
#define LSM9DS1_INT_GEN_CFG_XL_YLIE_XL (1 << 2) /* Y-axis low byte interrupt enable */
|
||||
#define LSM9DS1_INT_GEN_CFG_XL_YHIE_XL (1 << 3) /* Y-axis high byte interrupt enable */
|
||||
#define LSM9DS1_INT_GEN_CFG_XL_ZLIE_XL (1 << 4) /* Z-axis low byte interrupt enable */
|
||||
#define LSM9DS1_INT_GEN_CFG_XL_ZHIE_XL (1 << 5) /* Z-axis high byte interrupt enable */
|
||||
#define LSM9DS1_INT_GEN_CFG_XL_6D (1 << 6) /* 6-direction detection function for interrupt */
|
||||
#define LSM9DS1_INT_GEN_CFG_XL_AOI_XL (1 << 7) /* AND/OR combination of interrupt events */
|
||||
|
||||
/* Accelerometer interrupt duration register */
|
||||
|
||||
#define LSM9DS1_INT_GEN_DUR_XL_DUR_XL_SHIFT 0 /* Enter/exit interrupt duration */
|
||||
#define LSM9DS1_INT_GEN_DUR_XL_DUR_XL_MASK (127 << LSM9DS1_INT_GEN_DUR_XL_DUR_XL_SHIFT)
|
||||
#define LSM9DS1_INT_GEN_DUR_XL_WAIT_XL (1 << 7) /* Wait function enabled on duration counter */
|
||||
|
||||
/* INT1_A/G pin control register */
|
||||
|
||||
#define LSM9DS1_INT1_CTRL_INT1_DRDY_XL (1 << 0) /* Accelerometer data ready */
|
||||
#define LSM9DS1_INT1_CTRL_INT1_DRDY_G (1 << 1) /* Gyroscope data ready */
|
||||
#define LSM9DS1_INT1_CTRL_INT1_BOOT (1 << 2) /* Boot status available */
|
||||
#define LSM9DS1_INT1_CTRL_INT1_FTH (1 << 3) /* FIFO threshold interrupt */
|
||||
#define LSM9DS1_INT1_CTRL_INT1_OVR (1 << 4) /* Overrun interrupt */
|
||||
#define LSM9DS1_INT1_CTRL_INT1_FSS5 (1 << 5) /* FSS5 interrupt */
|
||||
#define LSM9DS1_INT1_CTRL_INT1_IG_XL (1 << 6) /* Accelerometer interrupt enable */
|
||||
#define LSM9DS1_INT1_CTRL_INT1_IG_G (1 << 7) /* Gyroscope interrupt enable */
|
||||
|
||||
/* INT2_A/G pin control register */
|
||||
|
||||
#define LSM9DS1_INT2_CTRL_INT2_DRDY_XL (1 << 0) /* Accelerometer data ready */
|
||||
#define LSM9DS1_INT2_CTRL_INT2_DRDY_G (1 << 1) /* Gyroscope data ready */
|
||||
#define LSM9DS1_INT2_CTRL_INT2_DRDY_TEMP (1 << 2) /* Temperature data ready */
|
||||
#define LSM9DS1_INT2_CTRL_INT2_FTH (1 << 3) /* FIFO threshold interrupt */
|
||||
#define LSM9DS1_INT2_CTRL_INT2_OVR (1 << 4) /* Overrun interrupt */
|
||||
#define LSM9DS1_INT2_CTRL_INT2_FSS5 (1 << 5) /* FSS5 interrupt */
|
||||
#define LSM9DS1_INT2_CTRL_INT2_INACT (1 << 7) /* Inactivity interrupt output signal */
|
||||
|
||||
/* Device identification register */
|
||||
|
||||
#define LSM9DS1_WHO_AM_I_VALUE 0x68
|
||||
|
||||
/* Gyroscope control register 1 */
|
||||
|
||||
#define LSM9DS1_CTRL_REG1_G_BW_G_SHIFT 0 /* Gyroscope bandwidth selection */
|
||||
#define LSM9DS1_CTRL_REG1_G_BW_G_MASK (3 << LSM9DS1_CTRL_REG1_G_BW_G_SHIFT)
|
||||
#define LSM9DS1_CTRL_REG1_G_FS_G_SHIFT 3 /* Gyroscope full-scale selection */
|
||||
#define LSM9DS1_CTRL_REG1_G_FS_G_MASK (3 << LSM9DS1_CTRL_REG1_G_FS_G_SHIFT)
|
||||
# define LSM9DS1_CTRL_REG1_G_FS_G_245DPS (0 << LSM9DS1_CTRL_REG1_G_FS_G_SHIFT) /* 245 dps */
|
||||
# define LSM9DS1_CTRL_REG1_G_FS_G_500DPS (1 << LSM9DS1_CTRL_REG1_G_FS_G_SHIFT) /* 500 dps */
|
||||
# define LSM9DS1_CTRL_REG1_G_FS_G_2000DPS (3 << LSM9DS1_CTRL_REG1_G_FS_G_SHIFT) /* 2000 dps */
|
||||
|
||||
#define LSM9DS1_CTRL_REG1_G_ODR_G_SHIFT 5 /* Gyroscope bandwidth selection */
|
||||
#define LSM9DS1_CTRL_REG1_G_ODR_G_MASK (7 << LSM9DS1_CTRL_REG1_G_ODR_G_SHIFT)
|
||||
# define LSM9DS1_CTRL_REG1_G_ODR_G_POWERDOWN (0 << LSM9DS1_CTRL_REG1_G_ODR_G_SHIFT) /* Power-down mode */
|
||||
# define LSM9DS1_CTRL_REG1_G_ODR_G_14p9HZ (1 << LSM9DS1_CTRL_REG1_G_ODR_G_SHIFT) /* 14.9 Hz */
|
||||
# define LSM9DS1_CTRL_REG1_G_ODR_G_59p5HZ (2 << LSM9DS1_CTRL_REG1_G_ODR_G_SHIFT) /* 59.5 Hz */
|
||||
# define LSM9DS1_CTRL_REG1_G_ODR_G_119HZ (3 << LSM9DS1_CTRL_REG1_G_ODR_G_SHIFT) /* 119 Hz */
|
||||
# define LSM9DS1_CTRL_REG1_G_ODR_G_238HZ (4 << LSM9DS1_CTRL_REG1_G_ODR_G_SHIFT) /* 238 Hz */
|
||||
# define LSM9DS1_CTRL_REG1_G_ODR_G_476HZ (5 << LSM9DS1_CTRL_REG1_G_ODR_G_SHIFT) /* 476 Hz */
|
||||
# define LSM9DS1_CTRL_REG1_G_ODR_G_952HZ (6 << LSM9DS1_CTRL_REG1_G_ODR_G_SHIFT) /* 952 Hz */
|
||||
|
||||
/* Gyroscope control register 2 */
|
||||
|
||||
#define LSM9DS1_CTRL_REG2_G_OUT_SEL_SHIFT 0 /* Out selection configuration */
|
||||
#define LSM9DS1_CTRL_REG2_G_OUT_SEL_MASK (3 << LSM9DS1_CTRL_REG2_G_OUT_SEL_SHIFT)
|
||||
#define LSM9DS1_CTRL_REG2_G_INT_SEL_SHIFT 2 /* INT selection configuration */
|
||||
#define LSM9DS1_CTRL_REG2_G_INT_SEL_MASK (3 << LSM9DS1_CTRL_REG2_G_INT_SEL_SHIFT)
|
||||
|
||||
/* Gyroscope control register 3 */
|
||||
|
||||
#define LSM9DS1_CTRL_REG3_G_HPCF_G_SHIFT 0 /* Gyroscope high-pass filter cutoff frequency selection */
|
||||
#define LSM9DS1_CTRL_REG3_G_HPCF_G_MASK (15 << LSM9DS1_CTRL_REG3_G_HPCF_G_SHIFT)
|
||||
#define LSM9DS1_CTRL_REG3_G_HP_EN (1 << 6) /* High-pass filter enable */
|
||||
#define LSM9DS1_CTRL_REG3_G_LP_MODE (1 << 7) /* Low-power mode enable */
|
||||
|
||||
/* Gyroscope sign and orientation register */
|
||||
|
||||
#define LSM9DS1_ORIENT_CFG_G_ORIENT_SHIFT 0 /* Directional user orientation selection */
|
||||
#define LSM9DS1_ORIENT_CFG_G_ORIENT_MASK (3 << LSM9DS1_ORIENT_CFG_G_ORIENT_SHIFT)
|
||||
#define LSM9DS1_ORIENT_CFG_G_SIGNZ_G (1 << 3) /* Yaw axis (Z) angular rate sign */
|
||||
#define LSM9DS1_ORIENT_CFG_G_SIGNY_G (1 << 4) /* Roll axis (Y) angular rate sign */
|
||||
#define LSM9DS1_ORIENT_CFG_G_SIGNX_G (1 << 5) /* Pitch axis (X) angular rate sign */
|
||||
|
||||
/* Gyroscope interrupt source register */
|
||||
|
||||
#define LSM9DS1_INT_GEN_SRC_G_XL_G (1 << 0) /* Pitch (X) low */
|
||||
#define LSM9DS1_INT_GEN_SRC_G_XH_G (1 << 1) /* Pitch (X) high */
|
||||
#define LSM9DS1_INT_GEN_SRC_G_YL_G (1 << 2) /* Roll (Y) low */
|
||||
#define LSM9DS1_INT_GEN_SRC_G_YH_G (1 << 3) /* Roll (Y) high */
|
||||
#define LSM9DS1_INT_GEN_SRC_G_ZL_G (1 << 4) /* Yaw (Z) low */
|
||||
#define LSM9DS1_INT_GEN_SRC_G_ZH_G (1 << 5) /* Yaw (Z) high */
|
||||
#define LSM9DS1_INT_GEN_SRC_G_IA_G (1 << 6) /* Interrupt active */
|
||||
|
||||
/* Status register */
|
||||
|
||||
#define LSM9DS1_STATUS_REG_XLDA (1 << 0) /* Accelerometer new data available */
|
||||
#define LSM9DS1_STATUS_REG_GDA (1 << 1) /* Gyroscope new data available */
|
||||
#define LSM9DS1_STATUS_REG_TDA (1 << 2) /* Temperature sensor new data available */
|
||||
#define LSM9DS1_STATUS_REG_BOOT_STATUS (1 << 3) /* Boot running flag signal */
|
||||
#define LSM9DS1_STATUS_REG_INACT (1 << 4) /* Inactivity interrupt output signal */
|
||||
#define LSM9DS1_STATUS_REG_IG_G (1 << 5) /* Gyroscope interrupt output signal */
|
||||
#define LSM9DS1_STATUS_REG_IG_XL (1 << 6) /* Accelerometer interrupt output signal */
|
||||
|
||||
/* Control register 4 */
|
||||
|
||||
#define LSM9DS1_CTRL_REG4_4D_XL1 (1 << 0) /* 4D option enabled on interrupt */
|
||||
#define LSM9DS1_CTRL_REG4_LIR_XL1 (1 << 1) /* Latched interrupt */
|
||||
#define LSM9DS1_CTRL_REG4_XEN_G (1 << 3) /* Gyroscope's pitch axis (X) output enable */
|
||||
#define LSM9DS1_CTRL_REG4_YEN_G (1 << 4) /* Gyroscope's roll axis (Y) output enable */
|
||||
#define LSM9DS1_CTRL_REG4_ZEN_G (1 << 5) /* Gyroscope's yaw axis (Z) output enable */
|
||||
|
||||
/* Accelerometer control register 5 */
|
||||
|
||||
#define LSM9DS1_CTRL_REG5_XL_XEN_XL (1 << 3) /* Accelerometer's X-axis output enable */
|
||||
#define LSM9DS1_CTRL_REG5_XL_YEN_XL (1 << 4) /* Accelerometer's Y-axis output enable */
|
||||
#define LSM9DS1_CTRL_REG5_XL_ZEN_XL (1 << 5) /* Accelerometer's Z-axis output enable */
|
||||
|
||||
#define LSM9DS1_CTRL_REG5_XL_DEC_SHIFT 6 /* Decimation of acceleration data on OUT REG and FIFO */
|
||||
#define LSM9DS1_CTRL_REG5_XL_DEC_MASK (3 << LSM9DS1_CTRL_REG5_XL_DEC_SHIFT)
|
||||
# define LSM9DS1_CTRL_REG5_XL_DEC_NODEC (0 << LSM9DS1_CTRL_REG5_XL_DEC_SHIFT) /* No decimation */
|
||||
# define LSM9DS1_CTRL_REG5_XL_DEC_2SAMPLES (1 << LSM9DS1_CTRL_REG5_XL_DEC_SHIFT) /* Update every 2 samples */
|
||||
# define LSM9DS1_CTRL_REG5_XL_DEC_4SAMPLES (2 << LSM9DS1_CTRL_REG5_XL_DEC_SHIFT) /* Update every 4 samples */
|
||||
# define LSM9DS1_CTRL_REG5_XL_DEC_8SAMPLES (3 << LSM9DS1_CTRL_REG5_XL_DEC_SHIFT) /* Update every 8 samples */
|
||||
|
||||
/* Accelerometer control register 6 */
|
||||
|
||||
#define LSM9DS1_CTRL_REG6_XL_BW_XL_SHIFT 0 /* Anti-aliasing filter bandwidth selection */
|
||||
#define LSM9DS1_CTRL_REG6_XL_BW_XL_MASK (3 << LSM9DS1_CTRL_REG6_XL_BW_XL_SHIFT)
|
||||
# define LSM9DS1_CTRL_REG6_XL_BW_XL_408HZ (0 << LSM9DS1_CTRL_REG6_XL_BW_XL_SHIFT) /* 408 Hz */
|
||||
# define LSM9DS1_CTRL_REG6_XL_BW_XL_211HZ (1 << LSM9DS1_CTRL_REG6_XL_BW_XL_SHIFT) /* 211 Hz */
|
||||
# define LSM9DS1_CTRL_REG6_XL_BW_XL_105HZ (2 << LSM9DS1_CTRL_REG6_XL_BW_XL_SHIFT) /* 105 Hz */
|
||||
# define LSM9DS1_CTRL_REG6_XL_BW_XL_50HZ (3 << LSM9DS1_CTRL_REG6_XL_BW_XL_SHIFT) /* 50 Hz */
|
||||
|
||||
#define LSM9DS1_CTRL_REG6_XL_BW_SCAL_ODR (1 << 2) /* Bandwidth selection */
|
||||
|
||||
#define LSM9DS1_CTRL_REG6_XL_FS_XL_SHIFT 3 /* Accelerometer full-scale selection */
|
||||
#define LSM9DS1_CTRL_REG6_XL_FS_XL_MASK (3 << LSM9DS1_CTRL_REG6_XL_FS_XL_SHIFT)
|
||||
# define LSM9DS1_CTRL_REG6_XL_FS_XL_2G (0 << LSM9DS1_CTRL_REG6_XL_FS_XL_SHIFT) /* +/- 2 g */
|
||||
# define LSM9DS1_CTRL_REG6_XL_FS_XL_16G (1 << LSM9DS1_CTRL_REG6_XL_FS_XL_SHIFT) /* +/- 16 g */
|
||||
# define LSM9DS1_CTRL_REG6_XL_FS_XL_4G (2 << LSM9DS1_CTRL_REG6_XL_FS_XL_SHIFT) /* +/- 4 g */
|
||||
# define LSM9DS1_CTRL_REG6_XL_FS_XL_8G (3 << LSM9DS1_CTRL_REG6_XL_FS_XL_SHIFT) /* +/- 8 g */
|
||||
|
||||
#define LSM9DS1_CTRL_REG6_XL_ODR_XL_SHIFT 5 /* Output data rate and power mode selection */
|
||||
#define LSM9DS1_CTRL_REG6_XL_ODR_XL_MASK (7 << LSM9DS1_CTRL_REG6_XL_ODR_XL_SHIFT)
|
||||
# define LSM9DS1_CTRL_REG6_XL_ODR_XL_POWERDOWN (0 << LSM9DS1_CTRL_REG6_XL_ODR_XL_SHIFT) /* Power-down mode */
|
||||
# define LSM9DS1_CTRL_REG6_XL_ODR_XL_10HZ (1 << LSM9DS1_CTRL_REG6_XL_ODR_XL_SHIFT) /* 10 Hz */
|
||||
# define LSM9DS1_CTRL_REG6_XL_ODR_XL_50HZ (2 << LSM9DS1_CTRL_REG6_XL_ODR_XL_SHIFT) /* 50 Hz */
|
||||
# define LSM9DS1_CTRL_REG6_XL_ODR_XL_119HZ (3 << LSM9DS1_CTRL_REG6_XL_ODR_XL_SHIFT) /* 119 Hz */
|
||||
# define LSM9DS1_CTRL_REG6_XL_ODR_XL_238HZ (4 << LSM9DS1_CTRL_REG6_XL_ODR_XL_SHIFT) /* 238 Hz */
|
||||
# define LSM9DS1_CTRL_REG6_XL_ODR_XL_476HZ (5 << LSM9DS1_CTRL_REG6_XL_ODR_XL_SHIFT) /* 476 Hz */
|
||||
# define LSM9DS1_CTRL_REG6_XL_ODR_XL_952HZ (6 << LSM9DS1_CTRL_REG6_XL_ODR_XL_SHIFT) /* 952 Hz */
|
||||
|
||||
/* Accelerometer control register 7 */
|
||||
|
||||
#define LSM9DS1_CTRL_REG7_XL_HPIS1 (1 << 0) /* High-pass filter enabled */
|
||||
#define LSM9DS1_CTRL_REG7_XL_FDS (1 << 2) /* Filtered data selection */
|
||||
|
||||
#define LSM9DS1_CTRL_REG7_XL_DCF_SHIFT 5 /* Accelerometer digital filter cutoff frequency selection */
|
||||
#define LSM9DS1_CTRL_REG7_XL_DCF_MASK (3 << LSM9DS1_CTRL_REG7_XL_DCF_SHIFT)
|
||||
# define LSM9DS1_CTRL_REG7_XL_DCF_ODR_DIV50 (0 << LSM9DS1_CTRL_REG7_XL_DCF_SHIFT)
|
||||
# define LSM9DS1_CTRL_REG7_XL_DCF_ODR_DIV100 (1 << LSM9DS1_CTRL_REG7_XL_DCF_SHIFT)
|
||||
# define LSM9DS1_CTRL_REG7_XL_DCF_ODR_DIV9 (2 << LSM9DS1_CTRL_REG7_XL_DCF_SHIFT)
|
||||
# define LSM9DS1_CTRL_REG7_XL_DCF_ODR_DIV400 (3 << LSM9DS1_CTRL_REG7_XL_DCF_SHIFT)
|
||||
#define LSM9DS1_CTRL_REG7_XL_HR (1 << 7) /* High resolution mode enable */
|
||||
|
||||
/* Control register 8 */
|
||||
|
||||
#define LSM9DS1_CTRL_REG8_SW_RESET (1 << 0) /* Software reset */
|
||||
#define LSM9DS1_CTRL_REG8_BLE (1 << 1) /* Big/little endian data selection */
|
||||
#define LSM9DS1_CTRL_REG8_IF_ADD_INC (1 << 2) /* Register address automatically incremented during a multibyte access */
|
||||
#define LSM9DS1_CTRL_REG8_SIM (1 << 3) /* SPI serial interface mode selection */
|
||||
#define LSM9DS1_CTRL_REG8_PP_OD (1 << 4) /* Push-pull/open-drain selection on the INT1_A/G and INT2_A/G pins */
|
||||
#define LSM9DS1_CTRL_REG8_H_LACTIVE (1 << 5) /* Interrupt activation level */
|
||||
#define LSM9DS1_CTRL_REG8_BDU (1 << 6) /* Block data update */
|
||||
#define LSM9DS1_CTRL_REG8_BOOT (1 << 7) /* Reboot memory content */
|
||||
|
||||
/* Control register 9 */
|
||||
|
||||
#define LSM9DS1_CTRL_REG9_STOP_ON_FTH (1 << 0) /* Enable FIFO threshold level use */
|
||||
#define LSM9DS1_CTRL_REG9_FIFO_EN (1 << 1) /* FIFO memory enable */
|
||||
#define LSM9DS1_CTRL_REG9_I2C_DISABLE (1 << 2) /* Disable I2C interface */
|
||||
#define LSM9DS1_CTRL_REG9_DRDY_MASK_BIT (1 << 3) /* Data available enable bit */
|
||||
#define LSM9DS1_CTRL_REG9_FIFO_TEMP_EN (1 << 4) /* Temperature data storage in FIFO enable */
|
||||
#define LSM9DS1_CTRL_REG9_SLEEP_G (1 << 6) /* Gyroscope sleep mode enable */
|
||||
|
||||
/* Control register 10 */
|
||||
|
||||
#define LSM9DS1_CTRL_REG10_ST_XL (1 << 0) /* Linear acceleration sensor self-test enable */
|
||||
#define LSM9DS1_CTRL_REG10_ST_G (1 << 2) /* Angular rate sensor self-test enable */
|
||||
|
||||
/* Accelerometer interrupt source register */
|
||||
|
||||
#define LSM9DS1_INT_GEN_SRC_XL_XL_XL (1 << 0) /* Accelerometer's X low event */
|
||||
#define LSM9DS1_INT_GEN_SRC_XL_XH_XL (1 << 1) /* Accelerometer's X high event */
|
||||
#define LSM9DS1_INT_GEN_SRC_XL_YL_XL (1 << 2) /* Accelerometer's Y low event */
|
||||
#define LSM9DS1_INT_GEN_SRC_XL_YH_XL (1 << 3) /* Accelerometer's Y high event */
|
||||
#define LSM9DS1_INT_GEN_SRC_XL_ZL_XL (1 << 4) /* Accelerometer's Z low event */
|
||||
#define LSM9DS1_INT_GEN_SRC_XL_ZH_XL (1 << 5) /* Accelerometer's Z high event */
|
||||
#define LSM9DS1_INT_GEN_SRC_XL_IA_XL (1 << 6) /* Interrupt active */
|
||||
|
||||
/* Status register 2 */
|
||||
|
||||
#define LSM9DS1_STATUS_REG2_XLDA (1 << 0) /* Accelerometer new data available */
|
||||
#define LSM9DS1_STATUS_REG2_GDA (1 << 1) /* Gyroscope new data available */
|
||||
#define LSM9DS1_STATUS_REG2_TDA (1 << 2) /* Temperature sensor new data available */
|
||||
#define LSM9DS1_STATUS_REG2_BOOT_STATUS (1 << 3) /* Boot running flag signal */
|
||||
#define LSM9DS1_STATUS_REG2_INACT (1 << 4) /* Inactivity interrupt output signal */
|
||||
#define LSM9DS1_STATUS_REG2_IG_G (1 << 5) /* Gyroscope interrupt output signal */
|
||||
#define LSM9DS1_STATUS_REG2_IG_XL (1 << 6) /* Accelerometer interrupt output signal */
|
||||
|
||||
/* FIFO control register */
|
||||
|
||||
#define LSM9DS1_FIFO_CTRL_FTH_SHIFT 0 /* FIFO threshold level setting */
|
||||
#define LSM9DS1_FIFO_CTRL_FTH_MASK (31 << LSM9DS1_FIFO_CTRL_FTH_SHIFT)
|
||||
#define LSM9DS1_FIFO_CTRL_FMODE_SHIFT 5 /* FIFO mode selection bits */
|
||||
#define LSM9DS1_FIFO_CTRL_FMODE_MASK (7 << LSM9DS1_FIFO_CTRL_FMODE_SHIFT)
|
||||
# define LSM9DS1_FIFO_CTRL_FMODE_BYPASS (0 << LSM9DS1_FIFO_CTRL_FMODE_SHIFT) /* Bypass mode */
|
||||
# define LSM9DS1_FIFO_CTRL_FMODE_FIFO (1 << LSM9DS1_FIFO_CTRL_FMODE_SHIFT) /* FIFO mode */
|
||||
# define LSM9DS1_FIFO_CTRL_FMODE_CONT_FIFO (3 << LSM9DS1_FIFO_CTRL_FMODE_SHIFT) /* Continuous-to-FIFO mode */
|
||||
# define LSM9DS1_FIFO_CTRL_FMODE_BYPASS_CONT (4 << LSM9DS1_FIFO_CTRL_FMODE_SHIFT) /* Bypass-to-continuous mode */
|
||||
# define LSM9DS1_FIFO_CTRL_FMODE_CONT (5 << LSM9DS1_FIFO_CTRL_FMODE_SHIFT) /* Continuous mode */
|
||||
|
||||
/* FIFO status control register */
|
||||
|
||||
#define LSM9DS1_FIFO_SRC_FSS_SHIFT 0 /* Number of unread samples stored into FIFO */
|
||||
#define LSM9DS1_FIFO_SRC_FSS_MASK (63 << LSM9DS1_FIFO_SRC_FSS_SHIFT)
|
||||
#define LSM9DS1_FIFO_SRC_OVRN (1 << 6) /* FIFO overrun status */
|
||||
#define LSM9DS1_FIFO_SRC_FTH (1 << 7) /* FIFO threshold status */
|
||||
|
||||
/* Gyroscope interrupt configuration register */
|
||||
|
||||
#define LSM9DS1_INT_GEN_CFG_G_XLIE_G (1 << 0) /* Pitch (X) axis low event interrupt enable */
|
||||
#define LSM9DS1_INT_GEN_CFG_G_XHIE_G (1 << 1) /* Pitch (X) axis high event interrupt enable */
|
||||
#define LSM9DS1_INT_GEN_CFG_G_YLIE_G (1 << 2) /* Roll (Y) axis low event interrupt enable */
|
||||
#define LSM9DS1_INT_GEN_CFG_G_YHIE_G (1 << 3) /* Roll (Y) axis high event interrupt enable */
|
||||
#define LSM9DS1_INT_GEN_CFG_G_ZLIE_G (1 << 4) /* Yaw (Z) axis low event interrupt enable */
|
||||
#define LSM9DS1_INT_GEN_CFG_G_ZHIE_G (1 << 5) /* Yaw (Z) axis high event interrupt enable */
|
||||
#define LSM9DS1_INT_GEN_CFG_G_LIR_G (1 << 6) /* Latch interrupt request */
|
||||
#define LSM9DS1_INT_GEN_CFG_G_AOI_G (1 << 7) /* AND/OR combination of interrupt events */
|
||||
|
||||
/* Gyroscope interrupt threshold registers */
|
||||
|
||||
#define LSM9DS1_INT_GEN_THS_XH_G_THS_XH_G_SHIFT 0 /* X interrupt threshold high byte */
|
||||
#define LSM9DS1_INT_GEN_THS_XH_G_THS_XH_G_MASK (127 << LSM9DS1_INT_GEN_THS_XH_G_THS_XH_G_SHIFT)
|
||||
#define LSM9DS1_INT_GEN_THS_XH_G_DCRM_G (1 << 7) /* Decrement or reset counter mode selection */
|
||||
|
||||
/* Gyroscope interrupt duration register */
|
||||
|
||||
#define LSM9DS1_INT_GEN_DUR_G_DUR_G_SHIFT 0 /* Enter/exit interrupt duration */
|
||||
#define LSM9DS1_INT_GEN_DUR_G_DUR_G_MASK (127 << LSM9DS1_INT_GEN_DUR_G_DUR_G_SHIFT)
|
||||
#define LSM9DS1_INT_GEN_DUR_G_WAIT_G (1 << 7) /* Exit from interrupt wait function enable */
|
||||
|
||||
/* Device identification register */
|
||||
|
||||
#define LSM9DS1_WHO_AM_I_M_VALUE 0x3d
|
||||
|
||||
/* Magnetometer control register 1 */
|
||||
|
||||
#define LSM9DS1_CTRL_REG1_M_ST (1 << 0) /* Self-test enable */
|
||||
#define LSM9DS1_CTRL_REG1_M_FAST_ODR (1 << 1) /* Enable data rates higher than 80 Hz */
|
||||
|
||||
#define LSM9DS1_CTRL_REG1_M_DO_SHIFT 2 /* Output data rate selection */
|
||||
#define LSM9DS1_CTRL_REG1_M_DO_MASK (7 << LSM9DS1_CTRL_REG1_M_DO_SHIFT)
|
||||
# define LSM9DS1_CTRL_REG1_M_DO_0p625HZ (0 << LSM9DS1_CTRL_REG1_M_DO_SHIFT) /* 0.625 Hz */
|
||||
# define LSM9DS1_CTRL_REG1_M_DO_1p25HZ (1 << LSM9DS1_CTRL_REG1_M_DO_SHIFT) /* 1.25 Hz */
|
||||
# define LSM9DS1_CTRL_REG1_M_DO_2p5HZ (2 << LSM9DS1_CTRL_REG1_M_DO_SHIFT) /* 2.5 Hz */
|
||||
# define LSM9DS1_CTRL_REG1_M_DO_5HZ (3 << LSM9DS1_CTRL_REG1_M_DO_SHIFT) /* 5 Hz */
|
||||
# define LSM9DS1_CTRL_REG1_M_DO_10HZ (4 << LSM9DS1_CTRL_REG1_M_DO_SHIFT) /* 10 Hz */
|
||||
# define LSM9DS1_CTRL_REG1_M_DO_20HZ (5 << LSM9DS1_CTRL_REG1_M_DO_SHIFT) /* 20 Hz */
|
||||
# define LSM9DS1_CTRL_REG1_M_DO_40HZ (6 << LSM9DS1_CTRL_REG1_M_DO_SHIFT) /* 40 Hz */
|
||||
# define LSM9DS1_CTRL_REG1_M_DO_80HZ (7 << LSM9DS1_CTRL_REG1_M_DO_SHIFT) /* 80 Hz */
|
||||
|
||||
#define LSM9DS1_CTRL_REG1_M_OM_SHIFT 5 /* X and Y axes operative mode selection */
|
||||
#define LSM9DS1_CTRL_REG1_M_OM_MASK (3 << LSM9DS1_CTRL_REG1_M_OM_SHIFT)
|
||||
# define LSM9DS1_CTRL_REG1_M_OM_LOW (0 << LSM9DS1_CTRL_REG1_M_OM_SHIFT) /* Low-power mode */
|
||||
# define LSM9DS1_CTRL_REG1_M_OM_MEDIUM (1 << LSM9DS1_CTRL_REG1_M_OM_SHIFT) /* Medium-performance mode */
|
||||
# define LSM9DS1_CTRL_REG1_M_OM_HIGH (2 << LSM9DS1_CTRL_REG1_M_OM_SHIFT) /* High-performance mode */
|
||||
# define LSM9DS1_CTRL_REG1_M_OM_ULTRAHIGH (3 << LSM9DS1_CTRL_REG1_M_OM_SHIFT) /* Ultra-high performance mode */
|
||||
|
||||
#define LSM9DS1_CTRL_REG1_M_TEMP_COMP (1 << 7) /* Temperature compensation enable */
|
||||
|
||||
/* Magnetometer control register 2 */
|
||||
|
||||
#define LSM9DS1_CTRL_REG2_M_SOFT_RST (1 << 2) /* Configuration register and user register reset */
|
||||
#define LSM9DS1_CTRL_REG2_M_REBOOT (1 << 3) /* Reboot memory content */
|
||||
|
||||
#define LSM9DS1_CTRL_REG2_M_FS_SHIFT 5 /* Full-scale configuration */
|
||||
#define LSM9DS1_CTRL_REG2_M_FS_MASK (3 << LSM9DS1_CTRL_REG2_M_FS_SHIFT)
|
||||
# define LSM9DS1_CTRL_REG2_M_FS_4GAUSS (0 << LSM9DS1_CTRL_REG2_M_FS_SHIFT) /* +/- 4 gauss */
|
||||
# define LSM9DS1_CTRL_REG2_M_FS_8GAUSS (1 << LSM9DS1_CTRL_REG2_M_FS_SHIFT) /* +/- 8 gauss */
|
||||
# define LSM9DS1_CTRL_REG2_M_FS_12GAUSS (2 << LSM9DS1_CTRL_REG2_M_FS_SHIFT) /* +/- 12 gauss */
|
||||
# define LSM9DS1_CTRL_REG2_M_FS_16GAUSS (3 << LSM9DS1_CTRL_REG2_M_FS_SHIFT) /* +/- 16 gauss */
|
||||
|
||||
/* Magnetometer control register 3 */
|
||||
|
||||
#define LSM9DS1_CTRL_REG3_M_MD_SHIFT 0 /* Operating mode selection */
|
||||
#define LSM9DS1_CTRL_REG3_M_MD_MASK (3 << LSM9DS1_CTRL_REG3_M_MD_SHIFT)
|
||||
# define LSM9DS1_CTRL_REG3_M_MD_CONT (0 << LSM9DS1_CTRL_REG3_M_MD_SHIFT) /* Continuous-conversion mode */
|
||||
# define LSM9DS1_CTRL_REG3_M_MD_SINGLE (1 << LSM9DS1_CTRL_REG3_M_MD_SHIFT) /* Single-conversion mode */
|
||||
# define LSM9DS1_CTRL_REG3_M_MD_POWERDOWN (2 << LSM9DS1_CTRL_REG3_M_MD_SHIFT) /* Power-down mode */
|
||||
# define LSM9DS1_CTRL_REG3_M_MD_POWERDOWN2 (3 << LSM9DS1_CTRL_REG3_M_MD_SHIFT) /* Power-down mode */
|
||||
|
||||
#define LSM9DS1_CTRL_REG3_M_SIM (1 << 2) /* SPI serial interface mode selection */
|
||||
#define LSM9DS1_CTRL_REG3_M_LP (1 << 5) /* Low-power mode configuration */
|
||||
#define LSM9DS1_CTRL_REG3_M_I2C_DISABLE (1 << 7) /* Disable I2C interface */
|
||||
|
||||
/* Magnetometer control register 4 */
|
||||
|
||||
#define LSM9DS1_CTRL_REG4_M_BLE (1 << 1) /* Big/little endian data selection */
|
||||
|
||||
#define LSM9DS1_CTRL_REG4_M_OMZ_SHIFT 2 /* Z-axis operative mode selection */
|
||||
#define LSM9DS1_CTRL_REG4_M_OMZ_MASK (3 << LSM9DS1_CTRL_REG4_M_OMZ_SHIFT)
|
||||
# define LSM9DS1_CTRL_REG4_M_OMZ_LOW (0 << LSM9DS1_CTRL_REG4_M_OMZ_SHIFT) /* Low-power mode */
|
||||
# define LSM9DS1_CTRL_REG4_M_OMZ_MEDIUM (1 << LSM9DS1_CTRL_REG4_M_OMZ_SHIFT) /* Medium-performance mode */
|
||||
# define LSM9DS1_CTRL_REG4_M_OMZ_HIGH (2 << LSM9DS1_CTRL_REG4_M_OMZ_SHIFT) /* High-performance mode */
|
||||
# define LSM9DS1_CTRL_REG4_M_OMZ_ULTRAHIGH (3 << LSM9DS1_CTRL_REG4_M_OMZ_SHIFT) /* Ultra-high performance mode */
|
||||
|
||||
/* Magnetometer control register 5 */
|
||||
|
||||
#define LSM9DS1_CTRL_REG5_M_BDU (1 << 6) /* Block data update */
|
||||
#define LSM9DS1_CTRL_REG5_M_FAST_READ (1 << 7) /* Fast read enable */
|
||||
|
||||
/* Magnetometer status register */
|
||||
|
||||
#define LSM9DS1_STATUS_REG_M_XDA (1 << 0) /* X-axis new data available */
|
||||
#define LSM9DS1_STATUS_REG_M_YDA (1 << 1) /* Y-axis new data available */
|
||||
#define LSM9DS1_STATUS_REG_M_ZDA (1 << 2) /* Z-axis new data available */
|
||||
#define LSM9DS1_STATUS_REG_M_ZYXDA (1 << 3) /* X, Y and Z-axis new data available */
|
||||
#define LSM9DS1_STATUS_REG_M_XOR (1 << 4) /* X-axis data overrun */
|
||||
#define LSM9DS1_STATUS_REG_M_YOR (1 << 5) /* Y-axis data overrun */
|
||||
#define LSM9DS1_STATUS_REG_M_ZOR (1 << 6) /* Z-axis data overrun */
|
||||
#define LSM9DS1_STATUS_REG_M_ZYXOR (1 << 7) /* X, Y and Z-axis data overrun */
|
||||
|
||||
/* Magnetometer interrupt configuration register */
|
||||
|
||||
#define LSM9DS1_INT_CFG_M_IEN (1 << 0) /* Interrupt enable on the INT_M pin */
|
||||
#define LSM9DS1_INT_CFG_M_IEL (1 << 1) /* Latch interrupt request */
|
||||
#define LSM9DS1_INT_CFG_M_IEA (1 << 2) /* Interrupt active configuration on INT_MAG */
|
||||
#define LSM9DS1_INT_CFG_M_ZIEN (1 << 5) /* Z-axis interrupt enable */
|
||||
#define LSM9DS1_INT_CFG_M_YIEN (1 << 6) /* Y-axis interrupt enable */
|
||||
#define LSM9DS1_INT_CFG_M_XIEN (1 << 7) /* X-axis interrupt enable */
|
||||
|
||||
/* Magnetometer interrupt source register */
|
||||
|
||||
#define LSM9DS1_INT_SRC_M_INT (1 << 0) /* Interrupt occurred */
|
||||
#define LSM9DS1_INT_SRC_M_MROI (1 << 1) /* Internal measurement range overflow */
|
||||
#define LSM9DS1_INT_SRC_M_NTH_Z (1 << 2) /* Value on Z-axis exceeds threshold on negative side */
|
||||
#define LSM9DS1_INT_SRC_M_NTH_Y (1 << 3) /* Value on Y-axis exceeds threshold on negative side */
|
||||
#define LSM9DS1_INT_SRC_M_NTH_X (1 << 4) /* Value on X-axis exceeds threshold on negative side */
|
||||
#define LSM9DS1_INT_SRC_M_PTH_Z (1 << 5) /* Value on Z-axis exceeds threshold on positive side */
|
||||
#define LSM9DS1_INT_SRC_M_PTH_Y (1 << 6) /* Value on Y-axis exceeds threshold on positive side */
|
||||
#define LSM9DS1_INT_SRC_M_PTH_X (1 << 7) /* Value on X-axis exceeds threshold on positive side */
|
||||
|
||||
/****************************************************************************
|
||||
* Public Types
|
||||
****************************************************************************/
|
||||
|
||||
struct lsm9ds1_dev_s;
|
||||
struct lsm9ds1_ops_s
|
||||
{
|
||||
CODE int (*config)(FAR struct lsm9ds1_dev_s *priv);
|
||||
CODE int (*start)(FAR struct lsm9ds1_dev_s *priv);
|
||||
CODE int (*stop)(FAR struct lsm9ds1_dev_s *priv);
|
||||
CODE int (*setsamplerate)(FAR struct lsm9ds1_dev_s *priv,
|
||||
uint32_t samplerate);
|
||||
CODE int (*setfullscale)(FAR struct lsm9ds1_dev_s *priv,
|
||||
uint32_t fullscale);
|
||||
};
|
||||
|
||||
struct lsm9ds1_dev_s
|
||||
{
|
||||
FAR struct i2c_master_s *i2c; /* I2C interface */
|
||||
FAR const struct lsm9ds1_ops_s *ops; /* Ops */
|
||||
uint8_t addr; /* I2C address */
|
||||
uint32_t samplerate; /* Output data rate */
|
||||
uint8_t datareg; /* Output data register of X low byte */
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Public data
|
||||
****************************************************************************/
|
||||
|
||||
extern const struct lsm9ds1_ops_s g_lsm9ds1accel_ops;
|
||||
extern const struct lsm9ds1_ops_s g_lsm9ds1gyro_ops;
|
||||
extern const struct lsm9ds1_ops_s g_lsm9ds1mag_ops;
|
||||
|
||||
/****************************************************************************
|
||||
* Public Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
int lsm9ds1_readreg8(FAR struct lsm9ds1_dev_s *priv,
|
||||
uint8_t regaddr, FAR uint8_t *regval);
|
||||
int lsm9ds1_readreg(FAR struct lsm9ds1_dev_s *priv,
|
||||
uint8_t regaddr, FAR uint8_t *regval, uint8_t len);
|
||||
int lsm9ds1_writereg8(FAR struct lsm9ds1_dev_s *priv,
|
||||
uint8_t regaddr, uint8_t regval);
|
||||
int lsm9ds1_modifyreg8(FAR struct lsm9ds1_dev_s *priv,
|
||||
uint8_t regaddr, uint8_t clearbits,
|
||||
uint8_t setbits);
|
||||
uint32_t lsm9ds1_midpoint(uint32_t a, uint32_t b);
|
||||
|
||||
#endif /* __INCLUDE_NUTTX_SENSORS_LSM9DS1_COMMOM_H */
|
803
drivers/sensors/lsm9ds1_uorb.c
Normal file
803
drivers/sensors/lsm9ds1_uorb.c
Normal file
|
@ -0,0 +1,803 @@
|
|||
/****************************************************************************
|
||||
* drivers/sensors/lsm9ds1_uorb.c
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership. The
|
||||
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <limits.h>
|
||||
#include <fcntl.h>
|
||||
#include <inttypes.h>
|
||||
#include <sys/param.h>
|
||||
|
||||
#include <nuttx/mutex.h>
|
||||
#include <nuttx/signal.h>
|
||||
#include <nuttx/compiler.h>
|
||||
#include <nuttx/nuttx.h>
|
||||
#include <nuttx/kthread.h>
|
||||
|
||||
#include <nuttx/sensors/sensor.h>
|
||||
#include <nuttx/sensors/ioctl.h>
|
||||
|
||||
#include "lsm9ds1_base.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
#define CONSTANTS_ONE_G 9.8f
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
|
||||
enum lsm9ds1_idx_e
|
||||
{
|
||||
LSM9DS1_ACCEL_IDX = 0,
|
||||
LSM9DS1_GYRO_IDX,
|
||||
LSM9DS1_MAG_IDX,
|
||||
LSM9DS1_MAX_IDX
|
||||
};
|
||||
|
||||
struct lsm9ds1_sensor_s
|
||||
{
|
||||
struct sensor_lowerhalf_s lower;
|
||||
uint64_t last_update;
|
||||
float scale;
|
||||
FAR void *dev;
|
||||
#ifdef CONFIG_SENSORS_LSM9DS1_POLL
|
||||
bool enabled;
|
||||
unsigned long interval;
|
||||
#endif
|
||||
struct lsm9ds1_dev_s base;
|
||||
};
|
||||
|
||||
struct lsm9ds1_sensor_dev_s
|
||||
{
|
||||
struct lsm9ds1_sensor_s priv[3];
|
||||
mutex_t lock;
|
||||
#ifdef CONFIG_SENSORS_LSM9DS1_POLL
|
||||
sem_t run;
|
||||
#endif
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Private Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
/* Sensor methods */
|
||||
|
||||
static int lsm9ds1_activate(FAR struct sensor_lowerhalf_s *lower,
|
||||
FAR struct file *filep,
|
||||
bool enable);
|
||||
static int lsm9ds1_set_interval(FAR struct sensor_lowerhalf_s *lower,
|
||||
FAR struct file *filep,
|
||||
FAR unsigned long *period_us);
|
||||
#ifndef CONFIG_SENSORS_LSM9DS1_POLL
|
||||
static int lsm9ds1_fetch(FAR struct sensor_lowerhalf_s *lower,
|
||||
FAR struct file *filep,
|
||||
FAR char *buffer, size_t buflen);
|
||||
#endif
|
||||
static int lsm9ds1_control(FAR struct sensor_lowerhalf_s *lower,
|
||||
FAR struct file *filep,
|
||||
int cmd, unsigned long arg);
|
||||
|
||||
/* Helpers */
|
||||
|
||||
static int lsm9ds1_mag_scale(FAR struct lsm9ds1_sensor_s *priv,
|
||||
uint8_t scale);
|
||||
static int lsm9ds1_accel_scale(FAR struct lsm9ds1_sensor_s *priv,
|
||||
uint8_t scale);
|
||||
static int lsm9ds1_gyro_scale(FAR struct lsm9ds1_sensor_s *priv,
|
||||
uint8_t scale);
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
static const struct sensor_ops_s g_sensor_ops =
|
||||
{
|
||||
NULL, /* open */
|
||||
NULL, /* close */
|
||||
.activate = lsm9ds1_activate,
|
||||
.set_interval = lsm9ds1_set_interval,
|
||||
NULL, /* batch */
|
||||
#ifdef CONFIG_SENSORS_LSM9DS1_POLL
|
||||
NULL, /* fetch */
|
||||
#else
|
||||
.fetch = lsm9ds1_fetch,
|
||||
#endif
|
||||
NULL, /* selftest */
|
||||
NULL, /* set_calibvalue */
|
||||
NULL, /* calibrate */
|
||||
.control = lsm9ds1_control
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: lsm9ds1_activate
|
||||
****************************************************************************/
|
||||
|
||||
static int lsm9ds1_activate(FAR struct sensor_lowerhalf_s *lower,
|
||||
FAR struct file *filep, bool enable)
|
||||
{
|
||||
#ifdef CONFIG_SENSORS_LSM9DS1_POLL
|
||||
FAR struct lsm9ds1_sensor_s *priv = NULL;
|
||||
FAR struct lsm9ds1_sensor_dev_s *dev = NULL;
|
||||
bool start_thread = false;
|
||||
int ret = OK;
|
||||
|
||||
priv = container_of(lower, struct lsm9ds1_sensor_s, lower);
|
||||
dev = priv->dev;
|
||||
|
||||
if (enable)
|
||||
{
|
||||
if (!priv->enabled)
|
||||
{
|
||||
start_thread = true;
|
||||
priv->last_update = sensor_get_timestamp();
|
||||
}
|
||||
|
||||
ret = priv->base.ops->start(&priv->base);
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = priv->base.ops->stop(&priv->base);
|
||||
}
|
||||
|
||||
priv->enabled = enable;
|
||||
|
||||
if (start_thread)
|
||||
{
|
||||
/* Wake up the thread */
|
||||
|
||||
nxsem_post(&dev->run);
|
||||
}
|
||||
|
||||
return ret;
|
||||
#else
|
||||
return OK;
|
||||
#endif
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: lsm9ds1_set_interval
|
||||
****************************************************************************/
|
||||
|
||||
static int lsm9ds1_set_interval(FAR struct sensor_lowerhalf_s *lower,
|
||||
FAR struct file *filep,
|
||||
FAR unsigned long *interval)
|
||||
{
|
||||
#ifdef CONFIG_SENSORS_LSM9DS1_POLL
|
||||
FAR struct lsm9ds1_sensor_s *priv = NULL;
|
||||
|
||||
priv = container_of(lower, struct lsm9ds1_sensor_s, lower);
|
||||
|
||||
priv->interval = *interval;
|
||||
#endif
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: lsm9ds1_data
|
||||
****************************************************************************/
|
||||
|
||||
static int16_t lsm9ds1_data(int16_t data)
|
||||
{
|
||||
/* The value is positive */
|
||||
|
||||
if (data < 0x8000)
|
||||
{
|
||||
data = data;
|
||||
}
|
||||
|
||||
/* The value is negative, so find its absolute value by taking the
|
||||
* two's complement
|
||||
*/
|
||||
|
||||
else if (data > 0x8000)
|
||||
{
|
||||
data = -(~data + 1);
|
||||
}
|
||||
|
||||
/* The value is negative and can't be represented as a positive
|
||||
* int16_t value
|
||||
*/
|
||||
|
||||
else
|
||||
{
|
||||
data = -32768;
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
#ifndef CONFIG_SENSORS_LSM9DS1_POLL
|
||||
/****************************************************************************
|
||||
* Name: lsm9ds1_set_interval
|
||||
****************************************************************************/
|
||||
|
||||
static int lsm9ds1_fetch(FAR struct sensor_lowerhalf_s *lower,
|
||||
FAR struct file *filep, FAR char *buffer,
|
||||
size_t buflen)
|
||||
{
|
||||
FAR struct lsm9ds1_sensor_s *priv = NULL;
|
||||
int16_t data[3];
|
||||
int ret = OK;
|
||||
|
||||
priv = container_of(lower, struct lsm9ds1_sensor_s, lower);
|
||||
|
||||
switch (lower->type)
|
||||
{
|
||||
case SENSOR_TYPE_ACCELEROMETER:
|
||||
{
|
||||
struct sensor_accel accel;
|
||||
|
||||
ret = lsm9ds1_readreg(&priv->base, LSM9DS1_OUT_X_L_XL,
|
||||
(FAR uint8_t *)data, 6);
|
||||
|
||||
accel.timestamp = sensor_get_timestamp();
|
||||
accel.x = (int16_t)lsm9ds1_data(data[0]) * priv->scale;
|
||||
accel.y = (int16_t)lsm9ds1_data(data[1]) * priv->scale;
|
||||
accel.z = (int16_t)lsm9ds1_data(data[2]) * priv->scale;
|
||||
|
||||
memcpy(buffer, &accel, sizeof(accel));
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case SENSOR_TYPE_GYROSCOPE:
|
||||
{
|
||||
struct sensor_gyro gyro;
|
||||
|
||||
ret = lsm9ds1_readreg(&priv->base, LSM9DS1_OUT_X_L_G,
|
||||
(FAR uint8_t *)data, 6);
|
||||
|
||||
gyro.timestamp = sensor_get_timestamp();
|
||||
gyro.x = (int16_t)lsm9ds1_data(data[0]) * priv->scale;
|
||||
gyro.y = (int16_t)lsm9ds1_data(data[1]) * priv->scale;
|
||||
gyro.z = (int16_t)lsm9ds1_data(data[2]) * priv->scale;
|
||||
|
||||
memcpy(buffer, &gyro, sizeof(gyro));
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case SENSOR_TYPE_MAGNETIC_FIELD:
|
||||
{
|
||||
struct sensor_mag mag;
|
||||
|
||||
ret = lsm9ds1_readreg(&priv->base, LSM9DS1_OUT_X_L_M,
|
||||
(FAR uint8_t *)data, 6);
|
||||
|
||||
mag.timestamp = sensor_get_timestamp();
|
||||
mag.x = (int16_t)lsm9ds1_data(data[0]) * priv->scale;
|
||||
mag.y = (int16_t)lsm9ds1_data(data[1]) * priv->scale;
|
||||
mag.z = (int16_t)lsm9ds1_data(data[2]) * priv->scale;
|
||||
|
||||
memcpy(buffer, &mag, sizeof(mag));
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
ret = -EINVAL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: lsm9ds1_cotrol
|
||||
****************************************************************************/
|
||||
|
||||
static int lsm9ds1_control(FAR struct sensor_lowerhalf_s *lower,
|
||||
FAR struct file *filep, int cmd,
|
||||
unsigned long arg)
|
||||
{
|
||||
FAR struct lsm9ds1_sensor_s *priv = NULL;
|
||||
int ret = OK;
|
||||
|
||||
priv = container_of(lower, struct lsm9ds1_sensor_s, lower);
|
||||
|
||||
switch (cmd)
|
||||
{
|
||||
/* Set full scale command */
|
||||
|
||||
case SNIOC_SET_SCALE_XL:
|
||||
{
|
||||
if (priv->lower.type == SENSOR_TYPE_GYROSCOPE)
|
||||
{
|
||||
ret = lsm9ds1_gyro_scale(priv, arg);
|
||||
}
|
||||
else if (priv->lower.type == SENSOR_TYPE_ACCELEROMETER)
|
||||
{
|
||||
ret = lsm9ds1_accel_scale(priv, arg);
|
||||
}
|
||||
else if (priv->lower.type == SENSOR_TYPE_MAGNETIC_FIELD)
|
||||
{
|
||||
ret = lsm9ds1_mag_scale(priv, arg);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
snerr("ERROR: Unrecognized cmd: %d\n", cmd);
|
||||
ret = -ENOTTY;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: lsm9ds1_mag_scale
|
||||
****************************************************************************/
|
||||
|
||||
static int lsm9ds1_mag_scale(FAR struct lsm9ds1_sensor_s *priv,
|
||||
uint8_t scale)
|
||||
{
|
||||
int ret = OK;
|
||||
|
||||
ret = priv->base.ops->setfullscale(&priv->base, scale);
|
||||
if (ret < 0)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (scale < lsm9ds1_midpoint(4, 8))
|
||||
{
|
||||
priv->scale = 8.f / 65536.f;
|
||||
}
|
||||
else if (scale < lsm9ds1_midpoint(8, 12))
|
||||
{
|
||||
priv->scale = 16.f / 65536.f;
|
||||
}
|
||||
else if (scale < lsm9ds1_midpoint(12, 16))
|
||||
{
|
||||
priv->scale = 24.f / 65536.f;
|
||||
}
|
||||
else
|
||||
{
|
||||
priv->scale = 32.f / 65536.f;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: lsm9ds1_accel_scale
|
||||
****************************************************************************/
|
||||
|
||||
static int lsm9ds1_accel_scale(FAR struct lsm9ds1_sensor_s *priv,
|
||||
uint8_t scale)
|
||||
{
|
||||
int ret = OK;
|
||||
|
||||
ret = priv->base.ops->setfullscale(&priv->base, scale);
|
||||
if (ret < 0)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (scale < lsm9ds1_midpoint(2, 4))
|
||||
{
|
||||
priv->scale = CONSTANTS_ONE_G / 16384.f;
|
||||
}
|
||||
else if (scale < lsm9ds1_midpoint(4, 8))
|
||||
{
|
||||
priv->scale = CONSTANTS_ONE_G / 8192.f;
|
||||
}
|
||||
else if (scale < lsm9ds1_midpoint(8, 16))
|
||||
{
|
||||
priv->scale = CONSTANTS_ONE_G / 4096.f;
|
||||
}
|
||||
else
|
||||
{
|
||||
priv->scale = CONSTANTS_ONE_G / 2048.f;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: lsm9ds1_gyro_scale
|
||||
****************************************************************************/
|
||||
|
||||
static int lsm9ds1_gyro_scale(FAR struct lsm9ds1_sensor_s *priv,
|
||||
uint8_t scale)
|
||||
{
|
||||
int ret = OK;
|
||||
|
||||
ret = priv->base.ops->setfullscale(&priv->base, scale);
|
||||
if (ret < 0)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (scale < lsm9ds1_midpoint(245, 500))
|
||||
{
|
||||
priv->scale = (M_PI / 180.0f) * 245.f / 32768.f;
|
||||
}
|
||||
else if (scale < lsm9ds1_midpoint(500, 2000))
|
||||
{
|
||||
priv->scale = (M_PI / 180.0f) * 500.f / 32768.f;
|
||||
}
|
||||
else
|
||||
{
|
||||
priv->scale = (M_PI / 180.0f) * 2000.f / 32768.f;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SENSORS_LSM9DS1_POLL
|
||||
/****************************************************************************
|
||||
* Name: lsm9ds1_accel_data
|
||||
*
|
||||
* Description: get and push accel data from struct sensor_data_s
|
||||
*
|
||||
* Parameter:
|
||||
* priv - Internal private lower half driver instance
|
||||
* buf - Point to data
|
||||
*
|
||||
* Return:
|
||||
* OK - on success
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void lsm9ds1_accel_data(FAR struct lsm9ds1_sensor_s *priv,
|
||||
FAR int16_t *buf)
|
||||
{
|
||||
FAR struct sensor_lowerhalf_s *lower = &priv->lower;
|
||||
struct sensor_accel accel;
|
||||
uint64_t now = sensor_get_timestamp();
|
||||
|
||||
if (!priv->enabled || now - priv->last_update < priv->interval)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
priv->last_update = now;
|
||||
|
||||
accel.timestamp = now;
|
||||
accel.x = (int16_t)lsm9ds1_data(buf[0]) * priv->scale;
|
||||
accel.y = (int16_t)lsm9ds1_data(buf[1]) * priv->scale;
|
||||
accel.z = (int16_t)lsm9ds1_data(buf[2]) * priv->scale;
|
||||
accel.temperature = 0;
|
||||
|
||||
lower->push_event(lower->priv, &accel, sizeof(accel));
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: lsm9ds1_gyro_data
|
||||
*
|
||||
* Description: get and push gyro data from struct sensor_data_s
|
||||
*
|
||||
* Parameter:
|
||||
* priv - Internal private lower half driver instance
|
||||
* buf - Point to data
|
||||
*
|
||||
* Return:
|
||||
* OK - on success
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void lsm9ds1_gyro_data(FAR struct lsm9ds1_sensor_s *priv,
|
||||
FAR int16_t *buf)
|
||||
{
|
||||
FAR struct sensor_lowerhalf_s *lower = &priv->lower;
|
||||
struct sensor_gyro gyro;
|
||||
uint64_t now = sensor_get_timestamp();
|
||||
|
||||
if (!priv->enabled || now - priv->last_update < priv->interval)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
priv->last_update = now;
|
||||
|
||||
gyro.timestamp = now;
|
||||
gyro.x = (int16_t)lsm9ds1_data(buf[0]) * priv->scale;
|
||||
gyro.y = (int16_t)lsm9ds1_data(buf[1]) * priv->scale;
|
||||
gyro.z = (int16_t)lsm9ds1_data(buf[2]) * priv->scale;
|
||||
gyro.temperature = 0;
|
||||
|
||||
lower->push_event(lower->priv, &gyro, sizeof(gyro));
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: lsm9ds1_mag_data
|
||||
*
|
||||
* Description: get and push magnetometer data from struct sensor_data_s
|
||||
*
|
||||
* Parameter:
|
||||
* priv - Internal private lower half driver instance
|
||||
* buf - Point to data
|
||||
*
|
||||
* Return:
|
||||
* OK - on success
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void lsm9ds1_mag_data(FAR struct lsm9ds1_sensor_s *priv,
|
||||
FAR int16_t *buf)
|
||||
{
|
||||
FAR struct sensor_lowerhalf_s *lower = &priv->lower;
|
||||
struct sensor_mag mag;
|
||||
uint64_t now = sensor_get_timestamp();
|
||||
|
||||
if (!priv->enabled || now - priv->last_update < priv->interval)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
priv->last_update = now;
|
||||
|
||||
mag.timestamp = now;
|
||||
mag.x = (int16_t)lsm9ds1_data(buf[0]) * priv->scale;
|
||||
mag.y = (int16_t)lsm9ds1_data(buf[1]) * priv->scale;
|
||||
mag.z = (int16_t)lsm9ds1_data(buf[2]) * priv->scale;
|
||||
mag.temperature = 0;
|
||||
|
||||
lower->push_event(lower->priv, &mag, sizeof(mag));
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: lsm9ds1_thread
|
||||
*
|
||||
* Description: Thread for performing interval measurement cycle and data
|
||||
* read.
|
||||
*
|
||||
* Parameter:
|
||||
* argc - Number opf arguments
|
||||
* argv - Pointer to argument list
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int lsm9ds1_thread(int argc, FAR char **argv)
|
||||
{
|
||||
FAR struct lsm9ds1_sensor_dev_s *dev
|
||||
= (FAR struct lsm9ds1_sensor_dev_s *)((uintptr_t)strtoul(argv[1], NULL,
|
||||
16));
|
||||
FAR struct lsm9ds1_sensor_s *accel = &dev->priv[LSM9DS1_ACCEL_IDX];
|
||||
FAR struct lsm9ds1_sensor_s *gyro = &dev->priv[LSM9DS1_GYRO_IDX];
|
||||
FAR struct lsm9ds1_sensor_s *mag = &dev->priv[LSM9DS1_MAG_IDX];
|
||||
unsigned long min_interval;
|
||||
int16_t adata[3];
|
||||
int16_t gdata[3];
|
||||
int16_t mdata[3];
|
||||
int ret;
|
||||
|
||||
while (true)
|
||||
{
|
||||
if ((!accel->enabled) && (!gyro->enabled) && (!mag->enabled))
|
||||
{
|
||||
/* Waiting to be woken up */
|
||||
|
||||
ret = nxsem_wait(&dev->run);
|
||||
if (ret < 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/* Read accel */
|
||||
|
||||
if (accel->enabled)
|
||||
{
|
||||
ret = lsm9ds1_readreg(&accel->base,
|
||||
LSM9DS1_OUT_X_L_XL, (uint8_t *)adata, 6);
|
||||
lsm9ds1_accel_data(accel, adata);
|
||||
}
|
||||
|
||||
/* Read gyro */
|
||||
|
||||
if (gyro->enabled)
|
||||
{
|
||||
ret = lsm9ds1_readreg(&gyro->base,
|
||||
LSM9DS1_OUT_X_L_G, (uint8_t *)gdata, 6);
|
||||
lsm9ds1_gyro_data(gyro, gdata);
|
||||
}
|
||||
|
||||
/* Read mag */
|
||||
|
||||
if (mag->enabled)
|
||||
{
|
||||
ret = lsm9ds1_readreg(&mag->base,
|
||||
LSM9DS1_OUT_X_L_M, (uint8_t *)mdata, 6);
|
||||
lsm9ds1_mag_data(mag, mdata);
|
||||
}
|
||||
|
||||
/* Sleeping thread before fetching the next sensor data */
|
||||
|
||||
min_interval = MIN(accel->interval, gyro->interval);
|
||||
min_interval = MIN(min_interval, mag->interval);
|
||||
nxsig_usleep(min_interval);
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: lsm9ds1_register_uorb
|
||||
*
|
||||
* Description:
|
||||
* Register the LSM9DS1 IMU as sensor device
|
||||
*
|
||||
* Input Parameters:
|
||||
* devno - Instance number for driver
|
||||
* config - configuratio
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero (OK) on success; a negated errno value on failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int lsm9ds1_register_uorb(int devno, FAR struct lsm9ds1_config_s *config)
|
||||
{
|
||||
FAR struct lsm9ds1_sensor_dev_s *dev = NULL;
|
||||
FAR struct lsm9ds1_sensor_s *tmp = NULL;
|
||||
#ifdef CONFIG_SENSORS_LSM9DS1_POLL
|
||||
FAR char *argv[2];
|
||||
char arg1[32];
|
||||
#endif
|
||||
int ret = OK;
|
||||
|
||||
/* Initialize the device structure. */
|
||||
|
||||
dev = (FAR struct lsm9ds1_sensor_dev_s *)kmm_malloc(sizeof(*dev));
|
||||
if (dev == NULL)
|
||||
{
|
||||
snerr("ERROR: Failed to allocate instance\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
memset(dev, 0, sizeof(*dev));
|
||||
nxmutex_init(&dev->lock);
|
||||
#ifdef CONFIG_SENSORS_LSM9DS1_POLL
|
||||
nxsem_init(&dev->run, 0, 0);
|
||||
#endif
|
||||
|
||||
/* Accelerometer register */
|
||||
|
||||
tmp = &dev->priv[LSM9DS1_ACCEL_IDX];
|
||||
tmp->dev = dev;
|
||||
tmp->base.ops = &g_lsm9ds1accel_ops;
|
||||
tmp->base.i2c = config->i2c;
|
||||
tmp->base.addr = config->addr_acc;
|
||||
tmp->lower.ops = &g_sensor_ops;
|
||||
tmp->lower.type = SENSOR_TYPE_ACCELEROMETER;
|
||||
tmp->lower.nbuffer = 1;
|
||||
#ifdef CONFIG_SENSORS_LSM9DS1_POLL
|
||||
tmp->enabled = false;
|
||||
tmp->interval = CONFIG_SENSORS_LSM9DS1_POLL_INTERVAL;
|
||||
#endif
|
||||
|
||||
ret = sensor_register(&tmp->lower, devno);
|
||||
if (ret < 0)
|
||||
{
|
||||
snerr("sensor_register failed: %d\n", ret);
|
||||
goto gyro_err;
|
||||
}
|
||||
|
||||
lsm9ds1_accel_scale(tmp, 2);
|
||||
|
||||
/* Gyroscope register */
|
||||
|
||||
tmp = &dev->priv[LSM9DS1_GYRO_IDX];
|
||||
tmp->dev = dev;
|
||||
tmp->base.ops = &g_lsm9ds1gyro_ops;
|
||||
tmp->base.i2c = config->i2c;
|
||||
tmp->base.addr = config->addr_gyro;
|
||||
tmp->lower.ops = &g_sensor_ops;
|
||||
tmp->lower.type = SENSOR_TYPE_GYROSCOPE;
|
||||
tmp->lower.nbuffer = 1;
|
||||
#ifdef CONFIG_SENSORS_LSM9DS1_POLL
|
||||
tmp->enabled = false;
|
||||
tmp->interval = CONFIG_SENSORS_LSM9DS1_POLL_INTERVAL;
|
||||
#endif
|
||||
|
||||
ret = sensor_register(&tmp->lower, devno);
|
||||
if (ret < 0)
|
||||
{
|
||||
snerr("sensor_register failed: %d\n", ret);
|
||||
goto gyro_err;
|
||||
}
|
||||
|
||||
lsm9ds1_gyro_scale(tmp, 245);
|
||||
|
||||
/* Magnetic register */
|
||||
|
||||
tmp = &dev->priv[LSM9DS1_MAG_IDX];
|
||||
tmp->dev = dev;
|
||||
tmp->base.ops = &g_lsm9ds1mag_ops;
|
||||
tmp->base.i2c = config->i2c;
|
||||
tmp->base.addr = config->addr_mag;
|
||||
tmp->lower.ops = &g_sensor_ops;
|
||||
tmp->lower.type = SENSOR_TYPE_MAGNETIC_FIELD;
|
||||
tmp->lower.nbuffer = 1;
|
||||
#ifdef CONFIG_SENSORS_LSM9DS1_POLL
|
||||
tmp->enabled = false;
|
||||
tmp->interval = CONFIG_SENSORS_LSM9DS1_POLL_INTERVAL;
|
||||
#endif
|
||||
|
||||
ret = sensor_register(&tmp->lower, devno);
|
||||
if (ret < 0)
|
||||
{
|
||||
snerr("sensor_register failed: %d\n", ret);
|
||||
goto mag_err;
|
||||
}
|
||||
|
||||
lsm9ds1_mag_scale(tmp, 4);
|
||||
|
||||
#ifdef CONFIG_SENSORS_LSM9DS1_POLL
|
||||
/* Create thread for polling sensor data */
|
||||
|
||||
snprintf(arg1, 16, "%p", dev);
|
||||
argv[0] = arg1;
|
||||
argv[1] = NULL;
|
||||
|
||||
ret = kthread_create("lsm9ds1_thread", SCHED_PRIORITY_DEFAULT,
|
||||
CONFIG_SENSORS_LSM9DS1_THREAD_STACKSIZE,
|
||||
lsm9ds1_thread,
|
||||
argv);
|
||||
if (ret < 0)
|
||||
{
|
||||
goto thr_err;
|
||||
}
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
|
||||
#ifdef CONFIG_SENSORS_LSM9DS1_POLL
|
||||
thr_err:
|
||||
#endif
|
||||
sensor_unregister(&dev->priv[LSM9DS1_MAG_IDX].lower, devno);
|
||||
mag_err:
|
||||
sensor_unregister(&dev->priv[LSM9DS1_GYRO_IDX].lower, devno);
|
||||
gyro_err:
|
||||
sensor_unregister(&dev->priv[LSM9DS1_ACCEL_IDX].lower, devno);
|
||||
|
||||
kmm_free(dev);
|
||||
|
||||
return ret;
|
||||
}
|
|
@ -57,6 +57,14 @@
|
|||
|
||||
struct i2c_master_s;
|
||||
|
||||
struct lsm9ds1_config_s
|
||||
{
|
||||
FAR struct i2c_master_s *i2c;
|
||||
int addr_acc;
|
||||
int addr_gyro;
|
||||
int addr_mag;
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Public Function Prototypes
|
||||
****************************************************************************/
|
||||
|
@ -66,6 +74,8 @@ extern "C"
|
|||
{
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_SENSORS_LSM9DS1_UORB
|
||||
|
||||
/****************************************************************************
|
||||
* Name: lsm9ds1accel_register
|
||||
*
|
||||
|
@ -126,6 +136,26 @@ int lsm9ds1mag_register(FAR const char *devpath,
|
|||
FAR struct i2c_master_s *i2c,
|
||||
uint8_t addr);
|
||||
|
||||
#else
|
||||
|
||||
/****************************************************************************
|
||||
* Name: lsm9ds1_register_uorb
|
||||
*
|
||||
* Description:
|
||||
* Register the LSM9DS1 IMU as sensor device
|
||||
*
|
||||
* Input Parameters:
|
||||
* devno - Instance number for driver
|
||||
* config - configuratio
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero (OK) on success; a negated errno value on failure.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int lsm9ds1_register_uorb(int devno, FAR struct lsm9ds1_config_s *config);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -966,7 +966,7 @@ struct sensor_ops_s
|
|||
FAR struct file *filep,
|
||||
unsigned long arg);
|
||||
|
||||
/****************************************************************************
|
||||
/**************************************************************************
|
||||
* Name: calibrate
|
||||
*
|
||||
* This operation can trigger the calibration operation, and if the
|
||||
|
|
Loading…
Reference in a new issue