MPL3115A2 driver

Dependents:   lmic_NAmote_GPS_tjm lmic_NAmote_GPS_tjm Senet NAMote scpi_sx127x ... more

mpl3115a2.cpp

Committer:
dudmuck
Date:
2015-08-31
Revision:
2:0eb8b0ad292b
Parent:
1:3cd1f21925e8

File content as of revision 2:0eb8b0ad292b:

#include "mpl3115a2.h"
 
#define MPL3115A_I2C_ADDRESS                        0xc0  //0x60

MPL3115A2::MPL3115A2(I2C& r, DigitalIn& int_pin) : m_i2c(r), m_int_pin(int_pin)
{
    write(CTRL_REG3, 0x10); // PP_OD1: INT1 to open-drain
}

MPL3115A2::~MPL3115A2()
{
}

void MPL3115A2::init()
{
    //MPL3115Reset( );
    ctrl_reg1.octet = 0;
    ctrl_reg1.bits.RST = 1;
    write(CTRL_REG1, /*4*/ ctrl_reg1.octet);
    wait(0.05);
    
    do
    {   // Wait for the RST bit to clear 
        wait(0.01);
        ctrl_reg1.octet = read(CTRL_REG1);
    } while (ctrl_reg1.octet);
   
    write( PT_DATA_CFG_REG, 0x07 ); // Enable data flags 
    write( CTRL_REG3, 0x11 );       // Open drain, active low interrupts 
    write( CTRL_REG4, 0x80 );       // Enable DRDY interrupt 
    write( CTRL_REG5, 0x00 );       // DRDY interrupt routed to INT2 - PTD3 
    
    ctrl_reg1.bits.ALT = 1; // altitude mode
    ctrl_reg1.bits.OS = 5;  // OSR = 32
    ctrl_reg1.bits.SBYB = 1; // Active
    write(CTRL_REG1, ctrl_reg1.octet);       
    
    SetModeActive( );
}

void MPL3115A2::setOSR(uint8_t osr)
{
    ctrl_reg1.bits.OS = osr;
    write(CTRL_REG1, ctrl_reg1.octet);
}

uint8_t MPL3115A2::getOSR(void)
{
    ctrl_reg1.octet = read(CTRL_REG1);
    return ctrl_reg1.bits.OS;
}

bool MPL3115A2::GetModeActive( )
{
    ctrl_reg1.octet = read(CTRL_REG1);
    return ctrl_reg1.bits.SBYB;
}

void MPL3115A2::SetModeActive( )
{
    ctrl_reg1.bits.SBYB = 1;
    write(CTRL_REG1, ctrl_reg1.octet); 
}

void MPL3115A2::SetModeStandby( )
{
    ctrl_reg1.bits.SBYB = 0;
    write(CTRL_REG1, ctrl_reg1.octet);     
}

void MPL3115A2::write(uint8_t a, uint8_t d)
{
    char cmd[2];
    
    cmd[0] = a;
    cmd[1] = d;

    if (m_i2c.write(MPL3115A_I2C_ADDRESS, cmd, 2))
        printf("MPL write-fail %02x %02x\n", cmd[0], cmd[1]);
        
    if (a == CTRL_REG4)
        ctrl_reg4 = d;
}

uint8_t MPL3115A2::read(uint8_t a)
{
    char cmd[2];
    
    cmd[0] = a;
    if (m_i2c.write(MPL3115A_I2C_ADDRESS, cmd, 1, true))
        printf("MPL write-fail %02x\n", cmd[0]);
    if (m_i2c.read(MPL3115A_I2C_ADDRESS, cmd, 1))
        printf("MPL read-fail\n");
        
    if (a == CTRL_REG4)
        ctrl_reg4 = cmd[0];
                      
    return cmd[0];
}

float MPL3115A2::ReadBarometer(void)
{
    uint32_t pasc;
    volatile uint8_t stat;

    SetModeBarometer();
    ToggleOneShot( );
       
    stat = read(STATUS_REG);       
    while( (stat & 0x04) != 0x04 ) {
        wait(0.01);   
        stat = read(STATUS_REG);
    }
    
    pasc = read(OUT_P_MSB_REG);
    pasc <<= 8;
    pasc |= read(OUT_P_CSB_REG);
    pasc <<= 8;
    pasc |= read(OUT_P_LSB_REG);
    
    return pasc / 64.0;
}

float MPL3115A2::ReadAltitude( void )
{
    uint8_t counter = 0;
    uint8_t val = 0;
    uint8_t msb = 0, csb = 0, lsb = 0;
    float decimal = 0;

    /*if( MPL3115Initialized == false )
    {
        return 0;
    }*/

    SetModeAltimeter( );
    ToggleOneShot( );

    while( ( val & 0x04 ) != 0x04 )
    {    
        val = read( STATUS_REG);
        wait(0.01); //DelayMs( 10 );
        counter++;
    
        if( counter > 20 )
        {    
            //MPL3115Initialized = false;
            init( );
            SetModeAltimeter( );
            ToggleOneShot( );
            counter = 0;
            while( ( val & 0x04 ) != 0x04 )
            {  
                val = read( STATUS_REG);
                wait(0.01); //DelayMs( 10 );
                counter++;
                if( counter > 20 )
                {
                    write( CTRL_REG4, 0x00 );
                    return( 0 ); //Error out after max of 512ms for a read
                }
            }
        }
    }

    msb = read( OUT_P_MSB_REG); // High byte of integer part of altitude,  
    csb = read( OUT_P_CSB_REG); // Low byte of integer part of altitude 
    lsb = read( OUT_P_LSB_REG); // Decimal part of altitude in bits 7-4
    
    decimal = ( ( float )( lsb >> 4 ) ) / 16.0;
    //Altitude = ( float )( ( msb << 8 ) | csb ) + decimal;
    Altitude = ( float )( ( int16_t )( ( msb << 8 ) | csb ) ) + decimal;
    
    write( CTRL_REG4, 0x00 );

    return( Altitude );
}

void MPL3115A2::SetModeAltimeter( void )
{
    SetModeStandby( );

    ctrl_reg1.bits.ALT = 1;
    write(CTRL_REG1, ctrl_reg1.octet); 
    
    SetModeActive( );
}

void MPL3115A2::SetModeBarometer(void)
{
    SetModeStandby( );

    ctrl_reg1.bits.ALT = 0;
    write(CTRL_REG1, ctrl_reg1.octet); 
    
    SetModeActive( );    
}

void MPL3115A2::ToggleOneShot( void )
{
    SetModeStandby( );
    
    ctrl_reg1.bits.OST = 0;
    write(CTRL_REG1, ctrl_reg1.octet); 
    
    ctrl_reg1.bits.OST = 1;
    write(CTRL_REG1, ctrl_reg1.octet); 

    SetModeActive( );
}

float MPL3115A2::ReadTemperature( void )
{
    uint8_t counter = 0;
    bool negSign = false;
    uint8_t val = 0;
    uint8_t msb = 0, lsb = 0;

    /*if( MPL3115Initialized == false )
    {
        return 0;
    }*/

    ToggleOneShot( );

    while( ( val & 0x02 ) != 0x02 )
    {    
        val = read( STATUS_REG);
        wait(0.01);
        counter++;
    
        if( counter > 20 )
        { 
            //MPL3115Initialized = false;
            init( );
            ToggleOneShot( );
            counter = 0;
            while( ( val & 0x02 ) != 0x02 )
            {
                val = read( STATUS_REG);
                wait(0.01);
                counter++;
            
                if( counter > 20 )
                { 
                    write( CTRL_REG4, 0x00 );
                    return( 0 ); //Error out after max of 512ms for a read
                }
            }
                
        }
    }

    msb = read( OUT_T_MSB_REG); // Integer part of temperature 
    lsb = read( OUT_T_LSB_REG); // Decimal part of temperature in bits 7-4

    if( msb > 0x7F )
    {
        val = ~( ( msb << 8 ) + lsb ) + 1;  //2?s complement
        msb = val >> 8;
        lsb = val & 0x00F0; 
        negSign = true;
    }

    if( negSign == true )
    {
        Temperature = 0 - ( msb + ( float )( ( lsb >> 4 ) / 16.0 ) );
    }
    else
    {
        Temperature = msb + ( float )( ( lsb >> 4 ) / 16.0 );
    }

    ToggleOneShot( );

    write( CTRL_REG4, 0x00 );

    return( Temperature );
}

void MPL3115A2::service()
{
    mpl_int_source_t int_src;
    
    if ((ctrl_reg4 == 0x00) || m_int_pin)   // if no interrupts enabled and no interrupt occuring
        return;
        
    int_src.octet = read(INT_SOURCE_REG);
    
    if (int_src.bits.SRC_TCHG) {
    }
    if (int_src.bits.SRC_PCHG) {
    }
    if (int_src.bits.SRC_TTH) {
    }
    if (int_src.bits.SRC_PTH) {
    }
    if (int_src.bits.SRC_TW) {
    }
    if (int_src.bits.SRC_PW) {
    }
    if (int_src.bits.SRC_FIFO) {
        read(F_STATUS_REG);
    }
    if (int_src.bits.SRC_DRDY) {
        read(STATUS_REG);
        
        read( OUT_T_MSB_REG); // Integer part of temperature 
        read( OUT_T_LSB_REG); // Decimal part of temperature in bits 7-4
        
        read( OUT_P_MSB_REG); // High byte of integer part of altitude,  
        read( OUT_P_CSB_REG); // Low byte of integer part of altitude 
        read( OUT_P_LSB_REG); // Decimal part of altitude in bits 7-4              
    }
            
}