A work in progress on an updated library

Dependents:   FRDM_N3110LCD test

Fork of MMA8451Q by Emilio Monti

MMA8451Q.cpp

Committer:
SomeRandomBloke
Date:
2013-03-27
Revision:
6:e8bacad228f6
Parent:
5:d813fe6c0c70

File content as of revision 6:e8bacad228f6:

/* Copyright (c) 2010-2011 mbed.org, MIT License
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
* and associated documentation files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all copies or
* substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
* BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/

#include "MMA8451Q.h"

#define MMA_845XQ_CTRL_REG1 0x2A
#define MMA_845XQ_CTRL_REG1_VALUE_ACTIVE 0x01
#define MMA_845XQ_CTRL_REG1_VALUE_F_READ 0x02

#define MMA_845XQ_CTRL_REG2 0x2B
#define MMA_845XQ_CTRL_REG2_RESET 0x40

#define MMA_845XQ_PL_STATUS 0x10
#define MMA_845XQ_PL_CFG 0x11
#define MMA_845XQ_PL_EN 0x40

#define MMA_845XQ_XYZ_DATA_CFG 0x0E
#define MMA_845XQ_2G_MODE 0x00 //Set Sensitivity to 2g
#define MMA_845XQ_4G_MODE 0x01 //Set Sensitivity to 4g
#define MMA_845XQ_8G_MODE 0x02 //Set Sensitivity to 8g
#define MMA_845XQ_HPF_OUT 0x10 //Set High pas filter out


#define MMA_845XQ_FF_MT_CFG 0x15
#define MMA_845XQ_FF_MT_CFG_ELE 0x80
#define MMA_845XQ_FF_MT_CFG_OAE 0x40

#define MMA_845XQ_FF_MT_SRC 0x16
#define MMA_845XQ_FF_MT_SRC_EA 0x80

#define MMA_845XQ_PULSE_CFG 0x21
#define MMA_845XQ_PULSE_CFG_ELE 0x80

#define MMA_845XQ_PULSE_SRC 0x22
#define MMA_845XQ_PULSE_SRC_EA 0x80

// Original
#define REG_WHO_AM_I      0x0D
#define REG_CTRL_REG_1    0x2A
#define REG_OUT_X_MSB     0x01
#define REG_OUT_Y_MSB     0x03
#define REG_OUT_Z_MSB     0x05

#define UINT14_MAX        16383

MMA8451Q::MMA8451Q(PinName sda, PinName scl, int addr, bool highres, uint8_t scale) : m_i2c(sda, scl), m_addr(addr)
{
    _highres = highres;
    _scale = scale;
    _step_factor = (_highres ? 0.0039 : 0.0156); // Base value at 2g setting
    if( _scale == 4 )
        _step_factor *= 2;
    else if (_scale == 8)
        _step_factor *= 4;

    // Set parameters
    uint8_t data[2] = {REG_CTRL_REG_1, 0x04};
    writeRegs(data, 2);

    // Activate
    data[1] = 0x05;
    writeRegs(data, 2);

  data[0] = MMA_845XQ_XYZ_DATA_CFG;
  if (_scale == 4 || _scale == 8)
    data[1] = (_scale == 4) ? MMA_845XQ_4G_MODE : MMA_845XQ_8G_MODE;
  else // Default to 2g mode
    data[1] = (uint8_t)MMA_845XQ_2G_MODE;
    
//  data[1] |= MMA_845XQ_HPF_OUT;
  writeRegs(data, 2);
}

MMA8451Q::~MMA8451Q() { }

uint8_t MMA8451Q::getWhoAmI()
{
    uint8_t who_am_i = 0;
    readRegs(REG_WHO_AM_I, &who_am_i, 1);
    return who_am_i;
}

float MMA8451Q::getAccX()
{
//    return (getAccAxis(REG_OUT_X_MSB));
    return (float(getAccAxis(REG_OUT_X_MSB))/4096.0);
}

float MMA8451Q::getAccY()
{
//    return (getAccAxis(REG_OUT_Y_MSB));
    return (float(getAccAxis(REG_OUT_Y_MSB))/4096.0);
}

float MMA8451Q::getAccZ()
{
//    return (getAccAxis(REG_OUT_Z_MSB));
    return (float(getAccAxis(REG_OUT_Z_MSB))/4096.0);
}

void MMA8451Q::getAccAllAxis(float * res)
{
    res[0] = getAccX();
    res[1] = getAccY();
    res[2] = getAccZ();
}

float MMA8451Q::getAccAxisF(uint8_t addr)
{
    int16_t acc;
//    float facc;
    uint8_t res[2];
    readRegs(addr, res, 2);

    acc = (res[0] << 6) | (res[1] >> 2);
    if (acc > UINT14_MAX/2)
        acc -= UINT14_MAX;
return (acc * 4096.0);
/*    
    if(_highres)
    {
      acc = (int16_t)(res[0] << 8) + res[1];
      facc = (acc / 64) * _step_factor;
    }
    else
    {
      facc = (float)((int16_t)(res[0] * _step_factor) * 1.0);
    }
    return acc;
*/
}

int16_t MMA8451Q::getAccAxis(uint8_t addr)
{
    int16_t acc;
    uint8_t res[2];
    readRegs(addr, res, 2);

//    acc = (res[0] << 6) | (res[1] >> 2);
    acc = (res[0] << 8) | (res[1]);
    acc = acc >> 2;
//    if (acc > UINT14_MAX/2)
//        acc -= UINT14_MAX;
    return acc;
}

void MMA8451Q::readRegs(int addr, uint8_t * data, int len)
{
    char t[1] = {addr};
    m_i2c.write(m_addr, t, 1, true);
    m_i2c.read(m_addr, (char *)data, len);
}

void MMA8451Q::writeRegs(uint8_t * data, int len)
{
    m_i2c.write(m_addr, (char *)data, len);
}