Paparazzi UAS  v7.0_unstable
Paparazzi is a free software Unmanned Aircraft System.
baro_MS5534A.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2007 ENAC
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 #include "mcu_periph/spi.h"
32 #include "mcu_periph/uart.h"
33 #ifndef BARO_NO_DOWNLINK
35 #endif
36 #include "modules/core/abi.h"
38 #include "state.h"
39 
40 
50 
51 
52 #define STATUS_INIT1 0
53 #define STATUS_INIT2 1
54 #define STATUS_INIT3 2
55 #define STATUS_INIT4 3
56 #define STATUS_MEASURE_PRESSURE 4
57 #define STATUS_MEASURE_TEMPERATURE 5
58 #define STATUS_RESET 6
59 
60 static uint8_t status;
61 static bool status_read_data;
62 static uint16_t words[4];
63 
64 #define InitStatus() (status <= STATUS_INIT4)
65 
66 #define NextStatus() { \
67  if (status_read_data) { \
68  status++; if (status > STATUS_MEASURE_TEMPERATURE) status = STATUS_MEASURE_PRESSURE; \
69  }; \
70  status_read_data = !status_read_data; \
71  }
72 
73 #define CMD_INIT 0x1D
74 #define CMD_MEASUREMENT 0x0F
75 
76 #define CMD_W1 0x50
77 #define CMD_W2 0x60
78 #define CMD_W3 0x90
79 #define CMD_W4 0xA0
80 #define CMD_PRESSURE 0x40
81 #define CMD_TEMPERATURE 0x20
83 static uint8_t reset[3] = {0x15, 0x55, 0x40};
84 
85 
86 
87 static uint8_t buf_input[3];
88 static uint8_t buf_output[3];
89 
90 #define Uint16(buf_input) (buf_input[0] << 8 | buf_input[1])
91 
92 /* PWM prescaler, set PWM input clock to 15MHz, PWM_CLK = PCLK / PWM_PRESCALER */
93 
94 #if (PCLK == 15000000)
95 #define PWM_PRESCALER 1
96 #else
97 
98 #if (PCLK == 30000000)
99 #define PWM_PRESCALER 2
100 #else
101 
102 #if (PCLK == 60000000)
103 #define PWM_PRESCALER 4
104 #else
105 
106 #error unknown PCLK frequency
107 #endif
108 #endif
109 #endif
110 
111 #define MS5534A_MCLK 32768
112 #define PWM_PERIOD ((PCLK / PWM_PRESCALER) / MS5534A_MCLK)
113 #define PWM_DUTY (PWM_PERIOD / 2)
114 
115 
116 static void calibration(void);
117 
119 {
120  /* 32768Hz on PWM2 */
121  /* Configure P0.7 pin as PWM */
122  PINSEL0 &= ~(_BV(14));
123  PINSEL0 |= _BV(15);
124 
125  /* No prescaler */
126  PWMPR = PWM_PRESCALER - 1;
127 
128  /* To get 32768Hz from a base frequency of 15MHz */
129  PWMMR0 = PWM_PERIOD;
130  PWMMR2 = PWM_DUTY;
131 
132  PWMLER = PWMLER_LATCH0 | PWMLER_LATCH2;
133  PWMTCR = PWMTCR_COUNTER_ENABLE | PWMTCR_PWM_ENABLE;
134  PWMPCR = PWMPCR_ENA2;
135 
136 #ifdef BARO_MS5534A_W1
137  words[0] = BARO_MS5534A_W1;
138  words[1] = BARO_MS5534A_W2;
139  words[2] = BARO_MS5534A_W3;
140  words[3] = BARO_MS5534A_W4;
141 
143  status_read_data = false;
144 
145  calibration();
146 #else
148  status_read_data = false;
149 #endif
150 
151 
152 
153  baro_MS5534A_available = false;
154  alt_baro_enabled = false;
155 
157  baro_MS5534A_r = 20.;
159  baro_MS5534A_do_reset = false;
160 }
161 
163 {
165  status_read_data = false;
166 }
167 
168 /* To be called not faster than 30Hz */
170 {
171  if (!SpiCheckAvailable()) {
172  SpiOverRun();
173  return;
174  }
175 
176  if (status == STATUS_RESET) {
177  uint8_t i;
178  for (i = 0; i < 3; i++) {
179  buf_output[i] = reset[i];
180  }
181  spi_buffer_length = 3;
182  } else {
183  if (status_read_data) {
184  buf_output[0] = buf_output[1] = 0;
185  } else {
187  buf_output[1] = cmds[status];
188  }
189  spi_buffer_length = 2;
190  }
191 
192  spi_buffer_input = (uint8_t *)&buf_input;
193  spi_buffer_output = (uint8_t *)&buf_output;
194  if (status_read_data) {
195  SpiSetCPHA();
196  } else {
197  SpiClrCPHA();
198  }
199  SpiStart();
200 }
201 
202 static uint16_t d1, d2;
203 static uint16_t c1, c2, c3, c4, ut1, c6;
204 
205 
206 static void calibration(void)
207 {
208  /* End of init, configuration (page 11) */
209  c1 = words[0] >> 1;
210  c2 = ((words[2] & 0x3f) << 6) | (words[3] & 0x3f);
211  c3 = words[3] >> 6;
212  c4 = words[2] >> 6;
213  uint16_t c5 = ((words[0] & 0x1) << 10) | (words[1] >> 6);
214  c6 = words[1] & 0x3f;
215 
216  ut1 = (c5 << 3) + 20224;
217 
218 #ifndef BARO_NO_DOWNLINK
219  float debug[4];
220  for (int i=0; i<4; i++){
221  debug[i] = words[i];
222  }
223  DOWNLINK_SEND_DEBUG_VECT(DefaultChannel, DefaultDevice, "baro_calib", 4, debug);
224 #endif
225 }
226 
227 
228 
229 /* Handle the SPI message, i.e. store the received values in variables */
231 {
232  if (status_read_data) {
233  switch (status) {
235  d1 = Uint16(buf_input);
236  break;
238  d2 = Uint16(buf_input);
239  /* Compute pressure and temp (page 10) */
240  int16_t dT = d2 - ut1;
241  baro_MS5534A_temp = 200 + (dT * (c6 + 50)) / (1 << 10);
242  int16_t off = c2 * 4 + ((c4 - 512) * dT) / (1 << 12);
243  uint32_t sens = c1 + (c3 * dT) / (1 << 10) + 24576;
244  uint16_t x = (sens * (d1 - 7168)) / (1 << 14) - off;
245  // baro_MS5534A = ((x*10)>>5) + 250*10;
246  baro_MS5534A_pressure = ((x * 100) >> 5) + 250 * 100;
247  baro_MS5534A_available = true;
248 
249  break;
250  case STATUS_RESET:
251  break;
252  default: /* Init status */
254  if (status == STATUS_INIT4) {
255  calibration();
256  }
257  }
258  } /* else nothing to read */
259 
260  NextStatus();
261  if (!status_read_data) {
262  /* Ask next conversion now */
264  }
265 }
266 
268 {
269  if (spi_message_received) {
270  /* Got a message on SPI. */
271  spi_message_received = false;
274  uint32_t now_ts = get_sys_time_usec();
275  baro_MS5534A_available = false;
277 #if SENSO_SYNC_SEND
279 #endif
280  float pressure = (float)baro_MS5534A_pressure;
281  AbiSendMsgBARO_ABS(BARO_MS5534A_SENDER_ID, now_ts, pressure);
282  }
283  }
284 }
Main include for ABI (AirBorneInterface).
#define BARO_MS5534A_SENDER_ID
static uint16_t d1
Definition: baro_MS5534A.c:202
void baro_MS5534A_event_task(void)
Definition: baro_MS5534A.c:230
void baro_MS5534A_event(void)
Definition: baro_MS5534A.c:267
#define CMD_PRESSURE
Definition: baro_MS5534A.c:80
static uint16_t c4
Definition: baro_MS5534A.c:203
#define STATUS_INIT4
Definition: baro_MS5534A.c:55
float baro_MS5534A_z
Definition: baro_MS5534A.c:49
uint16_t baro_MS5534A_temp
Definition: baro_MS5534A.c:43
#define STATUS_INIT1
Definition: baro_MS5534A.c:52
#define CMD_INIT
Definition: baro_MS5534A.c:73
void baro_MS5534A_send(void)
Definition: baro_MS5534A.c:169
#define NextStatus()
Definition: baro_MS5534A.c:66
static uint16_t ut1
Definition: baro_MS5534A.c:203
#define CMD_W2
Definition: baro_MS5534A.c:77
static uint16_t c6
Definition: baro_MS5534A.c:203
static uint8_t buf_input[3]
Definition: baro_MS5534A.c:87
static uint16_t d2
Definition: baro_MS5534A.c:202
void baro_MS5534A_init(void)
Definition: baro_MS5534A.c:118
float baro_MS5534A_sigma2
Definition: baro_MS5534A.c:48
#define STATUS_MEASURE_TEMPERATURE
Definition: baro_MS5534A.c:57
bool alt_baro_enabled
Definition: baro_MS5534A.c:45
bool baro_MS5534A_do_reset
Definition: baro_MS5534A.c:41
static uint16_t c1
Definition: baro_MS5534A.c:203
#define CMD_MEASUREMENT
Definition: baro_MS5534A.c:74
uint32_t baro_MS5534A_pressure
Definition: baro_MS5534A.c:42
#define Uint16(buf_input)
Definition: baro_MS5534A.c:90
void baro_MS5534A_reset(void)
Definition: baro_MS5534A.c:162
#define InitStatus()
Definition: baro_MS5534A.c:64
float baro_MS5534A_r
Definition: baro_MS5534A.c:47
static uint16_t words[4]
Definition: baro_MS5534A.c:62
#define CMD_W4
Definition: baro_MS5534A.c:79
#define PWM_PERIOD
Definition: baro_MS5534A.c:112
static uint16_t c3
Definition: baro_MS5534A.c:203
static void calibration(void)
Definition: baro_MS5534A.c:206
#define CMD_W3
Definition: baro_MS5534A.c:78
static uint16_t c2
Definition: baro_MS5534A.c:203
#define CMD_W1
Definition: baro_MS5534A.c:76
#define STATUS_RESET
Definition: baro_MS5534A.c:58
static uint8_t cmds[6]
Definition: baro_MS5534A.c:82
bool baro_MS5534A_available
Definition: baro_MS5534A.c:44
static bool status_read_data
Definition: baro_MS5534A.c:61
static uint8_t status
Definition: baro_MS5534A.c:60
static uint8_t buf_output[3]
Definition: baro_MS5534A.c:88
#define STATUS_MEASURE_PRESSURE
Definition: baro_MS5534A.c:56
static uint8_t reset[3]
Definition: baro_MS5534A.c:83
#define CMD_TEMPERATURE
Definition: baro_MS5534A.c:81
uint32_t baro_MS5534A_ground_pressure
Definition: baro_MS5534A.c:46
#define PWM_DUTY
Definition: baro_MS5534A.c:113
uint32_t get_sys_time_usec(void)
Get the time in microseconds since startup.
Definition: sys_time_arch.c:71
float ground_alt
size == nb_waypoint, waypoint 0 is a dummy waypoint
Definition: common_nav.c:46
Handling of the MS5534a pressure sensor.
Fixedwing Navigation library.
Architecture independent SPI (Serial Peripheral Interface) API.
API to get/set the generic vehicle states.
arch independent UART (Universal Asynchronous Receiver/Transmitter) API
unsigned short uint16_t
Typedef defining 16 bit unsigned short type.
Definition: vl53l1_types.h:88
unsigned int uint32_t
Typedef defining 32 bit unsigned int type.
Definition: vl53l1_types.h:78
short int16_t
Typedef defining 16 bit short type.
Definition: vl53l1_types.h:93
unsigned char uint8_t
Typedef defining 8 bit unsigned char type.
Definition: vl53l1_types.h:98