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 /*
2  * Copyright (C) 2011 Martin Mueller <martinmm@pfump.org>
3  *
4  * This file is part of paparazzi.
5  *
6  * paparazzi is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2, or (at your option)
9  * any later version.
10  *
11  * paparazzi is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with paparazzi; see the file COPYING. If not, write to
18  * the Free Software Foundation, 59 Temple Place - Suite 330,
19  * Boston, MA 02111-1307, USA.
20  *
21  */
22 
31 
32 #include "mcu_periph/sys_time.h"
33 #include "mcu_periph/i2c.h"
34 #include "mcu_periph/uart.h"
35 #include "messages.h"
37 #include "subsystems/nav.h"
38 
39 #ifndef DOWNLINK_DEVICE
40 #define DOWNLINK_DEVICE DOWNLINK_AP_DEVICE
41 #endif
42 
43 #ifndef MS5611_I2C_DEV
44 #define MS5611_I2C_DEV i2c0
45 #endif
46 
47 /* address can be 0xEC or 0xEE (CSB\ low = 0xEE) */
48 #ifndef MS5611_SLAVE_ADDR
49 #define MS5611_SLAVE_ADDR 0xEE
50 #endif
51 
52 
64 
66  int32_t i, j;
67  uint32_t res = 0;
68  uint8_t crc = prom[7] & 0xF;
69  prom[7] &= 0xFF00;
70  for (i = 0; i < 16; i++) {
71  if (i & 1) res ^= ((prom[i>>1]) & 0x00FF);
72  else res ^= (prom[i>>1]>>8);
73  for (j = 8; j > 0; j--) {
74  if (res & 0x8000) res ^= 0x1800;
75  res <<= 1;
76  }
77  }
78  prom[7] |= crc;
79  if (crc == ((res >> 12) & 0xF)) return 0;
80  else return -1;
81 }
82 
83 void baro_ms5611_init(void) {
89  prom_cnt = 0;
90 }
91 
92 void baro_ms5611_periodic( void ) {
93  if (sys_time.nb_sec > 1) {
94  if (ms5611_status >= MS5611_IDLE) {
95  /* start D1 conversion */
99  RunOnceEvery((4*30), DOWNLINK_SEND_MS5611_COEFF(DefaultChannel, DefaultDevice,
100  &ms5611_c[0], &ms5611_c[1], &ms5611_c[2], &ms5611_c[3],
101  &ms5611_c[4], &ms5611_c[5], &ms5611_c[6], &ms5611_c[7]));
102  }
103  else if (ms5611_status == MS5611_UNINIT) {
104  /* reset sensor */
108  }
109  else if (ms5611_status == MS5611_RESET_OK) {
110  /* start getting prom data */
114  }
115  }
116 }
117 
118 void baro_ms5611_d1( void ) {
119  if (sys_time.nb_sec > 1) {
121  /* read D1 adc */
125  }
126  }
127 }
128 
129 void baro_ms5611_d2( void ) {
130  if (sys_time.nb_sec > 1) {
132  /* read D2 adc */
136  }
137  }
138 }
139 
140 void baro_ms5611_event( void ) {
142  switch (ms5611_status) {
143 
144  case MS5611_RESET:
147  break;
148 
149  case MS5611_PROM:
150  /* read prom data */
151  ms5611_c[prom_cnt++] = (ms5611_trans.buf[0] << 8) | ms5611_trans.buf[1];
152  if (prom_cnt < PROM_NB) {
153  /* get next prom data */
156  }
157  else {
158  /* done reading prom */
160  /* check prom crc */
161  if (baro_ms5611_crc(ms5611_c) == 0) {
162  DOWNLINK_SEND_MS5611_COEFF(DefaultChannel, DefaultDevice,
163  &ms5611_c[0], &ms5611_c[1], &ms5611_c[2], &ms5611_c[3],
164  &ms5611_c[4], &ms5611_c[5], &ms5611_c[6], &ms5611_c[7]);
166  }
167  else {
168  /* checksum error, try again */
170  }
171  }
172  break;
173 
174  case MS5611_CONV_D1:
177  break;
178 
179  case MS5611_ADC_D1:
180  /* read D1 (pressure) */
181  ms5611_d1 = (ms5611_trans.buf[0] << 16) |
182  (ms5611_trans.buf[1] << 8) |
183  ms5611_trans.buf[2];
184  /* start D2 conversion */
188  break;
189 
190  case MS5611_CONV_D2:
193  break;
194 
195  case MS5611_ADC_D2: {
196  int64_t dt, baroms, tempms, off, sens, t2, off2, sens2;
197  /* read D2 (temperature) */
198  ms5611_d2 = (ms5611_trans.buf[0] << 16) |
199  (ms5611_trans.buf[1] << 8) |
200  ms5611_trans.buf[2];
203 
204  /* difference between actual and ref temperature */
205  dt = ms5611_d2 - (int64_t)ms5611_c[5] * (1<<8);
206  /* actual temperature */
207  tempms = 2000 + ((int64_t)dt * ms5611_c[6]) / (1<<23);
208  /* offset at actual temperature */
209  off = ((int64_t)ms5611_c[2] * (1<<16)) + ((int64_t)ms5611_c[4] * dt) / (1<<7);
210  /* sensitivity at actual temperature */
211  sens = ((int64_t)ms5611_c[1] * (1<<15)) + ((int64_t)ms5611_c[3] * dt) / (1<<8);
212  /* second order temperature compensation */
213  if (tempms < 2000) {
214  t2 = (dt*dt) / (1<<31);
215  off2 = 5 * ((int64_t)(tempms-2000)*(tempms-2000)) / (1<<1);
216  sens2 = 5 * ((int64_t)(tempms-2000)*(tempms-2000)) / (1<<2);
217  if (tempms < -1500) {
218  off2 = off2 + 7 * (int64_t)(tempms+1500)*(tempms+1500);
219  sens2 = sens2 + 11 * ((int64_t)(tempms+1500)*(tempms+1500)) / (1<<1);
220  }
221  tempms = tempms - t2;
222  off = off - off2;
223  sens = sens - sens2;
224  }
225  /* temperature compensated pressure */
226  baroms = (((int64_t)ms5611_d1 * sens) / (1<<21) - off) / (1<<15);
227 
228  float tmp_float = baroms/101325.0; //pressure at sea level
229  tmp_float = pow(tmp_float,0.190295); //eleva pressao ao expoente
230  baro_ms5611_alt = 44330*(1.0-tmp_float); //altitude above MSL
231 
233 
234 #ifdef SENSOR_SYNC_SEND
235  ftempms = tempms / 100.;
236  fbaroms = baroms / 100.;
237  DOWNLINK_SEND_BARO_MS5611(DefaultChannel, DefaultDevice,
239 #endif
240 
241  break;
242  }
243 
244  default:
246  break;
247  }
248  }
249 }
#define PROM_NB
unsigned short uint16_t
Definition: types.h:16
arch independent UART (Universal Asynchronous Receiver/Transmitter) API
#define MS5611_SLAVE_ADDR
#define MS5611_SOFT_RESET
#define MS5611_START_CONV_D1
bool_t baro_ms5611_valid
static int8_t baro_ms5611_crc(uint16_t *prom)
uint8_t ms5611_status
bool_t baro_ms5611_enabled
#define BARO_MS5611_R
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
double tmp_float
Definition: baro_bmp.c:78
#define FALSE
Definition: imu_chimu.h:141
#define MS5611_START_CONV_D2
void baro_ms5611_d1(void)
void baro_ms5611_d2(void)
float baro_ms5611_r
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
void baro_ms5611_init(void)
float ftempms
enum I2CTransactionStatus status
Definition: i2c.h:83
float baro_ms5611_alt
signed long int32_t
Definition: types.h:19
#define TRUE
Definition: imu_chimu.h:144
volatile uint8_t buf[I2C_BUF_LEN]
Definition: i2c.h:82
#define MS5611_I2C_DEV
void baro_ms5611_event(void)
unsigned char uint8_t
Definition: types.h:14
volatile uint32_t nb_sec
full seconds since startup
Definition: sys_time.h:69
void baro_ms5611_periodic(void)
float baro_ms5611_sigma2
struct i2c_transaction t2
uint32_t ms5611_d2
signed char int8_t
Definition: types.h:15
uint32_t ms5611_d1
#define BARO_MS5611_SIGMA2
uint16_t ms5611_c[PROM_NB]
Architecture independent I2C (Inter-Integrated Circuit Bus) API.