Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: KL25Z_Batt_Test WIGO_MPL3115A2 Multi-Sensor SPACEmk2 ... more
MPL3115A2.cpp
- Committer:
- clemente
- Date:
- 2013-08-22
- Revision:
- 6:03c24251e500
- Parent:
- 5:9edec5ee8bf4
- Child:
- 7:59e9ba115d0a
File content as of revision 6:03c24251e500:
#include "MPL3115A2.h"
#define REG_WHO_AM_I 0x0C // return 0xC4 by default
#define REG_STATUS 0x00
#define REG_CTRL_REG_1 0x26
#define REG_CTRL_REG_3 0x28
#define REG_CTRL_REG_4 0x29
#define REG_CTRL_REG_5 0x2A
#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 REG_P_TGT_MSB 0x16
#define REG_P_WND_MSB 0x19
#define UINT14_MAX 16383
// Status flag for data ready.
#define PTDR_STATUS 0x03 // Pressure Altitude and Temperature ready
#define PDR_STATUS 0x02 // Pressure and Altitude data ready
#define TDR_STATUS 0x01 // Temperature data ready
/** Interrupt schema
*
* :: The Altitude Trigger use the IRQ1.
*
* Altitude Trigger -- MPL3115A2_Int1.fall --- AltitudeTrg_IRQ --- user1_fptr
*
*
* :: The Data ready use the IRQ2.
*
* Data Ready -- MPL3115A2_Int2.fall --- DataReady_IRQ --- user2_fptr
*
*/
void (*user2_fptr)(void); // Pointers to user function called after
void (*user1_fptr)(void); // IRQ assertion.
//
InterruptIn MPL3115A2_Int1( PTD4); // INT1
InterruptIn MPL3115A2_Int2( PTA12); // INT2
MPL3115A2::MPL3115A2(PinName sda, PinName scl, int addr) : m_i2c(sda, scl), m_addr(addr) {
MPL3115A2_mode = BAROMETRIC_MODE;
MPL3115A2_oversampling = OVERSAMPLE_RATIO_1;
//
user1_fptr = NULL;
user2_fptr = NULL;
MPL3115A2_Int1.fall( NULL);
MPL3115A2_Int2.fall( NULL);
}
void MPL3115A2::Reset( void)
{
unsigned char t;
// soft reset...
readRegs( REG_CTRL_REG_1, &t, 1);
unsigned char data[2] = { REG_CTRL_REG_1, t|0x04};
writeRegs(data, 2);
wait( 0.1);
}
void MPL3115A2::DataReady( void(*fptr)(void), unsigned char OS)
{
unsigned char dt[5];
unsigned char data[2];
// Soft Reset
Reset();
Standby();
// Clear all interrupts by reading the output registers.
readRegs( REG_ALTIMETER_MSB, &dt[0], 5);
getStatus();
// Configure INT active low and pullup
data[0] = REG_CTRL_REG_3;
data[1] = 0x00;
writeRegs(data, 2);
// Enable Interrupt fot data ready
data[0] = REG_CTRL_REG_4;
data[1] = 0x80;
writeRegs(data, 2);
// Configure Interrupt to route to INT2
data[0] = REG_CTRL_REG_5;
data[1] = 0x00;
writeRegs(data, 2);
data[0] = REG_PT_DATA_CFG;
data[1] = 0x07;
writeRegs(data, 2);
// Configure the OverSampling rate, Altimeter/Barometer mode and set the sensor Active
data[0] = REG_CTRL_REG_1;
data[1] = (OS<<3);
//
if (MPL3115A2_mode == BAROMETRIC_MODE)
data[1] &= 0x7F;
else
data[1] |= 0x80;
//
data[1] |= 0x01;
writeRegs(data, 2);
user2_fptr = fptr;
MPL3115A2_Int2.fall( this, &MPL3115A2::DataReady_IRQ);
}
void MPL3115A2::DataReady_IRQ( void)
{
// Clear the IRQ flag
getStatus();
// Run the user supplied function
user2_fptr();
}
void MPL3115A2::AltitudeTrigger( void(*fptr)(void), unsigned short level)
{
unsigned char dt[5];
unsigned char data[2];
// Soft Reset
Reset();
// The device is on standby
Standby();
// Clear all interrupts by reading the output registers.
readRegs( REG_ALTIMETER_MSB, &dt[0], 5);
getStatus();
// Write Target and Window Values
dt[0] = REG_P_TGT_MSB;
dt[1] = (level>>8);
dt[2] = (level&0xFF);
writeRegs( dt, 3);
// Window values are zero
dt[0] = REG_P_WND_MSB;
dt[1] = 0;
dt[2] = 0;
writeRegs( dt, 3);
// Enable Pressure Threshold interrupt
data[0] = REG_CTRL_REG_4;
data[1] = 0x08;
writeRegs( data, 2);
// Interrupt is routed to INT1
data[0] = REG_CTRL_REG_5;
data[1] = 0x08;
writeRegs( data, 2);
data[0] = REG_PT_DATA_CFG;
data[1] = 0x07;
writeRegs(data, 2);
// Configure the OverSampling rate, Altimeter mode and set the sensor Active
data[0] = REG_CTRL_REG_1;
data[1] = 0x81 | (MPL3115A2_oversampling<<3);
writeRegs(data, 2);
user1_fptr = fptr;
MPL3115A2_Int1.fall( this, &MPL3115A2::AltitudeTrg_IRQ);
}
void MPL3115A2::AltitudeTrg_IRQ( void)
{
// Clear the IRQ flag
getStatus();
// Run the user supplied function
user1_fptr();
}
void MPL3115A2::Barometric_Mode( void)
{
unsigned char t;
unsigned char data[2];
Standby();
// soft reset...
Reset();
Standby();
readRegs( REG_CTRL_REG_1, &t, 1);
// Set the Barometric mode
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;
unsigned char data[2];
Standby();
// soft reset...
Reset();
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);
return ((status>>1));
}
unsigned char MPL3115A2::getStatus( void)
{
unsigned char status;
readRegs( REG_STATUS, &status, 1);
return status;
}
unsigned int MPL3115A2::getAllData( float *f)
{
if ( isDataAvailable() & PTDR_STATUS) {
if ( MPL3115A2_mode == ALTIMETER_MODE) {
f[0] = getAltimeter();
} else {
f[0] = getPressure();
}
f[1] = getTemperature();
//
return 1;
} else
return 0;
}
float MPL3115A2::getAltimeter( void)
{
unsigned char dt[3];
unsigned short altm;
float faltm;
/*
* dt[0] = Bits 12-19 of 20-bit real-time Altitude sample. (b7-b0)
* dt[1] = Bits 4-11 of 20-bit real-time Altitude sample. (b7-b0)
* dt[2] = Bits 0-3 of 20-bit real-time Altitude 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;
}
unsigned int MPL3115A2::getAllDataRaw( unsigned char *dt)
{
// Check for Press/Alti and Temp value ready
if ( isDataAvailable() & PTDR_STATUS) {
if ( MPL3115A2_mode == ALTIMETER_MODE) {
getAltimeterRaw( &dt[0]); // 3 bytes
} else {
getPressureRaw( &dt[0]); // 3 bytes
}
getTemperatureRaw( &dt[3]); // 2 bytes
return 1;
} else {
return 0;
}
}
unsigned int MPL3115A2::getAltimeterRaw( unsigned char *dt)
{
/*
* 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)
*/
// Check for Press/Alti value ready
if ( isDataAvailable() & PDR_STATUS) {
readRegs( REG_ALTIMETER_MSB, &dt[0], 3);
return 1;
} else
return 0;
}
unsigned int MPL3115A2::getPressureRaw( unsigned char *dt)
{
/*
* 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)
*/
// Check for Press/Alti value ready
if ( isDataAvailable() & PDR_STATUS) {
readRegs( REG_PRESSURE_MSB, &dt[0], 3);
return 1;
} else
return 0;
}
unsigned int MPL3115A2::getTemperatureRaw( unsigned char *dt)
{
/*
* 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)
*/
// Check for Temp value ready
if ( isDataAvailable() & TDR_STATUS) {
readRegs( REG_TEMP_MSB, &dt[0], 2);
return 1;
} else
return 0;
}
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);
}
NXP MPL3115A2 Altimeter