diff --git a/drivers/Makefile.dep b/drivers/Makefile.dep index 3065cab2ed..053d54a3c7 100644 --- a/drivers/Makefile.dep +++ b/drivers/Makefile.dep @@ -301,3 +301,8 @@ ifneq (,$(filter xbee,$(USEMODULE))) USEMODULE += xtimer USEMODULE += netif endif + +ifneq (,$(filter lis3mdl,$(USEMODULE))) + FEATURES_REQUIRED += periph_i2c + USEMODULE += xtimer +endif diff --git a/drivers/Makefile.include b/drivers/Makefile.include index ff5dac66bf..7f6c3571bd 100644 --- a/drivers/Makefile.include +++ b/drivers/Makefile.include @@ -151,3 +151,6 @@ endif ifneq (,$(filter hts221,$(USEMODULE))) USEMODULE_INCLUDES += $(RIOTBASE)/drivers/hts221/include endif +ifneq (,$(filter lis3mdl,$(USEMODULE))) + USEMODULE_INCLUDES += $(RIOTBASE)/drivers/lis3mdl/include +endif diff --git a/drivers/include/lis3mdl.h b/drivers/include/lis3mdl.h index 4e8370a823..0630124f0a 100644 --- a/drivers/include/lis3mdl.h +++ b/drivers/include/lis3mdl.h @@ -38,14 +38,6 @@ typedef struct { int16_t z_axis; /**< Magnometer data from z_axis */ } lis3mdl_3d_data_t; -/** - * @brief Device descriptor for LIS3MDL sensor - */ -typedef struct { - i2c_t i2c; /**< I2C device */ - uint8_t addr; /**< Magnometer I2C address */ -} lis3mdl_t; - /** * @brief Operating mode of x- and y-axis for LIS3MDL */ @@ -98,25 +90,37 @@ typedef enum { LIS3MDL_OP_PDOWN = 0x11, /**< Power-down mode */ } lis3mdl_op_t; +/** + * @brief Device initialization parameters + */ +typedef struct { + i2c_t i2c; /**< I2C device */ + uint8_t addr; /**< Magnometer I2C address */ + lis3mdl_xy_mode_t xy_mode; /**< Power mode of x- and y-axis */ + lis3mdl_z_mode_t z_mode; /**< Power mode of z-axis */ + lis3mdl_odr_t odr; /**< Output data rate */ + lis3mdl_scale_t scale; /**< Scale factor */ + lis3mdl_op_t op_mode; /**< Operation mode */ +} lis3mdl_params_t; + + +/** + * @brief Device descriptor for LIS3MDL sensor + */ +typedef struct { + lis3mdl_params_t params; /**< Initialization parameters */ +} lis3mdl_t; + /** * @brief Initialize a new LIS3DML device. * * @param[in] dev device descriptor of LIS3MDL - * @param[in] i2c I2C device connected to - * @param[in] address I2C address of the magnometer - * @param[in] xy_mode power mode of x- and y-axis - * @param[in] z_mode power mode of z-axis - * @param[in] odr output data rate of magnometer - * @param[in] scale scale configuration of magnometer - * @param[in] op_mode operation mode of the device + * @param[in] params initialization parameters * * @return 0 on success * @return -1 on error */ -int lis3mdl_init(lis3mdl_t *dev, i2c_t i2c, uint8_t address, - lis3mdl_xy_mode_t xy_mode, lis3mdl_z_mode_t z_mode, - lis3mdl_odr_t odr, lis3mdl_scale_t scale, - lis3mdl_op_t op_mode); +int lis3mdl_init(lis3mdl_t *dev, const lis3mdl_params_t *params); /** * @brief Reads the magnometer value of LIS3MDL. diff --git a/drivers/lis3mdl/include/lis3mdl_params.h b/drivers/lis3mdl/include/lis3mdl_params.h new file mode 100644 index 0000000000..1ad49976cd --- /dev/null +++ b/drivers/lis3mdl/include/lis3mdl_params.h @@ -0,0 +1,91 @@ +/* + * Copyright (C) 2017 Inria + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @ingroup drivers_lis3mdl + * + * @{ + * @file + * @brief Default configuration for LIS3MDL devices + * + * @author Alexandre Abadie + */ + +#ifndef LIS3MDL_PARAMS_H +#define LIS3MDL_PARAMS_H + +#include "board.h" +#include "lis3mdl.h" +#include "saul_reg.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @name Set default configuration parameters + * @{ + */ +#ifndef LIS3MDL_PARAM_I2C +#define LIS3MDL_PARAM_I2C (I2C_DEV(0)) +#endif +#ifndef LIS3MDL_PARAM_ADDR +#define LIS3MDL_PARAM_ADDR (0x1E) +#endif +#ifndef LIS3MDL_PARAM_XYMODE +#define LIS3MDL_PARAM_XYMODE (LIS3MDL_XY_MODE_HIGH) +#endif +#ifndef LIS3MDL_PARAM_ZMODE +#define LIS3MDL_PARAM_ZMODE (LIS3MDL_Z_MODE_HIGH) +#endif +#ifndef LIS3MDL_PARAM_ODR +#define LIS3MDL_PARAM_ODR (LIS3MDL_ODR_10Hz) +#endif +#ifndef LIS3MDL_PARAM_SCALE +#define LIS3MDL_PARAM_SCALE (4) +#endif +#ifndef LIS3MDL_PARAM_OPMODE +#define LIS3MDL_PARAM_OPMODE (LIS3MDL_OP_CONT_CONV) +#endif + +#ifndef LIS3MDL_PARAMS +#define LIS3MDL_PARAMS { .i2c = LIS3MDL_PARAM_I2C, \ + .addr = LIS3MDL_PARAM_ADDR, \ + .xy_mode = LIS3MDL_PARAM_XYMODE, \ + .z_mode = LIS3MDL_PARAM_ZMODE, \ + .odr = LIS3MDL_PARAM_SCALE, \ + .scale = LIS3MDL_PARAM_ODR, \ + .op_mode = LIS3MDL_PARAM_OPMODE } +#endif +#ifndef LIS3MDL_SAUL_INFO +#define LIS3MDL_SAUL_INFO { .name = "lis3mdl" } +#endif +/**@}*/ + +/** + * @brief Allocate some memory to store the actual configuration + */ +static const lis3mdl_params_t lis3mdl_params[] = +{ + LIS3MDL_PARAMS +}; + +/** + * @brief Additional meta information to keep in the SAUL registry + */ +static const saul_reg_info_t lis3mdl_saul_info[] = +{ + LIS3MDL_SAUL_INFO +}; + +#ifdef __cplusplus +} +#endif + +#endif /* LIS3MDL_PARAMS_H */ +/** @} */ diff --git a/drivers/lis3mdl/lis3mdl.c b/drivers/lis3mdl/lis3mdl.c index 665bfa7222..e9612907ed 100644 --- a/drivers/lis3mdl/lis3mdl.c +++ b/drivers/lis3mdl/lis3mdl.c @@ -32,6 +32,9 @@ #define GAUSS_DIVIDER (1000) +#define DEV_I2C (dev->params.i2c) +#define DEV_ADDR (dev->params.addr) + /** * @brief Takes an unsigned value representing a two's complement number * and returns the signed number it represents @@ -51,47 +54,41 @@ } } -int lis3mdl_init(lis3mdl_t *dev, - i2c_t i2c, - uint8_t address, - lis3mdl_xy_mode_t xy_mode, - lis3mdl_z_mode_t z_mode, - lis3mdl_odr_t odr, - lis3mdl_scale_t scale, - lis3mdl_op_t op_mode) { +int lis3mdl_init(lis3mdl_t *dev, const lis3mdl_params_t *params) +{ + dev->params = *params; + uint8_t tmp; - dev->i2c = i2c; - dev->addr = address; + i2c_acquire(DEV_I2C); - i2c_acquire(dev->i2c); - - if (i2c_init_master(i2c, I2C_SPEED_NORMAL) < 0) { + if (i2c_init_master(DEV_I2C, I2C_SPEED_NORMAL) < 0) { DEBUG("LIS3MDL: Master initialization failed\n"); return -1; } - i2c_read_reg(dev->i2c, dev->addr, LIS3DML_WHO_AM_I_REG, &tmp); + i2c_read_reg(DEV_I2C, DEV_ADDR, LIS3DML_WHO_AM_I_REG, &tmp); if (tmp != LIS3MDL_CHIP_ID) { - DEBUG("LIS3MDL: Identification failed\n"); + DEBUG("LIS3MDL: Identification failed, %02X != %02X\n", + tmp, LIS3MDL_CHIP_ID); return -1; } tmp = ( LIS3MDL_MASK_REG1_TEMP_EN /* enable temperature sensor */ - | xy_mode /* set x-, y-axis operative mode */ - | odr); /* set output data rate */ - i2c_write_reg(dev->i2c, dev->addr, LIS3MDL_CTRL_REG1, tmp); + | dev->params.xy_mode /* set x-, y-axis operative mode */ + | dev->params.odr); /* set output data rate */ + i2c_write_reg(DEV_I2C, DEV_ADDR, LIS3MDL_CTRL_REG1, tmp); /* set Full-scale configuration */ - i2c_write_reg(dev->i2c, dev->addr, LIS3MDL_CTRL_REG2, scale); + i2c_write_reg(DEV_I2C, DEV_ADDR, LIS3MDL_CTRL_REG2, dev->params.scale); /* set continuous-conversion mode */ - i2c_write_reg(dev->i2c, dev->addr, LIS3MDL_CTRL_REG3, op_mode); + i2c_write_reg(DEV_I2C, DEV_ADDR, LIS3MDL_CTRL_REG3, dev->params.op_mode); /* set z-axis operative mode */ - i2c_write_reg(dev->i2c, dev->addr, LIS3MDL_CTRL_REG4, z_mode); + i2c_write_reg(DEV_I2C, DEV_ADDR, LIS3MDL_CTRL_REG4, dev->params.z_mode); - i2c_release(dev->i2c); + i2c_release(DEV_I2C); return 0; } @@ -100,15 +97,15 @@ void lis3mdl_read_mag(const lis3mdl_t *dev, lis3mdl_3d_data_t *data) { uint8_t tmp[2] = {0, 0}; - i2c_acquire(dev->i2c); + i2c_acquire(DEV_I2C); - i2c_read_regs(dev->i2c, dev->addr, LIS3MDL_OUT_X_L_REG, &tmp[0], 2); + i2c_read_regs(DEV_I2C, DEV_ADDR, LIS3MDL_OUT_X_L_REG, &tmp[0], 2); data->x_axis = (tmp[1] << 8) | tmp[0]; - i2c_read_regs(dev->i2c, dev->addr, LIS3MDL_OUT_Y_L_REG, &tmp[0], 2); + i2c_read_regs(DEV_I2C, DEV_ADDR, LIS3MDL_OUT_Y_L_REG, &tmp[0], 2); data->y_axis = (tmp[1] << 8) | tmp[0]; - i2c_read_regs(dev->i2c, dev->addr, LIS3MDL_OUT_Z_L_REG, &tmp[0], 2); + i2c_read_regs(DEV_I2C, DEV_ADDR, LIS3MDL_OUT_Z_L_REG, &tmp[0], 2); data->z_axis = (tmp[1] << 8) | tmp[0]; data->x_axis = _twos_complement(data->x_axis); @@ -120,14 +117,14 @@ void lis3mdl_read_mag(const lis3mdl_t *dev, lis3mdl_3d_data_t *data) data->y_axis /= GAUSS_DIVIDER; data->z_axis /= GAUSS_DIVIDER; - i2c_release(dev->i2c); + i2c_release(DEV_I2C); } void lis3mdl_read_temp(const lis3mdl_t *dev, int16_t *value) { - i2c_acquire(dev->i2c); - i2c_read_regs(dev->i2c, dev->addr, LIS3MDL_TEMP_OUT_L_REG, (uint8_t*)value, 2); - i2c_release(dev->i2c); + i2c_acquire(DEV_I2C); + i2c_read_regs(DEV_I2C, DEV_ADDR, LIS3MDL_TEMP_OUT_L_REG, (uint8_t*)value, 2); + i2c_release(DEV_I2C); *value = _twos_complement(*value); @@ -136,11 +133,11 @@ void lis3mdl_read_temp(const lis3mdl_t *dev, int16_t *value) void lis3mdl_enable(const lis3mdl_t *dev) { - i2c_acquire(dev->i2c); + i2c_acquire(DEV_I2C); /* Z-axis medium-power mode */ - i2c_write_reg(dev->i2c, dev->addr, + i2c_write_reg(DEV_I2C, DEV_ADDR, LIS3MDL_CTRL_REG3, LIS3MDL_MASK_REG3_Z_MEDIUM_POWER); - i2c_release(dev->i2c); + i2c_release(DEV_I2C); } void lis3mdl_disable(const lis3mdl_t *dev) @@ -148,7 +145,7 @@ void lis3mdl_disable(const lis3mdl_t *dev) uint8_t tmp = ( LIS3MDL_MASK_REG3_LOW_POWER_EN /**< enable power-down mode */ | LIS3MDL_MASK_REG3_Z_LOW_POWER); /**< Z-axis low-power mode */ - i2c_acquire(dev->i2c); - i2c_write_reg(dev->i2c, dev->addr, LIS3MDL_CTRL_REG3, tmp); - i2c_release(dev->i2c); + i2c_acquire(DEV_I2C); + i2c_write_reg(DEV_I2C, DEV_ADDR, LIS3MDL_CTRL_REG3, tmp); + i2c_release(DEV_I2C); }