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.
MPL3115A2.cpp
- Committer:
- clemente
- Date:
- 2013-05-29
- Revision:
- 3:a2f1752add9a
- Parent:
- 2:a2fcfb7ff611
- Child:
- 4:fdf14a259af8
File content as of revision 3:a2f1752add9a:
#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_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 /** 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; } 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]; Reset(); /* ** Read contents of CTRL_REG_1 ** Clear SBYB mask while holding all other values of CTRL_REG_1. ** To put part into Standby mode */ Standby(); /* ** Clear all interrupts by reading the output registers. ** Activate sensor in Altimeter mode. */ readRegs( REG_ALTIMETER_MSB, &dt[0], 5); getStatus(); // 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); /* ** Configure the OverSampling rate, Altimeter mode and set the sensor Active */ data[0] = REG_CTRL_REG_1; data[1] = 0x81 | (OS<<3); 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 data[0] = (level<<8); data[1] = (level&0xFF); writeRegs( data, 2); // Window values are zero data[0] = 0; data[1] = 0; writeRegs( data, 2); // 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); Active(); 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); 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); }