1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2024-12-29 04:50:03 +01:00

drivers, lsm6dsl: cleanup

This commit is contained in:
smlng 2017-07-02 13:21:42 +02:00
parent a7d9547d5e
commit 2b9eddfbeb
5 changed files with 269 additions and 248 deletions

View File

@ -13,10 +13,13 @@
* @brief Device driver for the LSM6DSL 3D accelerometer/gyroscope
*
* @{
*
* @file
* @brief Device driver interface for the LSM6DSL 3D accelerometer/gyroscope.
*
* @author Vincent Dupont <vincent@otakeys.com>
* @author Sebastian Meiling <s@mlng.net>
*
*/
#ifndef LSM6DSL_H
@ -28,7 +31,9 @@ extern "C" {
#include "periph/i2c.h"
/** Data rate */
/**
* @brief Data rate settings
*/
enum {
LSM6DSL_DATA_RATE_POWER_DOWN = 0x0,
LSM6DSL_DATA_RATE_1_6HZ = 0xB,
@ -44,35 +49,45 @@ enum {
LSM6DSL_DATA_RATE_6_66KHZ = 0xa,
};
/** Decimation */
/**
* @brief Decimation settings
*/
enum {
LSM6DSL_DECIMATION_NOT_IN_FIFO = 0,
LSM6DSL_DECIMATION_NO = 1,
LSM6DSL_DECIMATION_2 = 2,
LSM6DSL_DECIMATION_3 = 3,
LSM6DSL_DECIMATION_4 = 4,
LSM6DSL_DECIMATION_8 = 5,
LSM6DSL_DECIMATION_16 = 6,
LSM6DSL_DECIMATION_32 = 7,
LSM6DSL_DECIMATION_NO,
LSM6DSL_DECIMATION_2,
LSM6DSL_DECIMATION_3,
LSM6DSL_DECIMATION_4,
LSM6DSL_DECIMATION_8,
LSM6DSL_DECIMATION_16,
LSM6DSL_DECIMATION_32,
};
/** Accelerometer full scale */
/**
* @brief Accelerometer full scale
*/
enum {
LSM6DSL_ACC_FS_2G = 0,
LSM6DSL_ACC_FS_4G = 2,
LSM6DSL_ACC_FS_8G = 3,
LSM6DSL_ACC_FS_16G = 1,
LSM6DSL_ACC_FS_16G,
LSM6DSL_ACC_FS_4G,
LSM6DSL_ACC_FS_8G,
LSM6DSL_ACC_FS_MAX,
};
/** Gyroscope full scale */
/**
* @brief Gyroscope full scale
*/
enum {
LSM6DSL_GYRO_FS_245DPS = 0,
LSM6DSL_GYRO_FS_500DPS = 1,
LSM6DSL_GYRO_FS_1000DPS = 2,
LSM6DSL_GYRO_FS_2000DPS = 3,
LSM6DSL_GYRO_FS_500DPS,
LSM6DSL_GYRO_FS_1000DPS,
LSM6DSL_GYRO_FS_2000DPS,
LSM6DSL_GYRO_FS_MAX,
};
/** LSM6DSL driver parameters */
/**
* @brief LSM6DSL driver parameters
*/
typedef struct {
i2c_t i2c; /**< i2c bus */
uint8_t addr; /**< i2c address */
@ -84,25 +99,39 @@ typedef struct {
uint8_t gyro_decimation; /**< gyroscope decimation */
} lsm6dsl_params_t;
/** LSM6DSL device descriptor */
/**
* @brief LSM6DSL device descriptor
*/
typedef struct {
lsm6dsl_params_t params; /**< driver parameters */
} lsm6dsl_t;
/** 3D output data */
/**
* @brief 3D output data
*/
typedef struct {
int16_t x; /**< X axis */
int16_t y; /**< Y axis */
int16_t z; /**< Z axis */
} lsm6dsl_3d_data_t;
/**
* @brief Named return values
*/
enum {
LSM6DSL_OK = 0, /**< all good */
LSM6DSL_ERROR_BUS, /**< I2C bus error */
LSM6DSL_ERROR_CNF, /**< Config error */
LSM6DSL_ERROR_DEV, /**< device error */
};
/**
* @brief Initialize a LSM6DSL device
*
* @param[in] dev device to initialize
* @param[out] dev device to initialize
* @param[in] params driver parameters
*
* @return 0 on success
* @return LSM6DSL_OK on success
* @return < 0 on error
*/
int lsm6dsl_init(lsm6dsl_t *dev, const lsm6dsl_params_t *params);
@ -113,7 +142,7 @@ int lsm6dsl_init(lsm6dsl_t *dev, const lsm6dsl_params_t *params);
* @param[in] dev device to read
* @param[out] data accelerometer values
*
* @return 0 on success
* @return LSM6DSL_OK on success
* @return < 0 on error
*/
int lsm6dsl_read_acc(const lsm6dsl_t *dev, lsm6dsl_3d_data_t *data);
@ -124,7 +153,7 @@ int lsm6dsl_read_acc(const lsm6dsl_t *dev, lsm6dsl_3d_data_t *data);
* @param[in] dev device to read
* @param[out] data gyroscope values
*
* @return 0 on success
* @return LSM6DSL_OK on success
* @return < 0 on error
*/
int lsm6dsl_read_gyro(const lsm6dsl_t *dev, lsm6dsl_3d_data_t *data);
@ -139,7 +168,7 @@ int lsm6dsl_read_gyro(const lsm6dsl_t *dev, lsm6dsl_3d_data_t *data);
* @param[in] dev device to read
* @param[out] data temperature value, in °C x 100
*
* @return 0 on success
* @return LSM6DSL_OK on success
* @return < 0 on error
*/
int lsm6dsl_read_temp(const lsm6dsl_t *dev, int16_t *data);

View File

@ -9,17 +9,21 @@
/**
* @ingroup drivers_lsm6dsl
*
* @{
*
* @file
* @brief Internal configuration for LSM6DSL devices
*
* @author Vincent Dupont <vincent@otakeys.com>
* @author Sebastian Meiling <s@mlng.net>
*
*/
#ifndef LSM6DSL_INTERNAL_H
#define LSM6DSL_INTERNAL_H
#include "xtimer.h"
#ifdef __cplusplus
extern "C" {
#endif
@ -28,131 +32,136 @@ extern "C" {
* @name LSM6DSL registers
* @{
*/
#define LSM6DSL_REG_FUNC_CFG_ACCESS (0x01)
#define LSM6DSL_REG_SENSOR_SYNC_TIME_FRAME (0x04)
#define LSM6DSL_REG_SENSOR_SYC_RES_RATIO (0x05)
#define LSM6DSL_REG_FIFO_CTRL1 (0x06)
#define LSM6DSL_REG_FIFO_CTRL2 (0x07)
#define LSM6DSL_REG_FIFO_CTRL3 (0x08)
#define LSM6DSL_REG_FIFO_CTRL4 (0x09)
#define LSM6DSL_REG_FIFO_CTRL5 (0x0A)
#define LSM6DSL_REG_DRDY_PULSE_CFG_G (0x0B)
#define LSM6DSL_REG_INT1_CTRL (0x0D)
#define LSM6DSL_REG_INT2_CTRL (0x0E)
#define LSM6DSL_REG_WHO_AM_I (0x0F)
#define LSM6DSL_REG_CTRL1_XL (0x10)
#define LSM6DSL_REG_CTRL2_G (0x11)
#define LSM6DSL_REG_CTRL3_C (0x12)
#define LSM6DSL_REG_CTRL4_C (0x13)
#define LSM6DSL_REG_CTRL5_C (0x14)
#define LSM6DSL_REG_CTRL6_C (0x15)
#define LSM6DSL_REG_CTRL7_G (0x16)
#define LSM6DSL_REG_CTRL8_XL (0x17)
#define LSM6DSL_REG_CTRL9_XL (0x18)
#define LSM6DSL_REG_CTRL10_C (0x19)
#define LSM6DSL_REG_MASTER_CONFIG (0x1A)
#define LSM6DSL_REG_WAKE_UP_SRC (0x1B)
#define LSM6DSL_REG_TAP_SRC (0x1C)
#define LSM6DSL_REG_D6D_SRC (0x1D)
#define LSM6DSL_REG_STATUS_REG (0x1E)
#define LSM6DSL_REG_OUT_TEMP_L (0x20)
#define LSM6DSL_REG_OUT_TEMP_H (0x21)
#define LSM6DSL_REG_OUTX_L_G (0x22)
#define LSM6DSL_REG_OUTX_H_G (0x23)
#define LSM6DSL_REG_OUTY_L_G (0x24)
#define LSM6DSL_REG_OUTY_H_G (0x25)
#define LSM6DSL_REG_OUTZ_L_G (0x26)
#define LSM6DSL_REG_OUTZ_H_G (0x27)
#define LSM6DSL_REG_OUTX_L_XL (0x28)
#define LSM6DSL_REG_OUTX_H_XL (0x29)
#define LSM6DSL_REG_OUTY_L_XL (0x2A)
#define LSM6DSL_REG_OUTY_H_XL (0x2B)
#define LSM6DSL_REG_OUTZ_L_XL (0x2C)
#define LSM6DSL_REG_OUTZ_H_XL (0x2D)
#define LSM6DSL_REG_SENSORHUB1_REG (0x2E)
#define LSM6DSL_REG_SENSORHUB2_REG (0x2F)
#define LSM6DSL_REG_SENSORHUB3_REG (0x30)
#define LSM6DSL_REG_SENSORHUB4_REG (0x31)
#define LSM6DSL_REG_SENSORHUB5_REG (0x32)
#define LSM6DSL_REG_SENSORHUB6_REG (0x33)
#define LSM6DSL_REG_SENSORHUB7_REG (0x34)
#define LSM6DSL_REG_SENSORHUB8_REG (0x35)
#define LSM6DSL_REG_SENSORHUB9_REG (0x36)
#define LSM6DSL_REG_SENSORHUB10_REG (0x37)
#define LSM6DSL_REG_SENSORHUB11_REG (0x38)
#define LSM6DSL_REG_SENSORHUB12_REG (0x39)
#define LSM6DSL_REG_FIFO_STATUS1 (0x3A)
#define LSM6DSL_REG_FIFO_STATUS2 (0x3B)
#define LSM6DSL_REG_FIFO_STATUS3 (0x3C)
#define LSM6DSL_REG_FIFO_STATUS4 (0x3D)
#define LSM6DSL_REG_FIFO_DATA_OUT_L (0x3E)
#define LSM6DSL_REG_FIFO_DATA_OUT_H (0x3F)
#define LSM6DSL_REG_TIMESTAMP0_REG (0x40)
#define LSM6DSL_REG_TIMESTAMP1_REG (0x41)
#define LSM6DSL_REG_TIMESTAMP2_REG (0x42)
#define LSM6DSL_REG_STEP_TIMESTAMP_L (0x49)
#define LSM6DSL_REG_STEP_TIMESTAMP_H (0x4A)
#define LSM6DSL_REG_STEP_COUNTER_L (0x4B)
#define LSM6DSL_REG_STEP_COUNTER_H (0x4C)
#define LSM6DSL_REG_SENSORHUB13_REG (0x4D)
#define LSM6DSL_REG_SENSORHUB14_REG (0x4E)
#define LSM6DSL_REG_SENSORHUB15_REG (0x4F)
#define LSM6DSL_REG_SENSORHUB16_REG (0x50)
#define LSM6DSL_REG_SENSORHUB17_REG (0x51)
#define LSM6DSL_REG_SENSORHUB18_REG (0x52)
#define LSM6DSL_REG_FUNC_SRC_1 (0x53)
#define LSM6DSL_REG_FUNC_SRC_2 (0x54)
#define LSM6DSL_REG_WRIST_TILT_IA (0x55)
#define LSM6DSL_REG_TAP_CFG (0x58)
#define LSM6DSL_REG_TAP_THS_6D (0x59)
#define LSM6DSL_REG_INT_DUR2 (0x5A)
#define LSM6DSL_REG_WAKE_UP_THS (0x5B)
#define LSM6DSL_REG_WAKE_UP_DUR (0x5C)
#define LSM6DSL_REG_FREE_FALL (0x5D)
#define LSM6DSL_REG_MD1_CFG (0x5E)
#define LSM6DSL_REG_MD2_CFG (0x5F)
#define LSM6DSL_REG_MASTER_CMD_CODE (0x60)
#define LSM6DSL_REG_SENS_SYNC_SPI_ERR_CODE (0x61)
#define LSM6DSL_REG_OUT_MAG_RAW_X_L (0x66)
#define LSM6DSL_REG_OUT_MAG_RAW_X_H (0x67)
#define LSM6DSL_REG_OUT_MAG_RAW_Y_L (0x68)
#define LSM6DSL_REG_OUT_MAG_RAW_Y_H (0x69)
#define LSM6DSL_REG_OUT_MAG_RAW_Z_L (0x6A)
#define LSM6DSL_REG_OUT_MAG_RAW_Z_H (0x6B)
#define LSM6DSL_REG_X_OFS_USR (0x73)
#define LSM6DSL_REG_Y_OFS_USR (0x74)
#define LSM6DSL_REG_Z_OFS_USR (0x75)
#define LSM6DSL_REG_FUNC_CFG_ACCESS (0x01)
#define LSM6DSL_REG_SENSOR_SYNC_TIME_FRAME (0x04)
#define LSM6DSL_REG_SENSOR_SYC_RES_RATIO (0x05)
#define LSM6DSL_REG_FIFO_CTRL1 (0x06)
#define LSM6DSL_REG_FIFO_CTRL2 (0x07)
#define LSM6DSL_REG_FIFO_CTRL3 (0x08)
#define LSM6DSL_REG_FIFO_CTRL4 (0x09)
#define LSM6DSL_REG_FIFO_CTRL5 (0x0A)
#define LSM6DSL_REG_DRDY_PULSE_CFG_G (0x0B)
#define LSM6DSL_REG_INT1_CTRL (0x0D)
#define LSM6DSL_REG_INT2_CTRL (0x0E)
#define LSM6DSL_REG_WHO_AM_I (0x0F)
#define LSM6DSL_REG_CTRL1_XL (0x10)
#define LSM6DSL_REG_CTRL2_G (0x11)
#define LSM6DSL_REG_CTRL3_C (0x12)
#define LSM6DSL_REG_CTRL4_C (0x13)
#define LSM6DSL_REG_CTRL5_C (0x14)
#define LSM6DSL_REG_CTRL6_C (0x15)
#define LSM6DSL_REG_CTRL7_G (0x16)
#define LSM6DSL_REG_CTRL8_XL (0x17)
#define LSM6DSL_REG_CTRL9_XL (0x18)
#define LSM6DSL_REG_CTRL10_C (0x19)
#define LSM6DSL_REG_MASTER_CONFIG (0x1A)
#define LSM6DSL_REG_WAKE_UP_SRC (0x1B)
#define LSM6DSL_REG_TAP_SRC (0x1C)
#define LSM6DSL_REG_D6D_SRC (0x1D)
#define LSM6DSL_REG_STATUS_REG (0x1E)
#define LSM6DSL_REG_OUT_TEMP_L (0x20)
#define LSM6DSL_REG_OUT_TEMP_H (0x21)
#define LSM6DSL_REG_OUTX_L_G (0x22)
#define LSM6DSL_REG_OUTX_H_G (0x23)
#define LSM6DSL_REG_OUTY_L_G (0x24)
#define LSM6DSL_REG_OUTY_H_G (0x25)
#define LSM6DSL_REG_OUTZ_L_G (0x26)
#define LSM6DSL_REG_OUTZ_H_G (0x27)
#define LSM6DSL_REG_OUTX_L_XL (0x28)
#define LSM6DSL_REG_OUTX_H_XL (0x29)
#define LSM6DSL_REG_OUTY_L_XL (0x2A)
#define LSM6DSL_REG_OUTY_H_XL (0x2B)
#define LSM6DSL_REG_OUTZ_L_XL (0x2C)
#define LSM6DSL_REG_OUTZ_H_XL (0x2D)
#define LSM6DSL_REG_SENSORHUB1_REG (0x2E)
#define LSM6DSL_REG_SENSORHUB2_REG (0x2F)
#define LSM6DSL_REG_SENSORHUB3_REG (0x30)
#define LSM6DSL_REG_SENSORHUB4_REG (0x31)
#define LSM6DSL_REG_SENSORHUB5_REG (0x32)
#define LSM6DSL_REG_SENSORHUB6_REG (0x33)
#define LSM6DSL_REG_SENSORHUB7_REG (0x34)
#define LSM6DSL_REG_SENSORHUB8_REG (0x35)
#define LSM6DSL_REG_SENSORHUB9_REG (0x36)
#define LSM6DSL_REG_SENSORHUB10_REG (0x37)
#define LSM6DSL_REG_SENSORHUB11_REG (0x38)
#define LSM6DSL_REG_SENSORHUB12_REG (0x39)
#define LSM6DSL_REG_FIFO_STATUS1 (0x3A)
#define LSM6DSL_REG_FIFO_STATUS2 (0x3B)
#define LSM6DSL_REG_FIFO_STATUS3 (0x3C)
#define LSM6DSL_REG_FIFO_STATUS4 (0x3D)
#define LSM6DSL_REG_FIFO_DATA_OUT_L (0x3E)
#define LSM6DSL_REG_FIFO_DATA_OUT_H (0x3F)
#define LSM6DSL_REG_TIMESTAMP0_REG (0x40)
#define LSM6DSL_REG_TIMESTAMP1_REG (0x41)
#define LSM6DSL_REG_TIMESTAMP2_REG (0x42)
#define LSM6DSL_REG_STEP_TIMESTAMP_L (0x49)
#define LSM6DSL_REG_STEP_TIMESTAMP_H (0x4A)
#define LSM6DSL_REG_STEP_COUNTER_L (0x4B)
#define LSM6DSL_REG_STEP_COUNTER_H (0x4C)
#define LSM6DSL_REG_SENSORHUB13_REG (0x4D)
#define LSM6DSL_REG_SENSORHUB14_REG (0x4E)
#define LSM6DSL_REG_SENSORHUB15_REG (0x4F)
#define LSM6DSL_REG_SENSORHUB16_REG (0x50)
#define LSM6DSL_REG_SENSORHUB17_REG (0x51)
#define LSM6DSL_REG_SENSORHUB18_REG (0x52)
#define LSM6DSL_REG_FUNC_SRC_1 (0x53)
#define LSM6DSL_REG_FUNC_SRC_2 (0x54)
#define LSM6DSL_REG_WRIST_TILT_IA (0x55)
#define LSM6DSL_REG_TAP_CFG (0x58)
#define LSM6DSL_REG_TAP_THS_6D (0x59)
#define LSM6DSL_REG_INT_DUR2 (0x5A)
#define LSM6DSL_REG_WAKE_UP_THS (0x5B)
#define LSM6DSL_REG_WAKE_UP_DUR (0x5C)
#define LSM6DSL_REG_FREE_FALL (0x5D)
#define LSM6DSL_REG_MD1_CFG (0x5E)
#define LSM6DSL_REG_MD2_CFG (0x5F)
#define LSM6DSL_REG_MASTER_CMD_CODE (0x60)
#define LSM6DSL_REG_SENS_SYNC_SPI_ERR_CODE (0x61)
#define LSM6DSL_REG_OUT_MAG_RAW_X_L (0x66)
#define LSM6DSL_REG_OUT_MAG_RAW_X_H (0x67)
#define LSM6DSL_REG_OUT_MAG_RAW_Y_L (0x68)
#define LSM6DSL_REG_OUT_MAG_RAW_Y_H (0x69)
#define LSM6DSL_REG_OUT_MAG_RAW_Z_L (0x6A)
#define LSM6DSL_REG_OUT_MAG_RAW_Z_H (0x6B)
#define LSM6DSL_REG_X_OFS_USR (0x73)
#define LSM6DSL_REG_Y_OFS_USR (0x74)
#define LSM6DSL_REG_Z_OFS_USR (0x75)
/** @} */
/** WHO_AM_I value */
#define LSM6DSL_WHO_AM_I (0b01101010)
#define LSM6DSL_WHO_AM_I (0b01101010)
/**
* @name CTRL_x registers
* @{
*/
#define LSM6DSL_CTRL_ODR_SHIFT (4)
#define LSM6DSL_CTRL_ODR_MASK (0xF0)
#define LSM6DSL_CTRL_FS_SHIFT (2)
#define LSM6DSL_CTRL_FS_MASK (0x0C)
#define LSM6DSL_CTRL_ODR_SHIFT (4)
#define LSM6DSL_CTRL_ODR_MASK (0xF0)
#define LSM6DSL_CTRL_FS_SHIFT (2)
#define LSM6DSL_CTRL_FS_MASK (0x0C)
#define LSM6DSL_CTRL3_C_BOOT (0x80)
#define LSM6DSL_CTRL3_C_BOOT (0x80)
/** @} */
/**
* @name FIFO_CTRL_x registers
* @{
*/
#define LSM6DSL_FIFO_CTRL5_CONTINUOUS_MODE (0x6)
#define LSM6DSL_FIFO_CTRL5_FIFO_ODR_SHIFT (3)
#define LSM6DSL_FIFO_CTRL5_CONTINUOUS_MODE (0x6)
#define LSM6DSL_FIFO_CTRL5_FIFO_ODR_SHIFT (3)
#define LSM6DSL_FIFO_CTRL3_GYRO_DEC_SHIFT (3)
#define LSM6DSL_FIFO_CTRL3_GYRO_DEC_SHIFT (3)
/** @} */
/**
* @brief Offset for temperature calculation
*/
#define LSM6DSL_TEMP_OFFSET (0x1900)
#define LSM6DSL_TEMP_OFFSET (0x1900)
/**
* @brief Reboot wait interval in us (15ms)
*/
#define LSM6DSL_BOOT_WAIT (15 * US_PER_MS)
#ifdef __cplusplus
}

View File

@ -9,12 +9,13 @@
/**
* @ingroup drivers_lsm6dsl
*
* @{
*
* @file
* @brief Default configuration for LSM6DSL devices
*
* @author Vincent Dupont <vincent@otakeys.com>
*
*/
#ifndef LSM6DSL_PARAMS_H

View File

@ -8,10 +8,16 @@
*/
/**
* @ingroup drivers_lsm6dsl
* @{
*
* @file
* @brief Device driver implementation for the LSM6DSL 3D accelerometer/gyroscope.
*
* @author Vincent Dupont <vincent@otakeys.com>
* @author Sebastian Meiling <s@mlng.net>
*
* @}
*/
#include "xtimer.h"
@ -24,6 +30,22 @@
#define MAX(a, b) ((a) > (b) ? (a) : (b))
#define BUS (dev->params.i2c)
#define ADDR (dev->params.addr)
/**
* order in arry [0, 1, 2, 3] is
* LSM6DSL_ACC_FS_2G, LSM6DSL_ACC_FS_16G, LSM6DSL_ACC_FS_4G, LSM6DSL_ACC_FS_8G
*/
static const int16_t range_acc[] = { 2000, 16000, 4000, 8000 };
/**
* order in arry [0, 1, 2, 3] is
* LSM6DSL_GYRO_FS_245DPS, LSM6DSL_GYRO_FS_500DPS,
* LSM6DSL_GYRO_FS_1000DPS, LSM6DSL_GYRO_FS_2000DPS
*/
static const int16_t range_gyro[] = { 2450, 5000, 10000, 20000 };
int lsm6dsl_init(lsm6dsl_t *dev, const lsm6dsl_params_t *params)
{
uint8_t tmp;
@ -33,47 +55,49 @@ int lsm6dsl_init(lsm6dsl_t *dev, const lsm6dsl_params_t *params)
dev->params = *params;
i2c_acquire(dev->params.i2c);
i2c_init_master(dev->params.i2c, I2C_SPEED_NORMAL);
i2c_acquire(BUS);
i2c_init_master(BUS, I2C_SPEED_NORMAL);
/* Reboot */
i2c_write_reg(dev->params.i2c, dev->params.addr,
LSM6DSL_REG_CTRL3_C, LSM6DSL_CTRL3_C_BOOT);
i2c_write_reg(BUS, ADDR, LSM6DSL_REG_CTRL3_C, LSM6DSL_CTRL3_C_BOOT);
xtimer_usleep(5000);
xtimer_usleep(LSM6DSL_BOOT_WAIT);
res = i2c_read_reg(dev->params.i2c, dev->params.addr, LSM6DSL_REG_WHO_AM_I, &tmp);
if ((res != 1) || (tmp != LSM6DSL_WHO_AM_I)) {
i2c_release(dev->params.i2c);
DEBUG("[!!failed!!] WHO_AM_I\n");
return -1;
if (i2c_read_reg(BUS, ADDR, LSM6DSL_REG_WHO_AM_I, &tmp) != 1) {
i2c_release(BUS);
DEBUG("[ERROR] lsm6dsl_init: i2c_read_reg LSM6DSL_REG_WHO_AM_I!\n");
return -LSM6DSL_ERROR_BUS;
}
if (tmp != LSM6DSL_WHO_AM_I) {
DEBUG("[ERROR] lsm6dsl_init: WHO_AM_I\n");
return -LSM6DSL_ERROR_DEV;
}
/* Set acc odr / full scale */
res = i2c_write_reg(dev->params.i2c, dev->params.addr, LSM6DSL_REG_CTRL1_XL,
((dev->params.acc_odr << LSM6DSL_CTRL_ODR_SHIFT) |
(dev->params.acc_fs << LSM6DSL_CTRL_FS_SHIFT)));
tmp = (dev->params.acc_odr << LSM6DSL_CTRL_ODR_SHIFT) |
(dev->params.acc_fs << LSM6DSL_CTRL_FS_SHIFT);
res = i2c_write_reg(BUS, ADDR, LSM6DSL_REG_CTRL1_XL, tmp);
/* Set gyro odr / full scale */
res += i2c_write_reg(dev->params.i2c, dev->params.addr, LSM6DSL_REG_CTRL2_G,
((dev->params.gyro_odr << LSM6DSL_CTRL_ODR_SHIFT) |
(dev->params.gyro_fs << LSM6DSL_CTRL_FS_SHIFT)));
tmp = (dev->params.gyro_odr << LSM6DSL_CTRL_ODR_SHIFT) |
(dev->params.gyro_fs << LSM6DSL_CTRL_FS_SHIFT);
res += i2c_write_reg(BUS, ADDR, LSM6DSL_REG_CTRL2_G, tmp);
/* Set continuous mode */
uint8_t fifo_odr = MAX(dev->params.acc_odr, dev->params.gyro_odr);
res += i2c_write_reg(dev->params.i2c, dev->params.addr, LSM6DSL_REG_FIFO_CTRL5,
(fifo_odr << LSM6DSL_FIFO_CTRL5_FIFO_ODR_SHIFT) |
LSM6DSL_FIFO_CTRL5_CONTINUOUS_MODE);
res += i2c_write_reg(dev->params.i2c, dev->params.addr, LSM6DSL_REG_FIFO_CTRL3,
(dev->params.gyro_decimation << LSM6DSL_FIFO_CTRL3_GYRO_DEC_SHIFT) |
dev->params.acc_decimation);
tmp = (fifo_odr << LSM6DSL_FIFO_CTRL5_FIFO_ODR_SHIFT) |
LSM6DSL_FIFO_CTRL5_CONTINUOUS_MODE;
res += i2c_write_reg(BUS, ADDR, LSM6DSL_REG_FIFO_CTRL5, tmp);
tmp = (dev->params.gyro_decimation << LSM6DSL_FIFO_CTRL3_GYRO_DEC_SHIFT) |
dev->params.acc_decimation;
res += i2c_write_reg(BUS, ADDR, LSM6DSL_REG_FIFO_CTRL3, tmp);
i2c_release(dev->params.i2c);
i2c_release(BUS);
if (res < 4) {
DEBUG("[!!failed!!] config\n");
return -1;
DEBUG("[ERROR] lsm6dsl_init: config\n");
return -LSM6DSL_ERROR_CNF;
}
return 0;
return LSM6DSL_OK;
}
int lsm6dsl_read_acc(const lsm6dsl_t *dev, lsm6dsl_3d_data_t *data)
@ -81,59 +105,35 @@ int lsm6dsl_read_acc(const lsm6dsl_t *dev, lsm6dsl_3d_data_t *data)
int res;
uint8_t tmp;
i2c_acquire(dev->params.i2c);
i2c_read_reg(dev->params.i2c, dev->params.addr, LSM6DSL_REG_STATUS_REG, &tmp);
i2c_acquire(BUS);
i2c_read_reg(BUS, ADDR, LSM6DSL_REG_STATUS_REG, &tmp);
DEBUG("lsm6dsl status: %x\n", tmp);
res = i2c_read_reg(dev->params.i2c, dev->params.addr,
LSM6DSL_REG_OUTX_L_XL, &tmp);
res = i2c_read_reg(BUS, ADDR, LSM6DSL_REG_OUTX_L_XL, &tmp);
data->x = tmp;
res += i2c_read_reg(dev->params.i2c, dev->params.addr,
LSM6DSL_REG_OUTX_H_XL, &tmp);
res += i2c_read_reg(BUS, ADDR, LSM6DSL_REG_OUTX_H_XL, &tmp);
data->x |= tmp << 8;
res += i2c_read_reg(dev->params.i2c, dev->params.addr,
LSM6DSL_REG_OUTY_L_XL, &tmp);
res += i2c_read_reg(BUS, ADDR, LSM6DSL_REG_OUTY_L_XL, &tmp);
data->y = tmp;
res += i2c_read_reg(dev->params.i2c, dev->params.addr,
LSM6DSL_REG_OUTY_H_XL, &tmp);
res += i2c_read_reg(BUS, ADDR, LSM6DSL_REG_OUTY_H_XL, &tmp);
data->y |= tmp << 8;
res += i2c_read_reg(dev->params.i2c, dev->params.addr,
LSM6DSL_REG_OUTZ_L_XL, &tmp);
res += i2c_read_reg(BUS, ADDR, LSM6DSL_REG_OUTZ_L_XL, &tmp);
data->z = tmp;
res += i2c_read_reg(dev->params.i2c, dev->params.addr,
LSM6DSL_REG_OUTZ_H_XL, &tmp);
res += i2c_read_reg(BUS, ADDR, LSM6DSL_REG_OUTZ_H_XL, &tmp);
data->z |= tmp << 8;
i2c_release(dev->params.i2c);
i2c_release(BUS);
if (res < 6) {
DEBUG("[!!failed!!]\n");
return -1;
}
DEBUG("[done]\n");
float range;
switch (dev->params.acc_fs) {
case LSM6DSL_ACC_FS_2G:
range = 2000.0;
break;
case LSM6DSL_ACC_FS_4G:
range = 4000.0;
break;
case LSM6DSL_ACC_FS_8G:
range = 8000.0;
break;
case LSM6DSL_ACC_FS_16G:
range = 16000.0;
break;
default:
return -1;
DEBUG("[ERROR] lsm6dsl_read_acc\n");
return -LSM6DSL_ERROR_BUS;
}
data->x = (data->x * range) / INT16_MAX;
data->y = (data->y * range) / INT16_MAX;
data->z = (data->z * range) / INT16_MAX;
assert(dev->params.acc_fs < LSM6DSL_ACC_FS_MAX);
data->x = ((int32_t)data->x * range_acc[dev->params.acc_fs]) / INT16_MAX;
data->y = ((int32_t)data->y * range_acc[dev->params.acc_fs]) / INT16_MAX;
data->z = ((int32_t)data->z * range_acc[dev->params.acc_fs]) / INT16_MAX;
return 0;
return LSM6DSL_OK;
}
int lsm6dsl_read_gyro(const lsm6dsl_t *dev, lsm6dsl_3d_data_t *data)
@ -141,59 +141,35 @@ int lsm6dsl_read_gyro(const lsm6dsl_t *dev, lsm6dsl_3d_data_t *data)
int res;
uint8_t tmp;
i2c_acquire(dev->params.i2c);
i2c_read_reg(dev->params.i2c, dev->params.addr, LSM6DSL_REG_STATUS_REG, &tmp);
i2c_acquire(BUS);
i2c_read_reg(BUS, ADDR, LSM6DSL_REG_STATUS_REG, &tmp);
DEBUG("lsm6dsl status: %x\n", tmp);
res = i2c_read_reg(dev->params.i2c, dev->params.addr,
LSM6DSL_REG_OUTX_L_G, &tmp);
res = i2c_read_reg(BUS, ADDR, LSM6DSL_REG_OUTX_L_G, &tmp);
data->x = tmp;
res += i2c_read_reg(dev->params.i2c, dev->params.addr,
LSM6DSL_REG_OUTX_H_G, &tmp);
res += i2c_read_reg(BUS, ADDR, LSM6DSL_REG_OUTX_H_G, &tmp);
data->x |= tmp << 8;
res += i2c_read_reg(dev->params.i2c, dev->params.addr,
LSM6DSL_REG_OUTY_L_G, &tmp);
res += i2c_read_reg(BUS, ADDR, LSM6DSL_REG_OUTY_L_G, &tmp);
data->y = tmp;
res += i2c_read_reg(dev->params.i2c, dev->params.addr,
LSM6DSL_REG_OUTY_H_G, &tmp);
res += i2c_read_reg(BUS, ADDR, LSM6DSL_REG_OUTY_H_G, &tmp);
data->y |= tmp << 8;
res += i2c_read_reg(dev->params.i2c, dev->params.addr,
LSM6DSL_REG_OUTZ_L_G, &tmp);
res += i2c_read_reg(BUS, ADDR, LSM6DSL_REG_OUTZ_L_G, &tmp);
data->z = tmp;
res += i2c_read_reg(dev->params.i2c, dev->params.addr,
LSM6DSL_REG_OUTZ_H_G, &tmp);
res += i2c_read_reg(BUS, ADDR, LSM6DSL_REG_OUTZ_H_G, &tmp);
data->z |= tmp << 8;
i2c_release(dev->params.i2c);
i2c_release(BUS);
if (res < 6) {
DEBUG("[!!failed!!]\n");
return -1;
}
DEBUG("[done]\n");
float range;
switch (dev->params.acc_fs) {
case LSM6DSL_GYRO_FS_245DPS:
range = 2450.0;
break;
case LSM6DSL_GYRO_FS_500DPS:
range = 5000.0;
break;
case LSM6DSL_GYRO_FS_1000DPS:
range = 10000.0;
break;
case LSM6DSL_GYRO_FS_2000DPS:
range = 20000.0;
break;
default:
return -1;
DEBUG("[ERROR] lsm6dsl_read_gyro\n");
return -LSM6DSL_ERROR_BUS;
}
data->x = (data->x * range) / INT16_MAX;
data->y = (data->y * range) / INT16_MAX;
data->z = (data->z * range) / INT16_MAX;
assert(dev->params.gyro_fs < LSM6DSL_GYRO_FS_MAX);
data->x = ((int32_t)data->x * range_gyro[dev->params.gyro_fs]) / INT16_MAX;
data->y = ((int32_t)data->y * range_gyro[dev->params.gyro_fs]) / INT16_MAX;
data->z = ((int32_t)data->z * range_gyro[dev->params.gyro_fs]) / INT16_MAX;
return 0;
return LSM6DSL_OK;
}
int lsm6dsl_read_temp(const lsm6dsl_t *dev, int16_t *data)
@ -201,21 +177,21 @@ int lsm6dsl_read_temp(const lsm6dsl_t *dev, int16_t *data)
uint8_t tmp;
uint16_t traw;
/* read raw temperature */
i2c_acquire(dev->params.i2c);
if (i2c_read_reg(dev->params.i2c, dev->params.addr, LSM6DSL_REG_OUT_TEMP_L, &tmp) != 1) {
i2c_release(dev->params.i2c);
return -1;
i2c_acquire(BUS);
if (i2c_read_reg(BUS, ADDR, LSM6DSL_REG_OUT_TEMP_L, &tmp) != 1) {
i2c_release(BUS);
return -LSM6DSL_ERROR_BUS;
}
traw = tmp;
if (i2c_read_reg(dev->params.i2c, dev->params.addr, LSM6DSL_REG_OUT_TEMP_H, &tmp) != 1) {
i2c_release(dev->params.i2c);
return -1;
if (i2c_read_reg(BUS, ADDR, LSM6DSL_REG_OUT_TEMP_H, &tmp) != 1) {
i2c_release(BUS);
return -LSM6DSL_ERROR_BUS;
}
traw |= (uint16_t)tmp << 8;
i2c_release(dev->params.i2c);
/* convert temperature */
i2c_release(BUS);
/* convert temperature to degC x 100 */
traw += LSM6DSL_TEMP_OFFSET;
*data = (int16_t)(((int32_t)traw * 100) / 256);
return 0;
return LSM6DSL_OK;
}

View File

@ -8,10 +8,16 @@
*/
/**
* @ingroup drivers_lsm6dsl
* @{
*
* @file
* @brief SAUL implementation for the LSM6DSL 3D accelerometer/gyroscope.
*
* @author Vincent Dupont <vincent@otakeys.com>
* @author Sebastian Meiling <s@mlng.net>
*
* @}
*/
#include "lsm6dsl.h"