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_spi.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/spi.h"
14 #ifndef MS5611_SPI_DEV
15 #define MS5611_SPI_DEV spi2
16 #endif
17 #define MS5611_BUFFER_LENGTH 4
18 
19 #ifdef DEBUG
20 #ifndef DOWNLINK_DEVICE
21 #define DOWNLINK_DEVICE DOWNLINK_AP_DEVICE
22 #endif
23 #include "mcu_periph/uart.h"
24 #include "messages.h"
26 #endif
27 
28 struct Baro baro;
37 static void trans_cb_ms5611( struct spi_transaction *trans );
38 
40  int32_t i, j;
41  uint32_t res = 0;
42  uint8_t crc = prom[7] & 0xF;
43  prom[7] &= 0xFF00;
44  for (i = 0; i < 16; i++) {
45  if (i & 1) res ^= ((prom[i>>1]) & 0x00FF);
46  else res ^= (prom[i>>1]>>8);
47  for (j = 8; j > 0; j--) {
48  if (res & 0x8000) res ^= 0x1800;
49  res <<= 1;
50  }
51  }
52  prom[7] |= crc;
53  if (crc == ((res >> 12) & 0xF)) return 0;
54  else return -1;
55 }
56 
57 static void trans_cb_ms5611( struct spi_transaction *trans ) {
58 #ifdef ROTORCRAFT_BARO_LED
59  RunOnceEvery(10,LED_TOGGLE(ROTORCRAFT_BARO_LED));
60 #endif
61 }
62 
63 void baro_init(void) {
76 
79  prom_cnt = 0;
80 }
81 
82 void baro_periodic(void) {
83  if (sys_time.nb_sec > 1) {
84  if (ms5611_status == MS5611_IDLE) {
85  /* start D1 conversion */
89  #ifdef DEBUG
90  RunOnceEvery(300, { DOWNLINK_SEND_MS5611_COEFF(DefaultChannel, DefaultDevice,
91  &ms5611_c[0], &ms5611_c[1], &ms5611_c[2], &ms5611_c[3],
92  &ms5611_c[4], &ms5611_c[5], &ms5611_c[6], &ms5611_c[7]);});
93  #endif
94  }
95  else if (ms5611_status == MS5611_CONV_D1) {
96  /* assume D1 conversion is done */
98  }
99  else if (ms5611_status == MS5611_CONV_D1_OK) {
100  /* read D1 adc */
104  }
105  else if (ms5611_status == MS5611_CONV_D2) {
106  /* assume D2 conversion is done */
108  }
109  else if (ms5611_status == MS5611_CONV_D2_OK) {
110  /* read D2 adc */
114  }
115  else if (ms5611_status == MS5611_UNINIT) {
116  /* reset sensor */
120  }
121  else if (ms5611_status == MS5611_RESET_OK) {
122  /* start getting prom data */
126  }
127  }
128 }
129 
130 void baro_event(void (*b_abs_handler)(void), void (*b_diff_handler)(void)){
132  switch (ms5611_status) {
133 
134  case MS5611_RESET:
137  break;
138 
139  case MS5611_PROM:
140  /* read prom data */
142  if (prom_cnt < PROM_NB) {//8 bytes at PROM
143  /* get next prom data */
146  }
147  else {
148  /* done reading prom */
150  /* check prom crc */
151  if (baro_ms5611_crc(ms5611_c) == 0) {
154  }
155  else {
156  /* checksum error, try again */
157  baro_init();
158  }
159  }
160  break;
161 
162  case MS5611_ADC_D1:
163  /* read D1 (pressure) */
164  ms5611_d1 = (ms5611_trans.input_buf[1] << 16) |
165  (ms5611_trans.input_buf[2] << 8) |
167  /* start D2 conversion */
171  break;
172 
173  case MS5611_ADC_D2: {
174  int64_t dt, baroms, tempms, off, sens, t2, off2, sens2;
175  /* read D2 (temperature) */
176  ms5611_d2 = (ms5611_trans.input_buf[1] << 16) |
177  (ms5611_trans.input_buf[2] << 8) |
181 
182  /* difference between actual and ref temperature */
183  dt = ms5611_d2 - (int64_t)ms5611_c[5] * (1<<8);
184  /* actual temperature */
185  tempms = 2000 + ((int64_t)dt * ms5611_c[6]) / (1<<23);
186  /* offset at actual temperature */
187  off = ((int64_t)ms5611_c[2] * (1<<16)) + ((int64_t)ms5611_c[4] * dt) / (1<<7);
188  /* sensitivity at actual temperature */
189  sens = ((int64_t)ms5611_c[1] * (1<<15)) + ((int64_t)ms5611_c[3] * dt) / (1<<8);
190  /* second order temperature compensation */
191  if (tempms < 2000) {
192  t2 = (dt*dt) / (1<<31);
193  off2 = 5 * ((int64_t)(tempms-2000)*(tempms-2000)) / (1<<1);
194  sens2 = 5 * ((int64_t)(tempms-2000)*(tempms-2000)) / (1<<2);
195  if (tempms < -1500) {
196  off2 = off2 + 7 * (int64_t)(tempms+1500)*(tempms+1500);
197  sens2 = sens2 + 11 * ((int64_t)(tempms+1500)*(tempms+1500)) / (1<<1);
198  }
199  tempms = tempms - t2;
200  off = off - off2;
201  sens = sens - sens2;
202  }
203  /* temperature compensated pressure */
204  baroms = (((int64_t)ms5611_d1 * sens) / (1<<21) - off) / (1<<15);
205 
206  /* Update baro structure */
207  baro.absolute = (int32_t)baroms;
208 
209  b_abs_handler();
210  b_diff_handler();
211 
212  #ifdef DEBUG
213  ftempms = tempms / 100.;
214  fbaroms = baroms / 100.;
215  DOWNLINK_SEND_BARO_MS5611(DefaultChannel, DefaultDevice,
217  #endif
218  break;
219  }
220 
221  default:
223  break;
224  }
225  }
226 }
enum SPIBitOrder bitorder
MSB/LSB order.
Definition: spi.h:152
#define PROM_NB
unsigned short uint16_t
Definition: types.h:16
arch independent UART (Universal Asynchronous Receiver/Transmitter) API
float fbaroms
enum SPIClockPolarity cpol
clock polarity control
Definition: spi.h:149
#define MS5611_SOFT_RESET
#define MS5611_START_CONV_D1
uint8_t input_length
number of data words to read
Definition: spi.h:145
Common barometric sensor implementation.
Definition: baro.h:40
void baro_event(void(*b_abs_handler)(void), void(*b_diff_handler)(void))
enum SPIClockPhase cpha
clock phase control
Definition: spi.h:150
CPHA = 1.
Definition: spi.h:69
uint32_t ms5611_d1
volatile uint8_t input_buf_ms5611[MS5611_BUFFER_LENGTH]
struct Baro baro
uint16_t ms5611_c[PROM_NB]
volatile uint8_t * input_buf
pointer to receive buffer for DMA
Definition: spi.h:143
CPOL = 1.
Definition: spi.h:78
signed long long int64_t
Definition: types.h:21
if(PrimarySpektrumState.SpektrumTimer)--PrimarySpektrumState.SpektrumTimer
enum SPISlaveSelect select
slave selection behavior
Definition: spi.h:148
volatile uint8_t output_buf_ms5611[MS5611_BUFFER_LENGTH]
enum SPITransactionStatus status
Definition: spi.h:156
#define MS5611_START_CONV_D2
Architecture independent SPI (Serial Peripheral Interface) API.
struct spi_transaction ms5611_trans
int32_t absolute
Definition: baro.h:41
static int8_t baro_ms5611_crc(uint16_t *prom)
Definition: spi.h:84
enum SPIClockDiv cdiv
prescaler of main clock to use as SPI clock
Definition: spi.h:153
bool_t spi_submit(struct spi_periph *p, struct spi_transaction *t)
Submit a spi transaction.
Definition: spi_arch.c:469
Architecture independent timing functions.
enum SPIDataSizeSelect dss
data transfer word size
Definition: spi.h:151
#define MS5611_PROM_READ
unsigned long uint32_t
Definition: types.h:18
uint32_t ms5611_d2
#define MS5611_ADC_READ
uint8_t output_length
number of data words to write
Definition: spi.h:146
void baro_init(void)
int32_t prom_cnt
float ftempms
#define LED_TOGGLE(i)
Definition: led_hw.h:30
signed long int32_t
Definition: types.h:19
unsigned char uint8_t
Definition: types.h:14
static void trans_cb_ms5611(struct spi_transaction *trans)
slave is selected before transaction and unselected after
Definition: spi.h:57
uint8_t slave_idx
slave id: SPI_SLAVE0 to SPI_SLAVE4
Definition: spi.h:147
enum BaroStatus status
Definition: baro.h:43
volatile uint32_t nb_sec
full seconds since startup
Definition: sys_time.h:69
#define MS5611_SPI_DEV
Measurement Specialties (Intersema) MS5611-01BA pressure/temperature sensor interface for I2C...
Definition: spi.h:119
arch independent LED (Light Emitting Diodes) API
struct i2c_transaction t2
SPI transaction structure.
Definition: spi.h:142
volatile uint8_t * output_buf
pointer to transmit buffer for DMA
Definition: spi.h:144
signed char int8_t
Definition: types.h:15
uint8_t ms5611_status
#define MS5611_BUFFER_LENGTH
void baro_periodic(void)
SPICallback after_cb
NULL or function called after the transaction.
Definition: spi.h:155
#define MS5611_SLAVE_DEV
Definition: ms5611.h:45