Sergii Doroshenko / MS5611_01BA03
Committer:
eseerge
Date:
Thu Jan 03 17:12:03 2013 +0000
Revision:
0:4343d7e75385
Initial revision for ms5611_01ba03 baro

Who changed what in which revision?

UserRevisionLine numberNew contents of line
eseerge 0:4343d7e75385 1 /**
eseerge 0:4343d7e75385 2 * @author Sergii Doroshenko
eseerge 0:4343d7e75385 3 *
eseerge 0:4343d7e75385 4 * @section LICENSE
eseerge 0:4343d7e75385 5 *
eseerge 0:4343d7e75385 6 * Copyright (c) 2010 ARM Limited
eseerge 0:4343d7e75385 7 *
eseerge 0:4343d7e75385 8 * Permission is hereby granted, free of charge, to any person obtaining a copy
eseerge 0:4343d7e75385 9 * of this software and associated documentation files (the "Software"), to deal
eseerge 0:4343d7e75385 10 * in the Software without restriction, including without limitation the rights
eseerge 0:4343d7e75385 11 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
eseerge 0:4343d7e75385 12 * copies of the Software, and to permit persons to whom the Software is
eseerge 0:4343d7e75385 13 * furnished to do so, subject to the following conditions:
eseerge 0:4343d7e75385 14 *
eseerge 0:4343d7e75385 15 * The above copyright notice and this permission notice shall be included in
eseerge 0:4343d7e75385 16 * all copies or substantial portions of the Software.
eseerge 0:4343d7e75385 17 *
eseerge 0:4343d7e75385 18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
eseerge 0:4343d7e75385 19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
eseerge 0:4343d7e75385 20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
eseerge 0:4343d7e75385 21 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
eseerge 0:4343d7e75385 22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
eseerge 0:4343d7e75385 23 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
eseerge 0:4343d7e75385 24 * THE SOFTWARE.
eseerge 0:4343d7e75385 25 *
eseerge 0:4343d7e75385 26 * @section DESCRIPTION
eseerge 0:4343d7e75385 27 *
eseerge 0:4343d7e75385 28 * MS5611_01BA03 Barometric Pressure Sensor, Variometer.
eseerge 0:4343d7e75385 29 *
eseerge 0:4343d7e75385 30 * Datasheet:
eseerge 0:4343d7e75385 31 *
eseerge 0:4343d7e75385 32 * http://www.meas-spec.com/downloads/MS5611-01BA03.pdf
eseerge 0:4343d7e75385 33 */
eseerge 0:4343d7e75385 34
eseerge 0:4343d7e75385 35 #include "MS5611_01BA03.h"
eseerge 0:4343d7e75385 36
eseerge 0:4343d7e75385 37 extern Serial pc;
eseerge 0:4343d7e75385 38
eseerge 0:4343d7e75385 39 uint8_t MS5611_01BA03::baro_read_reg(char reg)
eseerge 0:4343d7e75385 40 {
eseerge 0:4343d7e75385 41 uint8_t byte;
eseerge 0:4343d7e75385 42
eseerge 0:4343d7e75385 43 ENABLE_BARO;
eseerge 0:4343d7e75385 44 spi_.write(reg);
eseerge 0:4343d7e75385 45 byte = spi_.write(0x00);
eseerge 0:4343d7e75385 46 DISABLE_BARO;
eseerge 0:4343d7e75385 47
eseerge 0:4343d7e75385 48 return byte;
eseerge 0:4343d7e75385 49 }
eseerge 0:4343d7e75385 50
eseerge 0:4343d7e75385 51 void MS5611_01BA03::baro_write_reg(uint8_t reg, uint8_t val)
eseerge 0:4343d7e75385 52 {
eseerge 0:4343d7e75385 53 ENABLE_BARO;
eseerge 0:4343d7e75385 54 spi_.write(reg);
eseerge 0:4343d7e75385 55 spi_.write(val);
eseerge 0:4343d7e75385 56 DISABLE_BARO;
eseerge 0:4343d7e75385 57 }
eseerge 0:4343d7e75385 58
eseerge 0:4343d7e75385 59 void MS5611_01BA03::ms5611_01ba_reset() {
eseerge 0:4343d7e75385 60 ENABLE_BARO;
eseerge 0:4343d7e75385 61 spi_.write(MS561101BA_RESET);
eseerge 0:4343d7e75385 62 wait(0.03);
eseerge 0:4343d7e75385 63 DISABLE_BARO;
eseerge 0:4343d7e75385 64 }
eseerge 0:4343d7e75385 65
eseerge 0:4343d7e75385 66 static bool ms5611_01ba_crc(uint16_t* n_prom) {
eseerge 0:4343d7e75385 67 uint8_t cnt; // simple counter
eseerge 0:4343d7e75385 68 uint16_t n_rem; // crc reminder
eseerge 0:4343d7e75385 69 uint8_t crc_read; // original value of the crc
eseerge 0:4343d7e75385 70 uint8_t n_bit;
eseerge 0:4343d7e75385 71
eseerge 0:4343d7e75385 72 n_rem = 0x00;
eseerge 0:4343d7e75385 73 crc_read = n_prom[7] & 0xF; //save read CRC
eseerge 0:4343d7e75385 74 n_prom[7]=(0xFFF0 & (n_prom[7])); //CRC byte is replaced by 0 - 0xFF00 // but 4 bit CRC!!!!!!
eseerge 0:4343d7e75385 75 for (cnt = 0; cnt < 16; cnt++) { // operation is performed on bytes
eseerge 0:4343d7e75385 76 // choose LSB or MSB
eseerge 0:4343d7e75385 77 if (cnt % 2 == 1)
eseerge 0:4343d7e75385 78 n_rem ^= (uint16_t)((n_prom[cnt>>1]) & 0x00FF);
eseerge 0:4343d7e75385 79 else
eseerge 0:4343d7e75385 80 n_rem ^= (uint16_t) (n_prom[cnt>>1]>>8);
eseerge 0:4343d7e75385 81
eseerge 0:4343d7e75385 82 for (n_bit = 8; n_bit > 0; n_bit--) {
eseerge 0:4343d7e75385 83 if (n_rem & (0x8000)) {
eseerge 0:4343d7e75385 84 n_rem = (n_rem << 1) ^ 0x3000;
eseerge 0:4343d7e75385 85 }
eseerge 0:4343d7e75385 86 else {
eseerge 0:4343d7e75385 87 n_rem = (n_rem << 1);
eseerge 0:4343d7e75385 88 }
eseerge 0:4343d7e75385 89 }
eseerge 0:4343d7e75385 90 }
eseerge 0:4343d7e75385 91
eseerge 0:4343d7e75385 92 n_rem = (0x000F & (n_rem >> 12)); // final 4-bit reminder is CRC code
eseerge 0:4343d7e75385 93 n_prom[7] = crc_read; // restore the crc_read to its original place
eseerge 0:4343d7e75385 94
eseerge 0:4343d7e75385 95 return (crc_read == (n_rem ^ 0x00)) ;
eseerge 0:4343d7e75385 96 }
eseerge 0:4343d7e75385 97
eseerge 0:4343d7e75385 98 static bool ms5611_01ba_crc2(uint16_t prom[]) {
eseerge 0:4343d7e75385 99 int32_t i, j;
eseerge 0:4343d7e75385 100 uint32_t res = 0;
eseerge 0:4343d7e75385 101 uint8_t crc = prom[7] & 0xF;
eseerge 0:4343d7e75385 102 prom[7] &= 0xFFF0;
eseerge 0:4343d7e75385 103
eseerge 0:4343d7e75385 104 for (i = 0; i < 16; i++) {
eseerge 0:4343d7e75385 105 if (i & 1)
eseerge 0:4343d7e75385 106 res ^= ((prom[i>>1]) & 0x00FF);
eseerge 0:4343d7e75385 107 else
eseerge 0:4343d7e75385 108 res ^= (prom[i>>1]>>8);
eseerge 0:4343d7e75385 109
eseerge 0:4343d7e75385 110 for (j = 8; j > 0; j--) {
eseerge 0:4343d7e75385 111 if (res & 0x8000) res ^= 0x1800;
eseerge 0:4343d7e75385 112 res <<= 1;
eseerge 0:4343d7e75385 113 }
eseerge 0:4343d7e75385 114 }
eseerge 0:4343d7e75385 115 prom[7] |= crc;
eseerge 0:4343d7e75385 116
eseerge 0:4343d7e75385 117 return (crc == ((res >> 12) & 0xF));
eseerge 0:4343d7e75385 118 }
eseerge 0:4343d7e75385 119
eseerge 0:4343d7e75385 120 void MS5611_01BA03::ms5611_01ba_readCalibration() {
eseerge 0:4343d7e75385 121 union { uint16_t val; uint8_t raw[2]; } data;
eseerge 0:4343d7e75385 122 uint8_t i;
eseerge 0:4343d7e75385 123
eseerge 0:4343d7e75385 124 //read first prom settings
eseerge 0:4343d7e75385 125 for(i=0;i<8;i++) {
eseerge 0:4343d7e75385 126 ENABLE_BARO;
eseerge 0:4343d7e75385 127 spi_.write(0xA0+2*i);
eseerge 0:4343d7e75385 128 data.raw[1] = spi_.write(0x0); // read a 16 bit register
eseerge 0:4343d7e75385 129 data.raw[0] = spi_.write(0x0);
eseerge 0:4343d7e75385 130 ms5611_01ba_ctx.c[i] = data.val;
eseerge 0:4343d7e75385 131 DISABLE_BARO;
eseerge 0:4343d7e75385 132 wait(0.01);
eseerge 0:4343d7e75385 133 }
eseerge 0:4343d7e75385 134 }
eseerge 0:4343d7e75385 135
eseerge 0:4343d7e75385 136 bool MS5611_01BA03::init() {
eseerge 0:4343d7e75385 137 ms5611_01ba_reset();
eseerge 0:4343d7e75385 138 ms5611_01ba_readCalibration();
eseerge 0:4343d7e75385 139 wait(0.5);
eseerge 0:4343d7e75385 140 return true; //ms5611_01ba_crc(ms5611_01ba_ctx.c);
eseerge 0:4343d7e75385 141 }
eseerge 0:4343d7e75385 142
eseerge 0:4343d7e75385 143 // read uncompensated temperature value: send command first
eseerge 0:4343d7e75385 144 void MS5611_01BA03::ms5611_01ba_UT_Start() {
eseerge 0:4343d7e75385 145 ENABLE_BARO;
eseerge 0:4343d7e75385 146 spi_.write(MS561101BA_TEMPERATURE + OSR);
eseerge 0:4343d7e75385 147 DISABLE_BARO;
eseerge 0:4343d7e75385 148 }
eseerge 0:4343d7e75385 149
eseerge 0:4343d7e75385 150 // read uncompensated pressure value: send command first
eseerge 0:4343d7e75385 151 void MS5611_01BA03::ms5611_01ba_UP_Start() {
eseerge 0:4343d7e75385 152 ENABLE_BARO;
eseerge 0:4343d7e75385 153 spi_.write(MS561101BA_PRESSURE + OSR);
eseerge 0:4343d7e75385 154 DISABLE_BARO;
eseerge 0:4343d7e75385 155 }
eseerge 0:4343d7e75385 156
eseerge 0:4343d7e75385 157 // read uncompensated pressure value: read result bytes
eseerge 0:4343d7e75385 158 void MS5611_01BA03::ms5611_01ba_UP_Read() {
eseerge 0:4343d7e75385 159 ENABLE_BARO;
eseerge 0:4343d7e75385 160 spi_.write(0x0);
eseerge 0:4343d7e75385 161 ms5611_01ba_ctx.up.raw[2] = spi_.write(0x0);
eseerge 0:4343d7e75385 162 ms5611_01ba_ctx.up.raw[1] = spi_.write(0x0);
eseerge 0:4343d7e75385 163 ms5611_01ba_ctx.up.raw[0] = spi_.write(0x0);
eseerge 0:4343d7e75385 164 DISABLE_BARO;
eseerge 0:4343d7e75385 165 }
eseerge 0:4343d7e75385 166
eseerge 0:4343d7e75385 167 // read uncompensated temperature value: read result bytes
eseerge 0:4343d7e75385 168 void MS5611_01BA03::ms5611_01ba_UT_Read() {
eseerge 0:4343d7e75385 169 ENABLE_BARO;
eseerge 0:4343d7e75385 170 spi_.write(0x0);
eseerge 0:4343d7e75385 171 ms5611_01ba_ctx.ut.raw[2] = spi_.write(0x0);
eseerge 0:4343d7e75385 172 ms5611_01ba_ctx.ut.raw[1] = spi_.write(0x0);
eseerge 0:4343d7e75385 173 ms5611_01ba_ctx.ut.raw[0] = spi_.write(0x0);
eseerge 0:4343d7e75385 174 DISABLE_BARO;
eseerge 0:4343d7e75385 175 }
eseerge 0:4343d7e75385 176
eseerge 0:4343d7e75385 177 void MS5611_01BA03::ms5611_01ba_Calculate() {
eseerge 0:4343d7e75385 178 int32_t temperature, off2 = 0, sens2 = 0, delt;
eseerge 0:4343d7e75385 179
eseerge 0:4343d7e75385 180 int32_t dT = ms5611_01ba_ctx.ut.val - ((uint32_t)ms5611_01ba_ctx.c[5] << 8);
eseerge 0:4343d7e75385 181 int64_t off = ((uint32_t)ms5611_01ba_ctx.c[2] << 16) + (((int64_t)dT * ms5611_01ba_ctx.c[4]) >> 7);
eseerge 0:4343d7e75385 182 int64_t sens = ((uint32_t)ms5611_01ba_ctx.c[1] << 15) + (((int64_t)dT * ms5611_01ba_ctx.c[3]) >> 8);
eseerge 0:4343d7e75385 183 temperature = 2000 + (((int64_t)dT * ms5611_01ba_ctx.c[6]) >> 23);
eseerge 0:4343d7e75385 184
eseerge 0:4343d7e75385 185 if (temperature < 2000) { // temperature lower than 20st.C
eseerge 0:4343d7e75385 186 delt = temperature - 2000;
eseerge 0:4343d7e75385 187 delt = delt * delt;
eseerge 0:4343d7e75385 188 off2 = (5 * delt) >> 1;
eseerge 0:4343d7e75385 189 sens2 = (5 * delt) >> 2;
eseerge 0:4343d7e75385 190 if (temperature < -1500) { // temperature lower than -15st.C
eseerge 0:4343d7e75385 191 delt = temperature + 1500;
eseerge 0:4343d7e75385 192 delt = delt * delt;
eseerge 0:4343d7e75385 193 off2 += 7 * delt;
eseerge 0:4343d7e75385 194 sens2 += (11 * delt) >> 1;
eseerge 0:4343d7e75385 195 }
eseerge 0:4343d7e75385 196 }
eseerge 0:4343d7e75385 197 off -= off2;
eseerge 0:4343d7e75385 198 sens -= sens2;
eseerge 0:4343d7e75385 199 pressure = (( (ms5611_01ba_ctx.up.val * sens ) >> 21) - off) >> 15;
eseerge 0:4343d7e75385 200 }
eseerge 0:4343d7e75385 201
eseerge 0:4343d7e75385 202 MS5611_01BA03::MS5611_01BA03(PinName mosi, PinName miso, PinName sclk, PinName cs): spi_(mosi, miso, sclk) {
eseerge 0:4343d7e75385 203
eseerge 0:4343d7e75385 204 cs_ = new DigitalOut(cs);
eseerge 0:4343d7e75385 205
eseerge 0:4343d7e75385 206 spi_.format(8,3);
eseerge 0:4343d7e75385 207 spi_.frequency(1000000); // default 1000000
eseerge 0:4343d7e75385 208
eseerge 0:4343d7e75385 209 timer.start();
eseerge 0:4343d7e75385 210
eseerge 0:4343d7e75385 211 altitude = 0;
eseerge 0:4343d7e75385 212 }
eseerge 0:4343d7e75385 213
eseerge 0:4343d7e75385 214 MS5611_01BA03::~MS5611_01BA03() {
eseerge 0:4343d7e75385 215 timer.stop();
eseerge 0:4343d7e75385 216 delete(cs_);
eseerge 0:4343d7e75385 217 cs_ = NULL;
eseerge 0:4343d7e75385 218 }
eseerge 0:4343d7e75385 219
eseerge 0:4343d7e75385 220 void MS5611_01BA03::ms5611_01ba_Update() {
eseerge 0:4343d7e75385 221 if (timer.read_us() < ms5611_01ba_ctx.deadline) return;
eseerge 0:4343d7e75385 222 ms5611_01ba_ctx.deadline = timer.read_us();
eseerge 0:4343d7e75385 223 switch (ms5611_01ba_ctx.state) {
eseerge 0:4343d7e75385 224 case 0:
eseerge 0:4343d7e75385 225 ms5611_01ba_UT_Start();
eseerge 0:4343d7e75385 226 ms5611_01ba_ctx.state++;
eseerge 0:4343d7e75385 227 ms5611_01ba_ctx.deadline += 10000; //according to the specs, the pause should be at least 8.22ms
eseerge 0:4343d7e75385 228 break;
eseerge 0:4343d7e75385 229 case 1:
eseerge 0:4343d7e75385 230 ms5611_01ba_UT_Read();
eseerge 0:4343d7e75385 231 ms5611_01ba_ctx.state++;
eseerge 0:4343d7e75385 232 break;
eseerge 0:4343d7e75385 233 case 2:
eseerge 0:4343d7e75385 234 ms5611_01ba_UP_Start();
eseerge 0:4343d7e75385 235 ms5611_01ba_ctx.state++;
eseerge 0:4343d7e75385 236 ms5611_01ba_ctx.deadline += 10000; //according to the specs, the pause should be at least 8.22ms
eseerge 0:4343d7e75385 237 break;
eseerge 0:4343d7e75385 238 case 3:
eseerge 0:4343d7e75385 239 ms5611_01ba_UP_Read();
eseerge 0:4343d7e75385 240 ms5611_01ba_Calculate();
eseerge 0:4343d7e75385 241 altitude = (1.0f - pow((float)pressure/101325.0f, 0.190295f)) * 4433000.0f; //centimeter
eseerge 0:4343d7e75385 242
eseerge 0:4343d7e75385 243 ms5611_01ba_ctx.state = 0;
eseerge 0:4343d7e75385 244 ms5611_01ba_ctx.deadline += 4000;
eseerge 0:4343d7e75385 245 break;
eseerge 0:4343d7e75385 246 }
eseerge 0:4343d7e75385 247 }
eseerge 0:4343d7e75385 248
eseerge 0:4343d7e75385 249 int32_t MS5611_01BA03::getPressure() {
eseerge 0:4343d7e75385 250 return pressure;
eseerge 0:4343d7e75385 251 }
eseerge 0:4343d7e75385 252
eseerge 0:4343d7e75385 253 int32_t MS5611_01BA03::getAltitude() {
eseerge 0:4343d7e75385 254 ms5611_01ba_Update();
eseerge 0:4343d7e75385 255 return altitude;
eseerge 0:4343d7e75385 256 }