diff --git a/drivers/Makefile.dep b/drivers/Makefile.dep index 45ab703c8484f361d50c9755301bf56dac986108..71783893fa9063bc0657f99505b79169c85c3930 100644 --- a/drivers/Makefile.dep +++ b/drivers/Makefile.dep @@ -1,5 +1,9 @@ # driver dependencies (in alphabetical order) +ifneq (,$(filter adxl345,$(USEMODULE))) + FEATURES_REQUIRED += periph_i2c +endif + ifneq (,$(filter at30tse75x,$(USEMODULE))) USEMODULE += xtimer FEATURES_REQUIRED += periph_i2c diff --git a/drivers/Makefile.include b/drivers/Makefile.include index 07eaa78bd89727bbe8229407cd1b04823592067d..971e91089bf734a37af926f7387e4b35dc8f03c3 100644 --- a/drivers/Makefile.include +++ b/drivers/Makefile.include @@ -103,3 +103,6 @@ endif ifneq (,$(filter veml6070,$(USEMODULE))) USEMODULE_INCLUDES += $(RIOTBASE)/drivers/veml6070/include endif +ifneq (,$(filter adxl345,$(USEMODULE))) + USEMODULE_INCLUDES += $(RIOTBASE)/drivers/adxl345/include +endif diff --git a/drivers/adxl345/Makefile b/drivers/adxl345/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..48422e909a47d7cd428d10fa73825060ccc8d8c2 --- /dev/null +++ b/drivers/adxl345/Makefile @@ -0,0 +1 @@ +include $(RIOTBASE)/Makefile.base diff --git a/drivers/adxl345/adxl345.c b/drivers/adxl345/adxl345.c new file mode 100644 index 0000000000000000000000000000000000000000..dfad7bbc9e1b46a9b094c8fe375c5c70110215ad --- /dev/null +++ b/drivers/adxl345/adxl345.c @@ -0,0 +1,224 @@ +/* + * Copyright (C) 2017 Mesotic SAS + * + * 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_adxl345 + * @{ + * + * @file + * @brief Device driver implementation for the ADXL345 accelerometer (i2c only) + * + * @author Dylan Laduranty <dylan.laduranty@mesotic.com> + * + * @} + */ +#include <stdint.h> +#include <stdbool.h> +#include <string.h> + +#include "assert.h" +#include "periph/i2c.h" +#include "adxl345.h" +#include "adxl345_regs.h" + +#define ENABLE_DEBUG (0) +#include "debug.h" + +#define I2C_SPEED I2C_SPEED_NORMAL + +#define BUS (dev->params.i2c) +#define ADDR (dev->params.addr) + +int adxl345_init(adxl345_t *dev, const adxl345_params_t* params) +{ + uint8_t reg; + + assert(dev && params); + + /* get device descriptor */ + dev->params= *params; + + /* Acquire exclusive access */ + i2c_acquire(BUS); + + /* Initialize I2C interface */ + if (i2c_init_master(BUS, I2C_SPEED) < 0) { + i2c_release(BUS); + DEBUG("[adxl345] init - error: unable to initialize I2C bus\n"); + return ADXL345_NOI2C; + } + + /* test if the target device responds */ + i2c_read_reg(BUS, ADDR, ACCEL_ADXL345_CHIP_ID_REG, ®); + if (reg != ACCEL_ADXL345_CHIP_ID) { + i2c_release(BUS); + DEBUG("[adxl345] init - error: invalid id value [0x%02x]\n", (int)reg); + return ADXL345_NODEV; + } + /* configure the user offset */ + i2c_write_regs(BUS, ADDR, ACCEL_ADXL345_OFFSET_X, dev->params.offset, 3); + /* Basic device setup */ + reg = (dev->params.full_res | dev->params.range); + i2c_write_reg(BUS, ADDR, ACCEL_ADXL345_DATA_FORMAT, reg); + i2c_write_reg(BUS, ADDR, ACCEL_ADXL345_BW_RATE, dev->params.rate); + /* Put device in measure mode */ + i2c_write_reg(BUS, ADDR, ACCEL_ADXL345_POWER_CTL, MEASURE_BIT); + + /* Release the bus */ + i2c_release(BUS); + + DEBUG("[adxl345] init: successful\n"); + + return ADXL345_OK; +} + +void adxl345_read(adxl345_t *dev, adxl345_data_t *data) +{ + uint8_t result[6]; + + assert(dev && data); + + i2c_acquire(BUS); + i2c_read_regs(BUS, ADDR, ACCEL_ADXL345_DATA_X0, result, 6); + i2c_release(BUS); + + data->x = (((result[1] << 8)+result[0]) * dev->params.scale_factor); + data->y = (((result[3] << 8)+result[2]) * dev->params.scale_factor); + data->z = (((result[5] << 8)+result[4]) * dev->params.scale_factor); +} + +void adxl345_set_interrupt(adxl345_t *dev) +{ + assert(dev); + + DEBUG("[adxl345] Update interruptions configuration\n"); + + i2c_acquire(BUS); + /* Set threshold */ + i2c_write_reg(BUS, ADDR, ACCEL_ADXL345_THRESH_TAP, dev->params.interrupt.thres_tap); + /* Set Map */ + i2c_write_reg(BUS, ADDR, ACCEL_ADXL345_INT_MAP, dev->params.interrupt.map); + /* Set Duration */ + i2c_write_reg(BUS, ADDR, ACCEL_ADXL345_TAP_DUR, dev->params.interrupt.thres_dur); + /* Enable axes */ + i2c_write_reg(BUS, ADDR, ACCEL_ADXL345_TAP_AXES, dev->params.interrupt.tap_axes); + /* Set source */ + i2c_write_reg(BUS, ADDR, ACCEL_ADXL345_INT_SOURCE, dev->params.interrupt.source); + /* Set latent threshold */ + i2c_write_reg(BUS, ADDR, ACCEL_ADXL345_TAP_LAT, dev->params.interrupt.thres_latent); + /* Set window threshold */ + i2c_write_reg(BUS, ADDR, ACCEL_ADXL345_TAP_WIN, dev->params.interrupt.thres_window); + /* Set activity threshold */ + i2c_write_reg(BUS, ADDR, ACCEL_ADXL345_THRESH_ACT, dev->params.interrupt.thres_act); + /* Set inactivity threshold */ + i2c_write_reg(BUS, ADDR, ACCEL_ADXL345_THRESH_INACT, dev->params.interrupt.thres_inact); + /* Set inactivity time */ + i2c_write_reg(BUS, ADDR, ACCEL_ADXL345_TIME_INACT, dev->params.interrupt.time_inact); + /* Set free-fall threshold */ + i2c_write_reg(BUS, ADDR, ACCEL_ADXL345_THRESH_FF, dev->params.interrupt.thres_ff); + /* Set free-fall time */ + i2c_write_reg(BUS, ADDR, ACCEL_ADXL345_TIME_FF, dev->params.interrupt.time_ff); + /* Set axis control */ + i2c_write_reg(BUS, ADDR, ACCEL_ADXL345_ACT_INACT_CTL, dev->params.interrupt.act_inact); + /* Enable interrupt */ + i2c_write_reg(BUS, ADDR, ACCEL_ADXL345_INT_ENABLE, dev->params.interrupt.enable); + + /* Release the bus */ + i2c_release(BUS); +} + +void adxl345_set_measure(adxl345_t *dev) +{ + uint8_t reg; + + assert(dev); + + DEBUG("[adxl345] set device to measure mode\n"); + + i2c_acquire(BUS); + i2c_read_reg(BUS, ADDR, ACCEL_ADXL345_POWER_CTL, ®); + reg |= MEASURE_BIT; + i2c_write_reg(BUS, ADDR, ACCEL_ADXL345_POWER_CTL, reg); + i2c_release(BUS); +} + +void adxl345_set_standby(adxl345_t *dev) +{ + uint8_t reg; + + assert(dev); + + DEBUG("[adxl345] set device to standby mode\n"); + + i2c_acquire(BUS); + i2c_read_reg(BUS, ADDR, ACCEL_ADXL345_POWER_CTL, ®); + reg &= ~MEASURE_BIT; + i2c_write_reg(BUS, ADDR, ACCEL_ADXL345_POWER_CTL, reg); + i2c_release(BUS); +} + +void adxl345_set_sleep(adxl345_t *dev) +{ + uint8_t reg; + + assert(dev); + + DEBUG("[adxl345] set device to sleep mode\n"); + + i2c_acquire(BUS); + i2c_read_reg(BUS, ADDR, ACCEL_ADXL345_POWER_CTL, ®); + reg |= SLEEP_BIT; + i2c_write_reg(BUS, ADDR, ACCEL_ADXL345_POWER_CTL, reg); + i2c_release(BUS); +} + +void adxl345_set_autosleep(adxl345_t *dev) +{ + uint8_t reg; + + assert(dev); + + DEBUG("[adxl345] set device to autosleep mode\n"); + + i2c_acquire(BUS); + i2c_read_reg(BUS, ADDR, ACCEL_ADXL345_POWER_CTL, ®); + reg |= AUTOSLEEP_BIT; + i2c_write_reg(BUS, ADDR, ACCEL_ADXL345_POWER_CTL, reg); + i2c_release(BUS); +} + +void adxl345_set_bandwidth_rate(adxl345_t *dev, uint8_t bw_rate) +{ + uint8_t reg; + + assert(dev); + + DEBUG("[adxl345] set device rate to %d Hz\n", (int)bw_rate); + + i2c_acquire(BUS); + i2c_read_reg(BUS, ADDR, ACCEL_ADXL345_BW_RATE, ®); + reg |= bw_rate; + i2c_write_reg(BUS, ADDR, ACCEL_ADXL345_BW_RATE, reg); + i2c_release(BUS); +} + +void adxl345_set_fifo_mode(adxl345_t *dev, uint8_t mode, + uint8_t output, uint8_t value) +{ + uint8_t reg; + + assert(dev); + + DEBUG("[adxl345] set fifo mode to %d, output trigger to %d and trigger " + "value to :%d\n", (int)mode, (int)output, (int)value); + + i2c_acquire(BUS); + reg = ((mode << FIFO_MODE_POS) | (output << FIFO_TRIGGER_POS) | value); + i2c_write_reg(BUS, ADDR, ACCEL_ADXL345_FIFO_CTL, reg); + i2c_release(BUS); +} diff --git a/drivers/adxl345/adxl345_saul.c b/drivers/adxl345/adxl345_saul.c new file mode 100644 index 0000000000000000000000000000000000000000..162afe54953b360dfce5e108b479c3b502e71a34 --- /dev/null +++ b/drivers/adxl345/adxl345_saul.c @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2017 Mesotic SAS + * + * 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_adxl345 + * @{ + * + * @file + * @brief SAUL adaption for ADXL345 device + * + * @author Dylan Laduranty <dylan.laduranty@mesotic.com> + * + * @} + */ + +#include "saul.h" +#include "adxl345.h" + +static int read_acc(void *dev, phydat_t *res) +{ + adxl345_t *d = (adxl345_t *)dev; + adxl345_read(d, (adxl345_data_t *)res->val); + + res->unit = UNIT_G; + res->scale = -3; + return 3; +} + +static int write(void *dev, phydat_t *state) +{ + return -ENOTSUP; +} + +const saul_driver_t adxl345_saul_driver = { + .read = read_acc, + .write = write, + .type = SAUL_SENSE_ACCEL, +}; diff --git a/drivers/adxl345/include/adxl345_params.h b/drivers/adxl345/include/adxl345_params.h new file mode 100644 index 0000000000000000000000000000000000000000..af6b010ed3224e12498e26a12f2699738426b4fe --- /dev/null +++ b/drivers/adxl345/include/adxl345_params.h @@ -0,0 +1,94 @@ +/* + * Copyright (C) 2017 Mesotic SAS + * + * 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_adxl345 + * @{ + * + * @file + * @brief Default configuration for ADXL345 devices + * + * @author Dylan Laduranty <dylan.laduranty@mesotic.com> + */ + +#ifndef ADXL345_PARAMS_H +#define ADXL345_PARAMS_H + +#include "board.h" +#include "saul_reg.h" +#include "adxl345.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Set default configuration parameters for the ADXL345 driver + * @{ + */ +#ifndef ADXL345_PARAM_I2C +#define ADXL345_PARAM_I2C (I2C_DEV(0)) +#endif +#ifndef ADXL345_PARAM_ADDR +#define ADXL345_PARAM_ADDR (ADXL345_ADDR_53) +#endif +#ifndef ADXL345_PARAM_RATE +#define ADXL345_PARAM_RATE (ADXL345_RATE_200HZ) +#endif +#ifndef ADXL345_PARAM_RANGE +#define ADXL345_PARAM_RANGE (ADXL345_RANGE_16G) +#endif +#ifndef ADXL345_PARAM_OFFSET +#define ADXL345_PARAM_OFFSET { 0, 0, 0 } +#endif +#ifndef ADXL345_PARAM_INTERRUPT +#define ADXL345_PARAM_INTERRUPT {0x0F, 0xBF, 0x40, 0xF0, 0xFF, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F} +#endif +#ifndef ADXL345_PARAM_FULL_RES +#define ADXL345_PARAM_FULL_RES (1) +#endif +#ifndef ADXL345_PARAM_SCALE_FACTOR +#define ADXL345_PARAM_SCALE_FACTOR (3.9) +#endif +#ifndef ADXL345_PARAMS +#define ADXL345_PARAMS { .i2c = ADXL345_PARAM_I2C, \ + .addr = ADXL345_PARAM_ADDR, \ + .rate = ADXL345_PARAM_RATE, \ + .range = ADXL345_PARAM_RANGE, \ + .offset = ADXL345_PARAM_OFFSET, \ + .interrupt = ADXL345_PARAM_INTERRUPT, \ + .full_res = ADXL345_PARAM_FULL_RES, \ + .scale_factor = ADXL345_PARAM_SCALE_FACTOR} +#endif +/**@}*/ + +/** + * @brief ADXL345 configuration + */ +static const adxl345_params_t adxl345_params[] = +{ + ADXL345_PARAMS +}; + +/** + * @brief Additional meta information to keep in the SAUL registry + */ +static const saul_reg_info_t adxl345_saul_info[] = +{ + { + .name = "adxl345" + } +}; + +#ifdef __cplusplus +} +#endif + +#endif /* ADXL345_PARAMS_H */ +/** @} */ diff --git a/drivers/adxl345/include/adxl345_regs.h b/drivers/adxl345/include/adxl345_regs.h new file mode 100644 index 0000000000000000000000000000000000000000..fe0a329e4d00a4970df08014e2de80ee047d1ff7 --- /dev/null +++ b/drivers/adxl345/include/adxl345_regs.h @@ -0,0 +1,189 @@ +/* + * Copyright (C) 2017 Mesotic SAS + * + * 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_adxl345 + * @{ + * + * @file + * @brief Register and bit definitions for the ADXL345 + * + * @author Dylan Laduranty <dylan.laduranty@mesotic.com> + */ + +#ifndef ADXL345_REGS_H +#define ADXL345_REGS_H + +#ifdef __cplusplus + extern "C" { +#endif + +/** \name Register addresses + * @{ + */ +#define ACCEL_ADXL345_CHIP_ID_REG (0x00) /**< Device ID */ +#define ACCEL_ADXL345_THRESH_TAP (0x1D) /**< Tap threshold */ +#define ACCEL_ADXL345_OFFSET_X (0x1E) /**< X-axis offset */ +#define ACCEL_ADXL345_OFFSET_Y (0x1F) /**< Y-axis offset */ +#define ACCEL_ADXL345_OFFSET_Z (0x20) /**< Z-axis offset */ +#define ACCEL_ADXL345_TAP_DUR (0x21) /**< Tap duration */ +#define ACCEL_ADXL345_TAP_LAT (0x22) /**< Tap latency */ +#define ACCEL_ADXL345_TAP_WIN (0x23) /**< Tap window */ +#define ACCEL_ADXL345_THRESH_ACT (0x24) /**< Activity threshold */ +#define ACCEL_ADXL345_THRESH_INACT (0x25) /**< Inactivity threshold */ +#define ACCEL_ADXL345_TIME_INACT (0x26) /**< Inactivity time */ +#define ACCEL_ADXL345_ACT_INACT_CTL (0x27) /**< Axis enable control for activity and inactivity detection */ +#define ACCEL_ADXL345_THRESH_FF (0x28) /**< Free-fall threshold */ +#define ACCEL_ADXL345_TIME_FF (0x29) /**< Free-fall time */ +#define ACCEL_ADXL345_TAP_AXES (0x2A) /**< Axis control for single tap/double tap */ +#define ACCEL_ADXL345_ACT_TAP_STATUS (0x2B) /**< Source of single tap/double tap */ +#define ACCEL_ADXL345_BW_RATE (0x2C) /**< Data rate and power mode control */ +#define ACCEL_ADXL345_POWER_CTL (0x2D) /**< Power-saving features control */ +#define ACCEL_ADXL345_INT_ENABLE (0x2E) /**< Interrupt enable control */ +#define ACCEL_ADXL345_INT_MAP (0x2F) /**< Interrupt mapping control */ +#define ACCEL_ADXL345_INT_SOURCE (0x30) /**< Source of interrupts */ +#define ACCEL_ADXL345_DATA_FORMAT (0x31) /**< Data format control */ +#define ACCEL_ADXL345_DATA_X0 (0x32) /**< X-Axis Data 0 */ +#define ACCEL_ADXL345_DATA_X1 (0x33) /**< X-Axis Data 1 */ +#define ACCEL_ADXL345_DATA_Y0 (0x34) /**< Y-Axis Data 0 */ +#define ACCEL_ADXL345_DATA_Y1 (0x35) /**< Y-Axis Data 1 */ +#define ACCEL_ADXL345_DATA_Z0 (0x36) /**< Z-Axis Data 0 */ +#define ACCEL_ADXL345_DATA_Z1 (0x37) /**< Z-Axis Data 1 */ +#define ACCEL_ADXL345_FIFO_CTL (0x38) /**< FIFO control */ +#define ACCEL_ADXL345_FIFO_STATUS (0x39) /**< FIFO status */ +/** @} */ + +/** + * @name Device ID for ADXL345 + * @{ + */ +#define ACCEL_ADXL345_CHIP_ID (0xE5) +/** @} */ + +/** + * @name Resolution masks for output data + * @{ + */ +#define RES_10_BITS (0x03FF) +#define RES_11_BITS (0x07FF) +#define RES_12_BITS (0x0FFF) +#define RES_13_BITS (0x1FFF) +/** @} */ + +/** + * @name bits definitions for ACT_INACT_CTL register + * @{ + */ +#define INACT_Z_ENABLE (1 << 0) +#define INACT_Y_ENABLE (1 << 1) +#define INACT_X_ENABLE (1 << 2) +#define INACT_ACDC (1 << 3) +#define ACT_Z_ENABLE (1 << 4) +#define ACT_Y_ENABLE (1 << 5) +#define ACT_X_ENABLE (1 << 6) +#define ACT_ACDC (1 << 7) +/** @} */ + +/** + * @name bits definitions for TAP_AXES register + * @{ + */ +#define TAP_Z_ENABLE (1 << 0) +#define TAP_Y_ENABLE (1 << 1) +#define TAP_X_ENABLE (1 << 2) +#define SUPPRESS (1 << 3) +#define TAP_ALL_ENABLE (TAP_Z_ENABLE|TAP_Y_ENABLE|TAP_X_ENABLE) +/** @} */ + +/** + * @name bits definitions for ACT_TAP_STATUS register + * @{ + */ +#define TAP_Z_SRC (1 << 0) +#define TAP_Y_SRC (1 << 1) +#define TAP_X_SRC (1 << 2) +#define ASLEEP (1 << 3) +#define ACT_Z_SRC (1 << 4) +#define ACT_Y_SRC (1 << 5) +#define ACT_X_SRC (1 << 6) +/** @} */ + +/** + * @name bits definitions for BW_RATE register + * @{ + */ +#define RATE_MASK (0x0F) +#define LOWPOWER (1 << 4) +/** @} */ + +/** + * @name bits definitions for PWR_CTL register + * @{ + */ +#define WAKEUP_8HZ (0x00) +#define WAKEUP_4HZ (0x01) +#define WAKEUP_2HZ (0x02) +#define WAKEUP_1HZ (0x03) +#define SLEEP_BIT (1 << 2) +#define MEASURE_BIT (1 << 3) +#define AUTOSLEEP_BIT (1 << 4) +#define LINK_BIT (1 << 5) +/** @} */ + +/** + * @name interrupts pins definitions for INT_ENABLE, INT_MAP and INT_SOURCE + * registers + * @{ + */ +#define OVERRUN (1 << 0) +#define WATERMARK (1 << 1) +#define FREEFALL (1 << 2) +#define INACTIVITY (1 << 3) +#define ACTIVITY (1 << 4) +#define DOUBLE_TAP (1 << 5) +#define SINGLE_TAP (1 << 6) +#define DATA_READY (1 << 7) +/** @} */ + +/** + * @name bits definitions for DATA_FORMAT register + * @{ + */ +#define RANGE_MASK (0x03) +#define JUSTIFY (1 << 2) +#define FULL_RES (1 << 3) +#define INT_INVERT (1 << 5) +#define SPI_BIT (1 << 6) +#define SELF_TEST (1 << 7) +/** @} */ + +/** + * @name bits definitions for FIFO_CTL register + * @{ + */ +#define SAMPLES_MASK (0x0F) +#define FIFO_TRIGGER_POS (4) +#define FIFO_TRIGGER (1 << FIFO_TRIGGER_POS) +#define FIFO_MODE_POS (6) +#define FIFO_MODE_MASK (0xC0) +/** @} */ + +/** + * @name bits definitions for FIFO_STATUS register + * @{ + */ +#define FIFO_ENTRIES_MASK (0x3F) +#define FIFO_TRIG (1 << 7) +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* ADXL345_REGS_H */ +/** @} */ diff --git a/drivers/include/adxl345.h b/drivers/include/adxl345.h new file mode 100644 index 0000000000000000000000000000000000000000..9b78e0878c10708e0edd5849c1319f4049df0012 --- /dev/null +++ b/drivers/include/adxl345.h @@ -0,0 +1,233 @@ +/* + * Copyright (C) 2017 Mesotic SAS + * + * 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. + */ + +/** + * @defgroup drivers_adxl345 ADXL345 3-Axis accelerometer + * @ingroup drivers_sensors + * @brief Device driver interface for the ADXL345 + * @{ + * + * @file + * @brief Interface definition for the ADXL345 + * + * @author Dylan Laduranty <dylan.laduranty@mesotic.com> + */ + +#ifndef ADXL345_H +#define ADXL345_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "periph/i2c.h" + +/** + * @brief Possible ADXL345 hardware addresses (wiring specific) + */ +enum { + ADXL345_ADDR_1D = 0x1D, /**< I2C device address if SDO / Alt address pin is high */ + ADXL345_ADDR_53 = 0x53, /**< I2C device address if SDO / Alt address pin is low */ +}; + +/** + * @brief Define ADXL345 sensitivity + */ +enum { + ADXL345_RANGE_2G, /**< +/- 2 g Full Scale Rang */ + ADXL345_RANGE_4G, /**< +/- 4 g Full Scale Rang */ + ADXL345_RANGE_8G, /**< +/- 8 g Full Scale Rang */ + ADXL345_RANGE_16G /**< +/- 16 g Full Scale Rang */ +}; + +/** + * @brief List bandwidth rate + */ +enum { + ADXL345_RATE_0HZ1 = 0, /**< 0.1 Hz Output Data Rate */ + ADXL345_RATE_0HZ2 = 1, /**< 0.2 Hz Output Data Rate */ + ADXL345_RATE_0HZ39 = 2, /**< 0.39 Hz Output Data Rate */ + ADXL345_RATE_0HZ78 = 3, /**< 0.78 Hz Output Data Rate */ + ADXL345_RATE_1HZ56 = 4, /**< 1.56 Hz Output Data Rate */ + ADXL345_RATE_3HZ13 = 5, /**< 3.13 Hz Output Data Rate */ + ADXL345_RATE_6HZ25 = 6, /**< 6.25 Hz Output Data Rate */ + ADXL345_RATE_12HZ50 = 7, /**< 12.5 Hz Output Data Rate */ + ADXL345_RATE_25HZ = 8, /**< 25 Hz Output Data Rate */ + ADXL345_RATE_50HZ = 9, /**< 50 Hz Output Data Rate */ + ADXL345_RATE_100HZ = 10, /**< 100 Hz Output Data Rate */ + ADXL345_RATE_200HZ = 11, /**< 200 Hz Output Data Rate */ + ADXL345_RATE_400HZ = 12, /**< 400 Hz Output Data Rate */ + ADXL345_RATE_800HZ = 13, /**< 800 Hz Output Data Rate */ + ADXL345_RATE_1600HZ = 14, /**< 1600 Hz Output Data Rate */ + ADXL345_RATE_3200HZ = 15 /**< 3200 Hz Output Data Rate */ +}; + +/** + * @brief List fifo mode + */ +enum { + BYPASS = 0, /**< FIFO bypass mode */ + FIFO = 1, /**< FIFO mode */ + STREAM = 2, /**< FIFO stream mode */ + TRIGGER = 3 /**< FIFO trigger mode */ +}; +/** + * @brief Output Interrupt selection + */ +enum { + INT1, /**< Output interrupt on INT1 pin */ + INT2 /**< Output interrupt on INT2 pin */ +}; + +/** + * @brief Named return values + */ +enum { + ADXL345_OK = 0, /**< everything was fine */ + ADXL345_DATA_READY = 1, /**< new data ready to be read */ + ADXL345_NOI2C = -1, /**< I2C communication failed */ + ADXL345_NODEV = -2, /**< no ADXL345 device found on the bus */ + ADXL345_NODATA = -3 /**< no data available */ +}; + +/** + * @brief ADXL345 result vector struct + */ +typedef struct { + int16_t x; /**< X-Axis measurement result */ + int16_t y; /**< Y-Axis measurement result */ + int16_t z; /**< Z-Axis measurement result */ +} adxl345_data_t; + +/** + * @brief Interrupt configuration struct for the ADXL345 sensor + */ +typedef struct { + uint8_t source; /**< Source of interrupts */ + uint8_t map; /**< Interrupt mapping control */ + uint8_t enable; /**< Interrupt enable control */ + uint8_t thres_tap; /**< Tap threshold */ + uint8_t thres_dur; /**< Tap duration */ + uint8_t thres_latent; /**< Tap latency */ + uint8_t thres_window; /**< Tap window */ + uint8_t thres_act; /**< Activity threshold */ + uint8_t thres_inact; /**< Inactivity threshold */ + uint8_t time_inact; /**< Inactivity time */ + uint8_t thres_ff; /**< Free-fall threshold */ + uint8_t time_ff; /**< Time threshold */ + uint8_t act_inact; /**< Axis enable control for activity and inactivity detection */ + uint8_t tap_axes; /**< Axis control for single tap/double tap */ +} adxl345_interrupt_t; + +/** + * @brief Configuration struct for the ADXL345 sensor + */ +typedef struct { + i2c_t i2c; /**< I2C device which is used */ + uint8_t addr; /**< I2C address */ + adxl345_interrupt_t interrupt; /**< Interrupts configuration */ + uint8_t offset[3]; /**< offset axis */ + uint8_t range; /**< Sensitivity configuration */ + uint8_t rate; /**< Configured sample rate for accel */ + uint8_t full_res; /**< Resolution bit */ + uint8_t scale_factor; /**< Scale factor for converting value to mg */ +} adxl345_params_t; + +/** + * @brief Device descriptor for the ADXL345 sensor + */ +typedef struct { + adxl345_params_t params; /**< Device configuration */ +} adxl345_t; + +/** + * @brief Initialize the ADXL345 accelerometer driver. + * + * @param[out] dev device descriptor of accelerometer to initialize + * @param[in] params configuration parameters + * + * @return ADXL345_OK on success + * @return ADXL345_NOI2C if initialization of I2C bus failed + * @return ADXL345_NODEV if accelerometer test failed + */ +int adxl345_init(adxl345_t *dev, const adxl345_params_t* params); + +/** + * @brief Read accelerometer's data + * + * Acceleration will be calculated as:<br> + * \f$ accel = {value \times 3.9} \f$ if full scale is set to 2g<br> + * \f$ accel = {value \times 7.8} \f$ if full scale is set to 4g<br> + * \f$ accel = {value \times 15.6} \f$ if full scale is set to 8g<br> + * \f$ accel = {value \times 31.2} \f$ if full scale is set to 16g<br> + * + * @param[in] dev device descriptor of accelerometer + * @param[out] data the current acceleration data [in mg] + */ +void adxl345_read(adxl345_t *dev, adxl345_data_t *data); + +/** + * @brief set ADXL345's interrupts configuration + * + * @param[in] dev device descriptor of accelerometer + */ +void adxl345_set_interrupt(adxl345_t *dev); + +/** + * @brief set ADXL345's measure mode + * + * @param[in] dev device descriptor of accelerometer + */ +void adxl345_set_measure(adxl345_t *dev); + +/** + * @brief Set standby mode + * + * @param[in] dev device descriptor of accelerometer + */ +void adxl345_set_standby(adxl345_t *dev); + +/** + * @brief Set sleep mode + * + * @param[in] dev device descriptor of accelerometer + */ +void adxl345_set_sleep(adxl345_t *dev); + +/** + * @brief Set autosleep mode + * + * @param[in] dev device descriptor of accelerometer + */ +void adxl345_set_autosleep(adxl345_t *dev); + +/** + * @brief Set bandwidth rate + * + * @param[in] dev device descriptor of accelerometer + * @param[in] bw_rate new datarate + */ +void adxl345_set_bandwidth_rate(adxl345_t *dev, uint8_t bw_rate); + +/** + * @brief Set fifo mode with its configuration. + * + * @param[in] dev device descriptor of accelerometer + * @param[in] mode fifo mode configuration + * @param[in] output set trigger output + * @param[in] value set trigger's value + */ +void adxl345_set_fifo_mode(adxl345_t *dev, uint8_t mode, + uint8_t output, uint8_t value); + +#ifdef __cplusplus +} +#endif + +#endif /* ADXL345_H */ +/** @} */ diff --git a/sys/auto_init/auto_init.c b/sys/auto_init/auto_init.c index 4a20d9dfb0b508d059997bfc27d3504716d8fbdf..be60b26303474768a4754890ac7302b8cfc7f1f5 100644 --- a/sys/auto_init/auto_init.c +++ b/sys/auto_init/auto_init.c @@ -319,6 +319,10 @@ void auto_init(void) extern void auto_init_veml6070(void); auto_init_veml6070(); #endif +#ifdef MODULE_ADXL345 + extern void auto_init_adxl345(void); + auto_init_adxl345(); +#endif #endif /* MODULE_AUTO_INIT_SAUL */ diff --git a/sys/auto_init/saul/auto_init_adxl345.c b/sys/auto_init/saul/auto_init_adxl345.c new file mode 100644 index 0000000000000000000000000000000000000000..dae23f1bc3368caa17e51722f1a7baec9d18b4dc --- /dev/null +++ b/sys/auto_init/saul/auto_init_adxl345.c @@ -0,0 +1,70 @@ +/* + * Copyright (C) 2017 Mesotic SAS + * + * 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 ADXL345 accelerometer + * + * @author Dylan Laduranty <dylan.laduranty@mesotic.com> + * + * @} + */ + +#ifdef MODULE_ADXL345 + +#include "log.h" +#include "saul_reg.h" +#include "adxl345.h" +#include "adxl345_params.h" + +/** + * @brief Define the number of configured sensors + */ +#define ADXL345_NUM (sizeof(adxl345_params)/sizeof(adxl345_params[0])) + +/** + * @brief Allocate memory for the device descriptors + */ +static adxl345_t adxl345_devs[ADXL345_NUM]; + +/** + * @brief Memory for the SAUL registry entries + */ +static saul_reg_t saul_entries[ADXL345_NUM]; + +/** + * @brief Reference the driver structs + * @{ + */ +extern saul_driver_t adxl345_saul_driver; +/** @} */ + +void auto_init_adxl345(void) +{ + for (unsigned i = 0; i < ADXL345_NUM; i++) { + LOG_DEBUG("[auto_init_saul] initializing adxl345 #%u\n", i); + + if (adxl345_init(&adxl345_devs[i], &adxl345_params[i]) != ADXL345_OK) { + LOG_ERROR("[auto_init_saul] error initializing adxl345 #%u\n", i); + continue; + } + + saul_entries[i].dev = &(adxl345_devs[i]); + saul_entries[i].name = adxl345_saul_info[i].name; + saul_entries[i].driver = &adxl345_saul_driver; + saul_reg_add(&(saul_entries[i])); + } +} + +#else +typedef int dont_be_pedantic; +#endif /* MODULE_ADXL345 */