Multi-Hackers / MPL3115A2

Dependents:   mDotEVBM2X MTDOT-EVBDemo-DRH MTDOT-BOX-EVB-Factory-Firmware-LIB-108 MTDOT-UDKDemo_Senet ... more

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers MPL3115A2.cpp Source File

MPL3115A2.cpp

Go to the documentation of this file.
00001 /**
00002  * @file    MPL3115A2.cpp
00003  * @brief   Device driver - MPL3115A2 barometric pressure IC w/RTOS support
00004  * @author  Tim Barr
00005  * @version 1.0
00006  * @see     http://cache.freescale.com/files/sensors/doc/data_sheet/MPL3115A2.pdf
00007  *
00008  * Copyright (c) 2015
00009  *
00010  * Licensed under the Apache License, Version 2.0 (the "License");
00011  * you may not use this file except in compliance with the License.
00012  * You may obtain a copy of the License at
00013  *
00014  *     http://www.apache.org/licenses/LICENSE-2.0
00015  *
00016  * Unless required by applicable law or agreed to in writing, software
00017  * distributed under the License is distributed on an "AS IS" BASIS,
00018  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00019  * See the License for the specific language governing permissions and
00020  * limitations under the License.
00021  */
00022 
00023 #include "MPL3115A2.h"
00024 #include "mbed_debug.h"
00025 #include "rtos.h"
00026 
00027 MPL3115A2::MPL3115A2( I2C &i2c, InterruptIn* int1, InterruptIn* int2)
00028 {
00029     _i2c =  &i2c;
00030     _int1 = int1;
00031     _int2 = int2;
00032 
00033     MPL3115A2::init();
00034 
00035     return;
00036 }
00037 
00038 bool MPL3115A2::testWhoAmI(void)
00039 {
00040     char reg_val[1];
00041 
00042     reg_val[0] = 0x00;
00043     MPL3115A2::readRegister(WHO_AM_I,reg_val);
00044 
00045     return (reg_val[0] == I_AM_MPL3115A2 );
00046 
00047 }
00048 
00049 uint8_t MPL3115A2::init(void)
00050 {
00051     uint8_t result = 0;
00052     uint8_t i = 0;
00053     char reg_val[1];
00054 
00055     // Reset all registers to POR values
00056     reg_val[0] = 0x04;
00057     result = MPL3115A2::writeRegister(CTRL_REG1, reg_val);
00058     do {
00059          // wait for the reset bit to clear. readRegister may error out so we re-try 10 times
00060         osDelay(200);
00061         reg_val[0] = 0x40;
00062         result = MPL3115A2::readRegister(CTRL_REG1,reg_val);
00063         reg_val[0] = reg_val[0] & 0x04;
00064         i++;
00065     } while(((reg_val[0] != 0) || (result != 0)) && (i<=10));
00066 
00067     if ((result == 0) && (MPL3115A2::testWhoAmI() == true)) {
00068 
00069         if ((_int1 == NULL) && (_int2 == NULL)) {
00070             _polling_mode = true;
00071             reg_val[0] = 0x07;
00072             result |= MPL3115A2::writeRegister(PT_DATA_CFG,reg_val);
00073         } else _polling_mode = false;
00074     } else {
00075         debug ("Device not supported by this library!\n\r");
00076         result = 1;
00077     }
00078 
00079     if (result != 0) {
00080         debug("MPL3115A2:init failed\n\r");
00081     }
00082     
00083     return result;
00084 }
00085 
00086 uint8_t MPL3115A2::setParameters(OUTPUT_MODE out_mode, DATA_MODE data_mode, OVERSAMPLE_RATIO os_ratio,
00087                                  ACQUISITION_TIMER measure_time)
00088 {
00089     uint8_t result = 0;
00090     char datain[4];
00091     char dataout[4];
00092 
00093     result |= MPL3115A2::readRegister(SYSMOD, datain); // Make sure MPL3115A2 is in Stand-By mode
00094     if ((datain[0] & 0x01) != 0 ) {
00095         debug ("MPL3115A2 not in STAND BY mode\n\f");
00096         debug("MPL3115A2:setParameters failed\n\r");
00097         result = 1;
00098         return result;
00099     }
00100 
00101     result |= MPL3115A2::readRegister(CTRL_REG1, datain, 2);
00102     dataout[0] = (datain[0] & 0x07) | os_ratio | out_mode | data_mode;
00103     dataout[1] = (datain[1] & 0xF0) | measure_time;
00104     result |= MPL3115A2::writeRegister(CTRL_REG1, dataout, 2);
00105 
00106     if(result != 0) {
00107         debug("MPL3115A2:setParameters failed\n\r");
00108     }
00109 
00110     return result;
00111 }
00112 
00113 uint8_t MPL3115A2::enableFIFO(void)
00114 {
00115     uint8_t result = 0;
00116     return result;
00117 }
00118 
00119 uint8_t MPL3115A2::activeMode(void)
00120 {
00121     uint8_t result = 0;
00122     char datain[1];
00123     char dataout[1];
00124 
00125     result |= MPL3115A2::readRegister(CTRL_REG1, datain , 2);
00126     dataout[0] = (datain[0] & 0xFE) | 0x01 ;
00127     result |= MPL3115A2::writeRegister(CTRL_REG1, dataout);        // Set to active mode
00128 
00129     return result;
00130 }
00131 uint8_t MPL3115A2::standbyMode(void)
00132 {
00133     uint8_t result = 0;
00134     char datain[1];
00135     char dataout[1];
00136 
00137     result |= MPL3115A2::readRegister(CTRL_REG1, datain);
00138     dataout[0] = (datain[0] & 0xFE);
00139     result |= MPL3115A2::writeRegister(CTRL_REG1, dataout);        // Set to standby mode
00140 
00141     return result;
00142 }
00143 
00144 uint8_t MPL3115A2::triggerOneShot(void)
00145 {
00146     uint8_t result = 0;
00147     char datain[1];
00148     char dataout[1];
00149 
00150     result |= MPL3115A2::readRegister(CTRL_REG1, datain);
00151     dataout[0] = ((datain[0] & 0xFD) | 0x02);
00152     result |= MPL3115A2::writeRegister(CTRL_REG1, dataout);        // Trigger a measurement
00153 
00154     return result;
00155 }
00156 
00157 uint8_t MPL3115A2::setAltitudeCalib(int16_t alti_calib)
00158 {
00159     uint8_t result = 0;
00160     char dataout[1];
00161 
00162     dataout[0] = alti_calib ;
00163     result |= MPL3115A2::writeRegister(CTRL_REG1, dataout);        // set msb of calibration value
00164 
00165     return result;
00166 }
00167 
00168 uint8_t MPL3115A2::clearMinMaxRegs(void)
00169 {
00170     uint8_t result = 0;
00171     char datain[10];
00172 
00173     memset(datain, 0, 10);
00174     result = MPL3115A2::writeRegister(P_MIN_MSB, datain, 10);
00175 
00176     return result;
00177 }
00178 
00179 uint8_t MPL3115A2::getStatus(void)
00180 {
00181     char datain[1];
00182     uint8_t dataout;
00183 
00184     MPL3115A2::readRegister(DR_STATUS, datain);
00185     dataout = datain[0];
00186 
00187     return dataout;
00188 }
00189 
00190 int32_t MPL3115A2::getBaroData(void)
00191 {
00192     if (_polling_mode) {
00193         char datain[3];
00194         MPL3115A2::readRegister(OUT_P_MSB, datain, 3);
00195         /* data is 20 bit signed/unsigned with 4 LSB = 0 Need to shift to 32 bits to preserve sign bit
00196          * Altitude is 16 bit signed and pressure is 18 bit unsigned
00197          */
00198         _data._baro  = ((datain[0] << 24) | (datain[1] << 16) | (datain[2]<<8));
00199     }
00200     return _data._baro ;
00201 }
00202 
00203 int16_t MPL3115A2::getTempData(void)
00204 {
00205     if (_polling_mode) {
00206         char datain[2];
00207         MPL3115A2::readRegister(OUT_T_MSB, datain, 2);
00208         /* data is 12 bit signed with 4 LSB = 0 Need to shift first to 16 bits to preserve sign bit then
00209          *  divide by 16 to remove LSBs
00210          */
00211         _data._temp = ((datain[0] << 8) | datain[1]);
00212         _data._temp /= 16;
00213     }
00214     return _data._temp;
00215 }
00216 
00217 int32_t MPL3115A2::getMinBaro(bool clear_data)
00218 {
00219     if (_polling_mode) {
00220         char datain[3];
00221         MPL3115A2::readRegister(P_MIN_MSB, datain, 3);
00222         /* data is 20 bit signed/unsigned with 4 LSB = 0 Need to shift to 32 bits to preserve sign bit
00223          * Altitude is 16 bit signed and pressure is 18 bit unsigned
00224          */
00225         _data._minbaro = ((datain[0] << 24) | (datain[1] << 16) | (datain[2] << 8));
00226 
00227         if (clear_data) {
00228             memset(datain, 0, 3);
00229             MPL3115A2::writeRegister(P_MIN_MSB, datain, 3);
00230         }
00231     }
00232 
00233     return _data._minbaro;
00234 }
00235 
00236 int32_t MPL3115A2::getMaxBaro(bool   clear_data)
00237 {
00238     if (_polling_mode) {
00239         char datain[3];
00240 
00241         MPL3115A2::readRegister(P_MAX_MSB, datain, 3);
00242         /* data is 20 bit signed/unsigned with 4 LSB = 0 Need to shift to 32 bits to preserve sign bit
00243          * Altitude is 16 bit signed and pressure is 18 bit unsigned
00244          */
00245         _data._maxbaro = ((datain[0] << 24) | (datain[1] << 16) | (datain[2] << 8));
00246 
00247         if (clear_data) {
00248             memset(datain, 0, 3);
00249             MPL3115A2::writeRegister(P_MAX_MSB, datain, 3);
00250         }
00251     }
00252 
00253     return _data._maxbaro;
00254 }
00255 
00256 int16_t MPL3115A2::getMinTemp(bool   clear_data)
00257 {
00258     if (_polling_mode) {
00259         char datain[2];
00260         MPL3115A2::readRegister(T_MIN_MSB, datain, 2);
00261         /* data is 12 bit signed with 4 LSB = 0 Need to shift first to 16 bits to preserve sign bit then
00262          *  divide by 16 to remove LSBs
00263          */
00264         _data._mintemp = ((datain[0] << 8) | datain[1] );
00265         _data._mintemp /= 16;
00266 
00267         if (clear_data) {
00268             memset(datain, 0, 2);
00269             MPL3115A2::writeRegister(T_MIN_MSB, datain, 2);
00270         }
00271     }
00272 
00273     return _data._mintemp;
00274 }
00275 
00276 int16_t MPL3115A2::getMaxTemp(bool   clear_data)
00277 {
00278     if (_polling_mode) {
00279         char datain[2];
00280         MPL3115A2::readRegister(T_MIN_MSB, datain, 2);
00281         /* data is 12 bit signed with 4 LSB = 0 Need to shift first to 16 bits to preserve sign bit then
00282          *  divide by 16 to remove LSBs
00283          */
00284         _data._maxtemp = ((datain[0] << 8) | datain[1] );
00285         _data._maxtemp /= 16;
00286 
00287         if (clear_data) {
00288             memset(datain, 0, 2);
00289             MPL3115A2::writeRegister(T_MAX_MSB, datain, 2);
00290         }
00291     }
00292 
00293     return _data._maxtemp;
00294 }
00295 
00296 MPL3115A2_DATA MPL3115A2::getAllData(bool clear_data)
00297 {
00298 
00299     if (_polling_mode) {
00300         char datain[10];
00301         MPL3115A2::readRegister(OUT_P_MSB, datain, 5);
00302         /* data is 20 bit signed/unsigned with 4 LSB = 0 Need to shift to 32 bits to preserve sign bit
00303          * Altitude is 16 bit signed and pressure is 18 bit unsigned
00304          */
00305         _data._baro  = ((datain[0] << 24) | (datain[1] << 16) | (datain[2]<<8));
00306 
00307         /* data is 12 bit signed with 4 LSB = 0 Need to shift first to 16 bits to preserve sign bit then
00308          *  divide by 16 to remove LSBs
00309          */
00310         _data._temp = ((datain[3] << 8) | datain[4]);
00311         _data._temp /= 16;
00312 
00313         MPL3115A2::readRegister(P_MIN_MSB, datain, 10);
00314         /* data is 20 bit signed/unsigned with 4 LSB = 0 Need to shift to 32 bits to preserve sign bit
00315          * Altitude is 16 bit signed and pressure is 18 bit unsigned
00316          *  temperature data is 12 bit signed with 4 LSB = 0 Need to shift first to 16 bits to preserve sign bit then
00317          *  divide by 16 to remove LSBs
00318          */
00319         _data._minbaro = ((datain[0] << 24) | (datain[1] << 16) | (datain[2] << 8));
00320         _data._mintemp = ((datain[3] << 8) | datain[4] );
00321         _data._mintemp /= 16;
00322         _data._maxbaro = ((datain[5] << 24) | (datain[6] << 16) | (datain[7] << 8));
00323         _data._maxtemp = ((datain[8] << 8) | datain[9] );
00324         _data._maxtemp /= 16;
00325 
00326         if (clear_data) {
00327             MPL3115A2::clearMinMaxRegs();
00328         }
00329     }
00330 
00331     return _data;
00332 }
00333 
00334 uint8_t MPL3115A2::writeRegister(uint8_t reg, char* data, uint8_t count)
00335 {
00336     char buf[11];
00337     uint8_t result = 0;
00338 
00339     buf[0] = reg;
00340     memcpy(buf+1,data,count);
00341 
00342     result |= _i2c->write(_i2c_addr, buf, (count + 1));
00343 
00344     if (result != 0) {
00345         debug("MPL3115A2::writeRegister failed r-%d\n\r",result);
00346     }
00347 
00348     return result;
00349 }
00350 
00351 uint8_t MPL3115A2::readRegister(uint8_t reg, char* data, uint8_t count)
00352 {
00353     uint8_t result = 0;
00354     char reg_out[1];
00355 
00356     reg_out[0] = reg;
00357     _i2c->lock();
00358 
00359     // MPL3115A2 expects a repeated start from the master
00360     result |= _i2c->write(_i2c_addr,reg_out,1,true);
00361 
00362     if (result != 0) {
00363         debug("MPL3115A2::readRegister failed write\n\r");
00364         goto exit;
00365     }
00366 
00367     result |= _i2c->read(_i2c_addr,data,count,false);
00368 
00369     if (result != 0) {
00370         debug("MPL3115A2::readRegister failed read\n\r");
00371     }
00372 
00373 exit:
00374     _i2c->unlock();
00375     return result;
00376 }