BMP180

Fork of BMP180 by Kevin Gillepsie

Committer:
kgills
Date:
Fri Apr 17 09:31:09 2015 -0500
Revision:
0:b2219e6e444b
Child:
1:817fb4e66714
Adding BMP180 library files.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
kgills 0:b2219e6e444b 1 /*******************************************************************************
kgills 0:b2219e6e444b 2 * Copyright (C) 2015 Maxim Integrated Products, Inc., All Rights Reserved.
kgills 0:b2219e6e444b 3 *
kgills 0:b2219e6e444b 4 * Permission is hereby granted, free of charge, to any person obtaining a
kgills 0:b2219e6e444b 5 * copy of this software and associated documentation files (the "Software"),
kgills 0:b2219e6e444b 6 * to deal in the Software without restriction, including without limitation
kgills 0:b2219e6e444b 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
kgills 0:b2219e6e444b 8 * and/or sell copies of the Software, and to permit persons to whom the
kgills 0:b2219e6e444b 9 * Software is furnished to do so, subject to the following conditions:
kgills 0:b2219e6e444b 10 *
kgills 0:b2219e6e444b 11 * The above copyright notice and this permission notice shall be included
kgills 0:b2219e6e444b 12 * in all copies or substantial portions of the Software.
kgills 0:b2219e6e444b 13 *
kgills 0:b2219e6e444b 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
kgills 0:b2219e6e444b 15 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
kgills 0:b2219e6e444b 16 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
kgills 0:b2219e6e444b 17 * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES
kgills 0:b2219e6e444b 18 * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
kgills 0:b2219e6e444b 19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
kgills 0:b2219e6e444b 20 * OTHER DEALINGS IN THE SOFTWARE.
kgills 0:b2219e6e444b 21 *
kgills 0:b2219e6e444b 22 * Except as contained in this notice, the name of Maxim Integrated
kgills 0:b2219e6e444b 23 * Products, Inc. shall not be used except as stated in the Maxim Integrated
kgills 0:b2219e6e444b 24 * Products, Inc. Branding Policy.
kgills 0:b2219e6e444b 25 *
kgills 0:b2219e6e444b 26 * The mere transfer of this software does not imply any licenses
kgills 0:b2219e6e444b 27 * of trade secrets, proprietary technology, copyrights, patents,
kgills 0:b2219e6e444b 28 * trademarks, maskwork rights, or any other form of intellectual
kgills 0:b2219e6e444b 29 * property whatsoever. Maxim Integrated Products, Inc. retains all
kgills 0:b2219e6e444b 30 * ownership rights.
kgills 0:b2219e6e444b 31 *******************************************************************************
kgills 0:b2219e6e444b 32 */
kgills 0:b2219e6e444b 33
kgills 0:b2219e6e444b 34 #include "BMP180.h"
kgills 0:b2219e6e444b 35
kgills 0:b2219e6e444b 36 /***** Definitions *****/
kgills 0:b2219e6e444b 37 #define I2C_ADDR (0xEE) // 1110111x
kgills 0:b2219e6e444b 38
kgills 0:b2219e6e444b 39 #define REG_ADDR_RESET (0xE0)
kgills 0:b2219e6e444b 40 #define REG_ADDR_ID (0xD0)
kgills 0:b2219e6e444b 41 #define REG_ADDR_CTRL (0xF4)
kgills 0:b2219e6e444b 42 #define REG_ADDR_DATA (0xF6)
kgills 0:b2219e6e444b 43 #define REG_ADDR_AC1 (0xAA)
kgills 0:b2219e6e444b 44
kgills 0:b2219e6e444b 45 #define CTRL_REG_TEMP (0x2E)
kgills 0:b2219e6e444b 46 #define CTRL_REG_PRESS_0 (0x34)
kgills 0:b2219e6e444b 47 #define CTRL_REG_PRESS_1 (0x74)
kgills 0:b2219e6e444b 48 #define CTRL_REG_PRESS_2 (0xB4)
kgills 0:b2219e6e444b 49 #define CTRL_REG_PRESS_3 (0xF4)
kgills 0:b2219e6e444b 50
kgills 0:b2219e6e444b 51 //******************************************************************************
kgills 0:b2219e6e444b 52 BMP180::BMP180(PinName sda, PinName scl)
kgills 0:b2219e6e444b 53 {
kgills 0:b2219e6e444b 54 i2c_ = new I2C(sda, scl);
kgills 0:b2219e6e444b 55 i2c_owner = true;
kgills 0:b2219e6e444b 56
kgills 0:b2219e6e444b 57 i2c_->frequency(400000);
kgills 0:b2219e6e444b 58 }
kgills 0:b2219e6e444b 59
kgills 0:b2219e6e444b 60 //******************************************************************************
kgills 0:b2219e6e444b 61 BMP180::BMP180(I2C *i2c) :
kgills 0:b2219e6e444b 62 i2c_(i2c)
kgills 0:b2219e6e444b 63 {
kgills 0:b2219e6e444b 64 i2c_owner = false;
kgills 0:b2219e6e444b 65 }
kgills 0:b2219e6e444b 66
kgills 0:b2219e6e444b 67 //******************************************************************************
kgills 0:b2219e6e444b 68 BMP180::~BMP180()
kgills 0:b2219e6e444b 69 {
kgills 0:b2219e6e444b 70 if(i2c_owner) {
kgills 0:b2219e6e444b 71 delete i2c_;
kgills 0:b2219e6e444b 72 }
kgills 0:b2219e6e444b 73 }
kgills 0:b2219e6e444b 74
kgills 0:b2219e6e444b 75 //******************************************************************************
kgills 0:b2219e6e444b 76 int BMP180::init(void)
kgills 0:b2219e6e444b 77 {
kgills 0:b2219e6e444b 78 char addr;
kgills 0:b2219e6e444b 79 char data[22];
kgills 0:b2219e6e444b 80 int i;
kgills 0:b2219e6e444b 81
kgills 0:b2219e6e444b 82 if (checkId() != 0) {
kgills 0:b2219e6e444b 83 return -1;
kgills 0:b2219e6e444b 84 }
kgills 0:b2219e6e444b 85
kgills 0:b2219e6e444b 86 addr = REG_ADDR_AC1;
kgills 0:b2219e6e444b 87 if (i2c_->write(I2C_ADDR, &addr, 1) != 0) {
kgills 0:b2219e6e444b 88 return -1;
kgills 0:b2219e6e444b 89 }
kgills 0:b2219e6e444b 90
kgills 0:b2219e6e444b 91 if (i2c_->read(I2C_ADDR, data, 22) != 0) {
kgills 0:b2219e6e444b 92 return -1;
kgills 0:b2219e6e444b 93 }
kgills 0:b2219e6e444b 94
kgills 0:b2219e6e444b 95 for (i = 0; i < 11; i++) {
kgills 0:b2219e6e444b 96 calib.value[i] = (data[2*i] << 8) | data[(2*i)+1];
kgills 0:b2219e6e444b 97 }
kgills 0:b2219e6e444b 98
kgills 0:b2219e6e444b 99 return 0;
kgills 0:b2219e6e444b 100 }
kgills 0:b2219e6e444b 101
kgills 0:b2219e6e444b 102 //******************************************************************************
kgills 0:b2219e6e444b 103 int BMP180::reset(void)
kgills 0:b2219e6e444b 104 {
kgills 0:b2219e6e444b 105 char data;
kgills 0:b2219e6e444b 106
kgills 0:b2219e6e444b 107 data = REG_ADDR_RESET;
kgills 0:b2219e6e444b 108 if (i2c_->write(I2C_ADDR, &data, 1) != 0) {
kgills 0:b2219e6e444b 109 return -1;
kgills 0:b2219e6e444b 110 }
kgills 0:b2219e6e444b 111
kgills 0:b2219e6e444b 112 data = 0xB6;
kgills 0:b2219e6e444b 113 if (i2c_->write(I2C_ADDR, &data, 1) != 0) {
kgills 0:b2219e6e444b 114 return -1;
kgills 0:b2219e6e444b 115 }
kgills 0:b2219e6e444b 116
kgills 0:b2219e6e444b 117 return 0;
kgills 0:b2219e6e444b 118 }
kgills 0:b2219e6e444b 119
kgills 0:b2219e6e444b 120 //******************************************************************************
kgills 0:b2219e6e444b 121 int BMP180::checkId(void)
kgills 0:b2219e6e444b 122 {
kgills 0:b2219e6e444b 123 char addr;
kgills 0:b2219e6e444b 124 char data;
kgills 0:b2219e6e444b 125
kgills 0:b2219e6e444b 126 addr = REG_ADDR_ID;
kgills 0:b2219e6e444b 127 if (i2c_->write(I2C_ADDR, &addr, 1) != 0) {
kgills 0:b2219e6e444b 128 return -1;
kgills 0:b2219e6e444b 129 }
kgills 0:b2219e6e444b 130
kgills 0:b2219e6e444b 131 if (i2c_->read(I2C_ADDR, &data, 1) != 0) {
kgills 0:b2219e6e444b 132 return -1;
kgills 0:b2219e6e444b 133 }
kgills 0:b2219e6e444b 134
kgills 0:b2219e6e444b 135 if (data != 0x55) {
kgills 0:b2219e6e444b 136 return -1;
kgills 0:b2219e6e444b 137 }
kgills 0:b2219e6e444b 138
kgills 0:b2219e6e444b 139 return 0;
kgills 0:b2219e6e444b 140 }
kgills 0:b2219e6e444b 141
kgills 0:b2219e6e444b 142 //******************************************************************************
kgills 0:b2219e6e444b 143 int BMP180::startPressure(BMP180::oversampling_t oss)
kgills 0:b2219e6e444b 144 {
kgills 0:b2219e6e444b 145 char data[2];
kgills 0:b2219e6e444b 146
kgills 0:b2219e6e444b 147 data[0] = REG_ADDR_CTRL;
kgills 0:b2219e6e444b 148 data[1] = CTRL_REG_PRESS_0 | ((oss & 0x3) << 6);
kgills 0:b2219e6e444b 149 oss_ = oss;
kgills 0:b2219e6e444b 150
kgills 0:b2219e6e444b 151 if (i2c_->write(I2C_ADDR, data, 2) != 0) {
kgills 0:b2219e6e444b 152 return -1;
kgills 0:b2219e6e444b 153 }
kgills 0:b2219e6e444b 154
kgills 0:b2219e6e444b 155 return 0;
kgills 0:b2219e6e444b 156 }
kgills 0:b2219e6e444b 157
kgills 0:b2219e6e444b 158 //******************************************************************************
kgills 0:b2219e6e444b 159 int BMP180::getPressure(int *pressure)
kgills 0:b2219e6e444b 160 {
kgills 0:b2219e6e444b 161 char addr, byte[3];
kgills 0:b2219e6e444b 162 uint32_t up;
kgills 0:b2219e6e444b 163 int32_t b6, x1, x2, x3, b3, p;
kgills 0:b2219e6e444b 164 uint32_t b4, b7;
kgills 0:b2219e6e444b 165
kgills 0:b2219e6e444b 166 addr = REG_ADDR_DATA;
kgills 0:b2219e6e444b 167 if (i2c_->write(I2C_ADDR, &addr, 1) != 0) {
kgills 0:b2219e6e444b 168 return -1;
kgills 0:b2219e6e444b 169 }
kgills 0:b2219e6e444b 170
kgills 0:b2219e6e444b 171 if (i2c_->read(I2C_ADDR, byte, 3) != 0) {
kgills 0:b2219e6e444b 172 return -1;
kgills 0:b2219e6e444b 173 }
kgills 0:b2219e6e444b 174
kgills 0:b2219e6e444b 175 up = ((byte[0] << 16) | (byte[1] << 8) | byte[2]) >> (8 - oss_);
kgills 0:b2219e6e444b 176
kgills 0:b2219e6e444b 177 b6 = b5 - 4000;
kgills 0:b2219e6e444b 178 x1 = (b6 * b6) >> 12;
kgills 0:b2219e6e444b 179 x1 *= calib.b2;
kgills 0:b2219e6e444b 180 x1 >>= 11;
kgills 0:b2219e6e444b 181 x2 = calib.ac2 * b6;
kgills 0:b2219e6e444b 182 x2 >>= 11;
kgills 0:b2219e6e444b 183 x3 = x1 + x2;
kgills 0:b2219e6e444b 184 b3 = (((((int32_t)calib.ac1) * 4 + x3) << oss_) + 2);
kgills 0:b2219e6e444b 185 b3 >>= 2;
kgills 0:b2219e6e444b 186
kgills 0:b2219e6e444b 187 x1 = (calib.ac3 * b6) >> 13;
kgills 0:b2219e6e444b 188 x2 = (calib.b1 * ((b6 * b6) >> 12)) >> 16;
kgills 0:b2219e6e444b 189 x3 = (x1 + x2 + 2) >> 2;
kgills 0:b2219e6e444b 190 b4 = (calib.ac4 * (uint32_t)(x3 + 32768)) >> 15;
kgills 0:b2219e6e444b 191 b7 = ((uint32_t)up - b3) * (50000 >> oss_);
kgills 0:b2219e6e444b 192 p = ((b7 < 0x80000000) ? ((b7 << 1) / b4) : ((b7 / b4) * 2));
kgills 0:b2219e6e444b 193 x1 = p >> 8;
kgills 0:b2219e6e444b 194 x1 *= x1;
kgills 0:b2219e6e444b 195 x1 = (x1 * 3038) >> 16;
kgills 0:b2219e6e444b 196 x2 = (-7357 * p) >> 16;
kgills 0:b2219e6e444b 197 p += (x1 + x2 + 3791) >> 4;
kgills 0:b2219e6e444b 198
kgills 0:b2219e6e444b 199 *pressure = p;
kgills 0:b2219e6e444b 200
kgills 0:b2219e6e444b 201 return 0;
kgills 0:b2219e6e444b 202 }
kgills 0:b2219e6e444b 203
kgills 0:b2219e6e444b 204 //******************************************************************************
kgills 0:b2219e6e444b 205 int BMP180::startTemperature(void)
kgills 0:b2219e6e444b 206 {
kgills 0:b2219e6e444b 207 char data[2] = { REG_ADDR_CTRL, CTRL_REG_TEMP };
kgills 0:b2219e6e444b 208
kgills 0:b2219e6e444b 209 if (i2c_->write(I2C_ADDR, data, 2) != 0) {
kgills 0:b2219e6e444b 210 return -1;
kgills 0:b2219e6e444b 211 }
kgills 0:b2219e6e444b 212
kgills 0:b2219e6e444b 213 return 0;
kgills 0:b2219e6e444b 214 }
kgills 0:b2219e6e444b 215
kgills 0:b2219e6e444b 216 //******************************************************************************
kgills 0:b2219e6e444b 217 int BMP180::getTemperature(float *tempC)
kgills 0:b2219e6e444b 218 {
kgills 0:b2219e6e444b 219 char addr, byte[2];
kgills 0:b2219e6e444b 220 uint16_t ut;
kgills 0:b2219e6e444b 221 int32_t x1, x2;
kgills 0:b2219e6e444b 222
kgills 0:b2219e6e444b 223 addr = REG_ADDR_DATA;
kgills 0:b2219e6e444b 224 if (i2c_->write(I2C_ADDR, &addr, 1) != 0) {
kgills 0:b2219e6e444b 225 return -1;
kgills 0:b2219e6e444b 226 }
kgills 0:b2219e6e444b 227
kgills 0:b2219e6e444b 228 if (i2c_->read(I2C_ADDR, byte, 2) != 0) {
kgills 0:b2219e6e444b 229 return -1;
kgills 0:b2219e6e444b 230 }
kgills 0:b2219e6e444b 231
kgills 0:b2219e6e444b 232 ut = (byte[0] << 8) | byte[1];
kgills 0:b2219e6e444b 233
kgills 0:b2219e6e444b 234 x1 = ((ut - calib.ac6) * calib.ac5) >> 15;
kgills 0:b2219e6e444b 235 x2 = (calib.mc << 11) / (x1 + calib.md);
kgills 0:b2219e6e444b 236 b5 = x1 + x2;
kgills 0:b2219e6e444b 237
kgills 0:b2219e6e444b 238 *tempC = (float)(b5 + 8) / 160;
kgills 0:b2219e6e444b 239
kgills 0:b2219e6e444b 240 return 0;
kgills 0:b2219e6e444b 241 }
kgills 0:b2219e6e444b 242
kgills 0:b2219e6e444b 243 //******************************************************************************
kgills 0:b2219e6e444b 244 int BMP180::getTemperature(int16_t *tempCx10)
kgills 0:b2219e6e444b 245 {
kgills 0:b2219e6e444b 246 char addr, byte[2];
kgills 0:b2219e6e444b 247 uint16_t ut;
kgills 0:b2219e6e444b 248 int32_t x1, x2;
kgills 0:b2219e6e444b 249
kgills 0:b2219e6e444b 250 addr = REG_ADDR_DATA;
kgills 0:b2219e6e444b 251 if (i2c_->write(I2C_ADDR, &addr, 1) != 0) {
kgills 0:b2219e6e444b 252 return -1;
kgills 0:b2219e6e444b 253 }
kgills 0:b2219e6e444b 254
kgills 0:b2219e6e444b 255 if (i2c_->read(I2C_ADDR, byte, 2) != 0) {
kgills 0:b2219e6e444b 256 return -1;
kgills 0:b2219e6e444b 257 }
kgills 0:b2219e6e444b 258
kgills 0:b2219e6e444b 259 ut = (byte[0] << 8) | byte[1];
kgills 0:b2219e6e444b 260
kgills 0:b2219e6e444b 261 x1 = ((ut - calib.ac6) * calib.ac5) >> 15;
kgills 0:b2219e6e444b 262 x2 = (calib.mc << 11) / (x1 + calib.md);
kgills 0:b2219e6e444b 263 b5 = x1 + x2;
kgills 0:b2219e6e444b 264
kgills 0:b2219e6e444b 265 *tempCx10 = (b5 + 8) >> 4;
kgills 0:b2219e6e444b 266
kgills 0:b2219e6e444b 267 return 0;
kgills 0:b2219e6e444b 268 }