mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-29 04:50:03 +01:00
Merge pull request #2119 from jfischer-phytec-iot/pr@mma8652
Driver for Freescale MMA8652 Accelerometer
This commit is contained in:
commit
77eab0c1ae
@ -31,3 +31,6 @@ endif
|
||||
ifneq (,$(filter mpl3115a2,$(USEMODULE)))
|
||||
USEMODULE_INCLUDES += $(RIOTBASE)/drivers/mpl3115a2/include
|
||||
endif
|
||||
ifneq (,$(filter mma8652,$(USEMODULE)))
|
||||
USEMODULE_INCLUDES += $(RIOTBASE)/drivers/mma8652/include
|
||||
endif
|
||||
|
175
drivers/include/mma8652.h
Normal file
175
drivers/include/mma8652.h
Normal file
@ -0,0 +1,175 @@
|
||||
/*
|
||||
* Copyright (C) 2014 PHYTEC Messtechnik GmbH
|
||||
*
|
||||
* 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_mma8652 MMA8652 Accelerometer
|
||||
* @ingroup drivers
|
||||
* @brief Driver for the Freescale MMA8652 3-Axis accelerometer.
|
||||
* The driver will initialize the accelerometer for
|
||||
* best resolution (12 bit).
|
||||
* After initialization and set activ the accelerometer
|
||||
* will make measurements at periodic times.
|
||||
* The measurements period and scale range can be determined by
|
||||
* accelerometer initialization.
|
||||
* This driver only implements basic functionality.
|
||||
*
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Interface definition for the MMA8652 accelerometer driver.
|
||||
*
|
||||
* @author Johann Fischer <j.fischer@phytec.de>
|
||||
*/
|
||||
|
||||
#ifndef MMA8652_H
|
||||
#define MMA8652_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include "periph/i2c.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#ifndef MMA8652_I2C_ADDRESS
|
||||
#define MMA8652_I2C_ADDRESS 0x1D /**< Accelerometer Default Address */
|
||||
#endif
|
||||
|
||||
#define MMA8652_DATARATE_800HZ 0 /**< 800 Hz Ouput Data Rate in WAKE mode */
|
||||
#define MMA8652_DATARATE_400HZ 1 /**< 400 Hz Ouput Data Rate in WAKE mode */
|
||||
#define MMA8652_DATARATE_200HZ 2 /**< 200 Hz Ouput Data Rate in WAKE mode */
|
||||
#define MMA8652_DATARATE_100HZ 3 /**< 100 Hz Ouput Data Rate in WAKE mode */
|
||||
#define MMA8652_DATARATE_50HZ 4 /**< 50 Hz Ouput Data Rate in WAKE mode */
|
||||
#define MMA8652_DATARATE_1HZ25 5 /**< 12.5 Hz Ouput Data Rate in WAKE mode */
|
||||
#define MMA8652_DATARATE_6HZ25 6 /**< 6.25 Hz Ouput Data Rate in WAKE mode */
|
||||
#define MMA8652_DATARATE_1HZ56 7 /**< 1.56 Hz Ouput Data Rate in WAKE mode */
|
||||
#define MMA8652_DATARATE_DEFAULT MMA8652_DATARATE_6HZ25 /**< Data Rate for testing */
|
||||
|
||||
#define MMA8652_FS_RANGE_2G 0 /**< +/- 2 g Full Scale Range */
|
||||
#define MMA8652_FS_RANGE_4G 1 /**< +/- 4 g Full Scale Range */
|
||||
#define MMA8652_FS_RANGE_8G 2 /**< +/- 8 g Full Scale Range */
|
||||
#define MMA8652_FS_RANGE_DEFAULT MMA8652_FS_RANGE_2G /**< Full-Scale Range for testing */
|
||||
|
||||
/**
|
||||
* @brief Device descriptor for MMA8652 accelerometer.
|
||||
*/
|
||||
typedef struct {
|
||||
i2c_t i2c; /**< I2C device, the accelerometer is connected to */
|
||||
uint8_t addr; /**< the accelerometer's slave address on the I2C bus */
|
||||
bool initialized; /**< accelerometer status, true if accelerometer is initialized */
|
||||
} mma8652_t;
|
||||
|
||||
/**
|
||||
* @brief MMA8652 accelerometer test.
|
||||
* This function looks for Device ID of the MMA8652 accelerometer.
|
||||
*
|
||||
* @param[in] dev device descriptor of accelerometer
|
||||
*
|
||||
* @return 0 on success
|
||||
* @return -1 on error
|
||||
*/
|
||||
int mma8652_test(mma8652_t *dev);
|
||||
|
||||
/**
|
||||
* @brief Initialize the MMA8652 accelerometer driver.
|
||||
*
|
||||
* @param[out] dev device descriptor of accelerometer to initialize
|
||||
* @param[in] i2c I2C bus the accelerometer is connected to
|
||||
* @param[in] address accelerometer's I2C slave address
|
||||
* @param[in] dr output data rate selection in WAKE mode
|
||||
* @param[in] range full scale range
|
||||
*
|
||||
* @return 0 on success
|
||||
* @return -1 if parameters are wrong
|
||||
* @return -2 if initialization of I2C bus failed
|
||||
* @return -3 if accelerometer test failed
|
||||
* @return -4 if accelerometer configuration failed
|
||||
*/
|
||||
int mma8652_init(mma8652_t *dev, i2c_t i2c, uint8_t address, uint8_t dr, uint8_t range);
|
||||
|
||||
/**
|
||||
* @brief Set user offset correction.
|
||||
* Offset correction registers will be erased after accelerometer reset.
|
||||
*
|
||||
* @param[out] dev device descriptor of accelerometer to initialize
|
||||
* @param[in] x offset correction value for x-axis
|
||||
* @param[in] y offset correction value for y-axis
|
||||
* @param[in] z offset correction value for z-axis
|
||||
*
|
||||
* @return 0 on success
|
||||
* @return -1 on error
|
||||
*/
|
||||
int mma8652_set_user_offset(mma8652_t *dev, int8_t x, int8_t y, int8_t z);
|
||||
|
||||
/**
|
||||
* @brief Reset the MMA8652 accelerometer. After that accelerometer should be reinitialized.
|
||||
*
|
||||
* @param[out] dev device descriptor of accelerometer to reset
|
||||
*
|
||||
* @return 0 on success
|
||||
* @return -1 on error
|
||||
*/
|
||||
int mma8652_reset(mma8652_t *dev);
|
||||
|
||||
/**
|
||||
* @brief Set active mode, this enables periodic measurements.
|
||||
*
|
||||
* @param[out] dev device descriptor of accelerometer to reset
|
||||
*
|
||||
* @return 0 on success
|
||||
* @return -1 on error
|
||||
*/
|
||||
int mma8652_set_active(mma8652_t *dev);
|
||||
|
||||
/**
|
||||
* @brief Set standby mode.
|
||||
*
|
||||
* @param[in] dev device descriptor of accelerometer
|
||||
*
|
||||
* @return 0 on success
|
||||
* @return -1 on error
|
||||
*/
|
||||
int mma8652_set_standby(mma8652_t *dev);
|
||||
|
||||
/**
|
||||
* @brief Check for new set of measurement data.
|
||||
*
|
||||
* @param[in] dev device descriptor of accelerometer
|
||||
*
|
||||
* @return >0 if x- ,y- ,z-axis new sample is ready
|
||||
* @return 0 measurement in progress
|
||||
* @return -1 on error
|
||||
*/
|
||||
int mma8652_is_ready(mma8652_t *dev);
|
||||
|
||||
/**
|
||||
* @brief Read accelerometer's data.
|
||||
* Acceleration can be calculated as:<br>
|
||||
* \f$ a = \frac{value}{1024} \cdot g \f$ if full scale is set to 2g<br>
|
||||
* \f$ a = \frac{value}{512} \cdot g \f$ if full scale is set to 4g<br>
|
||||
* \f$ a = \frac{value}{256} \cdot g \f$ if full scale is set to 8g<br>
|
||||
*
|
||||
* @param[in] dev device descriptor of accelerometer
|
||||
* @param[out] x x-axis value
|
||||
* @param[out] y y-axis value
|
||||
* @param[out] z z-axis value
|
||||
* @param[out] status accelerometer status register
|
||||
*
|
||||
* @return 0 on success
|
||||
* @return -1 on error
|
||||
*/
|
||||
int mma8652_read(mma8652_t *dev, int16_t *x, int16_t *y, int16_t *z, uint8_t *status);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
/** @} */
|
3
drivers/mma8652/Makefile
Normal file
3
drivers/mma8652/Makefile
Normal file
@ -0,0 +1,3 @@
|
||||
MODULE = mma8652
|
||||
|
||||
include $(RIOTBASE)/Makefile.base
|
256
drivers/mma8652/include/mma8652_reg.h
Normal file
256
drivers/mma8652/include/mma8652_reg.h
Normal file
@ -0,0 +1,256 @@
|
||||
/*
|
||||
* Copyright (C) 2014 PHYTEC Messtechnik GmbH
|
||||
*
|
||||
* 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_mma8652
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Register definition for the MMA8652 accelerometer driver.
|
||||
*
|
||||
* @author Johann Fischer <j.fischer@phytec.de>
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __MMA8652_REG_H__
|
||||
#define __MMA8652_REG_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#define MMA8652_STATUS 0x00 /**< Data or FIFO Status */
|
||||
#define MMA8652_OUT_X_MSB 0x01 /**< [7:0] are 8 MSBs of X data */
|
||||
#define MMA8652_OUT_X_LSB 0x02 /**< [7:4] are 4 LSBs of X data */
|
||||
#define MMA8652_OUT_Y_MSB 0x03 /**< [7:0] are 8 MSBs of Y data */
|
||||
#define MMA8652_OUT_Y_LSB 0x04 /**< [7:4] are 4 LSBs of Y data */
|
||||
#define MMA8652_OUT_Z_MSB 0x05 /**< [7:0] are 8 MSBs of Z data */
|
||||
#define MMA8652_OUT_Z_LSB 0x06 /**< [7:4] are 8 LSBs of Z data */
|
||||
#define MMA8652_F_SETUP 0x09 /**< FIFO setup */
|
||||
#define MMA8652_TRIG_CFG 0x0A /**< Map of FIFO data capture events */
|
||||
#define MMA8652_SYSMOD 0x0B /**< Current System mode */
|
||||
#define MMA8652_INT_SOURCE 0x0C /**< Interrupt status */
|
||||
#define MMA8652_WHO_AM_I 0x0D /**< Device ID */
|
||||
#define MMA8652_XYZ_DATA_CFG 0x0E /**< Dynamic Range Settings */
|
||||
#define MMA8652_HP_FILTER_CUTOFF 0x0F /**< High-Pass Filter Selection */
|
||||
#define MMA8652_PL_STATUS 0x10 /**< Landscape/Portrait orientation status */
|
||||
#define MMA8652_PL_CFG 0x11 /**< Landscape/Portrait configuration */
|
||||
#define MMA8652_PL_COUNT 0x12 /**< Landscape/Portrait debounce counter */
|
||||
#define MMA8652_PL_BF_ZCOMP 0x13 /**< Back/Front, Z-Lock Trip threshold */
|
||||
#define MMA8652_P_L_THS_REG 0x14 /**< Portrait/Landscape Threshold and Hysteresis */
|
||||
#define MMA8652_FF_MT_CFG 0x15 /**< Freefall/Motion functional block configuration */
|
||||
#define MMA8652_FF_MT_SRC 0x16 /**< Freefall/Motion event source register */
|
||||
#define MMA8652_FF_MT_THS 0x17 /**< Freefall/Motion threshold register */
|
||||
#define MMA8652_FF_MT_COUNT 0x18 /**< Freefall/Motion debounce counter */
|
||||
#define MMA8652_TRANSIENT_CFG 0x1D /**< Transient functional block configuration */
|
||||
#define MMA8652_TRANSIENT_SRC 0x1E /**< Transient event status register */
|
||||
#define MMA8652_TRANSIENT_THS 0x1F /**< Transient event threshold */
|
||||
#define MMA8652_TRANSIENT_COUNT 0x20 /**< Transient debounce counter */
|
||||
#define MMA8652_PULSE_CFG 0x21 /**< Pulse enable configuration */
|
||||
#define MMA8652_PULSE_SRC 0x22 /**< Pulse detection source */
|
||||
#define MMA8652_PULSE_THSX 0x23 /**< X pulse threshold */
|
||||
#define MMA8652_PULSE_THSY 0x24 /**< Y pulse threshold */
|
||||
#define MMA8652_PULSE_THSZ 0x25 /**< Z pulse threshold */
|
||||
#define MMA8652_PULSE_TMLT 0x26 /**< Time limit for pulse */
|
||||
#define MMA8652_PULSE_LTCY 0x27 /**< Latency time for 2nd pulse */
|
||||
#define MMA8652_PULSE_WIND 0x28 /**< Window time for 2nd pulse */
|
||||
#define MMA8652_ASLP_COUNT 0x29 /**< Counter setting for Auto-SLEEP */
|
||||
#define MMA8652_CTRL_REG1 0x2A /**< Data rates and modes setting */
|
||||
#define MMA8652_CTRL_REG2 0x2B /**< Sleep Enable, OS modes, RST, ST */
|
||||
#define MMA8652_CTRL_REG3 0x2C /**< Wake from Sleep, IPOL, PP_OD */
|
||||
#define MMA8652_CTRL_REG4 0x2D /**< Interrupt enable register */
|
||||
#define MMA8652_CTRL_REG5 0x2E /**< Interrupt pin (INT1/INT2) map */
|
||||
#define MMA8652_OFF_X 0x2F /**< X-axis offset adjust */
|
||||
#define MMA8652_OFF_Y 0x30 /**< Y-axis offset adjust */
|
||||
#define MMA8652_OFF_Z 0x31 /**< Z-axis offset adjust */
|
||||
|
||||
#define MMA8652_STATUS_XDR (1 << 0)
|
||||
#define MMA8652_STATUS_YDR (1 << 1)
|
||||
#define MMA8652_STATUS_ZDR (1 << 2)
|
||||
#define MMA8652_STATUS_ZYXDR (1 << 3)
|
||||
#define MMA8652_STATUS_XOW (1 << 4)
|
||||
#define MMA8652_STATUS_YOW (1 << 5)
|
||||
#define MMA8652_STATUS_ZOW (1 << 6)
|
||||
#define MMA8652_STATUS_ZYXOW (1 << 7)
|
||||
|
||||
#define MMA8652_F_STATUS_F_CNT_MASK 0x3F
|
||||
#define MMA8652_F_STATUS_F_WMRK_FLAG (1 << 6)
|
||||
#define MMA8652_F_STATUS_F_OVF (1 << 7)
|
||||
|
||||
#define MMA8652_F_SETUP_MODE_MASK 0xC0
|
||||
#define MMA8652_F_SETUP_MODE_DISABLED 0
|
||||
#define MMA8652_F_SETUP_MODE_CIRCULAR 1
|
||||
#define MMA8652_F_SETUP_MODE_STOP 2
|
||||
#define MMA8652_F_SETUP_MODE_TRIGGER 3
|
||||
#define MMA8652_F_SETUP_F_WMRK_MASK 0x3F
|
||||
|
||||
#define MMA8652_TRIG_CFG_FF_MT (1 << 2)
|
||||
#define MMA8652_TRIG_CFG_PULSE (1 << 3)
|
||||
#define MMA8652_TRIG_CFG_LNDPRT (1 << 4)
|
||||
#define MMA8652_TRIG_CFG_TRANS (1 << 5)
|
||||
|
||||
#define MMA8652_SYSMOD_MASK 0x3
|
||||
#define MMA8652_SYSMOD_STANDBY 0
|
||||
#define MMA8652_SYSMOD_WAKE 1
|
||||
#define MMA8652_SYSMOD_SLEEP 2
|
||||
#define MMA8652_SYSMOD_FGT_MASK 0x7C
|
||||
#define MMA8652_SYSMOD_FGERR (1 << 7)
|
||||
|
||||
#define MMA8652_INT_SOURCE_DRDY (1 << 0)
|
||||
#define MMA8652_INT_SOURCE_FF_MT (1 << 2)
|
||||
#define MMA8652_INT_SOURCE_PULSE (1 << 3)
|
||||
#define MMA8652_INT_SOURCE_LNDPRT (1 << 4)
|
||||
#define MMA8652_INT_SOURCE_TRANS (1 << 5)
|
||||
#define MMA8652_INT_SOURCE_FIFO (1 << 6)
|
||||
#define MMA8652_INT_SOURCE_ASLP (1 << 7)
|
||||
|
||||
#define MMA8652_XYZ_DATA_CFG_FS_MASK 0x3
|
||||
#define MMA8652_XYZ_DATA_CFG_FS(x) ((uint8_t)(x)&MMA8652_XYZ_DATA_CFG_FS_MASK)
|
||||
#define MMA8652_XYZ_DATA_CFG_HPF_OUT (1 << 4)
|
||||
|
||||
#define MMA8652_HP_FILTER_SEL_MASK 0x03
|
||||
#define MMA8652_HP_FILTER_LPF_EN (1 << 4)
|
||||
#define MMA8652_HP_FILTER_HPF_BYP (1 << 5)
|
||||
|
||||
#define MMA8652_PL_STATUS_BAFRO (1 << 0)
|
||||
#define MMA8652_PL_STATUS_LAPO_MASK 0x6
|
||||
#define MMA8652_PL_STATUS_LAPO_P_UP 0
|
||||
#define MMA8652_PL_STATUS_LAPO_P_DOWN 1
|
||||
#define MMA8652_PL_STATUS_LAPO_L_RIGHT 2
|
||||
#define MMA8652_PL_STATUS_LAPO_L_LEFT 3
|
||||
#define MMA8652_PL_STATUS_LO (1 << 6)
|
||||
#define MMA8652_PL_STATUS_NEWLP (1 << 7)
|
||||
|
||||
#define MMA8652_PL_CFG_PL_EN (1 << 6)
|
||||
#define MMA8652_PL_CFG_DBCNTM (1 << 7)
|
||||
|
||||
#define MMA8652_PL_BF_ZCOMP_ZLOCK_MASK 0x07
|
||||
#define MMA8652_PL_BF_ZCOMP_BKFR_MASK 0xC0
|
||||
|
||||
#define MMA8652_P_L_HYS_MASK 0x07
|
||||
#define MMA8652_P_L_THS_MASK 0xF8
|
||||
|
||||
#define MMA8652_FF_MT_CFG_XEFE (1 << 3)
|
||||
#define MMA8652_FF_MT_CFG_YEFE (1 << 4)
|
||||
#define MMA8652_FF_MT_CFG_ZEFE (1 << 5)
|
||||
#define MMA8652_FF_MT_CFG_OAE (1 << 6)
|
||||
#define MMA8652_FF_MT_CFG_ELE (1 << 7)
|
||||
|
||||
#define MMA8652_FF_MT_SRC_XHP (1 << 0)
|
||||
#define MMA8652_FF_MT_SRC_XHE (1 << 1)
|
||||
#define MMA8652_FF_MT_SRC_YHP (1 << 2)
|
||||
#define MMA8652_FF_MT_SRC_YHE (1 << 3)
|
||||
#define MMA8652_FF_MT_SRC_ZHP (1 << 4)
|
||||
#define MMA8652_FF_MT_SRC_ZHE (1 << 5)
|
||||
#define MMA8652_FF_MT_SRC_EA (1 << 7)
|
||||
|
||||
#define MMA8652_FF_MT_THS_MASK 0x7F
|
||||
#define MMA8652_FF_MT_THS_DBCNTM (1 << 7)
|
||||
|
||||
#define MMA8652_TRANSIENT_CFG_HPF_BYP (1 << 0)
|
||||
#define MMA8652_TRANSIENT_CFG_XTEFE (1 << 1)
|
||||
#define MMA8652_TRANSIENT_CFG_YTEFE (1 << 2)
|
||||
#define MMA8652_TRANSIENT_CFG_ZTEFE (1 << 3)
|
||||
#define MMA8652_TRANSIENT_CFG_ELE (1 << 4)
|
||||
|
||||
#define MMA8652_TRANSIENT_SRC_XTPOL (1 << 0)
|
||||
#define MMA8652_TRANSIENT_SRC_XTEVENT (1 << 1)
|
||||
#define MMA8652_TRANSIENT_SRC_YTPOL (1 << 2)
|
||||
#define MMA8652_TRANSIENT_SRC_YTEVENT (1 << 3)
|
||||
#define MMA8652_TRANSIENT_SRC_ZTPOL (1 << 4)
|
||||
#define MMA8652_TRANSIENT_SRC_ZTEVENT (1 << 5)
|
||||
#define MMA8652_TRANSIENT_SRC_EA (1 << 6)
|
||||
|
||||
#define MMA8652_TRANSIENT_THS_MASK 0x7F
|
||||
#define MMA8652_TRANSIENT_THS_DBCNTM (1<< 7)
|
||||
|
||||
#define MMA8652_PULSE_CFG_XSPEFE (1 << 0)
|
||||
#define MMA8652_PULSE_CFG_XDPEFE (1 << 1)
|
||||
#define MMA8652_PULSE_CFG_YSPEFE (1 << 2)
|
||||
#define MMA8652_PULSE_CFG_YDPEFE (1 << 3)
|
||||
#define MMA8652_PULSE_CFG_ZSPEFE (1 << 4)
|
||||
#define MMA8652_PULSE_CFG_ZDPEFE (1 << 5)
|
||||
#define MMA8652_PULSE_CFG_ELE (1 << 6)
|
||||
#define MMA8652_PULSE_CFG_DPA (1 << 7)
|
||||
|
||||
#define MMA8652_PULSE_SRC_POLX (1 << 0)
|
||||
#define MMA8652_PULSE_SRC_POLY (1 << 1)
|
||||
#define MMA8652_PULSE_SRC_POLZ (1 << 2)
|
||||
#define MMA8652_PULSE_SRC_DPE (1 << 3)
|
||||
#define MMA8652_PULSE_SRC_AXX (1 << 4)
|
||||
#define MMA8652_PULSE_SRC_AXY (1 << 5)
|
||||
#define MMA8652_PULSE_SRC_AXZ (1 << 6)
|
||||
#define MMA8652_PULSE_SRC_EA (1 << 7)
|
||||
|
||||
#define MMA8652_PULSE_THSX_MASK 0x7F
|
||||
#define MMA8652_PULSE_THSY_MASK 0x7F
|
||||
#define MMA8652_PULSE_THSZ_MASK 0x7F
|
||||
|
||||
#define MMA8652_CTRL_REG1_ACTIVE (1 << 0)
|
||||
#define MMA8652_CTRL_REG1_F_READ (1 << 1)
|
||||
#define MMA8652_CTRL_REG1_DR_MASK 0x38
|
||||
#define MMA8652_CTRL_REG1_DR_SHIFT 3
|
||||
#define MMA8652_CTRL_REG1_DR(x) (((uint8_t)(((uint8_t)(x))<<MMA8652_CTRL_REG1_DR_SHIFT))\
|
||||
&MMA8652_CTRL_REG1_DR_MASK)
|
||||
#define MMA8652_CTRL_REG1_ASR_MASK 0xC0
|
||||
#define MMA8652_CTRL_REG1_ASR_50HZ 0
|
||||
#define MMA8652_CTRL_REG1_ASR_12HZ5 1
|
||||
#define MMA8652_CTRL_REG1_ASR_6HZ25 2
|
||||
#define MMA8652_CTRL_REG1_ASR_1HZ56 3
|
||||
|
||||
#define MMA8652_CTRL_REG2_MODS_MASK 0x3
|
||||
#define MMA8652_CTRL_REG2_MODS_NORMAL 0
|
||||
#define MMA8652_CTRL_REG2_MODS_LNLP 1
|
||||
#define MMA8652_CTRL_REG2_MODS_HR 2
|
||||
#define MMA8652_CTRL_REG2_MODS_LP 3
|
||||
#define MMA8652_CTRL_REG2_SLPE (1 << 2)
|
||||
#define MMA8652_CTRL_REG2_SMODS_MASK 0x18
|
||||
#define MMA8652_CTRL_REG2_SMODS_NORMAL 0
|
||||
#define MMA8652_CTRL_REG2_SMODS_LNLP 1
|
||||
#define MMA8652_CTRL_REG2_SMODS_HR 2
|
||||
#define MMA8652_CTRL_REG2_SMODS_LP 3
|
||||
#define MMA8652_CTRL_REG2_RST (1 << 6)
|
||||
#define MMA8652_CTRL_REG2_ST (1 << 7)
|
||||
|
||||
#define MMA8652_CTRL_REG3_PP_OD (1 << 0)
|
||||
#define MMA8652_CTRL_REG3_IPOL (1 << 1)
|
||||
#define MMA8652_CTRL_REG3_WAKE_FF_MT (1 << 3)
|
||||
#define MMA8652_CTRL_REG3_WAKE_PULSE (1 << 4)
|
||||
#define MMA8652_CTRL_REG3_WAKE_LNDPRT (1 << 5)
|
||||
#define MMA8652_CTRL_REG3_WAKE_TRANS (1 << 6)
|
||||
#define MMA8652_CTRL_REG3_FIFO_GATE (1 << 7)
|
||||
|
||||
#define MMA8652_CTRL_REG4_INT_EN_DRDY (1 << 0)
|
||||
#define MMA8652_CTRL_REG4_INT_EN_FF_MT (1 << 2)
|
||||
#define MMA8652_CTRL_REG4_INT_EN_PULSE (1 << 3)
|
||||
#define MMA8652_CTRL_REG4_INT_EN_LNDPRT (1 << 4)
|
||||
#define MMA8652_CTRL_REG4_INT_EN_TRANS (1 << 5)
|
||||
#define MMA8652_CTRL_REG4_INT_EN_FIFO (1 << 6)
|
||||
#define MMA8652_CTRL_REG4_INT_EN_ASLP (1 << 7)
|
||||
|
||||
#define MMA8652_CTRL_REG5_INT_CFG_DRDY (1 << 0)
|
||||
#define MMA8652_CTRL_REG5_INT_CFG_FF_MT (1 << 2)
|
||||
#define MMA8652_CTRL_REG5_INT_CFG_PULSE (1 << 3)
|
||||
#define MMA8652_CTRL_REG5_INT_CFG_LNDPRT (1 << 4)
|
||||
#define MMA8652_CTRL_REG5_INT_CFG_TRANS (1 << 5)
|
||||
#define MMA8652_CTRL_REG5_INT_CFG_FIFO (1 << 6)
|
||||
#define MMA8652_CTRL_REG5_INT_CFG_ASLP (1 << 7)
|
||||
|
||||
/**
|
||||
* @brief Device ID
|
||||
*/
|
||||
#define MMA8652_ID 0x4A
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
/** @} */
|
187
drivers/mma8652/mma8652.c
Normal file
187
drivers/mma8652/mma8652.c
Normal file
@ -0,0 +1,187 @@
|
||||
/*
|
||||
* Copyright (C) 2014 PHYTEC Messtechnik GmbH
|
||||
*
|
||||
* 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_mma8652
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Driver for the Freescale MMA8652 accelerometer.
|
||||
*
|
||||
* @author Johann Fischer <j.fischer@phytec.de>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include "periph/i2c.h"
|
||||
#include "mma8652.h"
|
||||
#include "mma8652_reg.h"
|
||||
|
||||
#define ENABLE_DEBUG (0)
|
||||
#include "debug.h"
|
||||
|
||||
#define I2C_SPEED I2C_SPEED_FAST
|
||||
|
||||
int mma8652_test(mma8652_t *dev)
|
||||
{
|
||||
char reg;
|
||||
|
||||
if (i2c_read_regs(dev->i2c, dev->addr, MMA8652_WHO_AM_I, ®, 1) != 1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (reg != MMA8652_ID) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mma8652_init(mma8652_t *dev, i2c_t i2c, uint8_t address, uint8_t dr, uint8_t range)
|
||||
{
|
||||
char reg;
|
||||
|
||||
/* write device descriptor */
|
||||
dev->i2c = i2c;
|
||||
dev->addr = address;
|
||||
dev->initialized = false;
|
||||
|
||||
if (dr > MMA8652_DATARATE_1HZ56 || range > MMA8652_FS_RANGE_8G) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* initialize the I2C bus */
|
||||
if (i2c_init_master(i2c, I2C_SPEED) < 0) {
|
||||
return -2;
|
||||
}
|
||||
|
||||
if (mma8652_test(dev)) {
|
||||
return -3;
|
||||
}
|
||||
|
||||
reg = MMA8652_XYZ_DATA_CFG_FS(range);
|
||||
|
||||
if (i2c_write_regs(dev->i2c, dev->addr, MMA8652_XYZ_DATA_CFG, ®, 1) != 1) {
|
||||
return -4;
|
||||
}
|
||||
|
||||
reg = MMA8652_CTRL_REG1_DR(dr);
|
||||
|
||||
if (i2c_write_regs(dev->i2c, dev->addr, MMA8652_CTRL_REG1, ®, 1) != 1) {
|
||||
return -4;
|
||||
}
|
||||
|
||||
dev->initialized = true;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mma8652_set_user_offset(mma8652_t *dev, int8_t x, int8_t y, int8_t z)
|
||||
{
|
||||
char buf[3];
|
||||
|
||||
buf[0] = (char)x;
|
||||
buf[1] = (char)y;
|
||||
buf[2] = (char)z;
|
||||
|
||||
if (i2c_write_regs(dev->i2c, dev->addr, MMA8652_OFF_X, buf, 3) != 3) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mma8652_reset(mma8652_t *dev)
|
||||
{
|
||||
char reg;
|
||||
|
||||
dev->initialized = false;
|
||||
reg = MMA8652_CTRL_REG2_RST;
|
||||
|
||||
if (i2c_write_regs(dev->i2c, dev->addr, MMA8652_CTRL_REG2, ®, 1) != 1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mma8652_set_active(mma8652_t *dev)
|
||||
{
|
||||
char reg;
|
||||
|
||||
if (dev->initialized == false) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (i2c_read_regs(dev->i2c, dev->addr, MMA8652_CTRL_REG1, ®, 1) != 1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
reg |= MMA8652_CTRL_REG1_ACTIVE;
|
||||
|
||||
if (i2c_write_regs(dev->i2c, dev->addr, MMA8652_CTRL_REG1, ®, 1) != 1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mma8652_set_standby(mma8652_t *dev)
|
||||
{
|
||||
char reg;
|
||||
|
||||
if (i2c_read_regs(dev->i2c, dev->addr, MMA8652_CTRL_REG1, ®, 1) != 1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
reg &= ~MMA8652_CTRL_REG1_ACTIVE;
|
||||
|
||||
if (i2c_write_regs(dev->i2c, dev->addr, MMA8652_CTRL_REG1, ®, 1) != 1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mma8652_is_ready(mma8652_t *dev)
|
||||
{
|
||||
char reg;
|
||||
|
||||
if (dev->initialized == false) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (i2c_read_regs(dev->i2c, dev->addr, MMA8652_STATUS, ®, 1) != 1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return reg & MMA8652_STATUS_ZYXDR;
|
||||
}
|
||||
|
||||
int mma8652_read(mma8652_t *dev, int16_t *x, int16_t *y, int16_t *z, uint8_t *status)
|
||||
{
|
||||
char buf[7];
|
||||
|
||||
if (dev->initialized == false) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (i2c_read_regs(dev->i2c, dev->addr, MMA8652_STATUS, buf, 7) != 7) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
*status = buf[0];
|
||||
*x = (int16_t)(((int16_t)buf[1] << 8) | buf[2]) / 16;
|
||||
*y = (int16_t)(((int16_t)buf[3] << 8) | buf[4]) / 16;
|
||||
*z = (int16_t)(((int16_t)buf[5] << 8) | buf[6]) / 16;
|
||||
|
||||
return 0;
|
||||
}
|
36
tests/driver_mma8652/Makefile
Normal file
36
tests/driver_mma8652/Makefile
Normal file
@ -0,0 +1,36 @@
|
||||
APPLICATION = driver_mma8652
|
||||
include ../Makefile.tests_common
|
||||
|
||||
FEATURES_REQUIRED = periph_i2c
|
||||
|
||||
USEMODULE += mma8652
|
||||
USEMODULE += vtimer
|
||||
|
||||
ifneq (,$(TEST_MMA8652_I2C))
|
||||
CFLAGS += -DTEST_MMA8652_I2C=$(TEST_MMA8652_I2C)
|
||||
else
|
||||
CFLAGS += -DTEST_MMA8652_I2C=I2C_0
|
||||
endif
|
||||
ifneq (,$(TEST_MMA8652_ADDR))
|
||||
CFLAGS += -DTEST_MMA8652_ADDR=$(TEST_MMA8652_ADDR)
|
||||
else
|
||||
CFLAGS += -DTEST_MMA8652_ADDR=0x1D
|
||||
endif
|
||||
|
||||
ifneq (,$(TEST_MMA8652_USER_OFFSET_X))
|
||||
CFLAGS += -DTEST_MMA8652_USER_OFFSET_X=$(TEST_MMA8652_USER_OFFSET_X)
|
||||
else
|
||||
CFLAGS += -DTEST_MMA8652_USER_OFFSET_X=0
|
||||
endif
|
||||
ifneq (,$(TEST_MMA8652_USER_OFFSET_Y))
|
||||
CFLAGS += -DTEST_MMA8652_USER_OFFSET_Y=$(TEST_MMA8652_USER_OFFSET_Y)
|
||||
else
|
||||
CFLAGS += -DTEST_MMA8652_USER_OFFSET_Y=0
|
||||
endif
|
||||
ifneq (,$(TEST_MMA8652_USER_OFFSET_Z))
|
||||
CFLAGS += -DTEST_MMA8652_USER_OFFSET_Z=$(TEST_MMA8652_USER_OFFSET_Z)
|
||||
else
|
||||
CFLAGS += -DTEST_MMA8652_USER_OFFSET_Z=0
|
||||
endif
|
||||
|
||||
include $(RIOTBASE)/Makefile.include
|
10
tests/driver_mma8652/README.md
Normal file
10
tests/driver_mma8652/README.md
Normal file
@ -0,0 +1,10 @@
|
||||
# About
|
||||
This is a manual test application for the MMA8652 accelerometer driver.
|
||||
|
||||
# Usage
|
||||
This test application will initialize the MMA8652 sensor with the following parameters:
|
||||
- full scale parameter set to +/-2 g
|
||||
- 6.25 Hz output data-rate
|
||||
|
||||
After initialization, the sensor reads the x-, y-, z-axis values every 1 s
|
||||
and prints them to STDOUT.
|
75
tests/driver_mma8652/main.c
Normal file
75
tests/driver_mma8652/main.c
Normal file
@ -0,0 +1,75 @@
|
||||
/*
|
||||
* Copyright (C) 2014 Freie Universität Berlin
|
||||
* Copyright (C) 2014 PHYTEC Messtechnik GmbH
|
||||
*
|
||||
* 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 MMA8652 accelerometer driver.
|
||||
*
|
||||
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
|
||||
* @author Johann Fischer <j.fischer@phytec.de>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifndef TEST_MMA8652_I2C
|
||||
#error "TEST_MMA8652_I2C not defined"
|
||||
#endif
|
||||
#ifndef TEST_MMA8652_ADDR
|
||||
#error "TEST_MMA8652_ADDR not defined"
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "vtimer.h"
|
||||
#include "mma8652.h"
|
||||
|
||||
#define SLEEP (1000 * 1000U)
|
||||
|
||||
int main(void)
|
||||
{
|
||||
mma8652_t dev;
|
||||
int16_t x, y, z;
|
||||
uint8_t status;
|
||||
|
||||
puts("MMA8652 accelerometer driver test application\n");
|
||||
printf("Initializing MMA8652 accelerometer at I2C_%i... ", TEST_MMA8652_I2C);
|
||||
|
||||
if (mma8652_init(&dev, TEST_MMA8652_I2C, TEST_MMA8652_ADDR,
|
||||
MMA8652_DATARATE_DEFAULT,
|
||||
MMA8652_FS_RANGE_DEFAULT) == 0) {
|
||||
puts("[OK]\n");
|
||||
}
|
||||
else {
|
||||
puts("[Failed]");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (mma8652_set_user_offset(&dev, TEST_MMA8652_USER_OFFSET_X,
|
||||
TEST_MMA8652_USER_OFFSET_Y,
|
||||
TEST_MMA8652_USER_OFFSET_Z)) {
|
||||
puts("Set user offset correction failed.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (mma8652_set_active(&dev)) {
|
||||
puts("Measurement start failed.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
while (1) {
|
||||
mma8652_read(&dev, &x, &y, &z, &status);
|
||||
printf("Acceleration, raw: X: %d Y: %d Z: %d S: %2x\n", x, y, z, status);
|
||||
vtimer_usleep(SLEEP);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue
Block a user