Device driver for the Freescale MMA845x family of accelerometers.

Dependents:   MMA845x_test KL05_accel-test

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers MMA845x.cpp Source File

MMA845x.cpp

Go to the documentation of this file.
00001 /**
00002  * @file    MMA845x.cpp
00003  * @brief   Device driver - MMA845X 3-axis accelerometer IC
00004  * @author  sam grove
00005  * @version 1.0
00006  * @see     http://cache.freescale.com/files/sensors/doc/data_sheet/MMA8451Q.pdf
00007  * @see     http://cache.freescale.com/files/sensors/doc/data_sheet/MMA8452Q.pdf
00008  * @see     http://cache.freescale.com/files/sensors/doc/data_sheet/MMA8453Q.pdf
00009  *
00010  * Copyright (c) 2013
00011  *
00012  * Licensed under the Apache License, Version 2.0 (the "License");
00013  * you may not use this file except in compliance with the License.
00014  * You may obtain a copy of the License at
00015  *
00016  *     http://www.apache.org/licenses/LICENSE-2.0
00017  *
00018  * Unless required by applicable law or agreed to in writing, software
00019  * distributed under the License is distributed on an "AS IS" BASIS,
00020  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00021  * See the License for the specific language governing permissions and
00022  * limitations under the License.
00023  */
00024  
00025 #include "MMA845x.h"
00026  
00027 MMA845x::MMA845x(I2C &i2c, InterruptIn &int1, InterruptIn &int2, MMA845x_SA0 const i2c_addr)
00028 {
00029     _i2c =  &i2c;
00030     _int1 = &int1;
00031     _int2 = &int2;
00032     
00033     _i2c_addr = (0x1c << 2) | (i2c_addr << 0x1);
00034  
00035     return;
00036 }
00037 
00038 void MMA845x::init(void) const
00039 {
00040     uint8_t reg_val = 0;
00041     
00042     _i2c->frequency(400000);
00043     
00044     // Reset all registers to POR values
00045     MMA845x::writeRegister(CTRL_REG2, 0xFF);        //REG 0x2B
00046     do{
00047         // wait for the reset bit to clear
00048         reg_val = MMA845x::readRegister(CTRL_REG2) & 0x40;
00049     }while(reg_val);
00050     
00051     // setup the registers that are common among modes
00052     MMA845x::writeRegister(CTRL_REG1, 0xd8);        //REG 0x2A
00053     MMA845x::writeRegister(CTRL_REG2, 0x00);        //REG 0x2B
00054     MMA845x::writeRegister(CTRL_REG3, 0x00);        //REG 0x2C
00055     
00056     MMA845x::writeRegister(XYZ_DATA_CFG, 0x0);      //REG 0xE HPF / scale +/-2,4,8g
00057     MMA845x::writeRegister(HP_FILTER_CUTOFF, 0x0);  //REG 0xF HPF settings
00058     
00059     return;
00060 }
00061 
00062 void MMA845x::enableDataReadyMode(void) const
00063 {
00064     MMA845x::init();
00065     MMA845x::writeRegister(SYSMOD, 0x1);        //REG 0x0B
00066     MMA845x::writeRegister(INT_SOURCE, 0x1);    //REG 0x0C
00067     // need to finish up these config registers..... 3/8/13
00068     
00069 }
00070 
00071 void MMA845x::enableMotionMode(void) const{}
00072 void MMA845x::enablePulseMode(void) const{}
00073 
00074 void MMA845x::enableOrientationMode(void) const
00075 {
00076     uint16_t who_am_i = MMA845x::readRegister(WHO_AM_I);
00077     if(who_am_i != MMA8451 )
00078     {
00079         error("%s %d: Feature not compatible with the connected device.\n", __FILE__, __LINE__);
00080     }
00081     
00082     return;
00083 }
00084 
00085 void MMA845x::enableTransitMode(void) const{}
00086 void MMA845x::enableAutoSleepMode(void) const{}
00087 
00088 void MMA845x::enableFIFOMode(void) const
00089 {
00090     uint16_t who_am_i = MMA845x::readRegister(WHO_AM_I);
00091     if(who_am_i != MMA8451 )
00092     {
00093         error("%s %d: Feature not compatible with the connected device.\n", __FILE__, __LINE__);
00094     }
00095     
00096     //MMA845x::writeRegister(
00097     
00098     return;
00099 }
00100 
00101 uint16_t MMA845x::getX(void) const
00102 {
00103     return _data._x ;
00104 }
00105     
00106 uint16_t MMA845x::getY(void) const
00107 {
00108     return _data._y ;
00109 }
00110 
00111 uint16_t MMA845x::getZ(void) const
00112 {
00113     return _data._z ;
00114 }
00115     
00116 MMA845x_DATA MMA845x::getXYZ(void) const
00117 {
00118     return _data;
00119 }
00120 
00121 void MMA845x::writeRegister(uint8_t const reg, uint8_t const data) const
00122 {
00123     char buf[2] = {reg, data};
00124     uint8_t result = 0;
00125     
00126     __disable_irq(); // Tickers and other timebase events can jack up the I2C bus for some deicse
00127     result = _i2c->write(_i2c_addr, buf, 2);
00128     __enable_irq();  // Just need to block during the transaction
00129     
00130     if(0 != result)
00131     {
00132         error("%s %d: I2c write failed\n", __FILE__, __LINE__);
00133     }
00134     
00135     return;
00136 }
00137 
00138 uint8_t MMA845x::readRegister(uint8_t const reg) const
00139 {
00140     uint8_t result = 1, data = 0;
00141     
00142     __disable_irq(); // Tickers and other timebase events can jack up the I2C bus
00143     _i2c->start();
00144     result &= _i2c->write(_i2c_addr);
00145     result &= _i2c->write(reg);
00146     // issue a repeated start...
00147     _i2c->start();
00148     result &= _i2c->write(_i2c_addr | 0x01);
00149     // read with nak
00150     data = _i2c->read(0);
00151     _i2c->stop();
00152     __enable_irq();  // Just need to block during the transaction
00153     
00154     if(1 != result)
00155     {
00156         error("%s %d: I2C read failed\n", __FILE__, __LINE__);
00157     }
00158     
00159     return data;
00160 }
00161 
00162 void MMA845x::registerDump(void) const
00163 {
00164     uint8_t reg_val = 0;
00165     
00166     for(int i=0; i<0x80; i++)
00167     {
00168         reg_val = MMA845x::readRegister(i);
00169         printf("Reg 0x%02x: 0x%02x \n", i, reg_val);
00170     }
00171     
00172     return;
00173 }
00174