diff --git a/drivers/include/lis3dh.h b/drivers/include/lis3dh.h index 3fcccbe1f..4e8377f81 100644 --- a/drivers/include/lis3dh.h +++ b/drivers/include/lis3dh.h @@ -387,16 +387,14 @@ typedef enum { /** @} */ /** - * @name Scale parameters - * - * Use these names when calling lis3dh_set_scale() + * @name Scale register values symbolic names */ /** @{ */ -#define LIS3DH_SCALE_2G (0) /**< Scale: +/- 2G */ -#define LIS3DH_SCALE_4G (LIS3DH_CTRL_REG4_FS0_MASK) /**< Scale: +/- 4G */ -#define LIS3DH_SCALE_8G (LIS3DH_CTRL_REG4_FS1_MASK) /**< Scale: +/- 8G */ +#define LIS3DH_CTRL_REG4_SCALE_2G (0) /**< Scale: +/- 2G */ +#define LIS3DH_CTRL_REG4_SCALE_4G (LIS3DH_CTRL_REG4_FS0_MASK) /**< Scale: +/- 4G */ +#define LIS3DH_CTRL_REG4_SCALE_8G (LIS3DH_CTRL_REG4_FS1_MASK) /**< Scale: +/- 8G */ /** Scale: +/- 16G */ -#define LIS3DH_SCALE_16G (LIS3DH_CTRL_REG4_FS1_MASK | LIS3DH_CTRL_REG4_FS0_MASK) +#define LIS3DH_CTRL_REG4_SCALE_16G (LIS3DH_CTRL_REG4_FS1_MASK | LIS3DH_CTRL_REG4_FS0_MASK) /** @} */ /** @@ -686,6 +684,13 @@ typedef struct { gpio_t cs; /**< Chip select pin */ gpio_t int1; /**< INT1 pin */ gpio_t int2; /**< INT2 (DRDY) pin */ + uint8_t scale; /**< Default sensor scale: 2, 4, 8, or 16 (G) */ + uint8_t odr; /**< Default sensor ODR setting: LIS3DH_ODR_xxxHz */ +} lis3dh_params_t; + +typedef struct { + spi_t spi; /**< SPI device the sensor is connected to */ + gpio_t cs; /**< Chip select pin */ int16_t scale; /**< Current scale setting of the sensor */ } lis3dh_t; @@ -697,8 +702,7 @@ typedef struct __attribute__((packed)) int16_t acc_x; /**< Acceleration in the X direction in milli-G */ int16_t acc_y; /**< Acceleration in the Y direction in milli-G */ int16_t acc_z; /**< Acceleration in the Z direction in milli-G */ -} -lis3dh_data_t; +} lis3dh_data_t; /** @@ -707,14 +711,12 @@ lis3dh_data_t; * @param[in] dev Device descriptor of sensor to initialize * @param[in] spi SPI bus the accelerometer is connected to * @param[in] cs_pin GPIO connected to the chip select pin of the accelerometer - * @param[in] int1_pin GPIO connected to the INT1 pin of the accelerometer - * @param[in] int2_pin GPIO connected to the INT2 pin of the accelerometer * @param[in] scale Initial scale setting of the sensor * * @return 0 on success * @return -1 on error */ -int lis3dh_init(lis3dh_t *dev, spi_t spi, gpio_t cs_pin, gpio_t int1_pin, gpio_t int2_pin, uint8_t scale); +int lis3dh_init(lis3dh_t *dev, spi_t spi, gpio_t cs_pin, uint8_t scale); /** * @brief Read 3D acceleration data from the accelerometer @@ -819,7 +821,7 @@ int lis3dh_set_odr(lis3dh_t *dev, const uint8_t odr); /** * @brief Set the full scale range of the sensor. * - * Valid values for scale is 2, 4, 8, 16 and represents the full range of the + * Valid values for scale are 2, 4, 8, 16 and represents the full range of the * sensor. * * @param[in] dev Device descriptor of sensor diff --git a/drivers/lis3dh/lis3dh.c b/drivers/lis3dh/lis3dh.c index 3c669b7e7..674d5218e 100644 --- a/drivers/lis3dh/lis3dh.c +++ b/drivers/lis3dh/lis3dh.c @@ -30,14 +30,12 @@ static int lis3dh_read_regs(const lis3dh_t *dev, const lis3dh_reg_t reg, const u uint8_t *buf); -int lis3dh_init(lis3dh_t *dev, spi_t spi, gpio_t cs_pin, gpio_t int1_pin, gpio_t int2_pin, uint8_t scale) +int lis3dh_init(lis3dh_t *dev, spi_t spi, gpio_t cs_pin, uint8_t scale) { uint8_t in; dev->spi = spi; dev->cs = cs_pin; - dev->int1 = int1_pin; - dev->int2 = int2_pin; dev->scale = 0; /* CS */ @@ -73,10 +71,6 @@ int lis3dh_init(lis3dh_t *dev, spi_t spi, gpio_t cs_pin, gpio_t int1_pin, gpio_t /* Configure scale */ lis3dh_set_scale(dev, scale); - /* Initialize the interrupt pins */ - gpio_init(dev->int1, GPIO_DIR_IN, GPIO_NOPULL); - gpio_init(dev->int2, GPIO_DIR_IN, GPIO_NOPULL); - return 0; } @@ -172,27 +166,32 @@ int lis3dh_set_odr(lis3dh_t *dev, const uint8_t odr) int lis3dh_set_scale(lis3dh_t *dev, const uint8_t scale) { + uint8_t scale_reg; /* Sensor full range is -32768 -- +32767 (measurements are left adjusted) */ /* => Scale factor is scale/32768 */ switch (scale) { - case LIS3DH_SCALE_2G: + case 2: dev->scale = 2000; + scale_reg = LIS3DH_CTRL_REG4_SCALE_2G; break; - case LIS3DH_SCALE_4G: + case 4: dev->scale = 4000; + scale_reg = LIS3DH_CTRL_REG4_SCALE_4G; break; - case LIS3DH_SCALE_8G: + case 8: dev->scale = 8000; + scale_reg = LIS3DH_CTRL_REG4_SCALE_8G; break; - case LIS3DH_SCALE_16G: + case 16: dev->scale = 16000; + scale_reg = LIS3DH_CTRL_REG4_SCALE_16G; break; default: return -1; } return lis3dh_write_bits(dev, LIS3DH_REG_CTRL_REG4, LIS3DH_CTRL_REG4_FS_MASK, - scale); + scale_reg); } int lis3dh_set_int1(lis3dh_t *dev, const uint8_t mode) diff --git a/drivers/lis3dh/lis3dh_saul.c b/drivers/lis3dh/lis3dh_saul.c new file mode 100644 index 000000000..8c238a5b6 --- /dev/null +++ b/drivers/lis3dh/lis3dh_saul.c @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2016 Eistec AB + * + * 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 driver_lis3dh + * @{ + * + * @file + * @brief LIS3DH adaption to the RIOT actuator/sensor interface + * + * @author Joakim Nohlgård + * + * @} + */ + +#include +#include + +#include "saul.h" +#include "lis3dh.h" + +static int read_acc(void *dev, phydat_t *res) +{ + lis3dh_data_t xyz; + + lis3dh_t *d = (lis3dh_t *)dev; + int err = lis3dh_read_xyz(d, &xyz); + if (err != 0) { + /* Something went wrong in the LIS3DH driver */ + return -ECANCELED; + } + + res->val[0] = xyz.acc_x; + res->val[1] = xyz.acc_y; + res->val[2] = xyz.acc_z; + /* unit: milli-G */ + res->scale = -3; + res->unit = UNIT_G; + + return 3; +} + +static int write(void *dev, phydat_t *state) +{ + (void) dev; + (void) state; + return -ENOTSUP; +} + +const saul_driver_t lis3dh_saul_driver = { + .read = read_acc, + .write = write, + .type = SAUL_SENSE_ACCEL, +}; diff --git a/sys/auto_init/auto_init.c b/sys/auto_init/auto_init.c index dfbd16888..0b4d2ef04 100644 --- a/sys/auto_init/auto_init.c +++ b/sys/auto_init/auto_init.c @@ -218,6 +218,10 @@ void auto_init(void) extern void auto_init_l3g4200d(void); auto_init_l3g4200d(); #endif +#ifdef MODULE_LIS3DH + extern void auto_init_lis3dh(void); + auto_init_lis3dh(); +#endif #endif /* MODULE_AUTO_INIT_SAUL */ } diff --git a/sys/auto_init/saul/auto_init_lis3dh.c b/sys/auto_init/saul/auto_init_lis3dh.c new file mode 100644 index 000000000..12f5a018c --- /dev/null +++ b/sys/auto_init/saul/auto_init_lis3dh.c @@ -0,0 +1,79 @@ +/* + * Copyright (C) 2016 Eistec AB + * + * 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 auto_init_saul + * @{ + * + * @file + * @brief Auto initialization of LIS3DH accelerometers + * + * @author Joakim Nohlgård + * + * @} + */ + +#ifdef MODULE_LIS3DH + +#include "saul_reg.h" +#include "lis3dh.h" +#include "lis3dh_params.h" + +#define ENABLE_DEBUG (0) +#include "debug.h" + +/** + * @brief Define the number of configured sensors + */ +#define LIS3DH_NUM (sizeof(lis3dh_params)/sizeof(lis3dh_params[0])) + +/** + * @brief Allocate memory for the device descriptors + */ +static lis3dh_t lis3dh_devs[LIS3DH_NUM]; + +/** + * @brief Memory for the SAUL registry entries + */ +static saul_reg_t saul_entries[LIS3DH_NUM]; + +/** + * @brief Reference the driver struct + */ +extern saul_driver_t lis3dh_saul_driver; + + +void auto_init_lis3dh(void) +{ + for (int i = 0; i < LIS3DH_NUM; i++) { + const lis3dh_params_t *p = &lis3dh_params[i]; + int res; + + DEBUG("[auto_init_saul] initializing lis3dh accelerometer\n"); + res = lis3dh_init(&lis3dh_devs[i], p->spi, p->cs, p->scale); + if (res < 0) { + DEBUG("[auto_init_saul] error during lis3dh_init\n"); + continue; + } + res = lis3dh_set_odr(&lis3dh_devs[i], p->odr); + if (res < 0) { + DEBUG("[auto_init_saul] error during lis3dh_set_odr\n"); + continue; + } + + saul_entries[i].dev = &(lis3dh_devs[i]); + saul_entries[i].name = lis3dh_saul_info[i].name; + saul_entries[i].driver = &lis3dh_saul_driver; + saul_reg_add(&(saul_entries[i])); + } +} + +#else +typedef int dont_be_pedantic; +#endif /* MODULE_LIS3DH */ diff --git a/tests/driver_lis3dh/main.c b/tests/driver_lis3dh/main.c index 1dfa996d0..3c7ec592e 100644 --- a/tests/driver_lis3dh/main.c +++ b/tests/driver_lis3dh/main.c @@ -57,7 +57,7 @@ #endif -#define SCALE LIS3DH_SCALE_4G +#define SCALE 4 #define ODR LIS3DH_ODR_100Hz #define SLEEP (100 * 1000U) #define SPI_CONF (SPI_CONF_SECOND_FALLING) @@ -89,8 +89,7 @@ int main(void) } puts("Initializing LIS3DH sensor... "); - if (lis3dh_init(&dev, TEST_LIS3DH_SPI, TEST_LIS3DH_CS, - TEST_LIS3DH_INT1, TEST_LIS3DH_INT2, SCALE) == 0) { + if (lis3dh_init(&dev, TEST_LIS3DH_SPI, TEST_LIS3DH_CS, SCALE) == 0) { puts("[OK]"); } else { @@ -153,7 +152,7 @@ int main(void) } puts("Set INT1 callback"); - if (gpio_init_int(dev.int1, GPIO_NOPULL, GPIO_RISING, test_int1, (void*)&int1_count) == 0) { + if (gpio_init_int(TEST_LIS3DH_INT1, GPIO_NOPULL, GPIO_RISING, test_int1, (void*)&int1_count) == 0) { puts("[OK]"); } else { @@ -181,7 +180,7 @@ int main(void) puts("[Failed]\n"); return 1; } - int1 = gpio_read(dev.int1); + int1 = gpio_read(TEST_LIS3DH_INT1); printf("X: %6d Y: %6d Z: %6d Temp: %6d, INT1: %08x\n", acc_data.acc_x, acc_data.acc_y, acc_data.acc_z, temperature, int1); --fifo_level;