Paparazzi UAS  v5.0.5_stable-7-g4b8bbb7
Paparazzi is a free software Unmanned Aircraft System.
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
baro_board.c
Go to the documentation of this file.
1 
3 #include <libopencm3/stm32/f1/gpio.h>
4 
5 struct Baro baro;
9 
10 #define BMP085_SAMPLE_PERIOD_MS (3 + (2 << BMP085_OSS) * 3)
11 #define BMP085_SAMPLE_PERIOD (BMP075_SAMPLE_PERIOD_MS >> 1)
12 
13 // FIXME: BARO DRDY connected to PB0 for lisa/m
14 
15 static inline void bmp085_write_reg(uint8_t addr, uint8_t value)
16 {
17  baro_trans.buf[0] = addr;
18  baro_trans.buf[1] = value;
19 
20  i2c_transmit(&i2c2, &baro_trans, BMP085_ADDR, 2);
21 
22  // FIXME, no while loops without timeout!!
24 }
25 
26 static inline void bmp085_read_reg16(uint8_t addr)
27 {
28  baro_trans.buf[0] = addr;
29  i2c_transceive(&i2c2, &baro_trans, BMP085_ADDR, 1, 2);
30 }
31 
32 static inline int16_t bmp085_read_reg16_blocking(uint8_t addr, uint32_t timeout)
33 {
34  uint32_t time = 0;
35 
36  bmp085_read_reg16(addr);
37 
39  if ((time == timeout) && (timeout != 0)) {
40  return 0; /* Timeout of the i2c read */
41  } else {
42  time++;
43  }
44  }
45 
46  return ((baro_trans.buf[0] << 8) | baro_trans.buf[1]);
47 }
48 
49 static inline void bmp085_read_reg24(uint8_t addr)
50 {
51  baro_trans.buf[0] = addr;
52  i2c_transceive(&i2c2, &baro_trans, BMP085_ADDR, 1, 3);
53 }
54 
56 {
57  calibration.ac1 = bmp085_read_reg16_blocking(0xAA, 10000); // AC1
58  calibration.ac2 = bmp085_read_reg16_blocking(0xAC, 10000); // AC2
59  calibration.ac3 = bmp085_read_reg16_blocking(0xAE, 10000); // AC3
60  calibration.ac4 = bmp085_read_reg16_blocking(0xB0, 10000); // AC4
61  calibration.ac5 = bmp085_read_reg16_blocking(0xB2, 10000); // AC5
62  calibration.ac6 = bmp085_read_reg16_blocking(0xB4, 10000); // AC6
63  calibration.b1 = bmp085_read_reg16_blocking(0xB6, 10000); // B1
64  calibration.b2 = bmp085_read_reg16_blocking(0xB8, 10000); // B2
65  calibration.mb = bmp085_read_reg16_blocking(0xBA, 10000); // MB
66  calibration.mc = bmp085_read_reg16_blocking(0xBC, 10000); // MC
67  calibration.md = bmp085_read_reg16_blocking(0xBE, 10000); // MD
68 }
69 
70 void baro_init(void) {
72  baro.absolute = 0;
73  baro.differential = 0;
76 
77  /* STM32 specific (maybe this is a LISA/M specific driver anyway?) */
78  gpio_clear(GPIOB, GPIO0);
79  gpio_set_mode(GPIOB, GPIO_MODE_INPUT,
80  GPIO_CNF_INPUT_PULL_UPDOWN, GPIO0);
81 }
82 
83 static inline int baro_eoc(void)
84 {
85  return gpio_get(GPIOB, GPIO0);
86 }
87 
88 static inline void bmp085_request_pressure(void)
89 {
90  bmp085_write_reg(0xF4, 0x34 + (BMP085_OSS << 6));
91 }
92 
93 static inline void bmp085_request_temp(void)
94 {
95  bmp085_write_reg(0xF4, 0x2E);
96 }
97 
98 static inline void bmp085_read_pressure(void)
99 {
100  bmp085_read_reg24(0xF6);
101 }
102 
103 static inline void bmp085_read_temp(void)
104 {
105  bmp085_read_reg16(0xF6);
106 }
107 
108 void baro_periodic(void) {
109  // check that nothing is in progress
110  if (baro_trans.status == I2CTransPending) return;
111  if (baro_trans.status == I2CTransRunning) return;
112  if (!i2c_idle(&i2c2)) return;
113 
114  switch (baro_board.status) {
115  case LBS_UNINITIALIZED:
119  break;
120  case LBS_REQUEST:
123  break;
124  case LBS_READ:
125  if (baro_eoc()) {
128  }
129  break;
130  case LBS_REQUEST_TEMP:
133  break;
134  case LBS_READ_TEMP:
135  if (baro_eoc()) {
138  }
139  break;
140  default:
141  break;
142  }
143 
144 }
145 
147  // This is a NOP at the moment
148 }
149 
150 // Apply temp calibration and sensor calibration to raw measurement to get Pa (from BMP085 datasheet)
152 {
153  int32_t b6 = calibration.b5 - 4000;
154  int x1 = (calibration.b2 * (b6 * b6 >> 12)) >> 11;
155  int x2 = calibration.ac2 * b6 >> 11;
156  int32_t x3 = x1 + x2;
157  int32_t b3 = (((calibration.ac1 * 4 + x3) << BMP085_OSS) + 2)/4;
158  x1 = calibration.ac3 * b6 >> 13;
159  x2 = (calibration.b1 * (b6 * b6 >> 12)) >> 16;
160  x3 = ((x1 + x2) + 2) >> 2;
161  uint32_t b4 = (calibration.ac4 * (uint32_t) (x3 + 32768)) >> 15;
162  uint32_t b7 = (raw - b3) * (50000 >> BMP085_OSS);
163  int32_t p = b7 < 0x80000000 ? (b7 * 2) / b4 : (b7 / b4) * 2;
164  x1 = (p >> 8) * (p >> 8);
165  x1 = (x1 * 3038) >> 16;
166  x2 = (-7357 * p) >> 16;
167  return p + ((x1 + x2 + 3791) >> 4);
168 }
169 
170 void baro_event(void (*b_abs_handler)(void), void (*b_diff_handler)(void))
171 {
172  if (baro_board.status == LBS_READING &&
176  int32_t tmp = (baro_trans.buf[0]<<16) | (baro_trans.buf[1] << 8) | baro_trans.buf[2];
177  tmp = tmp >> (8 - BMP085_OSS);
179  b_abs_handler();
180  }
181  }
186  // abuse differential to store temp in 0.1C for now
187  int32_t tmp = (baro_trans.buf[0] << 8) | baro_trans.buf[1];
188  int32_t x1 = ((tmp - calibration.ac6) * calibration.ac5) >> 15;
189  int32_t x2 = (calibration.mc << 11) / (x1 + calibration.md);
190  calibration.b5 = x1 + x2;
191  baro.differential = (calibration.b5 + 8) >> 4;
192  b_diff_handler();
193  }
194  }
195 }
#define BMP085_OSS
Definition: baro_board.h:20
void baro_event(void(*b_abs_handler)(void), void(*b_diff_handler)(void))
Definition: baro_board.c:170
struct BaroBoard baro_board
Definition: baro_board.c:35
Common barometric sensor implementation.
static int baro_eoc(void)
Definition: baro_board.c:83
static void bmp085_read_pressure(void)
Definition: baro_board.c:98
Definition: baro.h:40
uint16_t value
ADC1+2 interrupt hander.
Definition: adc_arch.c:577
void baro_init(void)
Definition: baro_board.c:42
static void bmp085_read_temp(void)
Definition: baro_board.c:103
bool_t i2c_transceive(struct i2c_periph *p, struct i2c_transaction *t, uint8_t s_addr, uint8_t len_w, uint16_t len_r)
Definition: i2c.c:105
void baro_periodic(void)
Definition: baro_board.c:50
static int16_t bmp085_read_reg16_blocking(uint8_t addr, uint32_t timeout)
Definition: baro_board.c:32
int32_t absolute
Definition: baro.h:41
static void bmp085_baro_read_calibration(void)
Definition: baro_board.c:55
int32_t differential
Definition: baro.h:42
bool_t i2c_transmit(struct i2c_periph *p, struct i2c_transaction *t, uint8_t s_addr, uint8_t len)
Definition: i2c.c:85
unsigned long uint32_t
Definition: types.h:18
signed short int16_t
Definition: types.h:17
enum I2CTransactionStatus status
Definition: i2c.h:83
struct bmp085_baro_calibration calibration
Definition: baro_board.c:8
signed long int32_t
Definition: types.h:19
static void bmp085_write_reg(uint8_t addr, uint8_t value)
Definition: baro_board.c:15
volatile uint8_t buf[I2C_BUF_LEN]
Definition: i2c.h:82
static void bmp085_request_pressure(void)
Definition: baro_board.c:88
struct Baro baro
Definition: baro_board.c:36
unsigned char uint8_t
Definition: types.h:14
static void bmp085_read_reg24(uint8_t addr)
Definition: baro_board.c:49
struct i2c_transaction baro_trans
Definition: baro_board.c:6
enum BaroStatus status
Definition: baro.h:43
static float p[2][2]
static int32_t baro_apply_calibration(int32_t raw)
Definition: baro_board.c:151
enum LisaBaroStatus status
Definition: baro_board.h:28
void baro_board_send_reset(void)
Definition: baro_board.c:84
static void bmp085_read_reg16(uint8_t addr)
Definition: baro_board.c:26
#define BMP085_ADDR
Definition: baro_board.h:18
bool_t i2c_idle(struct i2c_periph *p)
Definition: i2c_arch.c:329
static void bmp085_request_temp(void)
Definition: baro_board.c:93