BMD-200 Evaluation board using the on-board accelerometer (Freescale MMA8653FC). There a couple operating modes (streaming ADC data out the USB COM, moving board in a single axis causes an interrupt, others). Work in progress.

Dependencies:   PinDetect mbed-src-bmd-200

Files at this revision

API Documentation at this revision

Comitter:
dcnichols
Date:
Wed Jul 15 21:25:42 2015 +0000
Commit message:
initial check in

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
PinDetect.lib Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
mbed-src-bmd-200.lib 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	Wed Jul 15 21:25:42 2015 +0000
@@ -0,0 +1,379 @@
+/**
+ * @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"
+#include "mbed.h"
+ 
+
+void MMA845x::disable(void)
+{
+    uint8_t reg_val = 0;
+    // Reset all registers to POR values
+    MMA845x::writeRegister(CTRL_REG2, 0xF0);        //REG 0x2B
+    wait(0.05);
+    do{
+        // wait for the reset bit to clear
+        reg_val = MMA845x::readRegister(CTRL_REG2) & 0x40;
+    }while(reg_val);
+    MMA845x::writeRegister(CTRL_REG1, 0x00);        //REG 0x2A 0x98 = ASLP_RATE: 6.25hz Data Rate: 50hz
+}
+
+void MMA845x::setIntMode(int intMode)
+{
+    _intMode = intMode;
+}
+
+void MMA845x::interrupt_1(void)
+{
+    //_int1_waiting = true;
+    
+    uint8_t reg_int_sts;
+    uint8_t reg_sts;
+    uint8_t reg_pulse_sts;
+    uint8_t reg_motion_sts;
+    char reg_data[3][2] = { 0 };
+    int16_t values[3] = { 0 };
+    float g_values[3] = { 0 };
+    reg_int_sts = MMA845x::readRegister(INT_SOURCE);    //REG 0x0C
+    if((reg_int_sts & 0x01)) //Mask register read with SRC_DRDY bit
+    {
+        printf("Int1:");
+        printf(" Data Ready");
+        reg_sts = MMA845x::readRegister(STATUS);    //REG 0x00
+        
+        reg_pulse_sts = MMA845x::readRegister(PULSE_SRC);    //REG 0x22
+        
+        reg_data[0][0] = MMA845x::readRegister(OUT_X_MSB);    //REG 0x01
+        reg_data[0][1] = MMA845x::readRegister(OUT_X_LSB);    //REG 0x02
+        reg_data[1][0] = MMA845x::readRegister(OUT_Y_MSB);    //REG 0x03
+        reg_data[1][1] = MMA845x::readRegister(OUT_Y_LSB);    //REG 0x04
+        reg_data[2][0] = MMA845x::readRegister(OUT_Z_MSB);    //REG 0x05
+        reg_data[2][1] = MMA845x::readRegister(OUT_Z_LSB);    //REG 0x06
+        //printf(" STATUS: 0x%02X X: %d %d Y: %d %d Z: %d %d\n\r", reg_sts, reg_data[0][0], reg_data[0][1], reg_data[1][0], reg_data[1][1], reg_data[2][0], reg_data[2][1]);
+            
+        values[0] = ((reg_data[0][0] * 256) + ((unsigned short) reg_data[0][1]));
+        values[1] = ((reg_data[1][0] * 256) + ((unsigned short) reg_data[1][1]));
+        values[2] = ((reg_data[2][0] * 256) + ((unsigned short) reg_data[2][1]));
+    
+        g_values[0] = ((float) values[0]) / 16384.0;
+        g_values[1] = ((float) values[1]) / 16384.0;
+        g_values[2] = ((float) values[2]) / 16384.0;
+            
+        //printf(" STATUS: 0x%02X X: %d Y: %d Z: %d\n\r", reg_sts, values[0], values[1], values[2]); 
+        
+        if (_intMode == 1)
+        {
+            printf(" STATUS: 0x%02X X: %.3f Y: %.3f Z: %.3f", reg_sts, g_values[0], g_values[1], g_values[2]);
+        }
+        else
+        {
+            int bars = abs( values[0] / 512 );
+            printf(" X: ");
+            for( int i = 0; i < bars; i++ )
+            {
+                printf(">");
+            }
+        }
+        
+        if (reg_pulse_sts & 0x10)
+        {
+            printf(" ***********************************************");
+            _callbackZAxisPulse.call();
+            if (reg_pulse_sts & 0x01)
+            {
+                printf("--------------");    
+            }
+        }
+        printf("\n\r");
+    }
+    if (reg_int_sts & 0x08) //Pulse interrupt
+    {
+        
+        reg_pulse_sts = MMA845x::readRegister(PULSE_SRC);    //REG 0x22
+        if (reg_pulse_sts & 0x40) //Z-axis event
+        {
+            
+            if (reg_pulse_sts & 0x08) //Pulse event was double pulse
+            {
+                
+                
+            }
+            if (reg_pulse_sts & 0x04)//Z-axis pulse direction
+            {
+                
+            }
+            _callbackZAxisPulse.call();
+            
+        }
+    }
+    if (reg_int_sts & 0x04) //Motion interrupt
+    {
+        
+        reg_motion_sts = MMA845x::readRegister(FF_MT_SRC);    //REG 0x16
+        if (reg_motion_sts & 0x02) //
+        {
+            /*
+            if (reg_motion_sts & 0x08) //
+            {
+                
+                
+            }
+            if (reg_motion_sts & 0x04)//
+            {
+                
+            }
+            */
+            _callbackZAxisPulse.call();
+            
+        }
+    }
+}
+
+     /* Call this function when a Z-axis pulse detected
+     *  @param function A C function pointer
+     */
+void MMA845x::attachZAxisPulse( void (*function)(void) )
+{
+    _callbackZAxisPulse.attach( function );
+}
+    
+void MMA845x::interrupt_handler(void)
+{
+    
+    uint8_t reg_int_sts;
+    uint8_t reg_sts;
+    int reg_data[3] = { 0x00, 0x00, 0x00 };
+    printf("Int1:");
+    reg_int_sts = MMA845x::readRegister(INT_SOURCE);    //REG 0x0C
+    if((reg_int_sts & 0x01)) //Mask register read with SRC_DRDY bit
+    {
+        printf(" Data Ready");
+        reg_sts = MMA845x::readRegister(STATUS);    //REG 0x00
+        reg_data[0] = MMA845x::readRegister(OUT_X_MSB);    //REG 0x01
+        reg_data[1] = MMA845x::readRegister(OUT_Y_MSB);    //REG 0x03
+        reg_data[2] = MMA845x::readRegister(OUT_Z_MSB);    //REG 0x05
+        printf(" STATUS: 0x%02X X: %d Y: %d Z: %d\n\r", reg_sts, reg_data[0], reg_data[1], reg_data[2]);
+    }
+}
+
+void MMA845x::init(void) const
+{
+    uint8_t reg_val = 0;
+    
+    _i2c->frequency(400000);
+    
+    // Reset all registers to POR values
+    MMA845x::writeRegister(CTRL_REG2, 0x40);        //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, 0xA0);        //REG 0x2A 0x98 = ASLP_RATE: 6.25hz Data Rate: 50hz
+    MMA845x::writeRegister(CTRL_REG2, 0x18);        //REG 0x2B Setup for low-power, no auto-sleep
+    MMA845x::writeRegister(CTRL_REG3, 0x00);        //REG 0x2C No interrupts wake device, active low int, push-pull
+    MMA845x::writeRegister(CTRL_REG4, 0x00);        //REG 0x2D
+    MMA845x::writeRegister(CTRL_REG5, 0xFD);        //REG 0x2E All interrupt sources to INT1
+    
+    MMA845x::writeRegister(XYZ_DATA_CFG, 0x11);      //REG 0x0E HPF / scale +/-2,4,8g
+    MMA845x::writeRegister(HP_FILTER_CUTOFF, 0x00);  //REG 0x0F HPF settings
+    
+    return;
+}
+
+void MMA845x::enableDataReadyMode(void) const
+{
+    MMA845x::init();
+    //MMA845x::writeRegister(SYSMOD, 0x01);        //REG 0x0B This register is read only
+    //MMA845x::writeRegister(INT_SOURCE, 0x01);    //REG 0x0C This register is read only
+    MMA845x::writeRegister(CTRL_REG4, 0x09);        //REG 0x2D Enable data ready interrupt
+    
+    
+    
+    //MMA845x::writeRegister(CTRL_REG1, 0xA3);        //REG 0x2A 0xA3 = ASLP_RATE: 6.25hz Data Rate: 50hz, Fast Read, Active mode
+    
+    MMA845x::writeRegister(XYZ_DATA_CFG, 0x11);      //REG 0x0E HPF / scale +/-2,4,8g - Enable HPF
+    MMA845x::writeRegister(HP_FILTER_CUTOFF, 0x10);  //REG 0x0F HPF settings - HPF for pulse on, 0.25Hz cutoff for 12.5rate
+    
+    
+    MMA845x::writeRegister(PULSE_CFG, 0x41);        //REG 0x21 Setup single pulse in x axis
+    MMA845x::writeRegister(PULSE_THSX, 0x09);        //REG 0x21 Setup pulse threshold in x axis
+    MMA845x::writeRegister(PULSE_TMLT, 0x14);        //REG 0x21 Setup single pulse in x axis
+    MMA845x::writeRegister(PULSE_LTCY, 0x04);        //REG 0x21 Setup single latency in x axis
+    
+    
+    MMA845x::writeRegister(CTRL_REG1, 0xA1);        //REG 0x2A 0x98 = ASLP_RATE: 6.25hz Data Rate: 12.5hz, Normal Read, Active mode
+    
+}
+
+void MMA845x::enableMotionMode(void) const
+{
+    MMA845x::init();
+    
+    MMA845x::writeRegister(CTRL_REG4, 0x04);        //REG 0x2D Enable pulse interrupt
+        
+    MMA845x::writeRegister(XYZ_DATA_CFG, 0xF1);      //REG 0x0E HPF / scale +/-4g, Enable HPF for output data
+    MMA845x::writeRegister(HP_FILTER_CUTOFF, 0x00);  //REG 0x0F HPF settings - HPF for pulse on, 4Hz cutoff for 100Hz rate
+    
+    MMA845x::writeRegister(FF_MT_CFG, 0xC8);        //REG 0x21 Setup 
+    MMA845x::writeRegister(FF_MT_THS, 0x01);        //REG 0x21 Setup 
+    MMA845x::writeRegister(FF_MT_COUNT, 0x5);        //REG 0x21 Setup 
+    
+    MMA845x::writeRegister(CTRL_REG2, 0x03);        //REG 0x2B Setup for low power mode, no auto-sleep
+    MMA845x::writeRegister(CTRL_REG1, 0xA1);        //REG 0x2A 0x98 = ASLP_RATE: 6.25hz Data Rate: 12.5Hz, Normal Read, Active mode
+    
+}
+
+void MMA845x::enablePulseMode(void) const
+{
+    MMA845x::init();
+    
+    MMA845x::writeRegister(CTRL_REG4, 0x08);        //REG 0x2D Enable pulse interrupt
+        
+    MMA845x::writeRegister(XYZ_DATA_CFG, 0xF1);      //REG 0x0E HPF / scale +/-2,4,8g - Enable HPF
+    MMA845x::writeRegister(HP_FILTER_CUTOFF, 0x00);  //REG 0x0F HPF settings - HPF for pulse on, 4Hz cutoff for 100Hz rate
+    
+    MMA845x::writeRegister(PULSE_CFG, 0x50);        //REG 0x21 Setup single pulse in z axis
+    MMA845x::writeRegister(PULSE_THSX, 0x06);        //REG 0x21 Setup pulse threshold in x axis
+    MMA845x::writeRegister(PULSE_THSZ, 0x2F);        //REG 0x21 Setup pulse threshold in z axis
+    MMA845x::writeRegister(PULSE_TMLT, 0x28);        //REG 0x21 Setup single pulse
+    MMA845x::writeRegister(PULSE_LTCY, 0x0D);        //REG 0x21 Setup single latency
+    MMA845x::writeRegister(PULSE_WIND, 0x2D);        //REG 0x21 Setup double pulse window
+    
+    MMA845x::writeRegister(CTRL_REG2, 0x00);        //REG 0x2B Setup for normal power mode, no auto-sleep
+    MMA845x::writeRegister(CTRL_REG1, 0x99);        //REG 0x2A 0x98 = ASLP_RATE: 6.25hz Data Rate: 100Hz, Normal Read, Active mode
+    
+}
+
+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 devices
+    result = _i2c->write(_i2c_addr, buf, 2);
+    __enable_irq();  // Just need to block during the transaction
+    */
+
+    result = _i2c->write(_i2c_addr, (const char *)&buf, 2, false);
+    
+    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
+    */
+    
+    result &= _i2c->write(_i2c_addr, (const char *)&reg, 1, true);
+    result &= _i2c->read(_i2c_addr, (char *)&data, 1);
+    
+    if(1 != result)
+    {
+        //error("%s %d: I2C read failed\n", __FILE__, __LINE__);
+    }
+    
+    return data;
+}
+
+void MMA845x::registerDump(void) const
+{
+    uint8_t reg_val = 0;
+    printf("Starting register dump...\n\r");
+    
+    for(int i=0; i<0x31; i++)
+    {
+        reg_val = MMA845x::readRegister(i);
+        printf("Reg 0x%02x: 0x%02x \n\r", i, reg_val);
+    }
+    
+    return;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MMA845x.h	Wed Jul 15 21:25:42 2015 +0000
@@ -0,0 +1,244 @@
+/**
+ * @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 */
+        MMA8652 = 0x4a, /*!< MMA8652 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, PinName p_int1, PinName p_int2, MMA845x_SA0 const i2c_addr) : _int1(p_int1), _int2(p_int2)
+    //MMA845x(I2C &i2c, InterruptIn int1, InterruptIn int2, MMA845x_SA0 const i2c_addr)
+    {
+        _i2c = &i2c;
+    
+        _i2c_addr = (0x1d << 1) | i2c_addr;
+        
+        _int1_waiting = false;
+        _intMode = 0;
+        
+        _int1.fall(this, &MMA845x::interrupt_1);
+        _int1.mode(PullUp);
+    };
+    
+    /** 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;
+    
+    /** Set display mode of interrupt
+     *  @return The last valid reading from the accelerometer
+     */
+    void setIntMode(int);
+    void attachZAxisPulse(void (*function)(void));
+    void interrupt_1(void);
+    void interrupt_handler(void);
+    
+private:
+    
+    I2C             *_i2c;
+    InterruptIn     _int1;
+    InterruptIn     _int2;
+    uint8_t         _i2c_addr;
+    MMA845x_DATA    _data;
+    bool            _int1_waiting;
+    int             _intMode;
+    FunctionPointer _callbackZAxisPulse;
+    
+    void init(void) const;
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/PinDetect.lib	Wed Jul 15 21:25:42 2015 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/AjK/code/PinDetect/#cb3afc45028b
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Wed Jul 15 21:25:42 2015 +0000
@@ -0,0 +1,174 @@
+#include "MMA845x.h"
+#include "PinDetect.h"
+#include "mbed.h"
+ 
+Serial pc(USBTX, USBRX);
+
+I2C accel(I2C_SDA0, I2C_SCL0);
+
+AnalogIn ambientLight(p6);
+
+PinDetect  user_btn_1 ( p11, PullUp );
+PinDetect  user_btn_2 ( p0,  PullUp );
+
+//InterruptIn int2(p0);
+
+//InterruptIn user_btn_1(p11);
+
+PwmOut ledR(LED1);
+PwmOut ledG(LED3);
+PwmOut ledB(LED2);
+
+int accel_int_mode = 0;
+int opMode = 0;
+int opModeMax = 3;
+
+
+//MMA845x(I2C &i2c, InterruptIn &int1, InterruptIn &int2, MMA845x_SA0 const i2c_addr);
+MMA845x accel_0(accel, p4, p23, MMA845x::SA0_VSS);
+//MMA845x accel_0(accel, int1, int2, MMA845x::SA0_VSS);
+
+#ifdef USE_EEPROM
+SPI spi1(SPI_PSELMOSI1, SPI_PSELMISO1, SPI_PSELSCK1);
+DigitalOut spi_cs(SPI_PSELSS1);
+#endif
+
+void toggleLED(PwmOut *led)
+{
+    if (led->read() < 0.001)
+    {
+        printf("led on");
+        led->write(.2);
+    }
+    else
+    {
+        printf("led off, %f",led->read());
+        led->write(0);
+    }
+}
+
+void btn_1_press(void)
+{
+    if (++opMode == opModeMax) {opMode = 0;}
+    printf("OpMode = %d\n\r",opMode);
+    switch ( opMode )
+    {
+        case 0:
+            accel_0.disable();
+            ledR = 0.2;
+            ledG = 0;
+            ledB = 0;
+            
+            break;
+        case 1:
+            ledR = 0;
+            ledG = 0.2;
+            ledB = 0;
+            accel_0.enablePulseMode();
+            break;
+        default:
+            ledR = 0;
+            ledG = 0;
+            ledB = 0.2;
+            accel_0.enableDataReadyMode();
+            break;
+    }
+}
+
+void btn_2_press(void)
+{
+    //ledR = !ledR;
+    //printf("Button 2 Pressed!\n\r");
+    switch ( opMode )
+    {
+        case 0:
+            break;
+        case 2:
+            if (accel_int_mode == 0)
+            {
+                accel_int_mode = 1;
+            }
+            else
+            {
+                accel_int_mode = 0;
+            }
+            accel_0.setIntMode(accel_int_mode);
+            break;
+        default:
+            break;
+            //do nothing
+    }
+}
+
+void zTap(void)
+{       
+    switch ( opMode )
+    {
+        case 0:
+            break;
+        case 1:
+            toggleLED(&ledB);  
+            break;
+        default:
+            toggleLED(&ledG);  
+            break;
+    }
+      
+}
+void SysTick_Handler (void)
+{
+    toggleLED(&ledB); 
+}
+
+int main()
+{
+    pc.baud(115200);
+    //int readings[3] = {0, 0, 0};
+    ledR.period_ms(10);
+    ledG.period_ms(10);
+    ledB.period_ms(10);
+    
+    ledR = .1;
+    ledG = .1;
+    ledB = .1;
+    
+    
+    //SysTick_Config(1000);
+    //SysTick_Enable();
+    //systick.attach_us(&systimer, 2500);
+    
+    user_btn_1.setAssertValue( 0 );
+    user_btn_2.setAssertValue( 0 );
+    user_btn_1.attach_asserted( &btn_1_press );
+    //user_btn_1.mode( PullUp );
+    //user_btn_1.rise( &btn_1_press );
+    user_btn_2.attach_asserted( &btn_2_press );
+    user_btn_1.setSampleFrequency( 20000 ); 
+    user_btn_2.setSampleFrequency( 20000 ); // Defaults to 20ms.
+    
+    accel_0.attachZAxisPulse( &zTap );
+    
+    //int adr = 0x3A;
+    char data[2];
+    char cmd = 0x0D;
+    accel.write(0x3A, &cmd, 1, true);
+    accel.read(0x3A, &data[0], 1);
+    printf("\n\r\n\rWho am I?: 0x%.2X\n\r",data[0]);
+    
+    //accel_0.enableMotionMode();
+    //accel_0.registerDump();
+    accel_0.enableDataReadyMode();
+    
+    
+    //--------------------
+    //int x = accel_0.getX();
+    //int y = accel_0.getY();
+    //int z = accel_0.getZ();
+    //printf("X: %d, Y: %d, Z: %d\n\r", x , y, z);
+    
+
+    while (1) {
+        sleep();
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed-src-bmd-200.lib	Wed Jul 15 21:25:42 2015 +0000
@@ -0,0 +1,1 @@
+http://developer.mbed.org/teams/Rigado/code/mbed-src-bmd-200/#5e2eb8beba71