airbourne_board.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2017, James Jackson and Daniel Koch, BYU MAGICC Lab
3  *
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions are met:
8  *
9  * * Redistributions of source code must retain the above copyright notice, this
10  * list of conditions and the following disclaimer.
11  *
12  * * Redistributions in binary form must reproduce the above copyright notice,
13  * this list of conditions and the following disclaimer in the documentation
14  * and/or other materials provided with the distribution.
15  *
16  * * Neither the name of the copyright holder nor the names of its
17  * contributors may be used to endorse or promote products derived from
18  * this software without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
24  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
27  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
28  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30  */
31 
32 #include "airbourne_board.h"
33 
35 {
36 
38 {
39 }
40 
42 {
43  systemInit();
46 
52 
54 
55  current_serial_ = &vcp_; //uncomment this to switch to VCP as the main output
56 }
57 
58 void AirbourneBoard::board_reset(bool bootloader)
59 {
60  (void)bootloader;
62 }
63 
64 // clock
66 {
67  return millis();
68 }
69 
71 {
72  return micros();
73 }
74 
75 void AirbourneBoard::clock_delay(uint32_t milliseconds)
76 {
77  delay(milliseconds);
78 }
79 
80 // serial
81 void AirbourneBoard::serial_init(uint32_t baud_rate, uint32_t dev)
82 {
83  vcp_.init();
84  switch (dev)
85  {
87  uart3_.init(&uart_config[UART3], baud_rate);
90  break;
91  default:
94  }
95 }
96 
97 void AirbourneBoard::serial_write(const uint8_t *src, size_t len)
98 {
99  current_serial_->write(src, len);
100 }
101 
103 {
105  {
107  }
108  else
109  {
110  switch (secondary_serial_device_)
111  {
112  case SERIAL_DEVICE_UART3:
114  break;
115  default:
116  // no secondary serial device
117  break;
118  }
119  }
120 
122 }
123 
125 {
126 
127  return current_serial_->read_byte();
128 }
129 
131 {
133 }
134 
135 
136 // sensors
138 {
139  while (millis() < 50) {} // wait for sensors to boot up
140  imu_.init(&spi1_);
141 
142  baro_.init(&int_i2c_);
143  mag_.init(&int_i2c_);
144  sonar_.init(&ext_i2c_);
146  gnss_.init(&uart3_);
147 }
148 
150 {
151  return ext_i2c_.num_errors();
152 }
153 
155 {
156  return imu_.new_data();
157 }
158 
159 bool AirbourneBoard::imu_read(float accel[3], float *temperature, float gyro[3], uint64_t *time_us)
160 {
161  float read_accel[3], read_gyro[3];
162  imu_.read(read_accel, read_gyro, temperature, time_us);
163 
164  accel[0] = -read_accel[1];
165  accel[1] = -read_accel[0];
166  accel[2] = -read_accel[2];
167 
168  gyro[0] = -read_gyro[1];
169  gyro[1] = -read_gyro[0];
170  gyro[2] = -read_gyro[2];
171 
172  return true;
173 }
174 
176 {
177  sensors_init();
178 }
179 
181 {
182  mag_.update();
183  return mag_.present();
184 }
185 
187 {
188  mag_.update();
189 }
190 
191 void AirbourneBoard::mag_read(float mag[3])
192 {
193  mag_.update();
194  mag_.read(mag);
195 }
197 {
198  baro_.update();
199  return baro_.present();
200 }
201 
203 {
204  baro_.update();
205 }
206 
208 {
209  baro_.update();
210  baro_.read(pressure, temperature);
211 }
212 
214 {
215  return airspeed_.present();
216 }
217 
219 {
220  airspeed_.update();
221 }
222 
223 
224 void AirbourneBoard::diff_pressure_read(float *diff_pressure, float *temperature)
225 {
226  (void) diff_pressure;
227  (void) temperature;
228  airspeed_.update();
229  airspeed_.read(diff_pressure, temperature);
230 }
231 
233 {
234  return sonar_.present();
235 }
236 
238 {
239  sonar_.update();
240 }
241 
243 {
244  return sonar_.read();
245 }
246 
248 {
249  return gnss_.present();
250 }
253 {
254  return this->gnss_.new_data();
255 }
256 //This method translates the UBLOX driver interface into the ROSFlight interface
257 //If not gnss_has_new_data(), then this may return 0's for ECEF position data,
258 //ECEF velocity data, or both
260 {
261  UBLOX::GNSSPVT gnss_pvt= gnss_.read();
264  GNSSData gnss = {};
265  gnss.time_of_week = gnss_pvt.time_of_week;
266  gnss.time = gnss_pvt.time;
267  gnss.nanos = gnss_pvt.nanos;
268  gnss.lat = gnss_pvt.lat;
269  gnss.lon = gnss_pvt.lon;
270  gnss.height = gnss_pvt.height;
271  gnss.vel_n = gnss_pvt.vel_n;
272  gnss.vel_e = gnss_pvt.vel_e;
273  gnss.vel_d = gnss_pvt.vel_d;
274  gnss.h_acc = gnss_pvt.h_acc;
275  gnss.v_acc = gnss_pvt.v_acc;
276  //Does not include ECEF position data if the timestamp doesn't match
277  //See UBLOX::new_data() for reasoning
278  if (gnss.time_of_week == pos_ecef.time_of_week)
279  {
280  gnss.ecef.x = pos_ecef.x;
281  gnss.ecef.y = pos_ecef.y;
282  gnss.ecef.z = pos_ecef.z;
283  gnss.ecef.p_acc = pos_ecef.p_acc;
284  }
285  //Does not include ECEF position data if the timestamp doesn't match
286  //See UBLOX::new_data() for reasoning
287  if (gnss.time_of_week == vel_ecef.time_of_week)
288  {
289  gnss.ecef.vx = vel_ecef.vx;
290  gnss.ecef.vy = vel_ecef.vy;
291  gnss.ecef.vz = vel_ecef.vz;
292  gnss.ecef.s_acc = vel_ecef.s_acc;
293  }
294 
295  return gnss;
296 }
298 {
299  UBLOX::NAV_PVT_t pvt = gnss_.read_raw();
300  GNSSRaw raw = {};
301  raw.time_of_week = pvt.iTOW;
302  raw.year = pvt.time.year;
303  raw.month = pvt.time.month;
304  raw.day = pvt.time.day;
305  raw.hour = pvt.time.hour;
306  raw.min = pvt.time.min;
307  raw.sec = pvt.time.sec;
308  raw.valid = pvt.time.valid;
309  raw.t_acc = pvt.time.tAcc;
310  raw.nano = pvt.time.nano;
311  raw.fix_type = pvt.fixType;
312  raw.num_sat = pvt.numSV;
313  raw.lon = pvt.lon;
314  raw.lat = pvt.lat;
315  raw.height = pvt.height;
316  raw.height_msl = pvt.hMSL;
317  raw.h_acc = pvt.hAcc;
318  raw.v_acc = pvt.vAcc;
319  raw.vel_n = pvt.velN;
320  raw.vel_e = pvt.velE;
321  raw.vel_d = pvt.velD;
322  raw.g_speed = pvt.gSpeed;
323  raw.head_mot = pvt.headMot;
324  raw.s_acc = pvt.sAcc;
325  raw.head_acc = pvt.headAcc;
326  raw.p_dop = pvt.pDOP;
328  return raw;
329 }
330 
331 // PWM
333 {
334  switch (rc_type)
335  {
336  case RC_TYPE_SBUS:
340  rc_ = &rc_sbus_;
341  break;
342  case RC_TYPE_PPM:
343  default:
345  rc_ = &rc_ppm_;
346  break;
347  }
348 }
349 
350 float AirbourneBoard::rc_read(uint8_t channel)
351 {
352  return rc_->read(channel);
353 }
354 
355 void AirbourneBoard::pwm_init(uint32_t refresh_rate, uint16_t idle_pwm)
356 {
357  for (int i = 0; i < PWM_NUM_OUTPUTS; i++)
358  {
359  esc_out_[i].init(&pwm_config[i], refresh_rate, 2000, 1000);
360  esc_out_[i].writeUs(idle_pwm);
361  }
362 }
363 
365 {
366  for (int i = 0; i < PWM_NUM_OUTPUTS; i++)
367  {
368  esc_out_[i].disable();
369  }
370 }
371 
372 void AirbourneBoard::pwm_write(uint8_t channel, float value)
373 {
374  esc_out_[channel].write(value);
375 }
376 
378 {
379  return rc_->lost();
380 }
381 
382 // non-volatile memory
384 {
385  return flash_.init(&spi3_);
386 }
387 
388 bool AirbourneBoard::memory_read(void *data, size_t len)
389 {
390  return flash_.read_config(reinterpret_cast<uint8_t *>(data), len);
391 }
392 
393 bool AirbourneBoard::memory_write(const void *data, size_t len)
394 {
395  return flash_.write_config(reinterpret_cast<const uint8_t *>(data), len);
396 }
397 
398 // LED
400 {
401  led1_.on();
402 }
404 {
405  led1_.off();
406 }
408 {
409  led1_.toggle();
410 }
411 
413 {
414  led2_.on();
415 }
417 {
418  led2_.off();
419 }
421 {
422  led2_.toggle();
423 }
424 
425 //Backup memory
427 {
428  BackupData backup_data = backup_sram_read();
429  return (check_backup_checksum(backup_data) && backup_data.error_code!=0);
430 }
432 {
433  return backup_sram_read();
434 }
435 } // namespace rosflight_firmware
uint32_t time_of_week
Definition: ublox.h:433
void systemInit(void)
Definition: system.c:55
bool present()
Definition: ms4525.cpp:57
bool present()
Definition: mb1242.cpp:72
void init(const uart_hardware_struct_t *conf, uint32_t baudrate_, uart_mode_t mode=MODE_8N1)
Definition: uart.cpp:41
int32_t vel_e
Definition: ublox.h:414
static volatile int16_t gyro[3]
Definition: drv_mpu6050.c:277
uint64_t get_last_pvt_timestamp()
Definition: ublox.h:459
void toggle(void)
Definition: gpio.cpp:52
struct rosflight_firmware::GNSSData::@109 ecef
void init(const pwm_hardware_struct_t *conf)
Definition: rc_ppm.cpp:37
void baro_read(float *pressure, float *temperature) override
volatile uint32_t millis(void)
Definition: system.c:50
float pressure
Definition: ms4525.c:41
bool connected()
Definition: vcp.cpp:112
uint32_t time_of_week
Definition: ublox.h:407
float temperature
Definition: ms4525.c:41
virtual bool lost()=0
bool memory_write(const void *src, size_t len) override
#define MPU6000_SPI
Definition: revo_f4.h:122
void init(GPIO_TypeDef *gpio_port, uint16_t pin)
Definition: led.cpp:34
int32_t vy
Definition: ublox.h:435
void backup_sram_init()
Definition: backup_sram.cpp:6
#define LED2_PIN
Definition: revo_f4.h:151
virtual bool flush()=0
void diff_pressure_read(float *diff_pressure, float *temperature) override
bool imu_read(float accel[3], float *temperature, float gyro[3], uint64_t *time_us) override
void init(const i2c_hardware_struct_t *c)
Definition: i2c.cpp:53
void init()
Definition: vcp.cpp:24
virtual uint8_t read_byte()=0
#define LED2_GPIO
Definition: revo_f4.h:150
void clock_delay(uint32_t milliseconds) override
volatile uint64_t micros(void)
Definition: system.c:44
uint32_t s_acc
Definition: ublox.h:437
bool present()
Definition: hmc5883l.cpp:69
void init(UART *uart)
Definition: ublox.cpp:23
#define LED1_GPIO
Definition: revo_f4.h:148
void init(GPIO_TypeDef *BasePort, uint16_t pin, gpio_mode_t mode)
Definition: gpio.cpp:34
uint16_t num_errors()
Definition: i2c.h:146
#define PWM_NUM_OUTPUTS
Definition: revo_f4.h:155
bool init(I2C *_i2c)
Definition: ms5611.cpp:39
#define FLASH_SPI
Definition: revo_f4.h:126
__STATIC_INLINE void NVIC_SystemReset(void)
System Reset.
Definition: core_cm0.h:647
PWM_OUT esc_out_[PWM_NUM_OUTPUTS]
bool read_config(uint8_t *data, uint32_t len)
Definition: M25P16.cpp:59
rosflight_firmware::BackupData get_backup_data() override
static volatile int16_t accel[3]
Definition: drv_mpu6050.c:276
void init(SPI *spi_drv)
Definition: mpu6000.cpp:52
uint64_t time
Definition: ublox.h:408
#define LED1_PIN
Definition: revo_f4.h:149
bool write_config(const uint8_t *data, const uint32_t len)
Definition: M25P16.cpp:73
#define SBUS_INV_GPIO
Definition: revo_f4.h:84
void writeUs(uint16_t value)
Definition: pwm.cpp:145
void update()
Definition: mb1242.cpp:84
rosflight_firmware::BackupData backup_sram_read()
Definition: backup_sram.cpp:50
const uart_hardware_struct_t uart_config[NUM_UART]
Definition: revo_f4.h:64
int32_t height
Definition: ublox.h:412
uint32_t p_acc
Definition: ublox.h:428
const pwm_hardware_struct_t pwm_config[PWM_NUM_CHANNELS]
Definition: revo_f4.h:166
int32_t lat
Definition: ublox.h:410
int32_t vx
Definition: ublox.h:434
void serial_init(uint32_t baud_rate, uint32_t dev) override
const NAV_PVT_t & read_raw()
Definition: ublox.cpp:384
void update()
Definition: hmc5883l.cpp:76
int32_t lon
Definition: ublox.h:411
virtual float read(uint8_t channel)=0
float rc_read(uint8_t channel) override
void disable()
Definition: pwm.cpp:129
bool check_backup_checksum(const rosflight_firmware::BackupData &)
Definition: backup_sram.cpp:56
uint32_t time_of_week
Definition: ublox.h:424
void init(I2C *_i2c)
Definition: mb1242.cpp:53
void on()
Definition: led.cpp:39
void init(SPI *_spi)
Definition: M25P16.cpp:37
void update()
Definition: ms5611.cpp:100
uint32_t v_acc
Definition: ublox.h:417
bool new_data()
Definition: ublox.cpp:333
#define SBUS_INV_PIN
Definition: revo_f4.h:85
int32_t vel_d
Definition: ublox.h:415
bool present()
Definition: ublox.cpp:133
GNSSPosECEF read_pos_ecef()
Definition: ublox.cpp:362
void update()
Definition: ms4525.cpp:64
#define BARO_I2C
Definition: revo_f4.h:144
#define EXTERNAL_I2C
Definition: revo_f4.h:145
bool memory_read(void *dest, size_t len) override
float read()
Definition: mb1242.cpp:100
void init(const pwm_hardware_struct_t *pwm_init, uint16_t frequency, uint32_t max_us, uint32_t min_us)
Definition: pwm.cpp:36
bool present()
Definition: ms5611.cpp:93
void init(const spi_hardware_struct_t *conf)
Definition: spi.cpp:40
virtual void write(const uint8_t *ch, uint8_t len)=0
int32_t vel_n
Definition: ublox.h:413
#define UART3
Definition: revo_f4.h:63
void mag_read(float mag[3]) override
bool init(I2C *i2c_drv)
Definition: hmc5883l.cpp:38
const spi_hardware_struct_t spi_config[NUM_SPI]
Definition: revo_f4.h:107
uint32_t h_acc
Definition: ublox.h:416
bool read(float mag_data[])
Definition: hmc5883l.cpp:100
void read(float *accel_data, float *gyro_data, float *temp_data, uint64_t *time_us)
Definition: mpu6000.cpp:121
void init(GPIO *inv_pin, UART *uart)
Definition: rc_sbus.cpp:42
bool init(I2C *_i2c)
Definition: ms4525.cpp:43
virtual uint32_t rx_bytes_waiting()=0
GNSSVelECEF read_vel_ecef()
Definition: ublox.cpp:373
void read(float *differential_pressure, float *temp)
Definition: ms4525.cpp:84
void pwm_write(uint8_t channel, float value) override
void pwm_init(uint32_t refresh_rate, uint16_t idle_pwm) override
int32_t vz
Definition: ublox.h:436
void serial_write(const uint8_t *src, size_t len) override
void off()
Definition: led.cpp:44
void board_reset(bool bootloader) override
const i2c_hardware_struct_t i2c_config[NUM_I2C]
Definition: revo_f4.h:132
uint8_t raw[15]
Definition: mpu6000.cpp:34
void write(float value)
Definition: pwm.cpp:140
void rc_init(rc_type_t rc_type) override
void read(float *press, float *temp)
Definition: ms5611.cpp:388
bool new_data()
Definition: mpu6000.cpp:140
void delay(uint32_t ms)
Definition: system.c:98
uint64_t nanos
Definition: ublox.h:409
uint16_t serial_bytes_available() override
#define RC_PPM_PIN
Definition: revo_f4.h:182
GNSSPVT read()
Definition: ublox.cpp:341


rosflight_firmware
Author(s): Daniel Koch , James Jackson
autogenerated on Wed Jul 3 2019 19:59:24