Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: Hexi_OLED_SSD1351
Diff: Barometer.cpp
- Revision:
- 0:a84d2425acba
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Barometer.cpp Fri Jul 26 13:37:55 2019 +0000
@@ -0,0 +1,570 @@
+#include "Barometer.h"
+
+#define deviceDetail_REG 0x0C // return 0xC4 by default
+#define STATUS_REG 0x00
+#define CTRL_REG_1 0x26
+#define CTRL_REG_3 0x28
+#define CTRL_REG_4 0x29
+#define CTRL_REG_5 0x2A
+#define PRESSURE_MSB 0x01 // pressure data
+#define ALTIMETER_MSB 0x01 // altimeter data
+#define TEMP_MSB 0x04 // temperature data
+#define PT_DATA_CFG 0x13
+#define P_TGT_MSB 0x16
+#define P_WND_MSB 0x19
+#define OFF_P 0x2b
+#define OFF_T 0x2c
+#define OFF_H 0x2d
+#define MIN_PRESSURE_MSB 0x1c
+#define ALTI_MIN_MSB 0x1c
+#define TEMP_MIN_MSB 0x1f
+#define PRES_MAX_MSB 0x21
+#define ALTI_MAX_MSB 0x21
+#define TEMP_MAX_MSB 0x24
+#define PRES_DELTA_MSB 0x07
+#define ALTI_DELTA_MSB 0x07
+#define TEMP_DELTA_MSB 0x0a
+
+
+#define UINT14_MAX 16383
+
+// Status flag for data ready.
+#define PTDR_STATUS 0x03 // Pressure Altitude
+#define PDR_STATUS 0x02 // Pressure and Altitude data ready
+#define TDR_STATUS 0x01
+
+
+void (*MPL3115A2_usr2_fptr)(void); // Pointers to user function called after
+void (*MPL3115A2_usr1_fptr)(void); // IRQ assertion.
+
+//
+InterruptIn Device_Int1( PTD4); // INT1
+InterruptIn Device_Int2( PTA12); // INT2
+
+DEVICE::DEVICE(PinName sda, PinName scl, int addr) : m_i2c(sda, scl), m_addr(addr) {
+ unsigned char data[6];
+
+ Device_mode = MODE_BAR;
+ Device_oversampling = OVERSAMPLE_1;
+
+ MPL3115A2_usr1_fptr = NULL;
+ MPL3115A2_usr2_fptr = NULL;
+ Device_Int1.fall( NULL);
+ Device_Int2.fall( NULL);
+
+ Reset(); //soft reset
+
+ data[0]=MIN_PRESSURE_MSB;
+ data[1]=0;data[2]=0;data[3]=0;data[4]=0;data[5]=0;
+ writeRegs( &data[0], 6);
+}
+
+void DEVICE::Reset( void)
+{
+ unsigned char t;
+
+
+ readRegs( CTRL_REG_1, &t, 1);
+ unsigned char data[2] = { CTRL_REG_1, t|0x04};
+
+
+ writeRegs(data, 2); //soft reset
+ wait( 0.1);
+
+}
+
+void DEVICE::DReady( void(*fptr)(void), unsigned char OS)
+{
+ unsigned char dt[5];
+ unsigned char data[2];
+
+ // Soft Reset
+ Reset();
+
+ Standby();
+
+ // Clear all interrupts by reading the output registers.
+ readRegs( ALTIMETER_MSB, &dt[0], 5);
+ statusRequest();
+ // Configure INT active low and pullup
+ data[0] = CTRL_REG_3;
+ data[1] = 0x00;
+ writeRegs(data, 2);
+ // Enable Interrupt fot data ready
+ data[0] = CTRL_REG_4;
+ data[1] = 0x80;
+ writeRegs(data, 2);
+ // Configure Interrupt to route to INT2
+ data[0] = CTRL_REG_5;
+ data[1] = 0x00;
+ writeRegs(data, 2);
+ data[0] = PT_DATA_CFG;
+ data[1] = 0x07;
+ writeRegs(data, 2);
+
+ // Configure the OverSampling rate, Altimeter/Barometer mode and set the sensor Active
+ data[0] = CTRL_REG_1;
+ data[1] = (OS<<3);
+ //
+ if (Device_mode == MODE_BAR)
+ data[1] &= 0x7F;
+ else
+ data[1] |= 0x80;
+ //
+ data[1] |= 0x01;
+ writeRegs(data, 2);
+
+ MPL3115A2_usr2_fptr = fptr;
+ Device_Int2.fall( this, &DEVICE::DReady_IRQ);
+
+}
+
+void DEVICE::DReady_IRQ( void)
+{
+ // Clear the IRQ flag
+ statusRequest();
+ // Run the user supplied function
+ MPL3115A2_usr2_fptr();
+}
+
+void DEVICE::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( ALTIMETER_MSB, &dt[0], 5);
+ statusRequest();
+
+ // Write Target and Window Values
+ dt[0] = P_TGT_MSB;
+ dt[1] = (level>>8);
+ dt[2] = (level&0xFF);
+ writeRegs( dt, 3);
+
+ // Window values are zero
+ dt[0] = P_WND_MSB;
+ dt[1] = 0;
+ dt[2] = 0;
+ writeRegs( dt, 3);
+
+ // Enable Pressure Threshold interrupt
+ data[0] = CTRL_REG_4;
+ data[1] = 0x08;
+ writeRegs( data, 2);
+ // Interrupt is routed to INT1
+ data[0] = CTRL_REG_5;
+ data[1] = 0x08;
+ writeRegs( data, 2);
+ data[0] = PT_DATA_CFG;
+ data[1] = 0x07;
+ writeRegs(data, 2);
+ // Configure the OverSampling rate, Altimeter mode and set the sensor Active
+ data[0] = CTRL_REG_1;
+ data[1] = 0x81 | (Device_oversampling<<3);
+ writeRegs(data, 2);
+
+ MPL3115A2_usr1_fptr = fptr;
+ Device_Int1.fall( this, &DEVICE::AltitudeTrg_IRQ);
+
+}
+
+void DEVICE::AltitudeTrg_IRQ( void)
+{
+ // Clear the IRQ flag
+ statusRequest();
+ // Run the user supplied function
+ MPL3115A2_usr1_fptr();
+
+}
+
+void DEVICE::Barometric( void)
+{
+ unsigned char t;
+ unsigned char data[2];
+
+ Standby();
+
+ // soft reset...
+ Reset();
+
+ Standby();
+ readRegs( CTRL_REG_1, &t, 1);
+
+ // Set the Barometric mode
+ data[0] = CTRL_REG_1;
+ data[1] = t&0x7F;
+ writeRegs(data, 2);
+
+ data[0] = PT_DATA_CFG;
+ data[1] = 0x07;
+ writeRegs(data, 2);
+
+ sampling_Ratio( Device_oversampling);
+
+ Active();
+
+ Device_mode = MODE_BAR;
+}
+
+void DEVICE::Altimeter( void)
+{
+ unsigned char t;
+ unsigned char data[2];
+
+ Standby();
+
+ // soft reset...
+ Reset();
+
+ Standby();
+ readRegs( CTRL_REG_1, &t, 1);
+
+ data[0] = CTRL_REG_1;
+ data[1] = t|0x80;
+ writeRegs(data, 2);
+
+ data[0] = PT_DATA_CFG;
+ data[1] = 0x07;
+ writeRegs(data, 2);
+
+ sampling_Ratio( Device_oversampling);
+
+ Active();
+
+ Device_mode = MODE_ALT;
+}
+
+void DEVICE::sampling_Ratio( unsigned int ratio)
+{
+ unsigned char t;
+
+ Standby();
+ readRegs( CTRL_REG_1, &t, 1);
+
+ t = t & 0xE7;
+ t = t | ( ratio<<3);
+
+ unsigned char data[2] = { CTRL_REG_1, t};
+ writeRegs(data, 2);
+
+ Active();
+
+
+ Device_oversampling = ratio;
+}
+
+
+void DEVICE::Active( void)
+{
+ unsigned char t;
+
+ // Activate the peripheral
+ readRegs(CTRL_REG_1, &t, 1);
+ unsigned char data[2] = {CTRL_REG_1, t|0x01};
+ writeRegs(data, 2);
+}
+
+void DEVICE::Standby( void)
+{
+ unsigned char t;
+
+ // Standby
+ readRegs(CTRL_REG_1, &t, 1);
+ unsigned char data[2] = {CTRL_REG_1, t&0xFE};
+ writeRegs(data, 2);
+}
+
+unsigned char DEVICE::requestDeviceID() {
+ unsigned char device_id = 0;
+ readRegs(deviceDetail_REG, &device_id, 1);
+ return device_id;
+}
+
+unsigned int DEVICE::isDataAvailable( void)
+{
+ unsigned char status;
+
+ readRegs( STATUS_REG, &status, 1);
+
+ return ((status>>1));
+
+}
+
+unsigned char DEVICE::statusRequest( void)
+{
+ unsigned char status;
+
+ readRegs( STATUS_REG, &status, 1);
+ return status;
+}
+
+unsigned int DEVICE::requestAllData( float *f)
+{
+ if ( isDataAvailable() & PTDR_STATUS) {
+ if ( Device_mode == MODE_ALT) {
+ f[0] = requestAltimeter( ALTIMETER_MSB);
+ } else {
+ f[0] = requestPressure( PRESSURE_MSB);
+ }
+
+ // f[1] = requestTemperature( TEMP_MSB);
+
+ return 1;
+ } else
+ return 0;
+}
+
+unsigned int DEVICE::requestAllData( float *f, float *d)
+{
+ if ( isDataAvailable() & PTDR_STATUS) {
+ if ( Device_mode == MODE_ALT) {
+ f[0] = requestAltimeter();
+ d[0] = requestAltimeter( ALTI_DELTA_MSB);
+ } else {
+ f[0] = requestPressure();
+ d[0] = requestPressure( PRES_DELTA_MSB);
+ }
+
+ // f[1] = requestTemperature();
+ // d[1] = requestTemperature( TEMP_DELTA_MSB);
+ //
+ return 1;
+ } else
+ return 0;
+}
+
+void DEVICE::requestAllMaximumData( float *f)
+{
+ if ( Device_mode == MODE_ALT) {
+ f[0] = requestAltimeter( ALTI_MAX_MSB);
+ } else {
+ f[0] = requestPressure( PRES_MAX_MSB);
+ }
+
+ // f[1] = requestTemperature( TEMP_MAX_MSB);
+}
+
+void DEVICE::requestAllMinimumData( float *f)
+{
+ if ( Device_mode == MODE_ALT) {
+ f[0] = requestAltimeter( ALTI_MIN_MSB);
+ } else {
+ f[0] = requestPressure( MIN_PRESSURE_MSB);
+ }
+
+ // f[1] = requestTemperature( TEMP_MIN_MSB);
+}
+
+float DEVICE::requestAltimeter( void)
+{
+ float a;
+
+ a = requestAltimeter( ALTIMETER_MSB);
+ return a;
+}
+
+float DEVICE::requestAltimeter( unsigned char reg)
+{
+ unsigned char dt[3];
+ unsigned short altm;
+ short tmp;
+ float faltm;
+
+ /*
+ * dt[0] = Bits 12-19 of 20-bit real-time Altitude sample. (b7-b0)
+ * dt[1] = Bits 4-11 of 20-bit real-time Altitude sample. (b7-b0)
+ * dt[2] = Bits 0-3 of 20-bit real-time Altitude sample (b7-b4)
+ */
+ readRegs( reg, &dt[0], 3);
+ altm = (dt[0]<<8) | dt[1];
+ //
+ if ( dt[0] > 0x7F) {
+ // negative number
+ tmp = ~altm + 1;
+ faltm = (float)tmp * -1.0f;
+ } else {
+ faltm = (float)altm * 1.0f;
+ }
+ //
+ faltm = faltm+((float)(dt[2]>>4) * 0.0625f);
+ return faltm;
+}
+
+float DEVICE::requestPressure( void)
+{
+ float a;
+
+ a = requestPressure(PRESSURE_MSB);
+ return a;
+}
+
+float DEVICE::requestPressure( unsigned char reg)
+{
+ unsigned char dt[3];
+ unsigned int prs;
+ int tmp;
+ float fprs;
+
+
+ readRegs( reg, &dt[0], 3);
+ prs = ((dt[0]<<10) | (dt[1]<<2) | (dt[2]>>6));
+ //
+ if ( dt[0] > 0x7f) {
+ // negative number
+ if ( dt[0] & 0x80)
+ prs |= 0xFFFC0000; // set at 1 the bits to complete the word len
+ else
+ prs |= 0xFFFE0000;
+ tmp = ~prs + 1; // invert bits
+ fprs = (float)tmp * -1.0f; // set the signe..
+ } else {
+ fprs = (float)prs * 1.0f;
+ }
+
+ if ( dt[2] & 0x10)
+ fprs += 0.25f;
+ if ( dt[2] & 0x20)
+ fprs += 0.5f;
+
+ return fprs;
+}
+
+/*
+ float DEVICE::requestTemperature( void)
+{
+ float a;
+
+ a = requestTemperature( TEMP_MSB);
+ return a;
+}
+
+float DEVICE::requestTemperature( unsigned char reg)
+{
+ unsigned char dt[2];
+ unsigned short temp;
+ float ftemp;
+
+
+ readRegs( reg, &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;
+
+}
+
+*/
+unsigned int DEVICE::getAllDataRaw( unsigned char *dt)
+{
+ // Check for Press/Alti and Temp value ready
+ if ( isDataAvailable() & PTDR_STATUS) {
+ if ( Device_mode == MODE_ALT) {
+ getAltimeterRaw( &dt[0]); // 3 bytes
+ } else {
+ getPressureRaw( &dt[0]); // 3 bytes
+ }
+
+ // getTemperatureRaw( &dt[3]); // 2 bytes
+
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
+unsigned int DEVICE::getAltimeterRaw( unsigned char *dt)
+{
+
+
+
+ // Check for Press/Alti value ready
+ if ( isDataAvailable() & PDR_STATUS) {
+ readRegs( ALTIMETER_MSB, &dt[0], 3);
+ return 1;
+ } else
+ return 0;
+}
+
+unsigned int DEVICE::getPressureRaw( unsigned char *dt)
+{
+
+
+
+ // Check for Press/Alti value ready
+ if ( isDataAvailable() & PDR_STATUS) {
+ readRegs( PRESSURE_MSB, &dt[0], 3);
+ return 1;
+ } else
+ return 0;
+
+}
+/*
+unsigned int DEVICE::getTemperatureRaw( unsigned char *dt)
+{
+
+
+
+ // Check for Temp value ready
+ if ( isDataAvailable() & TDR_STATUS) {
+ readRegs( TEMP_MSB, &dt[0], 2);
+ return 1;
+ } else
+ return 0;
+}
+*/
+void DEVICE::SetPressureOffset( char offset)
+{
+ unsigned char data [2] = {OFF_P, offset};
+
+ Standby();
+ writeRegs(data,2);
+
+ Active();
+}
+/*
+void DEVICE::SetTemperatureOffset( char offset)
+{
+ unsigned char data [2] = {OFF_T, offset};
+
+ Standby();
+ writeRegs(data,2);
+
+ Active();
+}
+*/
+void DEVICE::SetAltitudeOffset( char offset)
+{
+ unsigned char data [2] = {OFF_H, offset};
+
+ Standby();
+ writeRegs(data,2);
+
+ Active();
+}
+
+void DEVICE::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 DEVICE::writeRegs(uint8_t * data, int len) {
+ m_i2c.write(m_addr, (char *)data, len);
+}
+
+
+