moon

Dependencies:   Hexi_OLED_SSD1351

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers Barometer.cpp Source File

Barometer.cpp

00001 #include "Barometer.h"
00002 
00003 #define deviceDetail_REG        0x0C        // return 0xC4 by default
00004 #define STATUS_REG          0x00
00005 #define CTRL_REG_1          0x26
00006 #define CTRL_REG_3          0x28
00007 #define CTRL_REG_4          0x29
00008 #define CTRL_REG_5          0x2A
00009 #define PRESSURE_MSB        0x01        // pressure data
00010 #define ALTIMETER_MSB       0x01        //  altimeter data
00011 #define TEMP_MSB            0x04        // temperature data
00012 #define PT_DATA_CFG         0x13
00013 #define P_TGT_MSB           0x16
00014 #define P_WND_MSB           0x19
00015 #define OFF_P           0x2b
00016 #define OFF_T           0x2c
00017 #define OFF_H           0x2d
00018 #define MIN_PRESSURE_MSB    0x1c
00019 #define ALTI_MIN_MSB        0x1c
00020 #define TEMP_MIN_MSB        0x1f
00021 #define PRES_MAX_MSB        0x21
00022 #define ALTI_MAX_MSB        0x21
00023 #define TEMP_MAX_MSB        0x24
00024 #define PRES_DELTA_MSB      0x07
00025 #define ALTI_DELTA_MSB      0x07
00026 #define TEMP_DELTA_MSB      0x0a
00027 
00028 
00029 #define UINT14_MAX        16383
00030 
00031 // Status flag for data ready.
00032 #define PTDR_STATUS       0x03        // Pressure Altitude
00033 #define PDR_STATUS        0x02        // Pressure and Altitude data ready
00034 #define TDR_STATUS        0x01
00035 
00036 
00037 void (*MPL3115A2_usr2_fptr)(void);               // Pointers to user function called after
00038 void (*MPL3115A2_usr1_fptr)(void);               // IRQ assertion.
00039 
00040 //
00041 InterruptIn Device_Int1( PTD4);       // INT1
00042 InterruptIn Device_Int2( PTA12);      // INT2
00043 
00044 DEVICE::DEVICE(PinName sda, PinName scl, int addr) : m_i2c(sda, scl), m_addr(addr) {
00045     unsigned char data[6];
00046     
00047     Device_mode = MODE_BAR;
00048     Device_oversampling = OVERSAMPLE_1;
00049 
00050     MPL3115A2_usr1_fptr = NULL;
00051     MPL3115A2_usr2_fptr = NULL;
00052     Device_Int1.fall( NULL);
00053     Device_Int2.fall( NULL);
00054     
00055     Reset();        //soft reset
00056     
00057     data[0]=MIN_PRESSURE_MSB;
00058     data[1]=0;data[2]=0;data[3]=0;data[4]=0;data[5]=0;
00059     writeRegs( &data[0], 6);
00060 }
00061 
00062 void DEVICE::Reset( void)
00063 {
00064     unsigned char t;
00065     
00066 
00067     readRegs( CTRL_REG_1, &t, 1);
00068     unsigned char data[2] = { CTRL_REG_1, t|0x04};
00069 
00070 
00071     writeRegs(data, 2);      //soft reset
00072     wait( 0.1);
00073 
00074 }
00075 
00076 void DEVICE::DReady( void(*fptr)(void), unsigned char OS)
00077 {
00078     unsigned char dt[5];
00079     unsigned char data[2];
00080     
00081     // Soft Reset
00082     Reset();
00083     
00084     Standby();
00085     
00086     // Clear all interrupts by reading the output registers.
00087     readRegs( ALTIMETER_MSB, &dt[0], 5);
00088     statusRequest();
00089     // Configure INT active low and pullup
00090     data[0] = CTRL_REG_3;
00091     data[1] = 0x00;
00092     writeRegs(data, 2);    
00093     // Enable Interrupt fot data ready
00094     data[0] = CTRL_REG_4;
00095     data[1] = 0x80;
00096     writeRegs(data, 2);    
00097     // Configure Interrupt to route to INT2
00098     data[0] = CTRL_REG_5;
00099     data[1] = 0x00;
00100     writeRegs(data, 2);    
00101     data[0] = PT_DATA_CFG;
00102     data[1] = 0x07;
00103     writeRegs(data, 2);    
00104 
00105     // Configure the OverSampling rate, Altimeter/Barometer mode and set the sensor Active
00106     data[0] = CTRL_REG_1;
00107     data[1] = (OS<<3);
00108     //
00109     if (Device_mode == MODE_BAR)
00110         data[1] &= 0x7F;
00111     else
00112         data[1] |= 0x80;
00113     //
00114     data[1] |= 0x01; 
00115     writeRegs(data, 2);    
00116 
00117     MPL3115A2_usr2_fptr = fptr;
00118     Device_Int2.fall( this, &DEVICE::DReady_IRQ);
00119 
00120 }
00121 
00122 void DEVICE::DReady_IRQ( void)
00123 {
00124     // Clear the IRQ flag
00125     statusRequest();
00126     // Run the user supplied function
00127     MPL3115A2_usr2_fptr();   
00128 }
00129 
00130 void DEVICE::AltitudeTrigger( void(*fptr)(void), unsigned short level)
00131 {
00132     unsigned char dt[5];
00133     unsigned char data[2];
00134 
00135     // Soft Reset
00136     Reset();
00137     
00138     // The device is on standby
00139     Standby();
00140     
00141     // Clear all interrupts by reading the output registers.
00142     readRegs( ALTIMETER_MSB, &dt[0], 5);
00143     statusRequest();
00144 
00145     // Write Target and Window Values
00146     dt[0] = P_TGT_MSB;
00147     dt[1] = (level>>8);
00148     dt[2] = (level&0xFF);
00149     writeRegs( dt, 3);
00150     
00151     // Window values are zero
00152     dt[0] = P_WND_MSB;
00153     dt[1] = 0;
00154     dt[2] = 0;
00155     writeRegs( dt, 3);
00156 
00157     // Enable Pressure Threshold interrupt
00158     data[0] = CTRL_REG_4;
00159     data[1] = 0x08;
00160     writeRegs( data, 2);
00161     // Interrupt is routed to INT1
00162     data[0] = CTRL_REG_5;
00163     data[1] = 0x08;
00164     writeRegs( data, 2);
00165     data[0] = PT_DATA_CFG;
00166     data[1] = 0x07;
00167     writeRegs(data, 2);    
00168     // Configure the OverSampling rate, Altimeter mode and set the sensor Active
00169     data[0] = CTRL_REG_1;
00170     data[1] = 0x81 | (Device_oversampling<<3);
00171     writeRegs(data, 2);    
00172 
00173     MPL3115A2_usr1_fptr = fptr;
00174     Device_Int1.fall( this, &DEVICE::AltitudeTrg_IRQ);
00175 
00176 }
00177 
00178 void DEVICE::AltitudeTrg_IRQ( void)
00179 {
00180     // Clear the IRQ flag
00181     statusRequest();
00182     // Run the user supplied function
00183     MPL3115A2_usr1_fptr();   
00184 
00185 }
00186 
00187 void DEVICE::Barometric( void)
00188 {
00189     unsigned char t;
00190     unsigned char data[2];
00191     
00192     Standby();
00193 
00194     // soft reset...
00195     Reset();
00196         
00197     Standby();
00198     readRegs( CTRL_REG_1, &t, 1);
00199     
00200     // Set the Barometric mode
00201     data[0] = CTRL_REG_1;
00202     data[1] = t&0x7F;
00203     writeRegs(data, 2);    
00204 
00205     data[0] = PT_DATA_CFG;
00206     data[1] = 0x07;
00207     writeRegs(data, 2);    
00208 
00209     sampling_Ratio( Device_oversampling);
00210     
00211     Active();
00212     
00213     Device_mode = MODE_BAR;
00214 }
00215 
00216 void DEVICE::Altimeter( void)
00217 {
00218     unsigned char t;
00219     unsigned char data[2];
00220     
00221     Standby();
00222 
00223     // soft reset...
00224     Reset();    
00225     
00226     Standby();
00227     readRegs( CTRL_REG_1, &t, 1);
00228 
00229     data[0] = CTRL_REG_1;
00230     data[1] = t|0x80;
00231     writeRegs(data, 2);    
00232 
00233     data[0] = PT_DATA_CFG;
00234     data[1] = 0x07;
00235     writeRegs(data, 2);    
00236 
00237     sampling_Ratio( Device_oversampling);
00238     
00239     Active();
00240     
00241     Device_mode = MODE_ALT;
00242 }
00243 
00244 void DEVICE::sampling_Ratio( unsigned int ratio)
00245 {
00246     unsigned char t;
00247     
00248     Standby();
00249     readRegs( CTRL_REG_1, &t, 1);
00250 
00251     t = t & 0xE7;
00252     t = t | ( ratio<<3);
00253 
00254     unsigned char data[2] = { CTRL_REG_1, t};
00255     writeRegs(data, 2);    
00256 
00257     Active();
00258     
00259 
00260     Device_oversampling = ratio;
00261 }
00262 
00263 
00264 void DEVICE::Active( void)
00265 {
00266     unsigned char t;
00267     
00268     // Activate the peripheral
00269     readRegs(CTRL_REG_1, &t, 1);
00270     unsigned char data[2] = {CTRL_REG_1, t|0x01};
00271     writeRegs(data, 2);
00272 }
00273 
00274 void DEVICE::Standby( void)
00275 {
00276     unsigned char t;
00277     
00278     // Standby
00279     readRegs(CTRL_REG_1, &t, 1);
00280     unsigned char data[2] = {CTRL_REG_1, t&0xFE};
00281     writeRegs(data, 2);
00282 }
00283 
00284 unsigned char DEVICE::requestDeviceID() {
00285     unsigned char device_id = 0;
00286     readRegs(deviceDetail_REG, &device_id, 1);
00287     return device_id;
00288 }
00289 
00290 unsigned int DEVICE::isDataAvailable( void)
00291 {
00292     unsigned char status;
00293     
00294     readRegs( STATUS_REG, &status, 1);
00295 
00296     return ((status>>1));
00297     
00298 }
00299 
00300 unsigned char DEVICE::statusRequest( void)
00301 {
00302     unsigned char status;
00303     
00304     readRegs( STATUS_REG, &status, 1);
00305     return status;
00306 }
00307 
00308 unsigned int DEVICE::requestAllData( float *f)
00309 {
00310     if ( isDataAvailable() & PTDR_STATUS) {
00311         if ( Device_mode == MODE_ALT) {
00312             f[0] = requestAltimeter( ALTIMETER_MSB);
00313         } else {
00314             f[0] = requestPressure( PRESSURE_MSB);
00315         }
00316         
00317     //    f[1] = requestTemperature( TEMP_MSB);
00318 
00319         return 1;
00320     } else
00321         return 0;
00322 }
00323 
00324 unsigned int DEVICE::requestAllData( float *f, float *d)
00325 {
00326     if ( isDataAvailable() & PTDR_STATUS) {
00327         if ( Device_mode == MODE_ALT) {
00328             f[0] = requestAltimeter();
00329             d[0] = requestAltimeter( ALTI_DELTA_MSB);
00330         } else {
00331             f[0] = requestPressure();
00332             d[0] = requestPressure( PRES_DELTA_MSB);
00333         }
00334         
00335       //  f[1] = requestTemperature();
00336      //   d[1] = requestTemperature( TEMP_DELTA_MSB);
00337         //
00338         return 1;
00339     } else
00340         return 0;
00341 }
00342 
00343 void DEVICE::requestAllMaximumData( float *f)
00344 {
00345     if ( Device_mode == MODE_ALT) {
00346         f[0] = requestAltimeter( ALTI_MAX_MSB);
00347     } else {
00348         f[0] = requestPressure( PRES_MAX_MSB);
00349     }
00350     
00351    // f[1] = requestTemperature( TEMP_MAX_MSB);
00352 }
00353 
00354 void DEVICE::requestAllMinimumData( float *f)
00355 {
00356     if ( Device_mode == MODE_ALT) {
00357         f[0] = requestAltimeter( ALTI_MIN_MSB);
00358     } else {
00359         f[0] = requestPressure( MIN_PRESSURE_MSB);
00360     }
00361     
00362    // f[1] = requestTemperature( TEMP_MIN_MSB);
00363 }
00364 
00365 float DEVICE::requestAltimeter( void)
00366 {
00367     float a;
00368     
00369     a = requestAltimeter( ALTIMETER_MSB);
00370     return a;
00371 }
00372 
00373 float DEVICE::requestAltimeter( unsigned char reg)
00374 {
00375     unsigned char dt[3];
00376     unsigned short altm;
00377     short tmp;
00378     float faltm;
00379     
00380     /*
00381     * dt[0] = Bits 12-19 of 20-bit real-time Altitude sample. (b7-b0)
00382     * dt[1] = Bits 4-11 of 20-bit real-time Altitude sample. (b7-b0)
00383     * dt[2] = Bits 0-3 of 20-bit real-time Altitude sample (b7-b4)
00384     */
00385     readRegs( reg, &dt[0], 3);
00386     altm = (dt[0]<<8) | dt[1];
00387     //
00388     if ( dt[0] > 0x7F) {
00389         // negative number
00390         tmp = ~altm + 1;
00391         faltm = (float)tmp * -1.0f;
00392     } else {
00393         faltm = (float)altm * 1.0f;
00394     }
00395     //
00396     faltm = faltm+((float)(dt[2]>>4) * 0.0625f);
00397     return faltm;
00398 }
00399 
00400 float DEVICE::requestPressure( void)
00401 {
00402     float a;
00403     
00404     a = requestPressure(PRESSURE_MSB);
00405     return a;
00406 }
00407 
00408 float DEVICE::requestPressure( unsigned char reg)
00409 {
00410     unsigned char dt[3];
00411     unsigned int prs;
00412     int tmp;
00413     float fprs;
00414     
00415 
00416     readRegs( reg, &dt[0], 3);
00417     prs = ((dt[0]<<10) | (dt[1]<<2) | (dt[2]>>6));
00418     //
00419     if ( dt[0] > 0x7f) {
00420         // negative number
00421         if ( dt[0] & 0x80)
00422             prs |= 0xFFFC0000;      // set at 1 the bits to complete the word len
00423         else
00424             prs |= 0xFFFE0000;
00425         tmp = ~prs + 1;             //  invert bits
00426         fprs = (float)tmp * -1.0f;  // set the signe..
00427     } else {
00428         fprs = (float)prs * 1.0f;
00429     }
00430 
00431     if ( dt[2] & 0x10)
00432         fprs += 0.25f;
00433     if ( dt[2] & 0x20)
00434         fprs += 0.5f;
00435         
00436     return fprs;
00437 }
00438 
00439 /*
00440  float DEVICE::requestTemperature( void)
00441 {
00442     float a;
00443     
00444     a = requestTemperature( TEMP_MSB);
00445     return a;
00446 }
00447 
00448 float DEVICE::requestTemperature( unsigned char reg)
00449 {
00450     unsigned char dt[2];
00451     unsigned short temp;
00452     float ftemp;
00453     
00454 
00455     readRegs( reg, &dt[0], 2);
00456     temp = dt[0];
00457     //
00458     if ( dt[0] > 0x7F) {
00459         temp = ~temp + 1;
00460         ftemp = (float)temp * -1.0f;
00461     } else {
00462         ftemp = (float)temp * 1.0f;
00463     }
00464     //
00465     ftemp = ftemp+((float)(dt[1]>>4) * 0.0625f);
00466     return ftemp;
00467 
00468 }
00469 
00470 */
00471 unsigned int DEVICE::getAllDataRaw( unsigned char *dt)
00472 {
00473     // Check for Press/Alti and Temp value ready
00474     if ( isDataAvailable() & PTDR_STATUS) {
00475         if ( Device_mode == MODE_ALT) {
00476             getAltimeterRaw( &dt[0]);               // 3 bytes
00477         } else {
00478             getPressureRaw( &dt[0]);                   // 3 bytes
00479         }
00480         
00481        // getTemperatureRaw( &dt[3]);                    // 2 bytes
00482         
00483         return 1;
00484     } else {
00485         return 0;
00486     }
00487 }
00488 
00489 unsigned int DEVICE::getAltimeterRaw( unsigned char *dt)
00490 {
00491     
00492 
00493     
00494     // Check for Press/Alti value ready
00495     if ( isDataAvailable() & PDR_STATUS) {
00496         readRegs( ALTIMETER_MSB, &dt[0], 3);
00497         return 1;
00498     } else
00499         return 0;
00500 }
00501 
00502 unsigned int  DEVICE::getPressureRaw( unsigned char *dt)
00503 {
00504     
00505 
00506     
00507     // Check for Press/Alti value ready
00508     if ( isDataAvailable() & PDR_STATUS) {
00509         readRegs( PRESSURE_MSB, &dt[0], 3);
00510         return 1;
00511     } else 
00512         return 0;
00513         
00514 }
00515 /*
00516 unsigned int DEVICE::getTemperatureRaw( unsigned char *dt)
00517 {
00518     
00519 
00520     
00521     // Check for Temp value ready
00522     if ( isDataAvailable() & TDR_STATUS) {
00523         readRegs( TEMP_MSB, &dt[0], 2);
00524         return 1;
00525     } else
00526         return 0;        
00527 }
00528 */
00529 void DEVICE::SetPressureOffset( char offset)
00530 {
00531     unsigned char data [2] = {OFF_P, offset};
00532 
00533     Standby();
00534     writeRegs(data,2);
00535 
00536     Active(); 
00537 }
00538 /*
00539 void DEVICE::SetTemperatureOffset( char offset)
00540 {
00541     unsigned char data [2] = {OFF_T, offset};
00542 
00543     Standby();
00544     writeRegs(data,2);
00545 
00546     Active(); 
00547 }
00548 */
00549 void DEVICE::SetAltitudeOffset( char offset)
00550 {
00551     unsigned char data [2] = {OFF_H, offset};
00552 
00553     Standby();
00554     writeRegs(data,2);
00555 
00556     Active(); 
00557 }
00558 
00559 void DEVICE::readRegs(int addr, uint8_t * data, int len) {
00560     char t[1] = {addr};
00561     m_i2c.write(m_addr, t, 1, true);
00562     m_i2c.read(m_addr, (char *)data, len);
00563 }
00564 
00565 void DEVICE::writeRegs(uint8_t * data, int len) {
00566     m_i2c.write(m_addr, (char *)data, len);
00567 }
00568 
00569 
00570