Skip to content

Commit

Permalink
feat: switch to a callback for SBG
Browse files Browse the repository at this point in the history
  • Loading branch information
jonapap committed Jun 7, 2023
1 parent 15687e5 commit 1073c0b
Show file tree
Hide file tree
Showing 13 changed files with 835 additions and 286 deletions.
495 changes: 421 additions & 74 deletions Cargo.lock

Large diffs are not rendered by default.

32 changes: 27 additions & 5 deletions boards/main/src/data_manager.rs
Original file line number Diff line number Diff line change
@@ -1,17 +1,39 @@
use messages::sensor::{Sbg, SbgShort};
use messages::sensor::{Air, EkfNav1, EkfNav2, EkfQuat, GpsVel, Imu1, Imu2, SensorData, UtcTime};

#[derive(Clone)]
pub struct DataManager {
pub sbg: Option<Sbg>,
pub sbg_short: Option<SbgShort>,
pub air: Option<Air>,
pub ekf_nav: Option<(EkfNav1, EkfNav2)>,
pub ekf_quat: Option<EkfQuat>,
pub imu: Option<(Imu1, Imu2)>,
pub utc_time: Option<UtcTime>,
pub gps_vel: Option<GpsVel>,
}

impl DataManager {
pub fn new() -> Self {
Self {
sbg: None,
sbg_short: None,
air: None,
ekf_nav: None,
ekf_quat: None,
imu: None,
utc_time: None,
gps_vel: None,
}
}

pub fn clone_sensors(&self) -> [Option<SensorData>; 8] {
[
self.air.clone().map(|x| x.into()),
self.ekf_nav.clone().map(|x| x.0.into()),
self.ekf_nav.clone().map(|x| x.1.into()),
self.ekf_quat.clone().map(|x| x.into()),
self.imu.clone().map(|x| x.0.into()),
self.imu.clone().map(|x| x.1.into()),
self.utc_time.clone().map(|x| x.into()),
self.gps_vel.clone().map(|x| x.into()),
]
}
}

impl Default for DataManager {
Expand Down
28 changes: 14 additions & 14 deletions boards/main/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ use mcan::messageram::SharedMemory;
use messages::sensor::Sensor;
use messages::*;
use panic_halt as _;
use sbg_manager::sbg_dma;
use sbg_manager::SBGManager;
use sbg_manager::{sbg_dma, sbg_handle_data, SBGManager};
use sbg_rs::sbg::CallbackData;
use sd_manager::SdManager;
use systick_monotonic::*;
use types::*;
Expand Down Expand Up @@ -227,23 +227,20 @@ mod app {
*/
#[task(shared = [data_manager, &em])]
fn sensor_send(mut cx: sensor_send::Context) {
let (data_long_sbg, data_short_sbg) = cx
let sensor_data = cx
.shared
.data_manager
.lock(|data_manager| (data_manager.sbg.clone(), data_manager.sbg_short.clone()));
.lock(|data_manager| data_manager.clone_sensors());

let message_radio =
data_long_sbg.map(|x| Message::new(&monotonics::now(), COM_ID, Sensor::new(9, x)));

let message_can =
data_short_sbg.map(|x| Message::new(&monotonics::now(), COM_ID, Sensor::new(9, x)));
let messages = sensor_data
.into_iter()
.flatten()
.map(|x| Message::new(&monotonics::now(), COM_ID, Sensor::new(x)));

cx.shared.em.run(|| {
if let Some(msg) = message_radio {
spawn!(send_gs, msg)?;
}
for msg in messages {
spawn!(send_gs, msg.clone())?;

if let Some(msg) = message_can {
spawn!(send_internal, msg)?;
}

Expand All @@ -270,7 +267,10 @@ mod app {
}

extern "Rust" {
#[task(binds = DMAC_0, shared = [data_manager, &em], local = [sbg_manager])]
#[task(binds = DMAC_0, shared = [&em], local = [sbg_manager])]
fn sbg_dma(context: sbg_dma::Context);

#[task(capacity = 20, shared = [data_manager])]
fn sbg_handle_data(context: sbg_handle_data::Context, data: CallbackData);
}
}
26 changes: 18 additions & 8 deletions boards/main/src/sbg_manager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,11 @@ use atsamd_hal::pac::{MCLK, RTC};
use atsamd_hal::prelude::_atsamd21_hal_time_U32Ext;
use atsamd_hal::rtc::Rtc;

use crate::app::sbg_handle_data;
use atsamd_hal::sercom::{uart, Sercom, Sercom0};
use rtic::Mutex;
use sbg_rs::sbg;
use sbg_rs::sbg::{SBG, SBG_BUFFER_SIZE};
use sbg_rs::sbg::{CallbackData, SBG, SBG_BUFFER_SIZE};

pub static mut BUF_DST: SBGBuffer = &mut [0; SBG_BUFFER_SIZE];
pub static mut BUF_DST2: SBGBuffer = &mut [0; SBG_BUFFER_SIZE];
Expand Down Expand Up @@ -57,7 +58,9 @@ impl SBGManager {
let mut rtc = rtc_temp.into_count32_mode();
rtc.set_count32(0);

let sbg: sbg::SBG = sbg::SBG::new(sbg_tx, rtc);
let sbg: sbg::SBG = sbg::SBG::new(sbg_tx, rtc, |data| {
sbg_handle_data::spawn(data).ok();
});

SBGManager {
sbg_device: sbg,
Expand All @@ -67,12 +70,23 @@ impl SBGManager {
}
}

pub fn sbg_handle_data(mut cx: sbg_handle_data::Context, data: CallbackData) {
cx.shared.data_manager.lock(|manager| match data {
CallbackData::UtcTime(x) => manager.utc_time = Some(x),
CallbackData::Air(x) => manager.air = Some(x),
CallbackData::EkfQuat(x) => manager.ekf_quat = Some(x),
CallbackData::EkfNav(x) => manager.ekf_nav = Some(x),
CallbackData::Imu(x) => manager.imu = Some(x),
CallbackData::GpsVel(x) => manager.gps_vel = Some(x),
});
}

/**
* Handles the DMA interrupt.
* Handles the SBG data.
* Logs data to the SD card.
*/
pub fn sbg_dma(mut cx: crate::app::sbg_dma::Context) {
pub fn sbg_dma(cx: crate::app::sbg_dma::Context) {
let sbg = cx.local.sbg_manager;

if sbg.xfer.complete() {
Expand All @@ -88,12 +102,8 @@ pub fn sbg_dma(mut cx: crate::app::sbg_dma::Context) {
}
};

cx.shared.data_manager.lock(|data_manager| {
let (sbg_long_data, sbg_short_data) = sbg.sbg_device.read_data(buf);
sbg.sbg_device.read_data(buf);

data_manager.sbg = Some(sbg_long_data);
data_manager.sbg_short = Some(sbg_short_data);
});
Ok(())
});
}
Expand Down
6 changes: 3 additions & 3 deletions libraries/messages/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,11 @@ ts-rs = { version = "6.2.1", optional = true }
mavlink = { git = "https://github.com/uorocketry/rust-mavlink", branch = "hydra_dialect", default-features = false}

[dev-dependencies]
quickcheck = "1.0.3"
quickcheck_macros = "1.0.0"
proptest = "1.2.0"
proptest-derive = "0.3.0"
postcard = { version = "1.0.4", features = ["alloc"] }

[features]
default = ["mavlink/embedded", "mavlink/uorocketry"]
std = ["mavlink/default"]
ts = ["std", "dep:ts-rs"]
ts = ["std", "dep:ts-rs"]
25 changes: 24 additions & 1 deletion libraries/messages/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,20 +15,24 @@ use serde::{Deserialize, Serialize};
/// This is to help control versions.
pub use mavlink;

#[cfg(test)]
use proptest_derive::Arbitrary;

#[cfg(feature = "ts")]
use ts_rs::TS;

mod logging;
pub mod sender;
pub mod sensor;

pub const MAX_SIZE: usize = 85;
pub const MAX_SIZE: usize = 64;

pub use logging::{ErrorContext, Event, Log, LogLevel};

/// Topmost message. Encloses all the other possible messages, and is the only thing that should
/// be sent over the wire.
#[derive(Serialize, Deserialize, Clone, Debug, Format)]
#[cfg_attr(test, derive(Arbitrary))]
pub struct Message {
/// Time in milliseconds since epoch. Note that the epoch here can be arbitrary and is not the
/// Unix epoch.
Expand All @@ -42,6 +46,7 @@ pub struct Message {
}

#[derive(Serialize, Deserialize, Clone, Debug, From, Format)]
#[cfg_attr(test, derive(Arbitrary))]
#[serde(rename_all = "lowercase")]
pub enum Data {
State(State),
Expand All @@ -50,6 +55,7 @@ pub enum Data {
}

#[derive(Serialize, Deserialize, Clone, Debug, Format)]
#[cfg_attr(test, derive(Arbitrary))]
#[cfg_attr(feature = "ts", derive(TS))]
#[cfg_attr(feature = "ts", ts(export))]
pub enum Status {
Expand All @@ -59,6 +65,7 @@ pub enum Status {
}

#[derive(Serialize, Deserialize, Clone, Debug, Format)]
#[cfg_attr(test, derive(Arbitrary))]
#[cfg_attr(feature = "ts", derive(TS))]
#[cfg_attr(feature = "ts", ts(export))]
pub struct State {
Expand All @@ -80,3 +87,19 @@ impl Message {
}
}
}

#[cfg(test)]
mod test {
use crate::{Message, MAX_SIZE};
use proptest::prelude::*;

proptest! {
#[test]
fn message_size(msg: Message) {
let bytes = postcard::to_allocvec(&msg).unwrap();

dbg!(msg);
assert!(dbg!(bytes.len()) <= MAX_SIZE);
}
}
}
5 changes: 5 additions & 0 deletions libraries/messages/src/logging/log.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,11 @@ use crate::logging::Event;
use defmt::Format;
use serde::{Deserialize, Serialize};

#[cfg(test)]
use proptest_derive::Arbitrary;

#[derive(Serialize, Deserialize, Clone, Debug, Format)]
#[cfg_attr(test, derive(Arbitrary))]
pub struct Log {
level: LogLevel,
event: Event,
Expand All @@ -15,6 +19,7 @@ impl Log {
}

#[derive(Serialize, Deserialize, Clone, Debug, Format)]
#[cfg_attr(test, derive(Arbitrary))]
pub enum LogLevel {
Info,
Warning,
Expand Down
5 changes: 5 additions & 0 deletions libraries/messages/src/logging/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,15 @@ use core::fmt::Formatter;
use macros::{display_context, display_event};
use serde::{Deserialize, Serialize};

#[cfg(test)]
use proptest_derive::Arbitrary;

pub use log::{Log, LogLevel};

/// Custom events for Hydra. These are used to send logging information to the ground-station in
/// a space efficient way.
#[derive(Serialize, Deserialize, Clone, Debug)]
#[cfg_attr(test, derive(Arbitrary))]
pub enum Event {
Initialized(),
Error(ErrorContext),
Expand All @@ -23,6 +27,7 @@ display_event!(
/// This is optionally used to add extra context to any errors. This information can then be sent
/// to the ground station to have a more informative error message.
#[derive(Serialize, Deserialize, Clone, Debug, Copy)]
#[cfg_attr(test, derive(Arbitrary))]
pub enum ErrorContext {
GroundStation,
}
Expand Down
4 changes: 4 additions & 0 deletions libraries/messages/src/sender.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
use defmt::Format;
use serde::{Deserialize, Serialize};

#[cfg(test)]
use proptest_derive::Arbitrary;

#[cfg(feature = "ts")]
use ts_rs::TS;

#[derive(Serialize, Deserialize, Clone, Debug, Format, Copy)]
#[cfg_attr(test, derive(Arbitrary))]
#[cfg_attr(feature = "ts", derive(TS))]
#[cfg_attr(feature = "ts", ts(export))]
pub enum Sender {
Expand Down
Loading

0 comments on commit 1073c0b

Please sign in to comment.