Class Module for MMA845x I2C Accelerometer.
Dependents: mDotEVBM2X MTDOT-EVBDemo-DRH MTDOT-BOX-EVB-Factory-Firmware-LIB-108 MTDOT-UDKDemo_Senet ... more
Fork of MMA845x by
Revision 0:9d1e3a344e4f, committed 2013-03-29
- Comitter:
- sam_grove
- Date:
- Fri Mar 29 21:51:11 2013 +0000
- Child:
- 1:41af2b3eefb5
- Commit message:
- Work in progress
Changed in this revision
| MMA845x.cpp | Show annotated file Show diff for this revision Revisions of this file |
| MMA845x.h | Show annotated file Show diff for this revision Revisions of this file |
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/MMA845x.cpp Fri Mar 29 21:51:11 2013 +0000
@@ -0,0 +1,174 @@
+/**
+ * @file MMA845x.cpp
+ * @brief Device driver - MMA845X 3-axis accelerometer IC
+ * @author sam grove
+ * @version 1.0
+ * @see http://cache.freescale.com/files/sensors/doc/data_sheet/MMA8451Q.pdf
+ * @see http://cache.freescale.com/files/sensors/doc/data_sheet/MMA8452Q.pdf
+ * @see http://cache.freescale.com/files/sensors/doc/data_sheet/MMA8453Q.pdf
+ *
+ * Copyright (c) 2013
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "MMA845x.h"
+
+MMA845x::MMA845x(I2C &i2c, InterruptIn &int1, InterruptIn &int2, MMA845x_SA0 const i2c_addr)
+{
+ _i2c = &i2c;
+ _int1 = &int1;
+ _int2 = &int2;
+
+ _i2c_addr = (0x1c << 2) | (i2c_addr << 0x1);
+
+ return;
+}
+
+void MMA845x::init(void) const
+{
+ uint8_t reg_val = 0;
+
+ _i2c->frequency(400000);
+
+ // Reset all registers to POR values
+ MMA845x::writeRegister(CTRL_REG2, 0xFF); //REG 0x2B
+ do{
+ // wait for the reset bit to clear
+ reg_val = MMA845x::readRegister(CTRL_REG2) & 0x40;
+ }while(reg_val);
+
+ // setup the registers that are common among modes
+ MMA845x::writeRegister(CTRL_REG1, 0xd8); //REG 0x2A
+ MMA845x::writeRegister(CTRL_REG2, 0x00); //REG 0x2B
+ MMA845x::writeRegister(CTRL_REG3, 0x00); //REG 0x2C
+
+ MMA845x::writeRegister(XYZ_DATA_CFG, 0x0); //REG 0xE HPF / scale +/-2,4,8g
+ MMA845x::writeRegister(HP_FILTER_CUTOFF, 0x0); //REG 0xF HPF settings
+
+ return;
+}
+
+void MMA845x::enableDataReadyMode(void) const
+{
+ MMA845x::init();
+ MMA845x::writeRegister(SYSMOD, 0x1); //REG 0x0B
+ MMA845x::writeRegister(INT_SOURCE, 0x1); //REG 0x0C
+ // need to finish up these config registers..... 3/8/13
+
+}
+
+void MMA845x::enableMotionMode(void) const{}
+void MMA845x::enablePulseMode(void) const{}
+
+void MMA845x::enableOrientationMode(void) const
+{
+ uint16_t who_am_i = MMA845x::readRegister(WHO_AM_I);
+ if(who_am_i != MMA8451)
+ {
+ error("%s %d: Feature not compatible with the connected device.\n", __FILE__, __LINE__);
+ }
+
+ return;
+}
+
+void MMA845x::enableTransitMode(void) const{}
+void MMA845x::enableAutoSleepMode(void) const{}
+
+void MMA845x::enableFIFOMode(void) const
+{
+ uint16_t who_am_i = MMA845x::readRegister(WHO_AM_I);
+ if(who_am_i != MMA8451)
+ {
+ error("%s %d: Feature not compatible with the connected device.\n", __FILE__, __LINE__);
+ }
+
+ //MMA845x::writeRegister(
+
+ return;
+}
+
+uint16_t MMA845x::getX(void) const
+{
+ return _data._x;
+}
+
+uint16_t MMA845x::getY(void) const
+{
+ return _data._y;
+}
+
+uint16_t MMA845x::getZ(void) const
+{
+ return _data._z;
+}
+
+MMA845x_DATA MMA845x::getXYZ(void) const
+{
+ return _data;
+}
+
+void MMA845x::writeRegister(uint8_t const reg, uint8_t const data) const
+{
+ char buf[2] = {reg, data};
+ uint8_t result = 0;
+
+ __disable_irq(); // Tickers and other timebase events can jack up the I2C bus for some deicse
+ result = _i2c->write(_i2c_addr, buf, 2);
+ __enable_irq(); // Just need to block during the transaction
+
+ if(0 != result)
+ {
+ error("%s %d: I2c write failed\n", __FILE__, __LINE__);
+ }
+
+ return;
+}
+
+uint8_t MMA845x::readRegister(uint8_t const reg) const
+{
+ uint8_t result = 1, data = 0;
+
+ __disable_irq(); // Tickers and other timebase events can jack up the I2C bus
+ _i2c->start();
+ result &= _i2c->write(_i2c_addr);
+ result &= _i2c->write(reg);
+ // issue a repeated start...
+ _i2c->start();
+ result &= _i2c->write(_i2c_addr | 0x01);
+ // read with nak
+ data = _i2c->read(0);
+ _i2c->stop();
+ __enable_irq(); // Just need to block during the transaction
+
+ if(1 != result)
+ {
+ error("%s %d: I2C read failed\n", __FILE__, __LINE__);
+ }
+
+ return data;
+}
+
+void MMA845x::registerDump(void) const
+{
+ uint8_t reg_val = 0;
+
+ for(int i=0; i<0x80; i++)
+ {
+ reg_val = MMA845x::readRegister(i);
+ printf("Reg 0x%02x: 0x%02x \n", i, reg_val);
+ }
+
+ return;
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/MMA845x.h Fri Mar 29 21:51:11 2013 +0000
@@ -0,0 +1,221 @@
+/**
+ * @file MMA845x.h
+ * @brief Device driver - MMA845x 3-axis accelerometer IC
+ * @author sam grove
+ * @version 1.0
+ * @see http://cache.freescale.com/files/sensors/doc/data_sheet/MMA8451Q.pdf
+ * @see http://cache.freescale.com/files/sensors/doc/data_sheet/MMA8452Q.pdf
+ * @see http://cache.freescale.com/files/sensors/doc/data_sheet/MMA8453Q.pdf
+ *
+ * Copyright (c) 2013
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef MMA845X_H
+#define MMA845X_H
+
+#include "mbed.h"
+
+/** Using the Sparkfun SEN-10955
+ *
+ * Example:
+ * @code
+ * #include "mbed.h"
+ * #include "MMA845x.h"
+ *
+
+ *
+ * int main()
+ * {
+
+ * }
+ * @endcode
+ */
+
+
+/**
+ * @class MMA845x_DATA
+ * @brief API abstraction for the MMA845x 3-axis accelerometer IC data
+ */
+class MMA845x_DATA
+{
+public:
+
+ volatile uint16_t _x; /*!< volatile data variable */
+ volatile uint16_t _y; /*!< volatile data variable */
+ volatile uint16_t _z; /*!< volatile data variable */
+
+ /** Create the MMA845x_DATA object initialized to the parameter (or 0 if none)
+ * @param x - the init value of _x
+ * @param y - the init value of _y
+ * @param x - the init value of _z
+ */
+ MMA845x_DATA(uint16_t x = 0, uint16_t y = 0, uint16_t z = 0) : _x(x), _y(y), _z(z) {}
+
+ /** Overloaded '=' operator to allow shorthand coding, assigning objects to one another
+ * @param rhs - an object of the same type to assign ourself the same values of
+ * @return this
+ */
+ MMA845x_DATA &operator= (MMA845x_DATA const &rhs)
+ {
+ _x = rhs._x;
+ _y = rhs._y;
+ _z = rhs._z;
+
+ return *this;
+ }
+
+ /** Overloaded '=' operator to allow shorthand coding, assigning objects to one another
+ * @param val - Assign each data member (_x, _y, _z) this value
+ * @return this
+ */
+ MMA845x_DATA &operator= (uint16_t const val)
+ {
+ _x = _y = _z = val;
+
+ return *this;
+ }
+
+ /** Overloaded '==' operator to allow shorthand coding, test objects to one another
+ * @param rhs - the object to compare against
+ * @return 1 if the data members are the same and 0 otherwise
+ */
+ bool operator== (MMA845x_DATA const &rhs) const
+ {
+ return ((_x == rhs._x)&&(_y == rhs._y)&&(_z == rhs._z)) ? 1 : 0;
+ }
+
+};
+
+/**
+ * @class MMA845x
+ * @brief API abstraction for the MMA845x 3-axis accelerometer IC
+ */
+class MMA845x
+{
+public:
+
+ /**
+ * @enum MMA845x_SA0
+ * @brief Possible terminations for the ADDR pin
+ */
+ enum MMA845x_SA0
+ {
+ SA0_VSS = 0, /*!< SA0 connected to VSS */
+ SA0_VDD /*!< SA0 connected to VDD */
+ };
+
+ /**
+ * @enum MMA845x_WHO_AM_I
+ * @brief Device ID's that this class is compatible with
+ */
+ enum MMA845x_WHO_AM_I
+ {
+ MMA8451 = 0x1a, /*!< MMA8451 WHO_AM_I register content */
+ MMA8452 = 0x2a, /*!< MMA8452 WHO_AM_I register content */
+ MMA8453 = 0x3a, /*!< MMA8453 WHO_AM_I register content */
+ };
+
+ /**
+ * @enum MMA845x_REGISTER
+ * @brief The device register map
+ */
+ enum MMA845x_REGISTER
+ {
+ STATUS = 0x0,
+ OUT_X_MSB, OUT_X_LSB, OUT_Y_MSB, OUT_Y_LSB, OUT_Z_MSB, OUT_Z_LSB,
+
+ F_SETUP = 0x9, TRIG_CFG, // only available on the MMA8451 variant
+
+ SYSMOD = 0xb,
+ INT_SOURCE, WHO_AM_I, XYZ_DATA_CFG, HP_FILTER_CUTOFF, PL_STATUS,
+ PL_CFG, PL_COUNT, PL_BF_ZCOMP, P_L_THS_REG, FF_MT_CFG, FF_MT_SRC,
+ FF_MT_THS, FF_MT_COUNT,
+
+ TRANSIENT_CFG = 0x1d,
+ TRANSIENT_SRC, TRANSIENT_THS, TRANSIENT_COUNT, PULSE_CFG, PULSE_SRC,
+ PULSE_THSX, PULSE_THSY, PULSE_THSZ, PULSE_TMLT, PULSE_LTCY, PULSE_WIND,
+ ASLP_COUNT, CTRL_REG1, CTRL_REG2, CTRL_REG3, CTRL_REG4, CTRL_REG5,
+ OFF_X, OFF_Y, OFF_Z
+ };
+
+ /** Create the MMA845x object
+ * @param i2c - A defined I2C object
+ * @param int1 - A defined InterruptIn object
+ * @param int2 - A defined InterruptIn object
+ * @param i2c_addr - Connection of the address line
+ */
+ MMA845x(I2C &i2c, InterruptIn &int1, InterruptIn &int2, MMA845x_SA0 const i2c_addr);
+
+ /** Get the X data
+ * @return The last valid reading from the accelerometer
+ */
+ uint16_t getX(void) const;
+
+ /** Get the Y data
+ * @return The last valid reading from the accelerometer
+ */
+ uint16_t getY(void) const;
+
+ /** Get the Z data
+ * @return The last valid reading from the accelerometer
+ */
+ uint16_t getZ(void) const;
+
+ /** Get the XYZ data structure
+ * @return The last valid reading from the accelerometer
+ */
+ MMA845x_DATA getXYZ(void) const;
+
+ void enableDataReadyMode(void) const;
+ void enableMotionMode(void) const;
+ void enablePulseMode(void) const;
+ void enableOrientationMode(void) const;
+ void enableTransitMode(void) const;
+ void enableAutoSleepMode(void) const;
+ void enableFIFOMode(void) const;
+
+ /** Put the MMA845x in the lowest possible power mode and suspend operation
+ */
+ void disable(void);
+
+ /** Write to a register (exposed for debugging reasons)
+ * Note: most writes are only valid in stop mode
+ * @param reg - The register to be written
+ * @param data - The data to be written
+ */
+ void writeRegister(uint8_t const reg, uint8_t const data) const;
+
+ /** Read from a register (exposed for debugging reasons)
+ * @param reg - The register to read from
+ * @return The register contents
+ */
+ uint8_t readRegister(uint8_t const reg) const;
+
+ /** print the register map and values to the console
+ */
+ void registerDump(void) const;
+
+private:
+
+ I2C *_i2c;
+ InterruptIn *_int1;
+ InterruptIn *_int2;
+ uint8_t _i2c_addr;
+ MMA845x_DATA _data;
+
+ void init(void) const;
+};
+
+#endif
