Llibrary for the WiGo MPL3115A2, I2C Precision Altimeter sensor. This is a temp fork

Dependents:   sensor AerCloud_MutliTech_Socket_Modem_Example Freescale_Multi-Sensor_Shield 2lemetry_Sensor_Example ... more

Fork of MPL3115A2 by clemente di caprio

MPL3115A2.cpp

Committer:
clemente
Date:
2013-05-23
Revision:
0:cfecfabc5e23
Child:
2:a2fcfb7ff611

File content as of revision 0:cfecfabc5e23:

#include "MPL3115A2.h"

#define REG_WHO_AM_I        0x0C        // 0xC4 by default
#define REG_STATUS          0x00
#define REG_CTRL_REG_1      0x26
#define REG_PRESSURE_MSB    0x01        // 3 byte pressure data
#define REG_ALTIMETER_MSB   0x01        // 3 byte altimeter data
#define REG_TEMP_MSB        0x04        // 2 byte temperature data
#define REG_PT_DATA_CFG     0x13

#define UINT14_MAX        16383

MPL3115A2::MPL3115A2(PinName sda, PinName scl, int addr) : m_i2c(sda, scl), m_addr(addr) {
    MPL3115A2_mode = BAROMETRIC_MODE;
    MPL3115A2_oversampling = OVERSAMPLE_RATIO_1;
}

void MPL3115A2::Barometric_Mode( void)
{
    unsigned char t;
    
    Standby();
    readRegs( REG_CTRL_REG_1, &t, 1);

    // soft reset...
    unsigned char data[2] = { REG_CTRL_REG_1, t|0x04};
    writeRegs(data, 2);    
    wait( 0.2);
    
    Standby();
    readRegs( REG_CTRL_REG_1, &t, 1);
    
    data[0] = REG_CTRL_REG_1;
    data[1] = t&0x7F;
    writeRegs(data, 2);    

    data[0] = REG_PT_DATA_CFG;
    data[1] = 0x07;
    writeRegs(data, 2);    

    Oversample_Ratio( MPL3115A2_oversampling);
    
    Active();
    
    MPL3115A2_mode = BAROMETRIC_MODE;
}

void MPL3115A2::Altimeter_Mode( void)
{
    unsigned char t;

    Standby();
    readRegs( REG_CTRL_REG_1, &t, 1);

    // soft reset...
    unsigned char data[2] = { REG_CTRL_REG_1, t|0x04};
    writeRegs(data, 2);    
    wait( 0.2);
    
    Standby();
    readRegs( REG_CTRL_REG_1, &t, 1);

    data[0] = REG_CTRL_REG_1;
    data[1] = t|0x80;
    writeRegs(data, 2);    

    data[0] = REG_PT_DATA_CFG;
    data[1] = 0x07;
    writeRegs(data, 2);    

    Oversample_Ratio( MPL3115A2_oversampling);
    
    Active();
    
    MPL3115A2_mode = ALTIMETER_MODE;
}

void MPL3115A2::Oversample_Ratio( unsigned int ratio)
{
    unsigned char t;
    
    Standby();
    readRegs( REG_CTRL_REG_1, &t, 1);

    t = t & 0xE7;
    t = t | ( ratio<<3);

    unsigned char data[2] = { REG_CTRL_REG_1, t};
    writeRegs(data, 2);    

    Active();
    
    MPL3115A2_oversampling = ratio;
}


void MPL3115A2::Active( void)
{
    unsigned char t;
    
    // Activate the peripheral
    readRegs(REG_CTRL_REG_1, &t, 1);
    unsigned char data[2] = {REG_CTRL_REG_1, t|0x01};
    writeRegs(data, 2);
}

void MPL3115A2::Standby( void)
{
    unsigned char t;
    
    // Standby
    readRegs(REG_CTRL_REG_1, &t, 1);
    unsigned char data[2] = {REG_CTRL_REG_1, t&0xFE};
    writeRegs(data, 2);
}

unsigned char MPL3115A2::getDeviceID() {
    unsigned char device_id = 0;
    readRegs(REG_WHO_AM_I, &device_id, 1);
    return device_id;
}

unsigned int MPL3115A2::isDataAvailable( void)
{
    unsigned char status;
    
    readRegs( REG_STATUS, &status, 1);
    
    if ( status & 0x08) {
        return 1;
    } else {
        return 0;
    }
    
}

unsigned char MPL3115A2::getStatus( void)
{
    unsigned char status;
    
    readRegs( REG_STATUS, &status, 1);
    return status;
}

void MPL3115A2::getAllData( float *f)
{
    if ( MPL3115A2_mode == ALTIMETER_MODE) {
        f[0] = getAltimeter();
    } else {
        f[0] = getPressure();
    }
    
    f[1] = getTemperature();
}

float MPL3115A2::getAltimeter( void)
{
    unsigned char dt[3];
    unsigned short altm;
    float faltm;
    
    /*
    * dt[0] = Bits 12-19 of 20-bit real-time Pressure sample. (b7-b0)
    * dt[1] = Bits 4-11 of 20-bit real-time Pressure sample. (b7-b0)
    * dt[2] = Bits 0-3 of 20-bit real-time Pressure sample (b7-b4)
    */
    readRegs( REG_ALTIMETER_MSB, &dt[0], 3);
    altm = (dt[0]<<8) | dt[1];
    //
    if ( dt[0] > 0x7F) {
        altm = ~altm + 1;
        faltm = (float)altm * -1.0f;
    } else {
        faltm = (float)altm * 1.0f;
    }
    //
    faltm = faltm+((float)(dt[2]>>4) * 0.0625f);
    return faltm;
}

float MPL3115A2::getPressure( void)
{
    unsigned char dt[3];
    unsigned int prs;
    float fprs;
    
    /*
    * dt[0] = Bits 12-19 of 20-bit real-time Pressure sample. (b7-b0)
    * dt[1] = Bits 4-11 of 20-bit real-time Pressure sample. (b7-b0)
    * dt[2] = Bits 0-3 of 20-bit real-time Pressure sample (b7-b4)
    */
    readRegs( REG_PRESSURE_MSB, &dt[0], 3);
    prs = (dt[0]<<10) | (dt[1]<<2) | (dt[2]>>6);
    //
    fprs = (float)prs * 1.0f;
    
    if ( dt[2] & 0x20)
        fprs += 0.25f;
    if ( dt[2] & 0x10)
        fprs += 0.5f;
    
    return fprs;
}


float MPL3115A2::getTemperature( void)
{
    unsigned char dt[2];
    unsigned short temp;
    float ftemp;
    
    /*
    * dt[0] = Bits 4-11 of 16-bit real-time temperature sample. (b7-b0)
    * dt[1] = Bits 0-3 of 16-bit real-time temperature sample. (b7-b4)
    */
    readRegs( REG_TEMP_MSB, &dt[0], 2);
    temp = dt[0];
    //
    if ( dt[0] > 0x7F) {
        temp = ~temp + 1;
        ftemp = (float)temp * -1.0f;
    } else {
        ftemp = (float)temp * 1.0f;
    }
    //
    ftemp = ftemp+((float)(dt[1]>>4) * 0.0625f);
    return ftemp;

}

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