This is a simple wrapper class for the MPL3115A5 pressure and temperature sensor. It allows either single readings for continuous readings using polling or interrupts. It also contains a wrapper class for mbed-rpc.

Committer:
rhourahane
Date:
Sun Mar 22 20:55:38 2015 +0000
Revision:
0:b12a7d396be9
Initial revision.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
rhourahane 0:b12a7d396be9 1 #include <mbed.h>
rhourahane 0:b12a7d396be9 2 #include "mpl3115a2.h"
rhourahane 0:b12a7d396be9 3
rhourahane 0:b12a7d396be9 4 namespace {
rhourahane 0:b12a7d396be9 5 const char STATUS = 0x00;
rhourahane 0:b12a7d396be9 6 const char OUT_P_MSB = 0x01;
rhourahane 0:b12a7d396be9 7 const char OUT_T_MSB = 0x04;
rhourahane 0:b12a7d396be9 8 const char WHO_AM_I = 0x0C;
rhourahane 0:b12a7d396be9 9 const char SYSMOD = 0x11;
rhourahane 0:b12a7d396be9 10 const char PT_DATA_CFG = 0x13;
rhourahane 0:b12a7d396be9 11 const char CTRL_REG1 = 0x26;
rhourahane 0:b12a7d396be9 12 const char CTRL_REG2 = 0x27;
rhourahane 0:b12a7d396be9 13 const char CTRL_REG3 = 0x28;
rhourahane 0:b12a7d396be9 14 const char CTRL_REG4 = 0x29;
rhourahane 0:b12a7d396be9 15 const char CTRL_REG5 = 0x2A;
rhourahane 0:b12a7d396be9 16
rhourahane 0:b12a7d396be9 17 // Values for bits in STATUS
rhourahane 0:b12a7d396be9 18 const char STATUS_TDR = 0x02;
rhourahane 0:b12a7d396be9 19 const char STATUS_PDR = 0x04;
rhourahane 0:b12a7d396be9 20 const char STATUS_TPDR = 0x08;
rhourahane 0:b12a7d396be9 21 const char STATUS_DR_MASK = 0x0E;
rhourahane 0:b12a7d396be9 22 const char STATUS_TOW = 0x20;
rhourahane 0:b12a7d396be9 23 const char STATUS_POW = 0x40;
rhourahane 0:b12a7d396be9 24 const char STATUS_TPOW = 0x80;
rhourahane 0:b12a7d396be9 25 const char STATUS_OW_MASK = 0xE0;
rhourahane 0:b12a7d396be9 26
rhourahane 0:b12a7d396be9 27 // Values for bits in PT_DATA_CFG
rhourahane 0:b12a7d396be9 28 const char PT_DATA_CFG_TDEFE = 0x01;
rhourahane 0:b12a7d396be9 29 const char PT_DATA_CFG_PDEFE = 0x02;
rhourahane 0:b12a7d396be9 30 const char PT_DATA_CFG_DREM = 0x04;
rhourahane 0:b12a7d396be9 31
rhourahane 0:b12a7d396be9 32 // Values for bits in CTRL_REG1
rhourahane 0:b12a7d396be9 33 const char CTRL_REG1_SBYB = 0x01;
rhourahane 0:b12a7d396be9 34 const char CTRL_REG1_OSB = 0x02;
rhourahane 0:b12a7d396be9 35 const char CTRL_REG1_RST = 0x04;
rhourahane 0:b12a7d396be9 36 const char CTRL_REG1_OS_MASK = 0x38;
rhourahane 0:b12a7d396be9 37 const char CTRL_REG1_RAW = 0x40;
rhourahane 0:b12a7d396be9 38 const char CTRL_REG1_ALT = 0x80;
rhourahane 0:b12a7d396be9 39
rhourahane 0:b12a7d396be9 40 // Values for bits in CTRL_REG2
rhourahane 0:b12a7d396be9 41 const char CTRL_REG2_ST_MASK = 0x0F;
rhourahane 0:b12a7d396be9 42 const char CTRL_REG2_ALARM_SEL = 0x10;
rhourahane 0:b12a7d396be9 43 const char CTRL_REG2_LOAD_OUTPUT = 0x20;
rhourahane 0:b12a7d396be9 44
rhourahane 0:b12a7d396be9 45 // Values for bits in CTRL_REG4
rhourahane 0:b12a7d396be9 46 const char CTRL_REG4_INT_EN_TCHG = 0x01;
rhourahane 0:b12a7d396be9 47 const char CTRL_REG4_INT_EN_PCHG = 0x02;
rhourahane 0:b12a7d396be9 48 const char CTRL_REG4_INT_EN_TTH = 0x04;
rhourahane 0:b12a7d396be9 49 const char CTRL_REG4_INT_EN_PTH = 0x08;
rhourahane 0:b12a7d396be9 50 const char CTRL_REG4_INT_EN_TW = 0x10;
rhourahane 0:b12a7d396be9 51 const char CTRL_REG4_INT_EN_PW = 0x20;
rhourahane 0:b12a7d396be9 52 const char CTRL_REG4_INT_EN_FIFO = 0x40;
rhourahane 0:b12a7d396be9 53 const char CTRL_REG4_INT_EN_DRDY = 0x80;
rhourahane 0:b12a7d396be9 54
rhourahane 0:b12a7d396be9 55 // Values for bits in CTRL_REG5
rhourahane 0:b12a7d396be9 56 const char CTRL_REG5_INT_CFG_TCHG = 0x01;
rhourahane 0:b12a7d396be9 57 const char CTRL_REG5_INT_CFG_PW = 0x20;
rhourahane 0:b12a7d396be9 58 const char CTRL_REG5_INT_CFG_TTH = 0x04;
rhourahane 0:b12a7d396be9 59 const char CTRL_REG5_INT_CFG_PTH = 0x08;
rhourahane 0:b12a7d396be9 60 const char CTRL_REG5_INT_CFG_TW = 0x10;
rhourahane 0:b12a7d396be9 61 const char CTRL_REG5_INT_CFG_PCHG = 0x02;
rhourahane 0:b12a7d396be9 62 const char CTRL_REG5_INT_CFG_FIFO = 0x40;
rhourahane 0:b12a7d396be9 63 const char CTRL_REG5_INT_CFG_DRDY = 0x80;
rhourahane 0:b12a7d396be9 64 };
rhourahane 0:b12a7d396be9 65
rhourahane 0:b12a7d396be9 66 MPL3115A2::MPL3115A2(PinName sda, PinName scl) :
rhourahane 0:b12a7d396be9 67 m_i2c(sda, scl),
rhourahane 0:b12a7d396be9 68 m_addr(0x60<<1),
rhourahane 0:b12a7d396be9 69 m_readMode(Single),
rhourahane 0:b12a7d396be9 70 m_dataMode(BarometricMode),
rhourahane 0:b12a7d396be9 71 m_overSample(0),
rhourahane 0:b12a7d396be9 72 m_samplePeriod(0),
rhourahane 0:b12a7d396be9 73 m_dataReadInt(INT2)
rhourahane 0:b12a7d396be9 74 {
rhourahane 0:b12a7d396be9 75 // Reset the chip so we know where we are.
rhourahane 0:b12a7d396be9 76 char data[2] = { CTRL_REG1, CTRL_REG1_RST};
rhourahane 0:b12a7d396be9 77 writeRegs(data, 2);
rhourahane 0:b12a7d396be9 78 wait(0.1);
rhourahane 0:b12a7d396be9 79
rhourahane 0:b12a7d396be9 80 // Configure to get data ready events.
rhourahane 0:b12a7d396be9 81 data[0] = PT_DATA_CFG;
rhourahane 0:b12a7d396be9 82 data[1] = PT_DATA_CFG_TDEFE | PT_DATA_CFG_PDEFE | PT_DATA_CFG_DREM;
rhourahane 0:b12a7d396be9 83 writeRegs(data, 2);
rhourahane 0:b12a7d396be9 84 }
rhourahane 0:b12a7d396be9 85
rhourahane 0:b12a7d396be9 86 void MPL3115A2::setDataMode(DataMode mode) {
rhourahane 0:b12a7d396be9 87 m_dataMode = mode;
rhourahane 0:b12a7d396be9 88 }
rhourahane 0:b12a7d396be9 89
rhourahane 0:b12a7d396be9 90 MPL3115A2::DataMode MPL3115A2::getDataMode(void) {
rhourahane 0:b12a7d396be9 91 return m_dataMode;
rhourahane 0:b12a7d396be9 92 }
rhourahane 0:b12a7d396be9 93
rhourahane 0:b12a7d396be9 94 void MPL3115A2::setReadMode(ReadMode mode) {
rhourahane 0:b12a7d396be9 95 m_readMode = mode;
rhourahane 0:b12a7d396be9 96 }
rhourahane 0:b12a7d396be9 97
rhourahane 0:b12a7d396be9 98 MPL3115A2::ReadMode MPL3115A2::getReadMode(void) {
rhourahane 0:b12a7d396be9 99 return m_readMode;
rhourahane 0:b12a7d396be9 100 }
rhourahane 0:b12a7d396be9 101
rhourahane 0:b12a7d396be9 102 void MPL3115A2::setOverSampling(int samples) {
rhourahane 0:b12a7d396be9 103 int pow = 0;
rhourahane 0:b12a7d396be9 104 while (((samples % 2) != 1) && (pow < 8)) {
rhourahane 0:b12a7d396be9 105 ++pow;
rhourahane 0:b12a7d396be9 106 samples = samples >> 1;
rhourahane 0:b12a7d396be9 107 }
rhourahane 0:b12a7d396be9 108 m_overSample = pow;
rhourahane 0:b12a7d396be9 109 }
rhourahane 0:b12a7d396be9 110
rhourahane 0:b12a7d396be9 111 int MPL3115A2::getOverSampling(void) {
rhourahane 0:b12a7d396be9 112 return 1 << m_overSample;
rhourahane 0:b12a7d396be9 113 }
rhourahane 0:b12a7d396be9 114
rhourahane 0:b12a7d396be9 115 void MPL3115A2::setSamplingPeriod(int period) {
rhourahane 0:b12a7d396be9 116 int pow = 0;
rhourahane 0:b12a7d396be9 117 while (((period % 2) != 1) && (pow < 16)) {
rhourahane 0:b12a7d396be9 118 ++pow;
rhourahane 0:b12a7d396be9 119 period = period >> 1;
rhourahane 0:b12a7d396be9 120 }
rhourahane 0:b12a7d396be9 121 m_samplePeriod = pow;
rhourahane 0:b12a7d396be9 122 }
rhourahane 0:b12a7d396be9 123
rhourahane 0:b12a7d396be9 124 int MPL3115A2::getSamplingPeriod(void) {
rhourahane 0:b12a7d396be9 125 return 1 << m_samplePeriod;
rhourahane 0:b12a7d396be9 126 }
rhourahane 0:b12a7d396be9 127
rhourahane 0:b12a7d396be9 128 void MPL3115A2::setDataReadyInt(InterruptPin intPin) {
rhourahane 0:b12a7d396be9 129 m_dataReadInt = intPin;
rhourahane 0:b12a7d396be9 130 }
rhourahane 0:b12a7d396be9 131
rhourahane 0:b12a7d396be9 132 MPL3115A2::InterruptPin MPL3115A2::getDataReadyInt(void) {
rhourahane 0:b12a7d396be9 133 return m_dataReadInt;
rhourahane 0:b12a7d396be9 134 }
rhourahane 0:b12a7d396be9 135
rhourahane 0:b12a7d396be9 136 int MPL3115A2::getId(void) {
rhourahane 0:b12a7d396be9 137 char id;
rhourahane 0:b12a7d396be9 138
rhourahane 0:b12a7d396be9 139 // Read the WHO_AM_I register to get the value.
rhourahane 0:b12a7d396be9 140 readRegs(WHO_AM_I, &id, 1);
rhourahane 0:b12a7d396be9 141 return id;
rhourahane 0:b12a7d396be9 142 }
rhourahane 0:b12a7d396be9 143
rhourahane 0:b12a7d396be9 144 int MPL3115A2::getStatus(void) {
rhourahane 0:b12a7d396be9 145 char status;
rhourahane 0:b12a7d396be9 146
rhourahane 0:b12a7d396be9 147 readRegs(STATUS, &status, 1);
rhourahane 0:b12a7d396be9 148 return status;
rhourahane 0:b12a7d396be9 149 }
rhourahane 0:b12a7d396be9 150
rhourahane 0:b12a7d396be9 151 bool MPL3115A2::isDataReady(void) {
rhourahane 0:b12a7d396be9 152 char status;
rhourahane 0:b12a7d396be9 153
rhourahane 0:b12a7d396be9 154 // Read the STATUS register and and in the data ready mask
rhourahane 0:b12a7d396be9 155 // to get a boolean.
rhourahane 0:b12a7d396be9 156 readRegs(STATUS, &status, 1);
rhourahane 0:b12a7d396be9 157 return (status & STATUS_DR_MASK) != 0;
rhourahane 0:b12a7d396be9 158 };
rhourahane 0:b12a7d396be9 159
rhourahane 0:b12a7d396be9 160 void MPL3115A2::activate() {
rhourahane 0:b12a7d396be9 161 if (m_readMode != Single) {
rhourahane 0:b12a7d396be9 162 char reg1 = CTRL_REG1_SBYB;
rhourahane 0:b12a7d396be9 163 char reg2 = 0;
rhourahane 0:b12a7d396be9 164 char reg4 = 0;
rhourahane 0:b12a7d396be9 165 char reg5 = 0;
rhourahane 0:b12a7d396be9 166
rhourahane 0:b12a7d396be9 167 // Set the data mode and over sampling correctly
rhourahane 0:b12a7d396be9 168 switch (m_dataMode) {
rhourahane 0:b12a7d396be9 169 case BarometricMode:
rhourahane 0:b12a7d396be9 170 // nothing to set.
rhourahane 0:b12a7d396be9 171 break;
rhourahane 0:b12a7d396be9 172
rhourahane 0:b12a7d396be9 173 case AltimeterMode:
rhourahane 0:b12a7d396be9 174 reg1 |= CTRL_REG1_ALT;
rhourahane 0:b12a7d396be9 175 break;
rhourahane 0:b12a7d396be9 176
rhourahane 0:b12a7d396be9 177 case RawMode:
rhourahane 0:b12a7d396be9 178 reg1 |= CTRL_REG1_RAW;
rhourahane 0:b12a7d396be9 179 break;
rhourahane 0:b12a7d396be9 180 }
rhourahane 0:b12a7d396be9 181 reg1 |= (m_overSample << 3) & CTRL_REG1_OS_MASK;
rhourahane 0:b12a7d396be9 182
rhourahane 0:b12a7d396be9 183 // Set the sampling period
rhourahane 0:b12a7d396be9 184 reg2 = m_samplePeriod & CTRL_REG2_ST_MASK;
rhourahane 0:b12a7d396be9 185
rhourahane 0:b12a7d396be9 186 // If we are using interupts then configure the
rhourahane 0:b12a7d396be9 187 // interrupt registers.
rhourahane 0:b12a7d396be9 188 if (m_readMode == Interupt) {
rhourahane 0:b12a7d396be9 189 reg4 = CTRL_REG4_INT_EN_DRDY;
rhourahane 0:b12a7d396be9 190 if (m_dataReadInt == INT1) {
rhourahane 0:b12a7d396be9 191 reg5 = CTRL_REG5_INT_CFG_DRDY;
rhourahane 0:b12a7d396be9 192 }
rhourahane 0:b12a7d396be9 193 }
rhourahane 0:b12a7d396be9 194
rhourahane 0:b12a7d396be9 195 char data[6] = { CTRL_REG1, reg1, reg2, 0, reg4, reg5 };
rhourahane 0:b12a7d396be9 196 writeRegs(data, 6);
rhourahane 0:b12a7d396be9 197 }
rhourahane 0:b12a7d396be9 198 }
rhourahane 0:b12a7d396be9 199
rhourahane 0:b12a7d396be9 200 bool MPL3115A2::isActive() {
rhourahane 0:b12a7d396be9 201 char status;
rhourahane 0:b12a7d396be9 202
rhourahane 0:b12a7d396be9 203 // read the active status from the SYSMOD register
rhourahane 0:b12a7d396be9 204 readRegs(SYSMOD, &status, 1);
rhourahane 0:b12a7d396be9 205 return status != 0;
rhourahane 0:b12a7d396be9 206 }
rhourahane 0:b12a7d396be9 207
rhourahane 0:b12a7d396be9 208 void MPL3115A2::standby() {
rhourahane 0:b12a7d396be9 209
rhourahane 0:b12a7d396be9 210 // Clear the CTRL_REG1 to put the chip into standby.
rhourahane 0:b12a7d396be9 211 char data[2] = { CTRL_REG1, 0 };
rhourahane 0:b12a7d396be9 212 writeRegs(data, 2);
rhourahane 0:b12a7d396be9 213 }
rhourahane 0:b12a7d396be9 214
rhourahane 0:b12a7d396be9 215
rhourahane 0:b12a7d396be9 216 bool MPL3115A2::getReadings(float &pres, float &temp) {
rhourahane 0:b12a7d396be9 217 if (m_dataMode == RawMode) {
rhourahane 0:b12a7d396be9 218 // Raw mode not supported.
rhourahane 0:b12a7d396be9 219 return false;
rhourahane 0:b12a7d396be9 220 }
rhourahane 0:b12a7d396be9 221
rhourahane 0:b12a7d396be9 222 // If we're in single read mode then we need to initiate
rhourahane 0:b12a7d396be9 223 // a new read cycle.
rhourahane 0:b12a7d396be9 224 if (m_readMode == Single) {
rhourahane 0:b12a7d396be9 225 // Set the OSB bit to initiate a new reading.
rhourahane 0:b12a7d396be9 226 char value = CTRL_REG1_OSB;
rhourahane 0:b12a7d396be9 227
rhourahane 0:b12a7d396be9 228 // Add in oversampling
rhourahane 0:b12a7d396be9 229 value |= (m_overSample << 3) & CTRL_REG1_OS_MASK;
rhourahane 0:b12a7d396be9 230
rhourahane 0:b12a7d396be9 231 // Set the pressure reading mode to altimeter if needed.
rhourahane 0:b12a7d396be9 232 if (m_dataMode == AltimeterMode) {
rhourahane 0:b12a7d396be9 233 value |= CTRL_REG1_ALT;
rhourahane 0:b12a7d396be9 234 }
rhourahane 0:b12a7d396be9 235
rhourahane 0:b12a7d396be9 236 // Write the new value to CTRL_REG1 to kick things off.
rhourahane 0:b12a7d396be9 237 char data[2] = { CTRL_REG1, value};
rhourahane 0:b12a7d396be9 238 writeRegs(data, 2);
rhourahane 0:b12a7d396be9 239 }
rhourahane 0:b12a7d396be9 240
rhourahane 0:b12a7d396be9 241 int status = 0;
rhourahane 0:b12a7d396be9 242
rhourahane 0:b12a7d396be9 243 // Loop until the data is ready.
rhourahane 0:b12a7d396be9 244 while ((status & STATUS_DR_MASK) == 0) {
rhourahane 0:b12a7d396be9 245 status = getStatus();
rhourahane 0:b12a7d396be9 246 printf("0x%X-", status);
rhourahane 0:b12a7d396be9 247 }
rhourahane 0:b12a7d396be9 248
rhourahane 0:b12a7d396be9 249 // Read the pressure and temperature data all at once
rhourahane 0:b12a7d396be9 250 // and then convert it into real values.
rhourahane 0:b12a7d396be9 251 char data[5];
rhourahane 0:b12a7d396be9 252 readRegs(OUT_P_MSB, &data[0], 5);
rhourahane 0:b12a7d396be9 253 if (m_dataMode == AltimeterMode) {
rhourahane 0:b12a7d396be9 254 pres = convAltimeter(&data[0]);
rhourahane 0:b12a7d396be9 255 } else {
rhourahane 0:b12a7d396be9 256 pres = convPressure(&data[0]);
rhourahane 0:b12a7d396be9 257 }
rhourahane 0:b12a7d396be9 258 temp = convTemperature(&data[3]);
rhourahane 0:b12a7d396be9 259
rhourahane 0:b12a7d396be9 260 return true;
rhourahane 0:b12a7d396be9 261 }
rhourahane 0:b12a7d396be9 262
rhourahane 0:b12a7d396be9 263
rhourahane 0:b12a7d396be9 264 float MPL3115A2::convTemperature(char *data) {
rhourahane 0:b12a7d396be9 265 short temp;
rhourahane 0:b12a7d396be9 266 float ftemp;
rhourahane 0:b12a7d396be9 267
rhourahane 0:b12a7d396be9 268 // Move the signed byte up to the top of the short so
rhourahane 0:b12a7d396be9 269 // that it is in the right place and or in the bottom
rhourahane 0:b12a7d396be9 270 // 8bits.
rhourahane 0:b12a7d396be9 271 temp = (data[0] << 8) | data[1];
rhourahane 0:b12a7d396be9 272
rhourahane 0:b12a7d396be9 273 // shift out the bottom 4 0 bits and convert
rhourahane 0:b12a7d396be9 274 // the integer temp into a float value by
rhourahane 0:b12a7d396be9 275 // dividing by 16.
rhourahane 0:b12a7d396be9 276 ftemp = (temp >> 4) / 16.0f;
rhourahane 0:b12a7d396be9 277 return ftemp;
rhourahane 0:b12a7d396be9 278 }
rhourahane 0:b12a7d396be9 279
rhourahane 0:b12a7d396be9 280 float MPL3115A2::convAltimeter(char *data) {
rhourahane 0:b12a7d396be9 281 int altInt;
rhourahane 0:b12a7d396be9 282 float altFloat;
rhourahane 0:b12a7d396be9 283
rhourahane 0:b12a7d396be9 284 // Put the 3 byte value in the upper 24 bits so the sign
rhourahane 0:b12a7d396be9 285 // is correct.
rhourahane 0:b12a7d396be9 286 altInt = (data[0] << 24) | (data[1] << 16) | (data[2] << 8);
rhourahane 0:b12a7d396be9 287
rhourahane 0:b12a7d396be9 288 // Shift down extending the sign as we go and then
rhourahane 0:b12a7d396be9 289 // divide by 16 to get fractions.
rhourahane 0:b12a7d396be9 290 altFloat = (altInt >> 12) / 16.0f;
rhourahane 0:b12a7d396be9 291
rhourahane 0:b12a7d396be9 292 return altFloat;
rhourahane 0:b12a7d396be9 293 }
rhourahane 0:b12a7d396be9 294
rhourahane 0:b12a7d396be9 295 float MPL3115A2::convPressure(char *data) {
rhourahane 0:b12a7d396be9 296 int presInt;
rhourahane 0:b12a7d396be9 297 float fprs;
rhourahane 0:b12a7d396be9 298
rhourahane 0:b12a7d396be9 299 // Or in the three bytes containing the 18bit int
rhourahane 0:b12a7d396be9 300 // into the top 18bits so the sign bit is correct.
rhourahane 0:b12a7d396be9 301 presInt = (data[0] << 24) | (data[1] << 16) | (data[2] << 8);
rhourahane 0:b12a7d396be9 302
rhourahane 0:b12a7d396be9 303 // Shift the in into the correct position and then
rhourahane 0:b12a7d396be9 304 // divide by 4 to generate the fractional part.
rhourahane 0:b12a7d396be9 305 fprs = (presInt >> 12) / 4.0f;
rhourahane 0:b12a7d396be9 306
rhourahane 0:b12a7d396be9 307 return fprs;
rhourahane 0:b12a7d396be9 308 }
rhourahane 0:b12a7d396be9 309
rhourahane 0:b12a7d396be9 310 void MPL3115A2::readRegs(char addr, char *data, int len) {
rhourahane 0:b12a7d396be9 311 m_i2c.write(m_addr, &addr, 1, true);
rhourahane 0:b12a7d396be9 312 m_i2c.read(m_addr, data, len);
rhourahane 0:b12a7d396be9 313 }
rhourahane 0:b12a7d396be9 314
rhourahane 0:b12a7d396be9 315 void MPL3115A2::writeRegs(const char *data, int len) {
rhourahane 0:b12a7d396be9 316 m_i2c.write(m_addr, data, len);
rhourahane 0:b12a7d396be9 317 }
rhourahane 0:b12a7d396be9 318