BMP085 Digital, barometric pressure sensor. Manufacturer: Bosch Sensortec.

Revision:
0:904377b11e64
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bmp085.cpp	Wed Mar 11 06:50:27 2015 +0000
@@ -0,0 +1,146 @@
+#include "bmp085.h"
+#include "mbed.h"
+#include "math.h"
+
+#define BMP085_ADDR 0xee
+
+const float BMP085::p0 = 1013.25;
+float BMP085::altitude(float p)
+{
+    return (float)(44330.0 * (1.0 - pow((double)p/p0, 1/5.255)));
+}
+    
+BMP085::BMP085(PinName sda, PinName scl): m_i2c(sda, scl), 
+    m_addr(BMP085_ADDR), oss(0)
+{
+    // calibration
+    uint8_t bmp085_cali_regs[] = {0xAA,0xAC,0xAE,0xB0,0xB2,0xB4,0xB6,0xB8,0xBA,0xBC,0xBE,0};
+    uint8_t *ptr = bmp085_cali_regs;
+    int16_t bmp085_value[11]={0};
+    int i = 0;
+    uint8_t data[2];
+    
+    while(*ptr)
+    {
+        readRegs(*ptr, data, 2);
+    
+        bmp085_value[i++] = (data[0] << 8) | data[1];
+        
+        ptr++;
+    }
+    
+    ac1 = bmp085_value[0];
+    ac2 = bmp085_value[1];
+    ac3 = bmp085_value[2];
+    ac4 = (uint16_t)bmp085_value[3];
+    ac5 = (uint16_t)bmp085_value[4];
+    ac6 = (uint16_t)bmp085_value[5];
+    b1 = bmp085_value[6];
+    b2 = bmp085_value[7];
+    mb = bmp085_value[8];
+    mc = bmp085_value[9];
+    md = bmp085_value[10];
+    
+    /*printf("\tAC1 = %d\r\n", ac1);
+    printf("\tAC2 = %d\r\n", ac2);
+    printf("\tAC3 = %d\r\n", ac3);
+    printf("\tAC4 = %d\r\n", ac4);
+    printf("\tAC5 = %d\r\n", ac5);
+    printf("\tAC6 = %d\r\n", ac6);
+    printf("\tB1 = %d\r\n", b1);
+    printf("\tB2 = %d\r\n", b2);
+    printf("\tMB = %d\r\n", mb);
+    printf("\tMC = %d\r\n", mc);
+    printf("\tMD = %d\r\n", md);
+    printf("------------------------\r\n");*/
+}
+
+void BMP085::set_oversampling(int osrs)
+{
+    if(osrs > 0 && osrs < 4)
+    {
+        oss = osrs;
+    }
+}
+    
+void BMP085::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 BMP085::writeRegs(uint8_t * data, int len)
+{
+    m_i2c.write(m_addr, (char *)data, len);
+}
+
+int32_t BMP085::read_temp(void)
+{
+    uint8_t data[2] = {0xf4, 0x2e};
+    
+    // write 0x2e into reg 0xf4
+    writeRegs(data, 2);
+    
+    // wait 4.5ms
+    wait_us(4500);
+    
+    // read reg 0xf6(MSB), 0xf7(LSB)
+    readRegs(0xf6, data, 2);
+    
+    // UT = (MSB << 8) + LSB
+    return (data[0] << 8) | data[1];
+}
+
+int32_t BMP085::read_pressure(void)
+{
+    static int delay_ms[] = {4500, 7500, 13500, 25500};
+    
+    uint8_t data[3] = {0};
+    
+    // write 0x34+(oss << 6) into reg 0xf4
+    data[0] = 0xf4;
+    data[1] = 0x34 + (oss << 6);
+    writeRegs(data, 2);
+    
+    // wait
+    wait_us(delay_ms[oss]);
+    
+    // read reg 0xf6(MSB), 0xf7(LSB), 0xf8(XLSB)
+    readRegs(0xf6, data, 3);
+    
+    // UP = ((MSB << 16) + (LSB << 8) + XLSB) >> (8-oss)
+    return ((data[0] << 16) | (data[1] << 8) | data[2]) >> (8-oss);
+}
+
+void BMP085::read(int32_t * temperature, int32_t * pressure)
+{
+    int32_t ut, up;
+    int32_t x1, x2, b5, b6, x3, b3, p;
+    uint32_t b4, b7;
+    
+    ut = read_temp();
+    up = read_pressure();
+    
+    x1 = ((int32_t)ut - ac6) * ac5 >> 15;
+    x2 = ((int32_t) mc << 11) / (x1 + md);
+    b5 = x1 + x2;
+    *temperature = (b5 + 8) >> 4;
+    
+    b6 = b5 - 4000;
+    x1 = (b2 * (b6 * b6 >> 12)) >> 11;
+    x2 = ac2 * b6 >> 11;
+    x3 = x1 + x2;
+    b3 = (((int32_t) ac1 * 4 + x3) + 2)/4;
+    x1 = ac3 * b6 >> 13;
+    x2 = (b1 * (b6 * b6 >> 12)) >> 16;
+    x3 = ((x1 + x2) + 2) >> 2;
+    b4 = (ac4 * (unsigned int32_t) (x3 + 32768)) >> 15;
+    b7 = ((unsigned int32_t) up - b3) * (50000 >> oss);
+    p = b7 < 0x80000000 ? (b7 * 2) / b4 : (b7 / b4) * 2;
+    x1 = (p >> 8) * (p >> 8);
+    x1 = (x1 * 3038) >> 16;
+    x2 = (-7357 * p) >> 16;
+    *pressure = p + ((x1 + x2 + 3791) >> 4);
+}