modified from jppang's MMA8451Q for MMA8491Q on sensor evaluation board with the FRDM-KL25Z

Dependencies:   mbed

Fork of MMA8491Q by JP PANG

MMA8491Q.cpp

Committer:
DiyGuy
Date:
2013-11-29
Revision:
3:3f5c717835c3
Parent:
2:b79d19bdfe10

File content as of revision 3:3f5c717835c3:

/* 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 "MMA8491Q.h"

#define REG_STATUS        0x00
#define REG_OUT_X_MSB     0x01
#define REG_OUT_Y_MSB     0x03
#define REG_OUT_Z_MSB     0x05

#define XDR               0x01  //X data ready flag position
#define YDR               0x02  //Y data ready flag position
#define ZDR               0x04  //Z data ready flag position
#define ZYXDR             0x08  //X, Y, Z data ready flag position

#define UINT14_MAX        16383 //maximum count for unsigned 14-bit integer

MMA8491Q::MMA8491Q(PinName sda, PinName scl, int addr, PinName en) : m_i2c(sda, scl), m_addr(addr), m_en(en) {
  
}

MMA8491Q::MMA8491Q(PinName sda, PinName scl, int addr, PinName en, PinName Xout, PinName Yout, PinName Zout) 
                : m_i2c(sda, scl), m_addr(addr), m_en(en), m_xout(Xout), m_yout(Yout), m_zout(Zout) {
    
}


MMA8491Q::~MMA8491Q() { }

float MMA8491Q::getAccX() {
    uint8_t res[2];
    uint8_t status;
    float acc = 0;
    
    toggleEN();
    
    status = isDataAvailable(XDR);
    if(status){
        readRegs(REG_OUT_X_MSB, res, 2);    //get X readings
        acc = intAccToFloat(res); 
        
   }
   return acc;
}    


float MMA8491Q::getAccY() {
    uint8_t res[2];
    uint8_t status;
    float acc = 0;
    
    toggleEN();
    
    status = isDataAvailable(YDR);
    if(status){
        readRegs(REG_OUT_Y_MSB, res, 2);    //get Y readings
        acc = intAccToFloat(res); 
        
   }
   return acc;
}


float MMA8491Q::getAccZ() {
    uint8_t res[2];
    uint8_t status;
    float acc = 0;
    
    toggleEN();
    
    status = isDataAvailable(ZDR);
    if(status){
        readRegs(REG_OUT_Z_MSB, res, 2);    //get Z readings
        acc = intAccToFloat(res); 
        
   }
   return acc;
}


uint8_t MMA8491Q::getAccAllAxis(float * acc) {
    uint8_t res[6];
    uint8_t status;

    toggleEN();
    
    status = isDataAvailable(ZYXDR);
    if(status){
        readRegs(REG_OUT_X_MSB, res, 6);    //get X,Y,Z readings
        for(int8_t i=0; i<3; i++){
            acc[i] = intAccToFloat(&res[(i*2)]); 
        }
   }
   return status;
}


uint8_t MMA8491Q::isDataAvailable( uint8_t mask){
    unsigned char status;   
    readRegs( REG_STATUS, &status, 1);
    status &= mask;    //check for requested Data Ready flag
    return status;    
}


//convert 14-bit 2's compliment (mg) number from sensor to float scaled to 1g
float MMA8491Q::intAccToFloat(uint8_t * data) {
    int16_t acc = 0;
    
    acc = (data[0] << 6) | (data[1] >> 2);
    if (acc > UINT14_MAX/2)     //MSB of 14-bit value is 1 or negative
        acc -= UINT14_MAX;      //extend sign to 16 bits
        
    return acc/1000.0;
 }
 
 
 void MMA8491Q::toggleEN(void){
    m_en = 0;             //cycle cycle enable low-high 
    wait(0.001);
    m_en = 1;             //start MMA8491Q reading
    wait(0.001);                //wait 1 ms for reading

 }
 
 
void MMA8491Q::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 MMA8491Q::writeRegs(uint8_t * data, int len) {
    m_i2c.write(m_addr, (char *)data, len);
}