Browse Source

Merge pull request #6749 from dylad/adxl345_support

drivers/adxl345: Initial support + saul
pr/rotary
Alexandre Abadie 6 years ago committed by GitHub
parent
commit
4618bcfa7b
  1. 4
      drivers/Makefile.dep
  2. 3
      drivers/Makefile.include
  3. 1
      drivers/adxl345/Makefile
  4. 224
      drivers/adxl345/adxl345.c
  5. 43
      drivers/adxl345/adxl345_saul.c
  6. 94
      drivers/adxl345/include/adxl345_params.h
  7. 189
      drivers/adxl345/include/adxl345_regs.h
  8. 233
      drivers/include/adxl345.h
  9. 4
      sys/auto_init/auto_init.c
  10. 70
      sys/auto_init/saul/auto_init_adxl345.c
  11. 7
      tests/driver_adxl345/Makefile
  12. 16
      tests/driver_adxl345/README.md
  13. 53
      tests/driver_adxl345/main.c

4
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

3
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

1
drivers/adxl345/Makefile

@ -0,0 +1 @@
include $(RIOTBASE)/Makefile.base

224
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, &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);
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);
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);
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);
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);
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);
}

43
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,
};

94
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 */
/** @} */

189
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 */
/** @} */

233
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 */
/** @} */

4
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 */

70
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 */

7
tests/driver_adxl345/Makefile

@ -0,0 +1,7 @@
APPLICATION = driver_adxl345
include ../Makefile.tests_common
USEMODULE += xtimer
USEMODULE += adxl345
include $(RIOTBASE)/Makefile.include

16
tests/driver_adxl345/README.md

@ -0,0 +1,16 @@
# About
This is a test application for the ADXL345 accelerometer.
# Datasheet
http://www.analog.com/media/en/technical-documentation/data-sheets/ADXL345.pdf
# Usage
This test application will initialize the ADXL345 sensor with the following parameters:
- I2C device address set to 0x53
- full scale parameter set to +/-16 g
- 200 Hz output data-rate
See RIOT/drivers/adxl345_params.h for the default configuration.
After initialization, the sensor reads the x-, y-, z-axis values every 100ms
and prints them to STDOUT.

53
tests/driver_adxl345/main.c

@ -0,0 +1,53 @@
/*
* 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 tests
* @{
*
* @file
* @brief ADXL345 test application
*
* @author Dylan Laduranty <dylan.laduranty@mesotic.com>
*
* @}
*/
#include <stdio.h>
#include "adxl345.h"
#include "adxl345_params.h"
#include "xtimer.h"
#define SLEEP_DELAY 100 * 1000U
int main(void)
{
adxl345_t dev;
adxl345_data_t data;
puts("ADXL345 test application");
printf("Initializing ADXL345 accelerometer at I2C_DEV(%i)... ",
adxl345_params->i2c);
if (adxl345_init(&dev, adxl345_params) == ADXL345_OK) {
puts("[OK]\n");
}
else {
puts("[Failed]");
return -1;
}
while(1) {
adxl345_read(&dev, &data);
printf("Acceleration [in mg]: X axis:%d Y axis:%d Z axis:%d\n",
data.x, data.y, data.z);
xtimer_usleep(SLEEP_DELAY);
}
return 0;
}
Loading…
Cancel
Save