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
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 "subsystems/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 
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  DOWNLINK_SEND_BARO_WORDS(DefaultChannel, DefaultDevice, &words[0], &words[1], &words[2], &words[3]);
220 #endif
221 }
222 
223 
224 
225 /* Handle the SPI message, i.e. store the received values in variables */
227 {
228  if (status_read_data) {
229  switch (status) {
231  d1 = Uint16(buf_input);
232  break;
234  d2 = Uint16(buf_input);
235  /* Compute pressure and temp (page 10) */
236  int16_t dT = d2 - ut1;
237  baro_MS5534A_temp = 200 + (dT * (c6 + 50)) / (1 << 10);
238  int16_t off = c2 * 4 + ((c4 - 512) * dT) / (1 << 12);
239  uint32_t sens = c1 + (c3 * dT) / (1 << 10) + 24576;
240  uint16_t x = (sens * (d1 - 7168)) / (1 << 14) - off;
241  // baro_MS5534A = ((x*10)>>5) + 250*10;
242  baro_MS5534A_pressure = ((x * 100) >> 5) + 250 * 100;
243  baro_MS5534A_available = true;
244 
245  break;
246  case STATUS_RESET:
247  break;
248  default: /* Init status */
250  if (status == STATUS_INIT4) {
251  calibration();
252  }
253  }
254  } /* else nothing to read */
255 
256  NextStatus();
257  if (!status_read_data) {
258  /* Ask next conversion now */
260  }
261 }
262 
264 {
265  if (spi_message_received) {
266  /* Got a message on SPI. */
267  spi_message_received = false;
270  uint32_t now_ts = get_sys_time_usec();
271  baro_MS5534A_available = false;
273 #if SENSO_SYNC_SEND
275 #endif
276  float pressure = (float)baro_MS5534A_pressure;
277  AbiSendMsgBARO_ABS(BARO_MS5534A_SENDER_ID, now_ts, pressure);
278  }
279  }
280 }
Handling of the MS5534a pressure sensor.
unsigned short uint16_t
Definition: types.h:16
static uint16_t d2
Definition: baro_MS5534A.c:202
#define PWM_DUTY
Definition: baro_MS5534A.c:113
arch independent UART (Universal Asynchronous Receiver/Transmitter) API
static uint8_t buf_output[3]
Definition: baro_MS5534A.c:88
float ground_alt
size == nb_waypoint, waypoint 0 is a dummy waypoint
Definition: common_nav.c:40
#define CMD_W3
Definition: baro_MS5534A.c:78
static void SpiStart(struct spi_periph *p, struct spi_transaction *t)
Definition: spi_arch.c:249
#define PWMMR0
Definition: LPC21xx.h:100
float baro_MS5534A_r
Definition: baro_MS5534A.c:47
static void SpiSetCPHA(struct spi_periph *p)
Definition: spi_arch.c:106
Main include for ABI (AirBorneInterface).
#define PWMTCR
Definition: LPC21xx.h:95
#define PWMPCR
Definition: LPC21xx.h:107
static uint16_t d1
Definition: baro_MS5534A.c:202
#define CMD_W2
Definition: baro_MS5534A.c:77
bool baro_MS5534A_do_reset
Definition: baro_MS5534A.c:41
void baro_MS5534A_event(void)
Definition: baro_MS5534A.c:263
#define PWMMR2
Definition: LPC21xx.h:102
static uint16_t words[4]
Definition: baro_MS5534A.c:62
#define Uint16(buf_input)
Definition: baro_MS5534A.c:90
#define STATUS_MEASURE_TEMPERATURE
Definition: baro_MS5534A.c:57
static void calibration(void)
Definition: baro_MS5534A.c:206
#define PWMTCR_COUNTER_ENABLE
Definition: lpcTMR.h:83
#define STATUS_INIT4
Definition: baro_MS5534A.c:55
Architecture independent SPI (Serial Peripheral Interface) API.
static uint8_t reset[3]
Definition: baro_MS5534A.c:83
#define PWMPCR_ENA2
Definition: lpcTMR.h:117
static uint8_t cmds[6]
Definition: baro_MS5534A.c:82
#define InitStatus()
Definition: baro_MS5534A.c:64
uint32_t pressure
pressure in 1/4 Pascal
Definition: mpl3115.h:80
static uint8_t buf_input[3]
Definition: baro_MS5534A.c:87
static uint16_t c4
Definition: baro_MS5534A.c:203
#define CMD_INIT
Definition: baro_MS5534A.c:73
#define PWMLER
Definition: LPC21xx.h:108
void baro_MS5534A_send(void)
Definition: baro_MS5534A.c:169
bool alt_baro_enabled
Definition: baro_MS5534A.c:45
unsigned long uint32_t
Definition: types.h:18
#define PWM_PERIOD
Definition: baro_MS5534A.c:112
signed short int16_t
Definition: types.h:17
#define PWMLER_LATCH2
Definition: lpcTMR.h:126
static uint16_t c1
Definition: baro_MS5534A.c:203
#define STATUS_MEASURE_PRESSURE
Definition: baro_MS5534A.c:56
#define BARO_MS5534A_SENDER_ID
#define CMD_W1
Definition: baro_MS5534A.c:76
#define CMD_W4
Definition: baro_MS5534A.c:79
static uint16_t c6
Definition: baro_MS5534A.c:203
float baro_MS5534A_sigma2
Definition: baro_MS5534A.c:48
static uint16_t c3
Definition: baro_MS5534A.c:203
uint32_t baro_MS5534A_ground_pressure
Definition: baro_MS5534A.c:46
#define PWMPR
Definition: LPC21xx.h:97
#define PINSEL0
Definition: LPC21xx.h:347
#define PWMTCR_PWM_ENABLE
Definition: lpcTMR.h:85
unsigned char uint8_t
Definition: types.h:14
API to get/set the generic vehicle states.
#define PWMLER_LATCH0
Definition: lpcTMR.h:124
bool baro_MS5534A_available
Definition: baro_MS5534A.c:44
static bool status_read_data
Definition: baro_MS5534A.c:61
#define CMD_MEASUREMENT
Definition: baro_MS5534A.c:74
static uint16_t ut1
Definition: baro_MS5534A.c:203
void baro_MS5534A_event_task(void)
Definition: baro_MS5534A.c:226
static uint16_t c2
Definition: baro_MS5534A.c:203
#define NextStatus()
Definition: baro_MS5534A.c:66
static uint8_t status
Definition: baro_MS5534A.c:60
#define CMD_PRESSURE
Definition: baro_MS5534A.c:80
void baro_MS5534A_reset(void)
Definition: baro_MS5534A.c:162
#define STATUS_INIT1
Definition: baro_MS5534A.c:52
#define STATUS_RESET
Definition: baro_MS5534A.c:58
float baro_MS5534A_z
Definition: baro_MS5534A.c:49
uint32_t get_sys_time_usec(void)
Get the time in microseconds since startup.
Definition: sys_time_arch.c:68
uint16_t baro_MS5534A_temp
Definition: baro_MS5534A.c:43
#define CMD_TEMPERATURE
Definition: baro_MS5534A.c:81
void baro_MS5534A_init(void)
Definition: baro_MS5534A.c:118
uint32_t baro_MS5534A_pressure
Definition: baro_MS5534A.c:42