silabs-abakurs / BMP085

Dependents:   Barometer-Example IOT_Repository

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers BMP085.cpp Source File

BMP085.cpp

00001 #include "BMP085.h"
00002 
00003 void BMP085::init(void) {
00004     _callback.attach(this, &BMP085::_callback_handler);
00005     
00006     _cal_data.ac1 = read_cal_register(BMP085_CAL_AC1);
00007     _cal_data.ac2 = read_cal_register(BMP085_CAL_AC2);
00008     _cal_data.ac3 = read_cal_register(BMP085_CAL_AC3);
00009     _cal_data.ac4 = read_cal_register(BMP085_CAL_AC4);
00010     _cal_data.ac5 = read_cal_register(BMP085_CAL_AC5);
00011     _cal_data.ac6 = read_cal_register(BMP085_CAL_AC6);
00012     _cal_data.b1 = read_cal_register(BMP085_CAL_B1);
00013     _cal_data.b2 = read_cal_register(BMP085_CAL_B2);
00014     _cal_data.mb = read_cal_register(BMP085_CAL_MB);
00015     _cal_data.mc = read_cal_register(BMP085_CAL_MC);
00016     _cal_data.md = read_cal_register(BMP085_CAL_MD);
00017 }
00018 
00019 uint16_t BMP085::read_cal_register(BMP085_Register reg) {
00020     _tx_buf[0] = reg;
00021     _state = BMP085_BUSY;
00022     _i2c.transfer(BMP085_ADDR, (char*)_tx_buf, 1, (char*)_rx_buf, 2, _callback);
00023     while(_state != BMP085_IDLE) {
00024         sleep();
00025     }
00026     return (_rx_buf[0] << 8) | _rx_buf[1];
00027 }
00028 
00029 uint16_t BMP085::read_uc_temperature(void) {
00030     LowPowerTimeout delay;
00031     _tx_buf[0] = BMP085_CTRL;
00032     _tx_buf[1] = BMP085_CMD_READ_TEMP;
00033     _state = BMP085_BUSY;
00034     _i2c.transfer(BMP085_ADDR, (char*)_tx_buf, 2, (char*)NULL, 0, _callback);
00035     while(_state != BMP085_IDLE) {
00036         sleep();
00037     }
00038 
00039     _state = BMP085_BUSY;
00040     delay.attach(this, &BMP085::_callback_handler, 0.01);
00041     while(_state != BMP085_IDLE) {
00042         sleep();
00043     }
00044 
00045     _tx_buf[0] = BMP085_DATA_TEMP;
00046     _state = BMP085_BUSY;
00047     _i2c.transfer(BMP085_ADDR, (char*)_tx_buf, 1, (char*)_rx_buf, 2, _callback);
00048     while(_state != BMP085_IDLE) {
00049         sleep();
00050     }
00051     return (_rx_buf[0] << 8) | _rx_buf[1];
00052 }
00053 
00054 uint32_t BMP085::read_uc_pressure(void) {
00055     LowPowerTimeout delay;
00056     _tx_buf[0] = BMP085_CTRL;
00057     _tx_buf[1] = BMP085_CMD_READ_PRESSURE + ((uint8_t)_mode << 6);
00058     _state = BMP085_BUSY;
00059     _i2c.transfer(BMP085_ADDR, (char*)_tx_buf, 2, (char*)NULL, 0, _callback);
00060     while(_state != BMP085_IDLE) {
00061         sleep();
00062     }
00063 
00064     _state = BMP085_BUSY;
00065     delay.attach(this, &BMP085::_callback_handler, 0.02);
00066     while(_state != BMP085_IDLE) {
00067         sleep();
00068     }
00069 
00070     _tx_buf[0] = BMP085_DATA_PRESSURE;
00071     _state = BMP085_BUSY;
00072     _i2c.transfer(BMP085_ADDR, (char*)_tx_buf, 1, (char*)_rx_buf, 3, _callback);
00073     while(_state != BMP085_IDLE) {
00074         sleep();
00075     }
00076     return ((_rx_buf[0] << 16) | (_rx_buf[1] << 8) | _rx_buf[2]) >> (8 - (uint8_t)_mode);    
00077 }
00078 
00079 void BMP085::measure() {
00080     int t, p, ut, up, x1, x2, x3, b3, b5, b6;
00081     uint32_t b4, b7;
00082 
00083     ut = read_uc_temperature();
00084 
00085     x1 = (ut - _cal_data.ac6) * _cal_data.ac5 / (1 << 15);
00086     x2 = (int)_cal_data.mc * (1 << 11) / (x1 + _cal_data.md);
00087     b5 = x1 + x2;
00088     t = (b5 + 8) / (1 << 4);
00089     _temperature = (float)t / 10.0;
00090     
00091     up = read_uc_pressure();
00092     
00093     b6 = b5 - 4000;
00094     x1 = (_cal_data.b2 * (b6 * b6 / (1 << 12))) / (1 << 11);
00095     x2 = _cal_data.ac2 * b6 / (1 << 11);
00096     x3 = x1 + x2;
00097     b3 = ((((unsigned int)_cal_data.ac1 * 4 + x3) << (int)_mode) + 2) / 4;
00098     x1 = _cal_data.ac3 * b6 / (1 << 13);
00099     x2 = (_cal_data.b1 * (b6 * b6 / (1 << 12))) / (1 << 16);
00100     x3 = ((x1 + x2) + 2) / (1 << 2);
00101     b4 = _cal_data.ac4 * (unsigned int)(x3 + 32768) / (1 << 15);
00102     b7 = ((unsigned int)up - b3) * (50000 >> (int)_mode);
00103     if (b7 < (unsigned int)0x80000000) {
00104         p = (b7 * 2) / b4;
00105     } else {
00106         p = (b7 / b4) * 2;
00107     }
00108     x1 = (p / (1 << 8)) * (p / (1 << 8));
00109     x1 = (x1 * 3038) / (1 << 16);
00110     x2 = (-7357 * p) / (1 << 16);
00111     p = p + (x1 + x2 + 3791) / (1 << 4);
00112     _pressure = (float)p / 100.0;
00113 }
00114 
00115 void BMP085::_callback_handler(int event) {
00116     _state = BMP085_IDLE;
00117 }
00118 
00119 void BMP085::_callback_handler() {
00120     _state = BMP085_IDLE;
00121 }