Paparazzi UAS  v5.18.0_stable
Paparazzi is a free software Unmanned Aircraft System.
bmp085.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2010 Martin Mueller
3  * Copyright (C) 2013 Felix Ruess <felix.ruess@gmail.com>
4  *
5  * This file is part of paparazzi.
6  *
7  * paparazzi is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2, or (at your option)
10  * any later version.
11  *
12  * paparazzi is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with paparazzi; see the file COPYING. If not, write to
19  * the Free Software Foundation, 59 Temple Place - Suite 330,
20  * Boston, MA 02111-1307, USA.
21  */
22 
27 #include "peripherals/bmp085.h"
29 
30 
32 {
33  int32_t x1 = (raw - calib->ac6) * calib->ac5 / (1 << 15);
34  int32_t x2 = (calib->mc << 11) / (x1 + calib->md);
35  calib->b5 = x1 + x2;
36  return (calib->b5 + 8) >> 4;
37 }
38 
39 
40 
45 {
46  int32_t b6 = calib->b5 - 4000;
47  int32_t x1 = (calib->b2 * (b6 * b6 >> 12)) >> 11;
48  int32_t x2 = calib->ac2 * b6 >> 11;
49  int32_t x3 = x1 + x2;
50  int32_t b3 = (((calib->ac1 * 4 + x3) << BMP085_OSS) + 2) / 4;
51  x1 = calib->ac3 * b6 >> 13;
52  x2 = (calib->b1 * (b6 * b6 >> 12)) >> 16;
53  x3 = ((x1 + x2) + 2) >> 2;
54  uint32_t b4 = (calib->ac4 * (uint32_t)(x3 + 32768)) >> 15;
55  uint32_t b7 = (raw - b3) * (50000 >> BMP085_OSS);
56  int32_t p = b7 < 0x80000000 ? (b7 * 2) / b4 : (b7 / b4) * 2;
57  x1 = (p >> 8) * (p >> 8);
58  x1 = (x1 * 3038) >> 16;
59  x2 = (-7357 * p) >> 16;
60  return p + ((x1 + x2 + 3791) >> 4);
61 }
62 
67 static bool bmp085_eoc_true(void)
68 {
69  return true;
70 }
71 
72 
74 {
75  if (bmp->status == BMP085_STATUS_UNINIT && bmp->i2c_trans.status == I2CTransDone) {
76  bmp->initialized = false;
78  i2c_transceive(bmp->i2c_p, &(bmp->i2c_trans), bmp->i2c_trans.slave_addr, 1, 22);
79  }
80 }
81 
82 
83 void bmp085_init(struct Bmp085 *bmp, struct i2c_periph *i2c_p, uint8_t addr)
84 {
85  /* set i2c_peripheral */
86  bmp->i2c_p = i2c_p;
87 
88  /* slave address */
89  bmp->i2c_trans.slave_addr = addr;
90  /* set initial status: Success or Done */
92 
93  bmp->data_available = false;
94  bmp->initialized = false;
96 
97  /* by default assign EOC function that always returns TRUE
98  * ensure proper timing through frequeny of bmp_periodic!
99  */
100  bmp->eoc = &bmp085_eoc_true;
101 }
102 
108 void bmp085_periodic(struct Bmp085 *bmp)
109 {
110  switch (bmp->status) {
111  case BMP085_STATUS_IDLE:
112  /* start temp measurement */
113  bmp->i2c_trans.buf[0] = BMP085_CTRL_REG;
114  bmp->i2c_trans.buf[1] = BMP085_START_TEMP;
115  i2c_transmit(bmp->i2c_p, &bmp->i2c_trans, bmp->i2c_trans.slave_addr, 2);
117  break;
118 
120  /* read temp measurement */
121  if (bmp->eoc()) {
122  bmp->i2c_trans.buf[0] = BMP085_DAT_MSB;
123  i2c_transceive(bmp->i2c_p, &bmp->i2c_trans, bmp->i2c_trans.slave_addr, 1, 2);
125  }
126  break;
127 
129  /* read press measurement */
130  if (bmp->eoc()) {
131  bmp->i2c_trans.buf[0] = BMP085_DAT_MSB;
132  i2c_transceive(bmp->i2c_p, &bmp->i2c_trans, bmp->i2c_trans.slave_addr, 1, 3);
134  }
135  break;
136 
137  default:
138  break;
139  }
140 }
141 
142 void bmp085_event(struct Bmp085 *bmp)
143 {
144  if (bmp->i2c_trans.status == I2CTransSuccess) {
145  switch (bmp->status) {
147  bmp->calib.ac1 = (bmp->i2c_trans.buf[0] << 8) | bmp->i2c_trans.buf[1];
148  bmp->calib.ac2 = (bmp->i2c_trans.buf[2] << 8) | bmp->i2c_trans.buf[3];
149  bmp->calib.ac3 = (bmp->i2c_trans.buf[4] << 8) | bmp->i2c_trans.buf[5];
150  bmp->calib.ac4 = (bmp->i2c_trans.buf[6] << 8) | bmp->i2c_trans.buf[7];
151  bmp->calib.ac5 = (bmp->i2c_trans.buf[8] << 8) | bmp->i2c_trans.buf[9];
152  bmp->calib.ac6 = (bmp->i2c_trans.buf[10] << 8) | bmp->i2c_trans.buf[11];
153  bmp->calib.b1 = (bmp->i2c_trans.buf[12] << 8) | bmp->i2c_trans.buf[13];
154  bmp->calib.b2 = (bmp->i2c_trans.buf[14] << 8) | bmp->i2c_trans.buf[15];
155  bmp->calib.mb = (bmp->i2c_trans.buf[16] << 8) | bmp->i2c_trans.buf[17];
156  bmp->calib.mc = (bmp->i2c_trans.buf[18] << 8) | bmp->i2c_trans.buf[19];
157  bmp->calib.md = (bmp->i2c_trans.buf[20] << 8) | bmp->i2c_trans.buf[21];
158  bmp->status = BMP085_STATUS_IDLE;
159  bmp->initialized = true;
160  break;
161 
163  /* get uncompensated temperature */
164  bmp->ut = (bmp->i2c_trans.buf[0] << 8) | bmp->i2c_trans.buf[1];
165  bmp->temperature = bmp085_compensated_temperature(&(bmp->calib), bmp->ut);
166  /* start high res pressure measurement */
167  bmp->i2c_trans.buf[0] = BMP085_CTRL_REG;
168  bmp->i2c_trans.buf[1] = BMP085_START_P3;
169  i2c_transmit(bmp->i2c_p, &bmp->i2c_trans, bmp->i2c_trans.slave_addr, 2);
171  break;
172 
174  /* get uncompensated pressure */
175  bmp->up = (bmp->i2c_trans.buf[0] << 16) |
176  (bmp->i2c_trans.buf[1] << 8) |
177  bmp->i2c_trans.buf[2];
178  bmp->up = bmp->up >> (8 - BMP085_OSS);
179  bmp->pressure = bmp085_compensated_pressure(&(bmp->calib), bmp->up);
180  bmp->data_available = true;
181  bmp->status = BMP085_STATUS_IDLE;
182  break;
183 
184  default:
185  break;
186  }
187  } else if (bmp->i2c_trans.status == I2CTransFailed) {
188  /* try again */
189  if (bmp->initialized) {
190  bmp->status = BMP085_STATUS_IDLE;
191  } else {
193  }
195  }
196 }
BMP085_STATUS_READ_PRESS
@ BMP085_STATUS_READ_PRESS
Definition: bmp085.h:39
i2c_transaction::buf
volatile uint8_t buf[I2C_BUF_LEN]
Transaction buffer With I2C_BUF_LEN number of bytes.
Definition: i2c.h:122
Bmp085Calib::ac2
int16_t ac2
Definition: bmp085.h:45
bmp085_eoc_true
static bool bmp085_eoc_true(void)
Dummy function to always return TRUE on EndOfConversion check.
Definition: bmp085.c:67
bmp085_periodic
void bmp085_periodic(struct Bmp085 *bmp)
Start new measurement if idle or read temp/pressure.
Definition: bmp085.c:108
Bmp085::status
enum Bmp085Status status
state machine status
Definition: bmp085.h:66
Bmp085Calib::ac1
int16_t ac1
Definition: bmp085.h:44
Bmp085Calib::mb
int16_t mb
Definition: bmp085.h:52
Bmp085::temperature
int32_t temperature
temperature in 0.1 deg Celcius
Definition: bmp085.h:72
I2CTransFailed
@ I2CTransFailed
transaction failed
Definition: i2c.h:58
uint32_t
unsigned long uint32_t
Definition: types.h:18
Bmp085::calib
struct Bmp085Calib calib
Definition: bmp085.h:69
BMP085_STATUS_IDLE
@ BMP085_STATUS_IDLE
Definition: bmp085.h:35
Bmp085Calib::mc
int16_t mc
Definition: bmp085.h:53
Bmp085::i2c_trans
struct i2c_transaction i2c_trans
Definition: bmp085.h:64
Bmp085Calib::b2
int16_t b2
Definition: bmp085.h:51
BMP085_EEPROM_AC1
#define BMP085_EEPROM_AC1
Definition: bmp085_regs.h:30
Bmp085Calib::md
int16_t md
Definition: bmp085.h:54
bmp085_init
void bmp085_init(struct Bmp085 *bmp, struct i2c_periph *i2c_p, uint8_t addr)
Definition: bmp085.c:83
Bmp085Calib::b1
int16_t b1
Definition: bmp085.h:50
I2CTransSuccess
@ I2CTransSuccess
transaction successfully finished by I2C driver
Definition: i2c.h:57
i2c_transmit
bool i2c_transmit(struct i2c_periph *p, struct i2c_transaction *t, uint8_t s_addr, uint8_t len)
Submit a write only transaction.
Definition: i2c.c:324
Bmp085Calib::ac5
uint16_t ac5
Definition: bmp085.h:48
Bmp085::ut
int32_t ut
uncompensated temperature
Definition: bmp085.h:70
BMP085_OSS
#define BMP085_OSS
Over sample setting (0-3)
Definition: bmp085_regs.h:55
Bmp085::eoc
Bmp085EOC eoc
function to check End Of Conversion
Definition: bmp085.h:65
bmp085_regs.h
bmp085.h
Bmp085::initialized
bool initialized
config done flag
Definition: bmp085.h:67
i2c_transceive
bool i2c_transceive(struct i2c_periph *p, struct i2c_transaction *t, uint8_t s_addr, uint8_t len_w, uint16_t len_r)
Submit a write/read transaction.
Definition: i2c.c:344
uint8_t
unsigned char uint8_t
Definition: types.h:14
i2c_transaction::status
enum I2CTransactionStatus status
Transaction status.
Definition: i2c.h:126
bmp085_compensated_pressure
static int32_t bmp085_compensated_pressure(struct Bmp085Calib *calib, int32_t raw)
Apply temp calibration and sensor calibration to raw measurement to get Pa (from BMP085 datasheet)
Definition: bmp085.c:44
BMP085_STATUS_UNINIT
@ BMP085_STATUS_UNINIT
Definition: bmp085.h:34
bmp085_read_eeprom_calib
void bmp085_read_eeprom_calib(struct Bmp085 *bmp)
Definition: bmp085.c:73
i2c_transaction::slave_addr
uint8_t slave_addr
Slave address.
Definition: i2c.h:104
Bmp085::i2c_p
struct i2c_periph * i2c_p
Definition: bmp085.h:63
BMP085_STATUS_START_PRESS
@ BMP085_STATUS_START_PRESS
Definition: bmp085.h:38
Bmp085::up
int32_t up
uncompensated pressure
Definition: bmp085.h:71
Bmp085Calib::b5
int32_t b5
Definition: bmp085.h:57
Bmp085::pressure
int32_t pressure
pressure in Pascal
Definition: bmp085.h:73
Bmp085Calib::ac6
uint16_t ac6
Definition: bmp085.h:49
Bmp085::data_available
volatile bool data_available
data ready flag
Definition: bmp085.h:68
BMP085_STATUS_READ_TEMP
@ BMP085_STATUS_READ_TEMP
Definition: bmp085.h:37
int32_t
signed long int32_t
Definition: types.h:19
bmp085_compensated_temperature
static int32_t bmp085_compensated_temperature(struct Bmp085Calib *calib, int32_t raw)
Definition: bmp085.c:31
Bmp085Calib::ac4
uint16_t ac4
Definition: bmp085.h:47
BMP085_CTRL_REG
#define BMP085_CTRL_REG
Definition: bmp085_regs.h:42
BMP085_START_TEMP
#define BMP085_START_TEMP
Definition: bmp085_regs.h:44
Bmp085
Definition: bmp085.h:62
I2CTransDone
@ I2CTransDone
transaction set to done by user level
Definition: i2c.h:59
Bmp085Calib
Definition: bmp085.h:42
i2c_periph
Definition: i2c.h:144
Bmp085Calib::ac3
int16_t ac3
Definition: bmp085.h:46
bmp085_event
void bmp085_event(struct Bmp085 *bmp)
Definition: bmp085.c:142
BMP085_START_P3
#define BMP085_START_P3
Definition: bmp085_regs.h:48
p
static float p[2][2]
Definition: ins_alt_float.c:268
BMP085_DAT_MSB
#define BMP085_DAT_MSB
Definition: bmp085_regs.h:50
BMP085_STATUS_START_TEMP
@ BMP085_STATUS_START_TEMP
Definition: bmp085.h:36