Llibrary for the WiGo MPL3115A2, I2C Precision Altimeter sensor.

Dependents:   KL25Z_Batt_Test WIGO_MPL3115A2 Multi-Sensor SPACEmk2 ... more

30/05/2013 Added and tested the data acquisition using Interrupt. Added code for Altimeter trigger Interrupt but not yet tested.

Very basic library. Under development. Need to add in order: 1. IRQ configuration. 2. FIFO mode configuration.

Revision:
0:cfecfabc5e23
Child:
2:a2fcfb7ff611
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MPL3115A2.cpp	Thu May 23 06:42:15 2013 +0000
@@ -0,0 +1,239 @@
+#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);
+}