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_ms5611_i2c.c
Go to the documentation of this file.
1 
8 #include "peripherals/ms5611.h"
9 #include "led.h"
10 #include "std.h"
11 #include "mcu_periph/sys_time.h"
12 
13 #include "mcu_periph/i2c.h"
14 #ifndef MS5611_I2C_DEV
15 #define MS5611_I2C_DEV i2c2
16 #endif
17 
18 #ifdef DEBUG
19 #ifndef DOWNLINK_DEVICE
20 #define DOWNLINK_DEVICE DOWNLINK_AP_DEVICE
21 #endif
22 #include "mcu_periph/uart.h"
23 #include "messages.h"
25 #endif
26 
27 struct Baro baro;
34 
36  int32_t i, j;
37  uint32_t res = 0;
38  uint8_t crc = prom[7] & 0xF;
39  prom[7] &= 0xFF00;
40  for (i = 0; i < 16; i++) {
41  if (i & 1) res ^= ((prom[i>>1]) & 0x00FF);
42  else res ^= (prom[i>>1]>>8);
43  for (j = 8; j > 0; j--) {
44  if (res & 0x8000) res ^= 0x1800;
45  res <<= 1;
46  }
47  }
48  prom[7] |= crc;
49  if (crc == ((res >> 12) & 0xF)) return 0;
50  else return -1;
51 }
52 
53 void baro_init(void) {
56  prom_cnt = 0;
57 }
58 
59 void baro_periodic(void) {
60  if (sys_time.nb_sec > 1) {
61  if (ms5611_status == MS5611_IDLE) {
62  /* start D1 conversion */
66  #ifdef DEBUG
67  RunOnceEvery(60, { DOWNLINK_SEND_MS5611_COEFF(DefaultChannel, DefaultDevice,
68  &ms5611_c[0], &ms5611_c[1], &ms5611_c[2], &ms5611_c[3],
69  &ms5611_c[4], &ms5611_c[5], &ms5611_c[6], &ms5611_c[7]);});
70  #endif
71  }
72  else if (ms5611_status == MS5611_CONV_D1) {
73  /* assume D1 conversion is done */
75  }
76  else if (ms5611_status == MS5611_CONV_D1_OK) {
77  /* read D1 adc */
81  }
82  else if (ms5611_status == MS5611_CONV_D2) {
83  /* assume D2 conversion is done */
85  }
86  else if (ms5611_status == MS5611_CONV_D2_OK) {
87  /* read D2 adc */
91  }
92  else if (ms5611_status == MS5611_UNINIT) {
93  /* reset sensor */
97  }
98  else if (ms5611_status == MS5611_RESET_OK) {
99  /* start getting prom data */
103  }
104  }
105 }
106 
107 void baro_event(void (*b_abs_handler)(void), void (*b_diff_handler)(void)){
109  #ifdef ROTORCRAFT_BARO_LED
110  RunOnceEvery(10,LED_TOGGLE(ROTORCRAFT_BARO_LED));
111  #endif
112  switch (ms5611_status) {
113 
114  case MS5611_RESET:
117  break;
118 
119  case MS5611_PROM:
120  /* read prom data */
121  ms5611_c[prom_cnt++] = (ms5611_trans.buf[0] << 8) | ms5611_trans.buf[1];
122  if (prom_cnt < PROM_NB) {//8 bytes at PROM
123  /* get next prom data */
126  }
127  else {
128  /* done reading prom */
130  /* check prom crc */
131  if (baro_ms5611_crc(ms5611_c) == 0) {
134  }
135  else {
136  /* checksum error, try again */
137  baro_init();
138  }
139  }
140  break;
141 
142  case MS5611_ADC_D1:
143  /* read D1 (pressure) */
144  ms5611_d1 = (ms5611_trans.buf[0] << 16) |
145  (ms5611_trans.buf[1] << 8) |
146  ms5611_trans.buf[2];
147  /* start D2 conversion */
151  break;
152 
153  case MS5611_ADC_D2: {
154  int64_t dt, baroms, tempms, off, sens, t2, off2, sens2;
155  /* read D2 (temperature) */
156  ms5611_d2 = (ms5611_trans.buf[0] << 16) |
157  (ms5611_trans.buf[1] << 8) |
158  ms5611_trans.buf[2];
161 
162  /* difference between actual and ref temperature */
163  dt = ms5611_d2 - (int64_t)ms5611_c[5] * (1<<8);
164  /* actual temperature */
165  tempms = 2000 + ((int64_t)dt * ms5611_c[6]) / (1<<23);
166  /* offset at actual temperature */
167  off = ((int64_t)ms5611_c[2] * (1<<16)) + ((int64_t)ms5611_c[4] * dt) / (1<<7);
168  /* sensitivity at actual temperature */
169  sens = ((int64_t)ms5611_c[1] * (1<<15)) + ((int64_t)ms5611_c[3] * dt) / (1<<8);
170  /* second order temperature compensation */
171  if (tempms < 2000) {
172  t2 = (dt*dt) / (1<<31);
173  off2 = 5 * ((int64_t)(tempms-2000)*(tempms-2000)) / (1<<1);
174  sens2 = 5 * ((int64_t)(tempms-2000)*(tempms-2000)) / (1<<2);
175  if (tempms < -1500) {
176  off2 = off2 + 7 * (int64_t)(tempms+1500)*(tempms+1500);
177  sens2 = sens2 + 11 * ((int64_t)(tempms+1500)*(tempms+1500)) / (1<<1);
178  }
179  tempms = tempms - t2;
180  off = off - off2;
181  sens = sens - sens2;
182  }
183  /* temperature compensated pressure */
184  baroms = (((int64_t)ms5611_d1 * sens) / (1<<21) - off) / (1<<15);
185 
186  /* Update baro structure */
187  baro.absolute = (int32_t)baroms;
188 
189  b_abs_handler();
190  b_diff_handler();
191 
192  #ifdef DEBUG
193  ftempms = tempms / 100.;
194  fbaroms = baroms / 100.;
195  DOWNLINK_SEND_BARO_MS5611(DefaultChannel, DefaultDevice,
197  #endif
198  break;
199  }
200 
201  default:
203  break;
204  }
205  }
206 }
#define PROM_NB
unsigned short uint16_t
Definition: types.h:16
#define MS5611_I2C_DEV
Measurement Specialties (Intersema) MS5611-01BA pressure/temperature sensor interface for I2C...
arch independent UART (Universal Asynchronous Receiver/Transmitter) API
#define MS5611_SLAVE_ADDR
#define MS5611_SOFT_RESET
#define MS5611_START_CONV_D1
void baro_event(void(*b_abs_handler)(void), void(*b_diff_handler)(void))
struct Baro baro
Common barometric sensor implementation.
Definition: baro.h:40
uint8_t ms5611_status
signed long long int64_t
Definition: types.h:21
int32_t prom_cnt
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
struct i2c_transaction ms5611_trans
if(PrimarySpektrumState.SpektrumTimer)--PrimarySpektrumState.SpektrumTimer
#define MS5611_START_CONV_D2
int32_t absolute
Definition: baro.h:41
float fbaroms
Architecture independent timing functions.
bool_t i2c_transmit(struct i2c_periph *p, struct i2c_transaction *t, uint8_t s_addr, uint8_t len)
Definition: i2c.c:85
#define MS5611_PROM_READ
unsigned long uint32_t
Definition: types.h:18
#define MS5611_ADC_READ
float ftempms
enum I2CTransactionStatus status
Definition: i2c.h:83
#define LED_TOGGLE(i)
Definition: led_hw.h:30
signed long int32_t
Definition: types.h:19
volatile uint8_t buf[I2C_BUF_LEN]
Definition: i2c.h:82
unsigned char uint8_t
Definition: types.h:14
enum BaroStatus status
Definition: baro.h:43
volatile uint32_t nb_sec
full seconds since startup
Definition: sys_time.h:69
void baro_init(void)
arch independent LED (Light Emitting Diodes) API
struct i2c_transaction t2
uint32_t ms5611_d2
signed char int8_t
Definition: types.h:15
static int8_t baro_ms5611_crc(uint16_t *prom)
uint32_t ms5611_d1
uint16_t ms5611_c[PROM_NB]
void baro_periodic(void)
Architecture independent I2C (Inter-Integrated Circuit Bus) API.