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.

Committer:
clemente
Date:
Wed May 29 05:57:15 2013 +0000
Revision:
2:a2fcfb7ff611
Parent:
0:cfecfabc5e23
Child:
3:a2f1752add9a
Streaming data using Interrupt. Not tested.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
clemente 0:cfecfabc5e23 1 #include "MPL3115A2.h"
clemente 0:cfecfabc5e23 2
clemente 2:a2fcfb7ff611 3 #define REG_WHO_AM_I 0x0C // return 0xC4 by default
clemente 0:cfecfabc5e23 4 #define REG_STATUS 0x00
clemente 0:cfecfabc5e23 5 #define REG_CTRL_REG_1 0x26
clemente 2:a2fcfb7ff611 6 #define REG_CTRL_REG_4 0x29
clemente 2:a2fcfb7ff611 7 #define REG_CTRL_REG_5 0x2A
clemente 0:cfecfabc5e23 8 #define REG_PRESSURE_MSB 0x01 // 3 byte pressure data
clemente 0:cfecfabc5e23 9 #define REG_ALTIMETER_MSB 0x01 // 3 byte altimeter data
clemente 0:cfecfabc5e23 10 #define REG_TEMP_MSB 0x04 // 2 byte temperature data
clemente 0:cfecfabc5e23 11 #define REG_PT_DATA_CFG 0x13
clemente 0:cfecfabc5e23 12
clemente 0:cfecfabc5e23 13 #define UINT14_MAX 16383
clemente 0:cfecfabc5e23 14
clemente 2:a2fcfb7ff611 15 void (*user2_fptr)(void); // Pointers to user function called after
clemente 2:a2fcfb7ff611 16 void (*user1_fptr)(void); // IRQ assertion.
clemente 2:a2fcfb7ff611 17
clemente 2:a2fcfb7ff611 18 //
clemente 2:a2fcfb7ff611 19 InterruptIn MPL3115A2_Int1( PTD4); // INT1
clemente 2:a2fcfb7ff611 20 InterruptIn MPL3115A2_Int2( PTA12); // INT2
clemente 2:a2fcfb7ff611 21
clemente 0:cfecfabc5e23 22 MPL3115A2::MPL3115A2(PinName sda, PinName scl, int addr) : m_i2c(sda, scl), m_addr(addr) {
clemente 0:cfecfabc5e23 23 MPL3115A2_mode = BAROMETRIC_MODE;
clemente 0:cfecfabc5e23 24 MPL3115A2_oversampling = OVERSAMPLE_RATIO_1;
clemente 0:cfecfabc5e23 25 }
clemente 0:cfecfabc5e23 26
clemente 2:a2fcfb7ff611 27 void MPL3115A2::Reset( void)
clemente 2:a2fcfb7ff611 28 {
clemente 2:a2fcfb7ff611 29 unsigned char t;
clemente 2:a2fcfb7ff611 30
clemente 2:a2fcfb7ff611 31 // soft reset...
clemente 2:a2fcfb7ff611 32 readRegs( REG_CTRL_REG_1, &t, 1);
clemente 2:a2fcfb7ff611 33 unsigned char data[2] = { REG_CTRL_REG_1, t|0x04};
clemente 2:a2fcfb7ff611 34 writeRegs(data, 2);
clemente 2:a2fcfb7ff611 35 wait( 0.1);
clemente 2:a2fcfb7ff611 36
clemente 2:a2fcfb7ff611 37 }
clemente 2:a2fcfb7ff611 38
clemente 2:a2fcfb7ff611 39 void MPL3115A2::DataReady( void(*fptr)(void), unsigned char OS)
clemente 2:a2fcfb7ff611 40 {
clemente 2:a2fcfb7ff611 41 unsigned char dt[5];
clemente 2:a2fcfb7ff611 42 unsigned char data[2];
clemente 2:a2fcfb7ff611 43
clemente 2:a2fcfb7ff611 44 Reset();
clemente 2:a2fcfb7ff611 45
clemente 2:a2fcfb7ff611 46 /*
clemente 2:a2fcfb7ff611 47 ** Read contents of CTRL_REG_1
clemente 2:a2fcfb7ff611 48 ** Clear SBYB mask while holding all other values of CTRL_REG_1.
clemente 2:a2fcfb7ff611 49 ** To put part into Standby mode
clemente 2:a2fcfb7ff611 50 */
clemente 2:a2fcfb7ff611 51 Standby();
clemente 2:a2fcfb7ff611 52
clemente 2:a2fcfb7ff611 53 /*
clemente 2:a2fcfb7ff611 54 ** Clear all interrupts by reading the output registers.
clemente 2:a2fcfb7ff611 55 ** Activate sensor in Altimeter mode.
clemente 2:a2fcfb7ff611 56 */
clemente 2:a2fcfb7ff611 57 readRegs( REG_ALTIMETER_MSB, &dt[0], 5);
clemente 2:a2fcfb7ff611 58 getStatus();
clemente 2:a2fcfb7ff611 59 // Enable Interrupt fot data ready
clemente 2:a2fcfb7ff611 60 data[0] = REG_CTRL_REG_4;
clemente 2:a2fcfb7ff611 61 data[1] = 0x80;
clemente 2:a2fcfb7ff611 62 writeRegs(data, 2);
clemente 2:a2fcfb7ff611 63 // Configure Interrupt route to INT2
clemente 2:a2fcfb7ff611 64 data[0] = REG_CTRL_REG_5;
clemente 2:a2fcfb7ff611 65 data[1] = 0x00;
clemente 2:a2fcfb7ff611 66 writeRegs(data, 2);
clemente 2:a2fcfb7ff611 67
clemente 2:a2fcfb7ff611 68 /*
clemente 2:a2fcfb7ff611 69 ** Write a 1 to the ALT and SBYB bits to go into Active Altimeter mode
clemente 2:a2fcfb7ff611 70 */
clemente 2:a2fcfb7ff611 71 // Configure the OverSampling rate, Altimeter mode and set the sensor Active
clemente 2:a2fcfb7ff611 72 data[0] = REG_CTRL_REG_1;
clemente 2:a2fcfb7ff611 73 data[1] = 0x81 | (OS<<3);
clemente 2:a2fcfb7ff611 74 writeRegs(data, 2);
clemente 2:a2fcfb7ff611 75
clemente 2:a2fcfb7ff611 76 user2_fptr = fptr;
clemente 2:a2fcfb7ff611 77 MPL3115A2_Int2.fall( this, &MPL3115A2::DataReady_IRQ);
clemente 2:a2fcfb7ff611 78
clemente 2:a2fcfb7ff611 79 }
clemente 2:a2fcfb7ff611 80
clemente 2:a2fcfb7ff611 81 void MPL3115A2::DataReady_IRQ( void)
clemente 2:a2fcfb7ff611 82 {
clemente 2:a2fcfb7ff611 83 // Clear the IRQ flag
clemente 2:a2fcfb7ff611 84 getStatus();
clemente 2:a2fcfb7ff611 85 // Run the user supplied function
clemente 2:a2fcfb7ff611 86 user2_fptr();
clemente 2:a2fcfb7ff611 87 }
clemente 2:a2fcfb7ff611 88
clemente 0:cfecfabc5e23 89 void MPL3115A2::Barometric_Mode( void)
clemente 0:cfecfabc5e23 90 {
clemente 0:cfecfabc5e23 91 unsigned char t;
clemente 2:a2fcfb7ff611 92 unsigned char data[2];
clemente 0:cfecfabc5e23 93
clemente 0:cfecfabc5e23 94 Standby();
clemente 0:cfecfabc5e23 95
clemente 0:cfecfabc5e23 96 // soft reset...
clemente 2:a2fcfb7ff611 97 Reset();
clemente 2:a2fcfb7ff611 98
clemente 0:cfecfabc5e23 99 Standby();
clemente 0:cfecfabc5e23 100 readRegs( REG_CTRL_REG_1, &t, 1);
clemente 0:cfecfabc5e23 101
clemente 2:a2fcfb7ff611 102 // Set the Barometric mode
clemente 0:cfecfabc5e23 103 data[0] = REG_CTRL_REG_1;
clemente 0:cfecfabc5e23 104 data[1] = t&0x7F;
clemente 0:cfecfabc5e23 105 writeRegs(data, 2);
clemente 0:cfecfabc5e23 106
clemente 0:cfecfabc5e23 107 data[0] = REG_PT_DATA_CFG;
clemente 0:cfecfabc5e23 108 data[1] = 0x07;
clemente 0:cfecfabc5e23 109 writeRegs(data, 2);
clemente 0:cfecfabc5e23 110
clemente 0:cfecfabc5e23 111 Oversample_Ratio( MPL3115A2_oversampling);
clemente 0:cfecfabc5e23 112
clemente 0:cfecfabc5e23 113 Active();
clemente 0:cfecfabc5e23 114
clemente 0:cfecfabc5e23 115 MPL3115A2_mode = BAROMETRIC_MODE;
clemente 0:cfecfabc5e23 116 }
clemente 0:cfecfabc5e23 117
clemente 0:cfecfabc5e23 118 void MPL3115A2::Altimeter_Mode( void)
clemente 0:cfecfabc5e23 119 {
clemente 0:cfecfabc5e23 120 unsigned char t;
clemente 2:a2fcfb7ff611 121 unsigned char data[2];
clemente 2:a2fcfb7ff611 122
clemente 0:cfecfabc5e23 123 Standby();
clemente 0:cfecfabc5e23 124
clemente 0:cfecfabc5e23 125 // soft reset...
clemente 2:a2fcfb7ff611 126 Reset();
clemente 0:cfecfabc5e23 127
clemente 0:cfecfabc5e23 128 Standby();
clemente 0:cfecfabc5e23 129 readRegs( REG_CTRL_REG_1, &t, 1);
clemente 0:cfecfabc5e23 130
clemente 0:cfecfabc5e23 131 data[0] = REG_CTRL_REG_1;
clemente 0:cfecfabc5e23 132 data[1] = t|0x80;
clemente 0:cfecfabc5e23 133 writeRegs(data, 2);
clemente 0:cfecfabc5e23 134
clemente 0:cfecfabc5e23 135 data[0] = REG_PT_DATA_CFG;
clemente 0:cfecfabc5e23 136 data[1] = 0x07;
clemente 0:cfecfabc5e23 137 writeRegs(data, 2);
clemente 0:cfecfabc5e23 138
clemente 0:cfecfabc5e23 139 Oversample_Ratio( MPL3115A2_oversampling);
clemente 0:cfecfabc5e23 140
clemente 0:cfecfabc5e23 141 Active();
clemente 0:cfecfabc5e23 142
clemente 0:cfecfabc5e23 143 MPL3115A2_mode = ALTIMETER_MODE;
clemente 0:cfecfabc5e23 144 }
clemente 0:cfecfabc5e23 145
clemente 0:cfecfabc5e23 146 void MPL3115A2::Oversample_Ratio( unsigned int ratio)
clemente 0:cfecfabc5e23 147 {
clemente 0:cfecfabc5e23 148 unsigned char t;
clemente 0:cfecfabc5e23 149
clemente 0:cfecfabc5e23 150 Standby();
clemente 0:cfecfabc5e23 151 readRegs( REG_CTRL_REG_1, &t, 1);
clemente 0:cfecfabc5e23 152
clemente 0:cfecfabc5e23 153 t = t & 0xE7;
clemente 0:cfecfabc5e23 154 t = t | ( ratio<<3);
clemente 0:cfecfabc5e23 155
clemente 0:cfecfabc5e23 156 unsigned char data[2] = { REG_CTRL_REG_1, t};
clemente 0:cfecfabc5e23 157 writeRegs(data, 2);
clemente 0:cfecfabc5e23 158
clemente 0:cfecfabc5e23 159 Active();
clemente 0:cfecfabc5e23 160
clemente 0:cfecfabc5e23 161 MPL3115A2_oversampling = ratio;
clemente 0:cfecfabc5e23 162 }
clemente 0:cfecfabc5e23 163
clemente 0:cfecfabc5e23 164
clemente 0:cfecfabc5e23 165 void MPL3115A2::Active( void)
clemente 0:cfecfabc5e23 166 {
clemente 0:cfecfabc5e23 167 unsigned char t;
clemente 0:cfecfabc5e23 168
clemente 0:cfecfabc5e23 169 // Activate the peripheral
clemente 0:cfecfabc5e23 170 readRegs(REG_CTRL_REG_1, &t, 1);
clemente 0:cfecfabc5e23 171 unsigned char data[2] = {REG_CTRL_REG_1, t|0x01};
clemente 0:cfecfabc5e23 172 writeRegs(data, 2);
clemente 0:cfecfabc5e23 173 }
clemente 0:cfecfabc5e23 174
clemente 0:cfecfabc5e23 175 void MPL3115A2::Standby( void)
clemente 0:cfecfabc5e23 176 {
clemente 0:cfecfabc5e23 177 unsigned char t;
clemente 0:cfecfabc5e23 178
clemente 0:cfecfabc5e23 179 // Standby
clemente 0:cfecfabc5e23 180 readRegs(REG_CTRL_REG_1, &t, 1);
clemente 0:cfecfabc5e23 181 unsigned char data[2] = {REG_CTRL_REG_1, t&0xFE};
clemente 0:cfecfabc5e23 182 writeRegs(data, 2);
clemente 0:cfecfabc5e23 183 }
clemente 0:cfecfabc5e23 184
clemente 0:cfecfabc5e23 185 unsigned char MPL3115A2::getDeviceID() {
clemente 0:cfecfabc5e23 186 unsigned char device_id = 0;
clemente 0:cfecfabc5e23 187 readRegs(REG_WHO_AM_I, &device_id, 1);
clemente 0:cfecfabc5e23 188 return device_id;
clemente 0:cfecfabc5e23 189 }
clemente 0:cfecfabc5e23 190
clemente 0:cfecfabc5e23 191 unsigned int MPL3115A2::isDataAvailable( void)
clemente 0:cfecfabc5e23 192 {
clemente 0:cfecfabc5e23 193 unsigned char status;
clemente 0:cfecfabc5e23 194
clemente 0:cfecfabc5e23 195 readRegs( REG_STATUS, &status, 1);
clemente 0:cfecfabc5e23 196
clemente 0:cfecfabc5e23 197 if ( status & 0x08) {
clemente 0:cfecfabc5e23 198 return 1;
clemente 0:cfecfabc5e23 199 } else {
clemente 0:cfecfabc5e23 200 return 0;
clemente 0:cfecfabc5e23 201 }
clemente 0:cfecfabc5e23 202
clemente 0:cfecfabc5e23 203 }
clemente 0:cfecfabc5e23 204
clemente 0:cfecfabc5e23 205 unsigned char MPL3115A2::getStatus( void)
clemente 0:cfecfabc5e23 206 {
clemente 0:cfecfabc5e23 207 unsigned char status;
clemente 0:cfecfabc5e23 208
clemente 0:cfecfabc5e23 209 readRegs( REG_STATUS, &status, 1);
clemente 0:cfecfabc5e23 210 return status;
clemente 0:cfecfabc5e23 211 }
clemente 0:cfecfabc5e23 212
clemente 0:cfecfabc5e23 213 void MPL3115A2::getAllData( float *f)
clemente 0:cfecfabc5e23 214 {
clemente 0:cfecfabc5e23 215 if ( MPL3115A2_mode == ALTIMETER_MODE) {
clemente 0:cfecfabc5e23 216 f[0] = getAltimeter();
clemente 0:cfecfabc5e23 217 } else {
clemente 0:cfecfabc5e23 218 f[0] = getPressure();
clemente 0:cfecfabc5e23 219 }
clemente 0:cfecfabc5e23 220
clemente 0:cfecfabc5e23 221 f[1] = getTemperature();
clemente 0:cfecfabc5e23 222 }
clemente 0:cfecfabc5e23 223
clemente 0:cfecfabc5e23 224 float MPL3115A2::getAltimeter( void)
clemente 0:cfecfabc5e23 225 {
clemente 0:cfecfabc5e23 226 unsigned char dt[3];
clemente 0:cfecfabc5e23 227 unsigned short altm;
clemente 0:cfecfabc5e23 228 float faltm;
clemente 0:cfecfabc5e23 229
clemente 0:cfecfabc5e23 230 /*
clemente 0:cfecfabc5e23 231 * dt[0] = Bits 12-19 of 20-bit real-time Pressure sample. (b7-b0)
clemente 0:cfecfabc5e23 232 * dt[1] = Bits 4-11 of 20-bit real-time Pressure sample. (b7-b0)
clemente 0:cfecfabc5e23 233 * dt[2] = Bits 0-3 of 20-bit real-time Pressure sample (b7-b4)
clemente 0:cfecfabc5e23 234 */
clemente 0:cfecfabc5e23 235 readRegs( REG_ALTIMETER_MSB, &dt[0], 3);
clemente 0:cfecfabc5e23 236 altm = (dt[0]<<8) | dt[1];
clemente 0:cfecfabc5e23 237 //
clemente 0:cfecfabc5e23 238 if ( dt[0] > 0x7F) {
clemente 0:cfecfabc5e23 239 altm = ~altm + 1;
clemente 0:cfecfabc5e23 240 faltm = (float)altm * -1.0f;
clemente 0:cfecfabc5e23 241 } else {
clemente 0:cfecfabc5e23 242 faltm = (float)altm * 1.0f;
clemente 0:cfecfabc5e23 243 }
clemente 0:cfecfabc5e23 244 //
clemente 0:cfecfabc5e23 245 faltm = faltm+((float)(dt[2]>>4) * 0.0625f);
clemente 0:cfecfabc5e23 246 return faltm;
clemente 0:cfecfabc5e23 247 }
clemente 0:cfecfabc5e23 248
clemente 0:cfecfabc5e23 249 float MPL3115A2::getPressure( void)
clemente 0:cfecfabc5e23 250 {
clemente 0:cfecfabc5e23 251 unsigned char dt[3];
clemente 0:cfecfabc5e23 252 unsigned int prs;
clemente 0:cfecfabc5e23 253 float fprs;
clemente 0:cfecfabc5e23 254
clemente 0:cfecfabc5e23 255 /*
clemente 0:cfecfabc5e23 256 * dt[0] = Bits 12-19 of 20-bit real-time Pressure sample. (b7-b0)
clemente 0:cfecfabc5e23 257 * dt[1] = Bits 4-11 of 20-bit real-time Pressure sample. (b7-b0)
clemente 0:cfecfabc5e23 258 * dt[2] = Bits 0-3 of 20-bit real-time Pressure sample (b7-b4)
clemente 0:cfecfabc5e23 259 */
clemente 0:cfecfabc5e23 260 readRegs( REG_PRESSURE_MSB, &dt[0], 3);
clemente 0:cfecfabc5e23 261 prs = (dt[0]<<10) | (dt[1]<<2) | (dt[2]>>6);
clemente 0:cfecfabc5e23 262 //
clemente 0:cfecfabc5e23 263 fprs = (float)prs * 1.0f;
clemente 0:cfecfabc5e23 264
clemente 0:cfecfabc5e23 265 if ( dt[2] & 0x20)
clemente 0:cfecfabc5e23 266 fprs += 0.25f;
clemente 0:cfecfabc5e23 267 if ( dt[2] & 0x10)
clemente 0:cfecfabc5e23 268 fprs += 0.5f;
clemente 0:cfecfabc5e23 269
clemente 0:cfecfabc5e23 270 return fprs;
clemente 0:cfecfabc5e23 271 }
clemente 0:cfecfabc5e23 272
clemente 0:cfecfabc5e23 273
clemente 0:cfecfabc5e23 274 float MPL3115A2::getTemperature( void)
clemente 0:cfecfabc5e23 275 {
clemente 0:cfecfabc5e23 276 unsigned char dt[2];
clemente 0:cfecfabc5e23 277 unsigned short temp;
clemente 0:cfecfabc5e23 278 float ftemp;
clemente 0:cfecfabc5e23 279
clemente 0:cfecfabc5e23 280 /*
clemente 0:cfecfabc5e23 281 * dt[0] = Bits 4-11 of 16-bit real-time temperature sample. (b7-b0)
clemente 0:cfecfabc5e23 282 * dt[1] = Bits 0-3 of 16-bit real-time temperature sample. (b7-b4)
clemente 0:cfecfabc5e23 283 */
clemente 0:cfecfabc5e23 284 readRegs( REG_TEMP_MSB, &dt[0], 2);
clemente 0:cfecfabc5e23 285 temp = dt[0];
clemente 0:cfecfabc5e23 286 //
clemente 0:cfecfabc5e23 287 if ( dt[0] > 0x7F) {
clemente 0:cfecfabc5e23 288 temp = ~temp + 1;
clemente 0:cfecfabc5e23 289 ftemp = (float)temp * -1.0f;
clemente 0:cfecfabc5e23 290 } else {
clemente 0:cfecfabc5e23 291 ftemp = (float)temp * 1.0f;
clemente 0:cfecfabc5e23 292 }
clemente 0:cfecfabc5e23 293 //
clemente 0:cfecfabc5e23 294 ftemp = ftemp+((float)(dt[1]>>4) * 0.0625f);
clemente 0:cfecfabc5e23 295 return ftemp;
clemente 0:cfecfabc5e23 296
clemente 0:cfecfabc5e23 297 }
clemente 0:cfecfabc5e23 298
clemente 0:cfecfabc5e23 299 void MPL3115A2::readRegs(int addr, uint8_t * data, int len) {
clemente 0:cfecfabc5e23 300 char t[1] = {addr};
clemente 0:cfecfabc5e23 301 m_i2c.write(m_addr, t, 1, true);
clemente 0:cfecfabc5e23 302 m_i2c.read(m_addr, (char *)data, len);
clemente 0:cfecfabc5e23 303 }
clemente 0:cfecfabc5e23 304
clemente 0:cfecfabc5e23 305 void MPL3115A2::writeRegs(uint8_t * data, int len) {
clemente 0:cfecfabc5e23 306 m_i2c.write(m_addr, (char *)data, len);
clemente 0:cfecfabc5e23 307 }