diff --git a/drivers/Makefile.dep b/drivers/Makefile.dep index 1216dadf67..a59395c06b 100644 --- a/drivers/Makefile.dep +++ b/drivers/Makefile.dep @@ -226,6 +226,10 @@ ifneq (,$(filter mag3110,$(USEMODULE))) FEATURES_REQUIRED += periph_i2c endif +ifneq (,$(filter mma7660,$(USEMODULE))) + FEATURES_REQUIRED += periph_i2c +endif + ifneq (,$(filter mma8x5x,$(USEMODULE))) FEATURES_REQUIRED += periph_i2c endif diff --git a/drivers/Makefile.include b/drivers/Makefile.include index e37c2b6752..11cc60b374 100644 --- a/drivers/Makefile.include +++ b/drivers/Makefile.include @@ -162,6 +162,10 @@ ifneq (,$(filter mag3110,$(USEMODULE))) USEMODULE_INCLUDES += $(RIOTBASE)/drivers/mag3110/include endif +ifneq (,$(filter mma7660,$(USEMODULE))) + USEMODULE_INCLUDES += $(RIOTBASE)/drivers/mma7660/include +endif + ifneq (,$(filter mma8x5x,$(USEMODULE))) USEMODULE_INCLUDES += $(RIOTBASE)/drivers/mma8x5x/include endif diff --git a/drivers/include/mma7660.h b/drivers/include/mma7660.h new file mode 100644 index 0000000000..c9ef872116 --- /dev/null +++ b/drivers/include/mma7660.h @@ -0,0 +1,261 @@ +/* + * Copyright (C) 2016 University of California, Berkeley + * + * 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_mma7660 MMA7660 Accelerometer + * @ingroup drivers_sensors + * @brief Driver for the Freescale MMA7660 3-Axis accelerometer. + * This driver only implements basic functionality. + * + * @{ + * + * @file + * @brief Interface definition for the MMA7660 accelerometer driver. + * + * @author Michael Andersen + */ + +#ifndef MMA7660_H +#define MMA7660_H + +#include +#include +#include "periph/i2c.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + +/** + * @brief Return codes + */ +enum { + MMA7660_OK, /**< all ok */ + MMA7660_I2C_ERR, /**< i2c bus initialization error */ + MMA7660_I2C_READ_ERR, /**< i2c bus cannot be read */ + MMA7660_I2C_WRITE_ERR, /**< i2c bus cannot be written */ + MMA7660_READ_ERR, /**< error when reading counts */ +}; + +/** + * @brief Parameters for an MMA7660 device + */ +typedef struct +{ + i2c_t i2c; /**< the I2C handle */ + uint8_t addr; /**< the device I2C address */ + uint8_t amsr; /**< active mode sample rate */ + uint8_t awsr; /**< auto wake sample rate */ + uint8_t filt; /**< filter samples */ +} mma7660_params_t; + +/** + * @brief Device descriptor for an MMA7660 device + */ +typedef struct +{ + mma7660_params_t params; /**< initialization parameters */ +} mma7660_t; + +/** + * @brief Data type for the result data + */ +typedef struct { + int16_t x; /**< acceleration in X direction */ + int16_t y; /**< acceleration in Y direction */ + int16_t z; /**< acceleration in Z direction */ +} mma7660_data_t; + +/** + * @name MMA7660 constants + * @{ + */ +#define MODE_ACTIVE_SHIFT (0U) +#define MODE_AUTOWAKE_SHIFT (3U) +#define MODE_AUTOSLEEP_SHIFT (4U) +#define MODE_PRESCALE_SHIFT (5U) +#define MODE_INTERRUPT_DEFAULT (0x40) /* Active low, push-pull */ + +#define MMA7660_INTSOURCE_NONE (0x00) +#define MMA7660_INTSOURCE_FB (0x01) +#define MMA7660_INTSOURCE_UDLR (0x02) +#define MMA7660_INTSOURCE_TAP (0x04) +#define MMA7660_INTSOURCE_AUTOSLEEP (0x08) +#define MMA7660_INTSOURCE_MEASURE (0x10) +#define MMA7660_INTSOURCE_SHX (0x20) +#define MMA7660_INTSOURCE_SHY (0x40) +#define MMA7660_INTSOURCE_SHZ (0x80) + +#define MMA7660_SR_AMPD (0x00) +#define MMA7660_SR_AM64 (0x01) +#define MMA7660_SR_AM32 (0x02) +#define MMA7660_SR_AM16 (0x03) +#define MMA7660_SR_AM8 (0x04) +#define MMA7660_SR_AM4 (0x05) +#define MMA7660_SR_AM2 (0x06) +#define MMA7660_SR_AM1 (0x07) +#define MMA7660_SR_AW32 (0x00) +#define MMA7660_SR_AW16 (0x08) +#define MMA7660_SR_AW8 (0x10) +#define MMA7660_SR_AW1 (0x18) +#define MMA7660_PDET_X (0x20) +#define MMA7660_PDET_Y (0x40) +#define MMA7660_PDET_Z (0x80) + +#define MMA7660_ADDR (0x4C) + +/* This is actually 46.9 but the sensor is not accurate enough + * for that to matter + */ +#define MMA7660_MG_PER_COUNT (47U) +/** @} */ + +/** + * @brief Initialize an MMA7660 device + * + * @param[out] dev device descriptor + * @param[in] params device configuration parameters + * + * @return MMA7660_OK on success + * @return -MMA7660_I2C_ERR on i2c bus initialization error + * @return -MMA7660_I2C_WRITE_ERR on i2c bus write error + */ +int mma7660_init(mma7660_t *dev, const mma7660_params_t *params); + + +/** + * @brief Set the mode register + * + * @param[in] dev device descriptor + * @param[in] active 0=sleep 1=active + * @param[in] autowake see datasheet + * @param[in] autosleep see datasheet + * @param[in] prescale main clock prescalar + * + * See page 17 of http://www.nxp.com/files/sensors/doc/data_sheet/MMA7660FC.pdf + * for information about the parameters + * + * @return MMA7660_OK on success + * @return -MMA7660_I2C_WRITE_ERR on i2c bus write error + */ +int mma7660_set_mode(const mma7660_t *dev, uint8_t active, + uint8_t autowake, uint8_t autosleep, uint8_t prescale); + +/** + * @brief Read the tilt register + * + * @param[in] dev device descriptor + * @param[out] res tilt register contents + * + * @return MMA7660_OK on success + * @return -MMA7660_I2C_READ_ERR on i2c bus read error + */ +int mma7660_read_tilt(const mma7660_t *dev, uint8_t *res); + +/** + * @brief Write the sleep count register + * + * @param[in] dev device descriptor + * @param[in] sleep sleep count + * + * @return MMA7660_OK on success + * @return -MMA7660_I2C_WRITE_ERR on i2c bus write error + */ +int mma7660_write_sleep_count(const mma7660_t *dev, uint8_t sleep); + +/** + * @brief Configure the interrupt sources + * + * @param[in] dev device descriptor + * @param[in] isource_flags interrupt source flags + * + * @return MMA7660_OK on success + * @return -MMA7660_I2C_WRITE_ERR on i2c bus write error + */ +int mma7660_config_interrupts(const mma7660_t *dev, uint8_t isource_flags); + +/** + * @brief Configure the sample rate + * + * @param[in] dev device descriptor + * @param[in] amsr active mode sample rate (pg 18 of DS) + * @param[in] awsr auto wake sample rate (pg 19 of DS) + * @param[in] filt filter samples (pg 19 of DS) + * + * See datasheet http://www.nxp.com/files/sensors/doc/data_sheet/MMA7660FC.pdf + * for details about the parameters + * + * @return MMA7660_OK on success + * @return -MMA7660_I2C_WRITE_ERR on i2c bus write error + */ +int mma7660_config_samplerate(const mma7660_t *dev, uint8_t amsr, uint8_t awsr, uint8_t filt); + +/** + * @brief Configure the tap detection + * + * @param[in] dev device descriptor + * @param[in] pdth pulse detection + * @param[in] enabled_axes enabled axes + * + * See page 21 of http://www.nxp.com/files/sensors/doc/data_sheet/MMA7660FC.pdf + * for details about the parameters + * + * @return MMA7660_OK on success + * @return -MMA7660_I2C_WRITE_ERR on i2c bus write error + */ +int mma7660_config_pdet(const mma7660_t *dev, uint8_t pdth, uint8_t enabled_axes); + +/** + * @brief Configure the tap detection debounce count + * + * @param[in] dev device descriptor + * @param[in] pd pulse debounce + * + * See page 21 of http://www.nxp.com/files/sensors/doc/data_sheet/MMA7660FC.pdf + * for details about the debouncer + * + * @return MMA7660_OK on success + * @return -MMA7660_I2C_WRITE_ERR on i2c bus write error + */ +int mma7660_config_pd(const mma7660_t *dev, uint8_t pd) ; + +/** + * @brief Read the acceleration counts converted to mG + * + * @param[in] dev device descriptor + * @param[out] data the acceleration data + * + * @return MMA7660_OK on success + * @return -MMA7660_I2C_READ_ERR on i2c bus read error + */ +int mma7660_read(const mma7660_t *dev, mma7660_data_t *data); + +/** + * @brief Read the acceleration counts (unconverted) + * + * @param[in] dev device descriptor + * @param[out] x the X axis value + * @param[out] y the Y axis value + * @param[out] z the Z axis value + * + * See page 28 of http://www.nxp.com/files/sensors/doc/data_sheet/MMA7660FC.pdf + * for conversion of acceleration counts to angles or G forces. + * + * @return MMA7660_OK on success + * @return -MMA7660_I2C_READ_ERR on i2c bus read error + * @return -MMA7660_READ_ERR on general read error + */ +int mma7660_read_counts(const mma7660_t *dev, int8_t *x, int8_t *y, int8_t *z); + +#ifdef __cplusplus +} +#endif + +#endif /* MMA7660_H */ +/** @} */ diff --git a/drivers/mma7660/Makefile b/drivers/mma7660/Makefile new file mode 100644 index 0000000000..48422e909a --- /dev/null +++ b/drivers/mma7660/Makefile @@ -0,0 +1 @@ +include $(RIOTBASE)/Makefile.base diff --git a/drivers/mma7660/include/mma7660_params.h b/drivers/mma7660/include/mma7660_params.h new file mode 100644 index 0000000000..9ff7daf65e --- /dev/null +++ b/drivers/mma7660/include/mma7660_params.h @@ -0,0 +1,86 @@ +/* + * Copyright (C) 2016 University of California, Berkeley + * Copyright (C) 2016 Michael Andersen + * + * 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_mma7660 + * @{ + * + * @file + * @brief Default configuration for MMA7660 accelerometer. + * + * @author Michael Andersen + * + */ + +#ifndef MMA7660_PARAMS_H +#define MMA7660_PARAMS_H + +#include "board.h" +#include "saul_reg.h" +#include "mma7660.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @name Set default configuration parameters for MMA7660 devices + * @{ + */ +#ifndef MMA7660_PARAM_I2C +#define MMA7660_PARAM_I2C I2C_DEV(0) +#endif +#ifndef MMA7660_PARAM_ADDR +#define MMA7660_PARAM_ADDR (MMA7660_ADDR) +#endif +#ifndef MMA7660_PARAM_AMSR +#define MMA7660_PARAM_AMSR (MMA7660_SR_AM1) +#endif +#ifndef MMA7660_PARAM_AWSR +#define MMA7660_PARAM_AWSR (MMA7660_SR_AW1) +#endif +#ifndef MMA7660_PARAM_FILT +#define MMA7660_PARAM_FILT (1) +#endif + +#ifndef MMA7660_PARAMS +#define MMA7660_PARAMS { .i2c = MMA7660_PARAM_I2C, \ + .addr = MMA7660_PARAM_ADDR, \ + .amsr = MMA7660_PARAM_AMSR, \ + .awsr = MMA7660_PARAM_AWSR, \ + .filt = MMA7660_PARAM_FILT} +#endif +#ifndef MMA7660_SAUL_INFO +#define MMA7660_SAUL_INFO { .name = "mma7660" } +#endif +/**@}*/ + +/** + * @brief MMA7660 configuration + */ +static const mma7660_params_t mma7660_params[] = +{ + MMA7660_PARAMS, +}; + +/** + * @brief Additional meta information to keep in the SAUL registry + */ +static const saul_reg_info_t mma7660_saul_info[] = +{ + MMA7660_SAUL_INFO +}; + +#ifdef __cplusplus +} +#endif + +#endif /* MMA7660_PARAMS_H */ +/** @} */ diff --git a/drivers/mma7660/include/mma7660_reg.h b/drivers/mma7660/include/mma7660_reg.h new file mode 100644 index 0000000000..92af20951a --- /dev/null +++ b/drivers/mma7660/include/mma7660_reg.h @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2016 University of California, Berkeley + * Copyright (C) 2016 Michael Andersen + * + * 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_mma7660 + * @{ + * + * @file + * @brief Register definition for the MMA7660 accelerometer driver. + * + * @author Michael Andersen + * + */ + +#ifndef MMA7660_REG_H +#define MMA7660_REG_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +/** + * @name Registers + * @{ + */ +#define MMA7660_XOUT (0x00) /**< X-axis out */ +#define MMA7660_YOUT (0x01) /**< Y-axis out */ +#define MMA7660_ZOUT (0x02) /**< Z-axis out */ +#define MMA7660_TILT (0x03) /**< Tilt, Shake, Tap, Alert */ +#define MMA7660_SRST (0x04) /**< Sample rate status */ +#define MMA7660_SPCNT (0x05) /**< Sleep count register */ +#define MMA7660_INTSU (0x06) /**< Interrupt setup */ +#define MMA7660_MODE (0x07) /**< Mode register */ +#define MMA7660_SR (0x08) /**< Sample rate register */ +#define MMA7660_PDET (0x09) /**< Tap / Pulse detection */ +#define MMA7660_PD (0x0A) /**< Tap / Pulse debounce */ +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* MMA7660_REG_H */ +/** @} */ diff --git a/drivers/mma7660/mma7660.c b/drivers/mma7660/mma7660.c new file mode 100644 index 0000000000..7623f41de9 --- /dev/null +++ b/drivers/mma7660/mma7660.c @@ -0,0 +1,258 @@ +/* + * Copyright (C) 2016 University of California, Berkeley + * 2018 HAW Hamburg + * + * 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_mma7660 + * @{ + * + * @file + * @brief Driver for the Freescale MMA7660 accelerometer. + * + * @author Michael Andersen + * @author Sebastian Meiling + * + * @} + */ + +#include +#include +#include "periph/i2c.h" + +#include "mma7660.h" +#include "mma7660_reg.h" + +#define ENABLE_DEBUG (0) +#include "debug.h" + +#define I2C_SPEED I2C_SPEED_FAST + +#define ALERT_MASK (0x40) +#define SIGN_BIT (0x20) +#define SIGN_EXTEND (0xC0) +#define SR_FILT_SHIFT (5U) + +#define PDET_AXIS_MASK (0xE0) + +#define DEV_I2C (dev->params.i2c) +#define DEV_ADDR (dev->params.addr) + +int mma7660_init(mma7660_t *dev, const mma7660_params_t *params) +{ + /* write device descriptor */ + dev->params = *params; + + i2c_acquire(DEV_I2C); + /* initialize the I2C bus */ + if (i2c_init_master(DEV_I2C, I2C_SPEED) < 0) { + i2c_release(DEV_I2C); + return -MMA7660_I2C_ERR; + } + i2c_release(DEV_I2C); + + /* set device to standby-mode befor configuration */ + if (mma7660_set_mode(dev, 0, 0, 0, 0) != MMA7660_OK) { + DEBUG("mma7660_set_mode failed!\n"); + return -MMA7660_I2C_WRITE_ERR; + } + + if (mma7660_config_samplerate(dev, params->amsr, + params->awsr, params->filt) != MMA7660_OK) { + DEBUG("mma7660_config_samplerate failed!\n"); + return -MMA7660_I2C_WRITE_ERR; + } + + if (mma7660_config_interrupts(dev, MMA7660_INTSOURCE_NONE) != MMA7660_OK) { + DEBUG("mma7660_config_interrupts failed!\n"); + return -MMA7660_I2C_WRITE_ERR; + } + + /* set device active after configuration */ + if (mma7660_set_mode(dev, 1, 0, 0, 0) != MMA7660_OK) { + DEBUG("mma7660_set_mode failed!\n"); + return -MMA7660_I2C_WRITE_ERR; + } + + return MMA7660_OK; +} + +int mma7660_set_mode(const mma7660_t *dev, uint8_t active, + uint8_t autowake, uint8_t autosleep, uint8_t prescale) +{ + char reg; + int rv; + reg = (active << MODE_ACTIVE_SHIFT) | + (autowake << MODE_AUTOWAKE_SHIFT) | + (autosleep << MODE_AUTOSLEEP_SHIFT) | + (prescale << MODE_PRESCALE_SHIFT) | + MODE_INTERRUPT_DEFAULT; + i2c_acquire(DEV_I2C); + rv = i2c_write_reg(DEV_I2C, DEV_ADDR, MMA7660_MODE, reg); + i2c_release(DEV_I2C); + if (rv != 1) { + return -MMA7660_I2C_WRITE_ERR; + } + + return MMA7660_OK; +} + +int mma7660_read_tilt(const mma7660_t *dev, uint8_t *res) +{ + int rv; + i2c_acquire(DEV_I2C); + rv = i2c_read_reg(DEV_I2C, DEV_ADDR, MMA7660_TILT, (char*)res); + i2c_release(DEV_I2C); + if (rv != 1) { + return -MMA7660_I2C_READ_ERR; + } + + return MMA7660_OK; +} + +int mma7660_write_sleep_count(const mma7660_t *dev, uint8_t sleep) +{ + int rv; + i2c_acquire(DEV_I2C); + rv = i2c_write_reg(DEV_I2C, DEV_ADDR, MMA7660_SPCNT, sleep); + i2c_release(DEV_I2C); + if (rv != 1) { + return -MMA7660_I2C_WRITE_ERR; + } + + return MMA7660_OK; +} + +int mma7660_config_interrupts(const mma7660_t *dev, uint8_t isource_flags) +{ + int rv; + i2c_acquire(DEV_I2C); + rv = i2c_write_reg(DEV_I2C, DEV_ADDR, MMA7660_INTSU, isource_flags); + i2c_release(DEV_I2C); + if (rv != 1) { + return -MMA7660_I2C_WRITE_ERR; + } + + return MMA7660_OK; +} + +int mma7660_config_samplerate(const mma7660_t *dev, uint8_t amsr, uint8_t awsr, uint8_t filt) +{ + int rv; + char ch = amsr | awsr | (filt << SR_FILT_SHIFT); + i2c_acquire(DEV_I2C); + rv = i2c_write_reg(DEV_I2C, DEV_ADDR, MMA7660_SR, ch); + i2c_release(DEV_I2C); + if (rv != 1) { + return -MMA7660_I2C_WRITE_ERR; + } + + return MMA7660_OK; +} + +int mma7660_config_pdet(const mma7660_t *dev, uint8_t pdth, uint8_t enabled_axes) { + int rv; + char ch = pdth | ((~enabled_axes) & PDET_AXIS_MASK); + i2c_acquire(DEV_I2C); + rv = i2c_write_reg(DEV_I2C, DEV_ADDR, MMA7660_PDET, ch); + i2c_release(DEV_I2C); + if (rv != 1) { + return -MMA7660_I2C_WRITE_ERR; + } + + return MMA7660_OK; +} + +int mma7660_config_pd(const mma7660_t *dev, uint8_t pd) { + int rv; + i2c_acquire(DEV_I2C); + rv = i2c_write_reg(DEV_I2C, DEV_ADDR, MMA7660_PD, (char)pd); + i2c_release(DEV_I2C); + if (rv != 1) { + return -MMA7660_I2C_WRITE_ERR; + } + + return MMA7660_OK; +} + +int mma7660_read_counts(const mma7660_t *dev, int8_t *x, int8_t *y, int8_t *z) +{ + int retries = 6; + char t; + i2c_acquire(DEV_I2C); + + while (retries > 0) { + if (i2c_read_reg(DEV_I2C, DEV_ADDR, MMA7660_XOUT, &t) != 1) { + i2c_release(DEV_I2C); + return -MMA7660_READ_ERR; + } + if ((t & ALERT_MASK) == 0) { + break; + } + retries--; + } + + if (t & SIGN_BIT) { + t |= SIGN_EXTEND; + } + *x = (int8_t)t; + + while (retries > 0) { + if (i2c_read_reg(DEV_I2C, DEV_ADDR, MMA7660_YOUT, &t) != 1) { + i2c_release(DEV_I2C); + return -MMA7660_READ_ERR; + } + if ((t & ALERT_MASK) == 0) { + break; + } + retries--; + } + + if (t & SIGN_BIT) { + t |= SIGN_EXTEND; + } + *y = (int8_t)t; + + while (retries > 0) { + if (i2c_read_reg(DEV_I2C, DEV_ADDR, MMA7660_ZOUT, &t) != 1) { + i2c_release(DEV_I2C); + return -MMA7660_READ_ERR; + } + if ((t & ALERT_MASK) == 0) { + break; + } + retries--; + } + + if (t & SIGN_BIT) t |= SIGN_EXTEND; + *z = (int8_t)t; + + i2c_release(DEV_I2C); + if (retries > 0) { + return MMA7660_OK; + } + + return -MMA7660_READ_ERR; +} + +int mma7660_read(const mma7660_t *dev, mma7660_data_t *data) +{ + int8_t countx, county, countz; + int rv; + + rv = mma7660_read_counts(dev, &countx, &county, &countz); + if (rv) { + return rv; + } + + data->x = ((int16_t)countx) * MMA7660_MG_PER_COUNT; + data->y = ((int16_t)county) * MMA7660_MG_PER_COUNT; + data->z = ((int16_t)countz) * MMA7660_MG_PER_COUNT; + + return MMA7660_OK; +} diff --git a/drivers/mma7660/mma7660_saul.c b/drivers/mma7660/mma7660_saul.c new file mode 100644 index 0000000000..ef0014ae66 --- /dev/null +++ b/drivers/mma7660/mma7660_saul.c @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2018 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_mma7660 + * @{ + * + * @file + * @brief MMA7660 adaption to the RIOT actuator/sensor interface + * + * @author Alexandre Abadie + * + * @} + */ + +#include +#include + +#include "saul.h" +#include "mma7660.h" + +static int read_acc(const void *dev, phydat_t *res) +{ + mma7660_read((const mma7660_t *)dev, (mma7660_data_t *)res); + + res->unit = UNIT_G; + res->scale = -3; + + return 3; +} + +const saul_driver_t mma7660_saul_driver = { + .read = read_acc, + .write = saul_notsup, + .type = SAUL_SENSE_ACCEL, +}; diff --git a/sys/auto_init/auto_init.c b/sys/auto_init/auto_init.c index 86c5479dda..883ed40eef 100644 --- a/sys/auto_init/auto_init.c +++ b/sys/auto_init/auto_init.c @@ -424,6 +424,10 @@ auto_init_mpu9150(); extern void auto_init_si114x(void); auto_init_si114x(); #endif +#ifdef MODULE_MMA7660 + extern void auto_init_mma7660(void); + auto_init_mma7660(); +#endif #endif /* MODULE_AUTO_INIT_SAUL */ diff --git a/sys/auto_init/saul/auto_init_mma7660.c b/sys/auto_init/saul/auto_init_mma7660.c new file mode 100644 index 0000000000..5d3662863e --- /dev/null +++ b/sys/auto_init/saul/auto_init_mma7660.c @@ -0,0 +1,77 @@ +/* + * Copyright (C) 2018 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 auto_init_saul + * @{ + * + * @file + * @brief Auto initialization of MMA7660 accelerometers + * + * @author Alexandre Abadie + * + * @} + */ + +#ifdef MODULE_MMA7660 + +#include "log.h" +#include "saul_reg.h" +#include "mma7660.h" +#include "mma7660_params.h" + +/** + * @brief Define the number of configured sensors + */ +#define MMA7660_NUM (sizeof(mma7660_params) / sizeof(mma7660_params[0])) + +/** + * @brief Allocate memory for the device descriptors + */ +static mma7660_t mma7660_devs[MMA7660_NUM]; + +/** + * @brief Memory for the SAUL registry entries + */ +static saul_reg_t saul_entries[MMA7660_NUM]; + +/** + * @brief Define the number of configured sensors + */ +#define MMA7660_INFO_NUM (sizeof(mma7660_saul_info) / sizeof(mma7660_saul_info[0])) + +/** + * @brief Reference the driver struct + * @{ + */ +extern saul_driver_t mma7660_saul_driver; +/** @} */ + +void auto_init_mma7660(void) +{ + assert(MMA7660_NUM == MMA7660_INFO_NUM); + + for (unsigned i = 0; i < MMA7660_NUM; i++) { + LOG_DEBUG("[auto_init_saul] initializing mma7660 #%u\n", i); + + if (mma7660_init(&mma7660_devs[i], &mma7660_params[i]) != MMA7660_OK) { + LOG_ERROR("[auto_init_saul] error initializing mma7660 #%u\n", i); + continue; + } + + saul_entries[i].dev = &(mma7660_devs[i]); + saul_entries[i].name = mma7660_saul_info[i].name; + saul_entries[i].driver = &mma7660_saul_driver; + saul_reg_add(&(saul_entries[i])); + } +} + +#else +typedef int dont_be_pedantic; +#endif /* MODULE_MMA7660 */ diff --git a/tests/driver_mma7660/Makefile b/tests/driver_mma7660/Makefile new file mode 100644 index 0000000000..46d714c06f --- /dev/null +++ b/tests/driver_mma7660/Makefile @@ -0,0 +1,6 @@ +include ../Makefile.tests_common + +USEMODULE += mma7660 +USEMODULE += xtimer + +include $(RIOTBASE)/Makefile.include diff --git a/tests/driver_mma7660/README.md b/tests/driver_mma7660/README.md new file mode 100644 index 0000000000..24bac3b832 --- /dev/null +++ b/tests/driver_mma7660/README.md @@ -0,0 +1,8 @@ +# About +This is a manual test application for the MMA7660 3 axis accelerometer driver. + +# Usage +This test application will initialize the MMA7660 sensor. + +After initialization, the sensor reads the x-, y-, z-axis values every 100ms +and prints them to STDOUT. diff --git a/tests/driver_mma7660/main.c b/tests/driver_mma7660/main.c new file mode 100644 index 0000000000..e4fd7b8bbe --- /dev/null +++ b/tests/driver_mma7660/main.c @@ -0,0 +1,54 @@ +/* + * 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 tests + * @{ + * + * @file + * @brief Test application for the MMA7660 3 axis accelerometer driver. + * + * @author Alexandre Abadie + * + * @} + */ + +#include + +#include "xtimer.h" +#include "mma7660.h" +#include "mma7660_params.h" + +#define SLEEP (100 * US_PER_MS) + +static mma7660_t dev; + +int main(void) +{ + puts("MMA7660 accelerometer driver test application\n"); + printf("Initializing MMA7660 accelerometer at I2C_DEV(%i)... ", + mma7660_params->i2c); + + if (mma7660_init(&dev, &mma7660_params[0]) == MMA7660_OK) { + puts("[OK]"); + } + else { + puts("[Failed]"); + return -1; + } + + while (1) { + mma7660_data_t data; + mma7660_read(&dev, &data); + printf("Acceleration [in mg]: X: %d Y: %d Z: %d\n", + data.x, data.y, data.z); + xtimer_usleep(SLEEP); + } + + return 0; +}