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 
53 
55 
56  current_serial_ = &vcp_; //uncomment this to switch to VCP as the main output
57 }
58 
59 void AirbourneBoard::board_reset(bool bootloader)
60 {
61  (void)bootloader;
63 }
64 
65 // clock
67 {
68  return millis();
69 }
70 
72 {
73  return micros();
74 }
75 
76 void AirbourneBoard::clock_delay(uint32_t milliseconds)
77 {
78  delay(milliseconds);
79 }
80 
81 // serial
82 void AirbourneBoard::serial_init(uint32_t baud_rate, uint32_t dev)
83 {
84  vcp_.init();
85  switch (dev)
86  {
88  uart3_.init(&uart_config[UART3], baud_rate);
91  break;
92  default:
95  }
96 }
97 
98 void AirbourneBoard::serial_write(const uint8_t *src, size_t len)
99 {
100  current_serial_->write(src, len);
101 }
102 
104 {
106  {
108  }
109  else
110  {
111  switch (secondary_serial_device_)
112  {
113  case SERIAL_DEVICE_UART3:
115  break;
116  default:
117  // no secondary serial device
118  break;
119  }
120  }
121 
123 }
124 
126 {
127 
128  return current_serial_->read_byte();
129 }
130 
132 {
134 }
135 
136 
137 // sensors
139 {
140  while (millis() < 50) {} // wait for sensors to boot up
141  imu_.init(&spi1_);
142 
143  baro_.init(&int_i2c_);
144  mag_.init(&int_i2c_);
145  sonar_.init(&ext_i2c_);
147  // gnss_.init(&uart1_);
148 }
149 
151 {
152  return ext_i2c_.num_errors();
153 }
154 
156 {
157  return imu_.new_data();
158 }
159 
160 bool AirbourneBoard::imu_read(float accel[3], float *temperature, float gyro[3], uint64_t *time_us)
161 {
162  float read_accel[3], read_gyro[3];
163  imu_.read(read_accel, read_gyro, temperature, time_us);
164 
165  accel[0] = -read_accel[1];
166  accel[1] = -read_accel[0];
167  accel[2] = -read_accel[2];
168 
169  gyro[0] = -read_gyro[1];
170  gyro[1] = -read_gyro[0];
171  gyro[2] = -read_gyro[2];
172 
173  return true;
174 }
175 
177 {
178  sensors_init();
179 }
180 
182 {
183  mag_.update();
184  return mag_.present();
185 }
186 
188 {
189  mag_.update();
190 }
191 
192 void AirbourneBoard::mag_read(float mag[3])
193 {
194  mag_.update();
195  mag_.read(mag);
196 }
198 {
199  baro_.update();
200  return baro_.present();
201 }
202 
204 {
205  baro_.update();
206 }
207 
209 {
210  baro_.update();
211  baro_.read(pressure, temperature);
212 }
213 
215 {
216  return airspeed_.present();
217 }
218 
220 {
221  airspeed_.update();
222 }
223 
224 
225 void AirbourneBoard::diff_pressure_read(float *diff_pressure, float *temperature)
226 {
227  (void) diff_pressure;
228  (void) temperature;
229  airspeed_.update();
230  airspeed_.read(diff_pressure, temperature);
231 }
232 
234 {
235  return sonar_.present();
236 }
237 
239 {
240  sonar_.update();
241 }
242 
244 {
245  return sonar_.read();
246 }
247 
249 {
250  // return gnss_.present();
251  return false;
252 }
255 {
256  // return this->gnss_.new_data();
257  return false;
258 }
259 //This method translates the UBLOX driver interface into the ROSFlight interface
260 //If not gnss_has_new_data(), then this may return 0's for ECEF position data,
261 //ECEF velocity data, or both
263 {
264  // UBLOX::GNSSPVT gnss_pvt= gnss_.read();
265  // UBLOX::GNSSPosECEF pos_ecef = gnss_.read_pos_ecef();
266  // UBLOX::GNSSVelECEF vel_ecef = gnss_.read_vel_ecef();
267  GNSSData gnss = {};
268  // gnss.time_of_week = gnss_pvt.time_of_week;
269  // gnss.time = gnss_pvt.time;
270  // gnss.nanos = gnss_pvt.nanos;
271  // gnss.lat = gnss_pvt.lat;
272  // gnss.lon = gnss_pvt.lon;
273  // gnss.height = gnss_pvt.height;
274  // gnss.vel_n = gnss_pvt.vel_n;
275  // gnss.vel_e = gnss_pvt.vel_e;
276  // gnss.vel_d = gnss_pvt.vel_d;
277  // gnss.h_acc = gnss_pvt.h_acc;
278  // gnss.v_acc = gnss_pvt.v_acc;
279  // //Does not include ECEF position data if the timestamp doesn't match
280  // //See UBLOX::new_data() for reasoning
281  // if (gnss.time_of_week == pos_ecef.time_of_week)
282  // {
283  // gnss.ecef.x = pos_ecef.x;
284  // gnss.ecef.y = pos_ecef.y;
285  // gnss.ecef.z = pos_ecef.z;
286  // gnss.ecef.p_acc = pos_ecef.p_acc;
287  // }
288  // //Does not include ECEF position data if the timestamp doesn't match
289  // //See UBLOX::new_data() for reasoning
290  // if (gnss.time_of_week == vel_ecef.time_of_week)
291  // {
292  // gnss.ecef.vx = vel_ecef.vx;
293  // gnss.ecef.vy = vel_ecef.vy;
294  // gnss.ecef.vz = vel_ecef.vz;
295  // gnss.ecef.s_acc = vel_ecef.s_acc;
296  // }
297 
298  return gnss;
299 }
301 {
302 // UBLOX::NAV_PVT_t pvt = gnss_.read_raw();
303  GNSSRaw raw = {};
304  // raw.time_of_week = pvt.iTOW;
305  // raw.year = pvt.time.year;
306  // raw.month = pvt.time.month;
307  // raw.day = pvt.time.day;
308  // raw.hour = pvt.time.hour;
309  // raw.min = pvt.time.min;
310  // raw.sec = pvt.time.sec;
311  // raw.valid = pvt.time.valid;
312  // raw.t_acc = pvt.time.tAcc;
313  // raw.nano = pvt.time.nano;
314  // raw.fix_type = pvt.fixType;
315  // raw.num_sat = pvt.numSV;
316  // raw.lon = pvt.lon;
317  // raw.lat = pvt.lat;
318  // raw.height = pvt.height;
319  // raw.height_msl = pvt.hMSL;
320  // raw.h_acc = pvt.hAcc;
321  // raw.v_acc = pvt.vAcc;
322  // raw.vel_n = pvt.velN;
323  // raw.vel_e = pvt.velE;
324  // raw.vel_d = pvt.velD;
325  // raw.g_speed = pvt.gSpeed;
326  // raw.head_mot = pvt.headMot;
327  // raw.s_acc = pvt.sAcc;
328  // raw.head_acc = pvt.headAcc;
329  // raw.p_dop = pvt.pDOP;
330  // raw.rosflight_timestamp = gnss_.get_last_pvt_timestamp();
331  return raw;
332 }
333 
334 // PWM
336 {
337  switch (rc_type)
338  {
339  case RC_TYPE_SBUS:
343  rc_ = &rc_sbus_;
344  break;
345  case RC_TYPE_PPM:
346  default:
348  rc_ = &rc_ppm_;
349  break;
350  }
351 }
352 
353 float AirbourneBoard::rc_read(uint8_t channel)
354 {
355  return rc_->read(channel);
356 }
357 
358 void AirbourneBoard::pwm_init(uint32_t refresh_rate, uint16_t idle_pwm)
359 {
360  for (int i = 0; i < PWM_NUM_OUTPUTS; i++)
361  {
362  esc_out_[i].init(&pwm_config[i], refresh_rate, 2000, 1000);
363  esc_out_[i].writeUs(idle_pwm);
364  }
365 }
366 
368 {
369  for (int i = 0; i < PWM_NUM_OUTPUTS; i++)
370  {
371  esc_out_[i].disable();
372  }
373 }
374 
375 void AirbourneBoard::pwm_write(uint8_t channel, float value)
376 {
377  if (channel < PWM_NUM_OUTPUTS)
378  {
379  esc_out_[channel].write(value);
380  }
381 }
382 
384 {
385  return rc_->lost();
386 }
387 
388 // non-volatile memory
390 {
391  return flash_.init(&spi3_);
392 }
393 
394 bool AirbourneBoard::memory_read(void *data, size_t len)
395 {
396  return flash_.read_config(reinterpret_cast<uint8_t *>(data), len);
397 }
398 
399 bool AirbourneBoard::memory_write(const void *data, size_t len)
400 {
401  return flash_.write_config(reinterpret_cast<const uint8_t *>(data), len);
402 }
403 
404 // LED
406 {
407  led1_.on();
408 }
409 
411 {
412  led1_.off();
413 }
414 
416 {
417  led1_.toggle();
418 }
419 
421 {
422  led2_.on();
423 }
424 
426 {
427  led2_.off();
428 }
429 
431 {
432  led2_.toggle();
433 }
434 
435 //Backup memory
437 {
438  BackupData backup_data = backup_sram_read();
439  return (check_backup_checksum(backup_data) && backup_data.error_code!=0);
440 }
441 
443 {
444  return backup_sram_read();
445 }
446 
447 } // namespace rosflight_firmware
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
static volatile int16_t gyro[3]
Definition: drv_mpu6050.c:277
void toggle(void)
Definition: gpio.cpp:52
#define UART1
Definition: revo_f4.h:61
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
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:110
void init(GPIO_TypeDef *gpio_port, uint16_t pin)
Definition: led.cpp:34
void backup_sram_init()
Definition: backup_sram.cpp:6
#define LED2_PIN
Definition: revo_f4.h:134
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:133
void clock_delay(uint32_t milliseconds) override
volatile uint64_t micros(void)
Definition: system.c:44
bool present()
Definition: hmc5883l.cpp:68
#define LED1_GPIO
Definition: revo_f4.h:131
void init(GPIO_TypeDef *BasePort, uint16_t pin, gpio_mode_t mode)
Definition: gpio.cpp:34
uint16_t num_errors()
Definition: i2c.h:144
#define PWM_NUM_OUTPUTS
Definition: revo_f4.h:138
bool init(I2C *_i2c)
Definition: ms5611.cpp:39
#define FLASH_SPI
Definition: revo_f4.h:114
__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
#define LED1_PIN
Definition: revo_f4.h:132
bool write_config(const uint8_t *data, const uint32_t len)
Definition: M25P16.cpp:73
#define SBUS_INV_GPIO
Definition: revo_f4.h:78
void writeUs(uint16_t value)
Definition: pwm.cpp:148
void update()
Definition: mb1242.cpp:84
rosflight_firmware::BackupData backup_sram_read()
Definition: backup_sram.cpp:49
const uart_hardware_struct_t uart_config[NUM_UART]
Definition: revo_f4.h:64
const pwm_hardware_struct_t pwm_config[PWM_NUM_CHANNELS]
Definition: revo_f4.h:149
void serial_init(uint32_t baud_rate, uint32_t dev) override
void update()
Definition: hmc5883l.cpp:75
virtual float read(uint8_t channel)=0
float rc_read(uint8_t channel) override
void disable()
Definition: pwm.cpp:134
bool check_backup_checksum(const rosflight_firmware::BackupData &)
Definition: backup_sram.cpp:55
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
#define SBUS_INV_PIN
Definition: revo_f4.h:79
void update()
Definition: ms4525.cpp:64
#define BARO_I2C
Definition: revo_f4.h:127
#define EXTERNAL_I2C
Definition: revo_f4.h:128
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
#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:101
bool read(float mag_data[])
Definition: hmc5883l.cpp:99
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
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
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:120
uint8_t raw[15]
Definition: mpu6000.cpp:34
void write(float value)
Definition: pwm.cpp:144
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
uint16_t serial_bytes_available() override
#define RC_PPM_PIN
Definition: revo_f4.h:165


rosflight_firmware
Author(s): Daniel Koch , James Jackson
autogenerated on Thu Oct 24 2019 03:17:18