Paparazzi UAS  v5.15_devel-230-gc96ce27
Paparazzi is a free software Unmanned Aircraft System.
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
ms5611_i2c.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2011 Martin Mueller <martinmm@pfump.org>
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 
30 #include "peripherals/ms5611_i2c.h"
31 
32 
33 void ms5611_i2c_init(struct Ms5611_I2c *ms, struct i2c_periph *i2c_p, uint8_t addr,
34  bool is_ms5607)
35 {
36  /* set i2c_peripheral */
37  ms->i2c_p = i2c_p;
38 
39  /* slave address */
40  ms->i2c_trans.slave_addr = addr;
41  /* set initial status: Success or Done */
43 
44  ms->data_available = false;
45  ms->initialized = false;
47  ms->prom_cnt = 0;
48  ms->is_ms5607 = is_ms5607;
49 }
50 
52 {
53  if (ms->status == MS5611_STATUS_UNINIT) {
54  ms->initialized = false;
55  ms->prom_cnt = 0;
57  i2c_transmit(ms->i2c_p, &(ms->i2c_trans), ms->i2c_trans.slave_addr, 1);
59  }
60 }
61 
63 {
64  if (ms->status == MS5611_STATUS_IDLE &&
65  ms->i2c_trans.status == I2CTransDone) {
66  /* start D1 conversion */
68  i2c_transmit(ms->i2c_p, &(ms->i2c_trans), ms->i2c_trans.slave_addr, 1);
70  }
71 }
72 
79 {
80  switch (ms->status) {
83  break;
85  if (ms->i2c_trans.status == I2CTransDone) {
86  /* start getting prom data */
87  ms->i2c_trans.buf[0] = MS5611_PROM_READ | (ms->prom_cnt << 1);
88  i2c_transceive(ms->i2c_p, &(ms->i2c_trans), ms->i2c_trans.slave_addr, 1, 2);
90  }
91  break;
94  break;
96  if (ms->i2c_trans.status == I2CTransDone) {
97  /* read D1 adc */
98  ms->i2c_trans.buf[0] = MS5611_ADC_READ;
99  i2c_transceive(ms->i2c_p, &(ms->i2c_trans), ms->i2c_trans.slave_addr, 1, 3);
101  }
102  break;
105  break;
107  if (ms->i2c_trans.status == I2CTransDone) {
108  /* read D2 adc */
109  ms->i2c_trans.buf[0] = MS5611_ADC_READ;
110  i2c_transceive(ms->i2c_p, &(ms->i2c_trans), ms->i2c_trans.slave_addr, 1, 3);
112  }
113  break;
114  default:
115  break;
116  }
117 }
118 
119 void ms5611_i2c_event(struct Ms5611_I2c *ms)
120 {
121  if (ms->initialized) {
122  if (ms->i2c_trans.status == I2CTransFailed) {
125  } else if (ms->i2c_trans.status == I2CTransSuccess) {
126  // Successfull reading
127  switch (ms->status) {
128 
130  /* read D1 (pressure) */
131  ms->data.d1 = (ms->i2c_trans.buf[0] << 16) |
132  (ms->i2c_trans.buf[1] << 8) |
133  ms->i2c_trans.buf[2];
135  if (ms->data.d1 == 0) {
136  /* if value is zero, it was read to soon and is invalid, back to idle */
138  } else {
139  /* start D2 conversion */
141  i2c_transmit(ms->i2c_p, &(ms->i2c_trans), ms->i2c_trans.slave_addr, 1);
143  }
144  break;
145 
147  /* read D2 (temperature) */
148  ms->data.d2 = (ms->i2c_trans.buf[0] << 16) |
149  (ms->i2c_trans.buf[1] << 8) |
150  ms->i2c_trans.buf[2];
152  if (ms->data.d2 == 0) {
153  /* if value is zero, it was read to soon and is invalid, back to idle */
155  } else {
156  /* calculate temp and pressure from measurements and set available if valid */
157  if (ms->is_ms5607) {
158  ms->data_available = ms5607_calc(&(ms->data));
159  }
160  else {
161  ms->data_available = ms5611_calc(&(ms->data));
162  }
164  }
165  break;
166 
167  default:
169  break;
170  }
171  }
172  } else if (ms->status != MS5611_STATUS_UNINIT) { // Configuring but not yet initialized
173  switch (ms->i2c_trans.status) {
174 
175  case I2CTransFailed:
176  /* try again */
179  break;
180 
181  case I2CTransSuccess:
182  if (ms->status == MS5611_STATUS_PROM) {
183  /* read prom data */
184  ms->data.c[ms->prom_cnt++] = (ms->i2c_trans.buf[0] << 8) |
185  ms->i2c_trans.buf[1];
187  if (ms->prom_cnt < PROM_NB) {
188  /* get next prom data */
189  ms->i2c_trans.buf[0] = MS5611_PROM_READ | (ms->prom_cnt << 1);
190  i2c_transceive(ms->i2c_p, &(ms->i2c_trans), ms->i2c_trans.slave_addr, 1, 2);
191  } else {
192  /* done reading prom, check prom crc */
193  if (ms5611_prom_crc_ok(ms->data.c)) {
194  ms->initialized = true;
196  } else {
197  /* checksum error, try again */
199  }
200  }
201  } else {
203  }
204  break;
205 
206  default:
208  break;
209  }
210  }
211 }
uint32_t d1
Definition: ms5611.h:55
#define PROM_NB
Definition: ms5611_regs.h:38
void ms5611_i2c_init(struct Ms5611_I2c *ms, struct i2c_periph *i2c_p, uint8_t addr, bool is_ms5607)
Definition: ms5611_i2c.c:33
bool ms5611_calc(struct Ms5611Data *ms)
Calculate temperature and compensated pressure for MS5611.
Definition: ms5611.c:81
uint16_t c[PROM_NB]
Definition: ms5611.h:54
volatile uint8_t buf[I2C_BUF_LEN]
Transaction buffer With I2C_BUF_LEN number of bytes.
Definition: i2c.h:122
transaction successfully finished by I2C driver
Definition: i2c.h:57
bool ms5607_calc(struct Ms5611Data *ms)
Calculate temperature and compensated pressure for MS5607.
Definition: ms5611.c:124
struct Ms5611Data data
Definition: ms5611_i2c.h:43
bool is_ms5607
TRUE if MS5607, FALSE if MS5611.
Definition: ms5611_i2c.h:40
uint32_t d2
Definition: ms5611.h:56
void ms5611_i2c_start_configure(struct Ms5611_I2c *ms)
Definition: ms5611_i2c.c:51
bool ms5611_prom_crc_ok(uint16_t *prom)
Check if CRC of PROM data is OK.
Definition: ms5611.c:36
#define MS5611_START_CONV_D1
Definition: ms5611_regs.h:69
#define MS5611_ADC_READ
Definition: ms5611_regs.h:66
int32_t prom_cnt
number of bytes read from PROM
Definition: ms5611_i2c.h:44
volatile bool data_available
data ready flag
Definition: ms5611_i2c.h:42
transaction set to done by user level
Definition: i2c.h:59
Measurement Specialties (Intersema) MS5611-01BA and MS5607-02BA03 pressure/temperature sensor interfa...
void ms5611_i2c_event(struct Ms5611_I2c *ms)
Definition: ms5611_i2c.c:119
transaction failed
Definition: i2c.h:58
enum Ms5611Status status
Definition: ms5611_i2c.h:39
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
enum I2CTransactionStatus status
Transaction status.
Definition: i2c.h:126
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
void ms5611_i2c_start_conversion(struct Ms5611_I2c *ms)
Definition: ms5611_i2c.c:62
uint8_t slave_addr
Slave address.
Definition: i2c.h:104
unsigned char uint8_t
Definition: types.h:14
struct i2c_transaction i2c_trans
Definition: ms5611_i2c.h:38
#define MS5611_PROM_READ
Definition: ms5611_regs.h:68
bool initialized
config done flag
Definition: ms5611_i2c.h:41
struct i2c_periph * i2c_p
Definition: ms5611_i2c.h:37
void ms5611_i2c_periodic_check(struct Ms5611_I2c *ms)
Periodic function to ensure proper delay after triggering reset or conversion.
Definition: ms5611_i2c.c:78
#define MS5611_SOFT_RESET
Definition: ms5611_regs.h:67
#define MS5611_START_CONV_D2
Definition: ms5611_regs.h:70