#![cfg(feature = "msp")]
#![allow(unused)]
use stream_buf::{StreamBufReader, StreamBufWriter};
use crate::{
config::{ConfigPublisher, FastConfigPublisher},
multiwii_serial_protocol::{Msp, MspSensorData},
};
#[cfg(feature = "barometer")]
use crate::tasks::barometer_task::BarometerSubscriber;
#[cfg(feature = "battery")]
use crate::tasks::battery_task::BatterySubscriber;
#[cfg(feature = "gps")]
use crate::{gps::GpsMessage, tasks::gps_task::GpsSubscriber};
#[cfg(feature = "magnetometer")]
use crate::tasks::magnetometer_task::MagnetometerSubscriber;
#[cfg(feature = "optical_flow")]
use crate::tasks::optical_flow_task::OpticalFlowSubscriber;
#[cfg(feature = "rangefinder")]
use crate::tasks::rangefinder_task::RangefinderSubscriber;
pub const MSP_READ_BUF_SIZE: usize = 256;
pub const MSP_WRITE_BUF_SIZE: usize = 512;
pub struct MspContext {
pub fast_config_publisher: FastConfigPublisher,
pub config_publisher: ConfigPublisher,
#[cfg(feature = "barometer")]
pub barometer_subscriber: BarometerSubscriber,
#[cfg(feature = "battery")]
pub battery_subscriber: BatterySubscriber,
#[cfg(feature = "gps")]
pub gps_subscriber: GpsSubscriber,
#[cfg(feature = "magnetometer")]
pub magnetometer_subscriber: MagnetometerSubscriber,
#[cfg(feature = "optical_flow")]
pub optical_flow_subscriber: OpticalFlowSubscriber,
#[cfg(feature = "rangefinder")]
pub rangefinder_subscriber: RangefinderSubscriber,
pub msp: Msp,
pub read_buf: [u8; MSP_READ_BUF_SIZE],
pub write_buf: [u8; MSP_WRITE_BUF_SIZE],
}
impl MspContext {
#[allow(clippy::too_many_arguments)]
#[rustfmt::skip]
pub fn new(
fast_config_publisher: FastConfigPublisher,
config_publisher: ConfigPublisher,
#[cfg(feature = "barometer")] barometer_subscriber: BarometerSubscriber,
#[cfg(feature = "battery")] battery_subscriber: BatterySubscriber,
#[cfg(feature = "gps")] gps_subscriber: GpsSubscriber,
#[cfg(feature = "magnetometer")] magnetometer_subscriber: MagnetometerSubscriber,
#[cfg(feature = "optical_flow")] optical_flow_subscriber: OpticalFlowSubscriber,
#[cfg(feature = "rangefinder")] rangefinder_subscriber: RangefinderSubscriber,
) -> Self {
Self {
msp: Msp::new(),
fast_config_publisher,
config_publisher,
#[cfg(feature = "barometer")] barometer_subscriber,
#[cfg(feature = "battery")] battery_subscriber,
#[cfg(feature = "gps")] gps_subscriber,
#[cfg(feature = "magnetometer")] magnetometer_subscriber,
#[cfg(feature = "optical_flow")] optical_flow_subscriber,
#[cfg(feature = "rangefinder")] rangefinder_subscriber,
read_buf: [0u8; MSP_READ_BUF_SIZE],
write_buf: [0u8; MSP_WRITE_BUF_SIZE],
}
}
}
impl MspContext {
pub fn reader(&'_ mut self) -> StreamBufReader<'_> {
StreamBufReader::new(&self.read_buf)
}
pub fn writer(&'_ mut self) -> StreamBufWriter<'_> {
StreamBufWriter::new(&mut self.write_buf)
}
}
#[embassy_executor::task]
pub async fn msp_task(ctx: &'static mut MspContext) {
let mut ticker = embassy_time::Ticker::every(embassy_time::Duration::from_millis(200));
let mut loop_count: u32 = 0;
let mut msp_sensor_data = MspSensorData::new();
log::info!(" MSP: task started");
loop {
ticker.next().await;
#[cfg(feature = "barometer")]
#[allow(clippy::cast_possible_truncation)]
if let Some(wait_result) = ctx.barometer_subscriber.try_next_message()
&& let embassy_sync::pubsub::WaitResult::Message(barometer_data) = wait_result
{
msp_sensor_data.barometer_altitude_cm = ((barometer_data.altitude_m * 100.0) as i32).cast_unsigned();
}
#[cfg(feature = "rangefinder")]
#[allow(clippy::cast_possible_truncation)]
if let Some(wait_result) = ctx.rangefinder_subscriber.try_next_message()
&& let embassy_sync::pubsub::WaitResult::Message(rangefinder_message) = wait_result
{
msp_sensor_data.rangefinder_altitude_cm = ((rangefinder_message.distance_m * 100.0) as i32).cast_unsigned();
}
#[cfg(feature = "gps")]
if let Some(wait_result) = ctx.gps_subscriber.try_next_message()
&& let embassy_sync::pubsub::WaitResult::Message(event) = wait_result
&& let GpsMessage::GpsSolution(gps_solution_data) = event
{
msp_sensor_data.gps_sol.llh = gps_solution_data.llh;
msp_sensor_data.gps_sol.satellite_count = gps_solution_data.satellite_count;
msp_sensor_data.gps_sol.ground_speed_cmps = gps_solution_data.ground_speed_cmps;
msp_sensor_data.gps_sol.ground_course_degrees_x10 = gps_solution_data.ground_course_degrees_x10;
msp_sensor_data.gps_sol.dop_positional = gps_solution_data.dop.positional;
}
let mut src = StreamBufReader::new(&ctx.read_buf);
let cmd_msp = Msp::SET_FAILSAFE_CONFIG;
let _result =
Msp::process_read_command(cmd_msp, &mut src, &ctx.config_publisher, &ctx.fast_config_publisher).await;
if loop_count.is_multiple_of(10) {
log::info!(" MSP: loop {loop_count}");
}
loop_count = loop_count.wrapping_add(1); }
}