Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions boards/argus/Makefile.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[tasks.attach]
command = "probe-rs"
args = ["attach", "--chip", "STM32H733VGTx", "--protocol", "swd", "../../target/thumbv7em-none-eabihf/debug/argus"]
242 changes: 0 additions & 242 deletions boards/argus/mono.txt

This file was deleted.

1 change: 1 addition & 0 deletions boards/argus/src/led_indicator/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
pub mod service;
33 changes: 33 additions & 0 deletions boards/argus/src/led_indicator/service.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
use defmt::warn;
use embassy_stm32::gpio::{Level, Output, Pin, Speed};
use embassy_stm32::Peripheral;
use embassy_time::Timer;

pub struct LedIndicatorService<const COUNT: usize> {
pub pins: [Output<'static>; COUNT],
}

impl<const COUNT: usize> LedIndicatorService<COUNT> {
pub fn new(peripherals: [impl Peripheral<P = impl Pin> + 'static; COUNT]) -> Self {
let pins: [Output<'static>; COUNT] = peripherals.map(|pin| {
let mut output = Output::new(pin, Level::Low, Speed::Low);
output.set_low();
output
});
Self { pins }
}

pub async fn blink(
&mut self,
index: usize,
) {
if index >= COUNT {
warn!("LED at an invalid index requested to blink: {}", index);
return;
}

self.pins[index].set_high();
Timer::after_millis(30).await;
self.pins[index].set_low();
}
}
1 change: 1 addition & 0 deletions boards/argus/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#![no_main]

pub mod adc;
pub mod led_indicator;
pub mod linear_transformation;
pub mod node;
pub mod sd;
Expand Down
16 changes: 14 additions & 2 deletions boards/argus/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ compile_error!("You must enable exactly one of the features: 'pressure', 'temper

use argus::adc::service::{AdcConfig, AdcService};
use argus::adc::types::AdcDevice;
use argus::led_indicator::service::LedIndicatorService;
use argus::sd::service::SDCardService;
use argus::sd::task::sd_card_task;
use argus::serial::service::SerialService;
Expand Down Expand Up @@ -35,6 +36,7 @@ static SD_CARD_SERVICE: StaticCell<AsyncMutex<SDCardService>> = StaticCell::new(
static ADC_SERVICE: StaticCell<AsyncMutex<AdcService<{ AdcDevice::COUNT }>>> = StaticCell::new();
static SERIAL_SERVICE: StaticCell<AsyncMutex<SerialService>> = StaticCell::new();
static SESSION_SERVICE: StaticCell<AsyncMutex<SessionService>> = StaticCell::new();
static LED_INDICATOR_SERVICE: StaticCell<AsyncMutex<LedIndicatorService<2>>> = StaticCell::new();
static STATE_MACHINE_ORCHESTRATOR: StaticCell<AsyncMutex<StateMachineOrchestrator>> = StaticCell::new();

#[cfg(feature = "temperature")]
Expand All @@ -58,6 +60,10 @@ async fn main(spawner: Spawner) {
peripherals.PC4,
)));
let session_service = SESSION_SERVICE.init(AsyncMutex::new(SessionService::new(sd_card_service)));
let led_indicator_service = LED_INDICATOR_SERVICE.init(AsyncMutex::new(LedIndicatorService::new([
peripherals.PA3.degrade(),
peripherals.PA2.degrade(),
])));
let adc_service = ADC_SERVICE.init(AsyncMutex::new(AdcService::new(
peripherals.SPI4,
peripherals.PE2,
Expand Down Expand Up @@ -96,7 +102,7 @@ async fn main(spawner: Spawner) {
let state_machine_orchestrator = STATE_MACHINE_ORCHESTRATOR.init(AsyncMutex::new(StateMachineOrchestrator::new()));

// General tasks that must run regardless of board type
spawner.must_spawn(sd_card_task(sd_card_service));
spawner.must_spawn(sd_card_task(sd_card_service, led_indicator_service));

// Spawn tasks needed for temperature board
#[cfg(feature = "temperature")]
Expand All @@ -122,6 +128,7 @@ async fn main(spawner: Spawner) {
spawner.must_spawn(tasks::measure_thermocouples(
StateMachineWorker::new(state_machine_orchestrator),
temperature_service,
led_indicator_service,
));
spawner.must_spawn(tasks::log_measurements(
StateMachineWorker::new(state_machine_orchestrator),
Expand Down Expand Up @@ -155,6 +162,7 @@ async fn main(spawner: Spawner) {
spawner.must_spawn(tasks::measure_pressure_sensors(
StateMachineWorker::new(state_machine_orchestrator),
pressure_service,
led_indicator_service,
));
spawner.must_spawn(tasks::measure_manifold_temperature(
StateMachineWorker::new(state_machine_orchestrator),
Expand Down Expand Up @@ -189,7 +197,11 @@ async fn main(spawner: Spawner) {
// Setup the strain service before starting the tasks
strain_service.lock().await.setup().await.unwrap();

spawner.must_spawn(tasks::measure_strain(StateMachineWorker::new(state_machine_orchestrator), strain_service));
spawner.must_spawn(tasks::measure_strain(
StateMachineWorker::new(state_machine_orchestrator),
strain_service,
led_indicator_service,
));
spawner.must_spawn(tasks::log_measurements(
StateMachineWorker::new(state_machine_orchestrator),
serial_service,
Expand Down
7 changes: 5 additions & 2 deletions boards/argus/src/pressure/service.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use defmt::error;
use embassy_time::Instant;
use defmt::{error, info};
use embassy_time::{Instant, Timer};
use strum::EnumCount;

use crate::adc::driver::types::{DataRate, Filter, Gain, ReferenceRange};
Expand Down Expand Up @@ -44,6 +44,9 @@ impl<const ADC_COUNT: usize> PressureService<ADC_COUNT> {
}

pub async fn setup(&mut self) -> Result<(), PressureServiceError> {
// Delay for 100ms to ensure ADCs are powered up
Timer::after_millis(100).await;

for driver in self.adc_service.lock().await.drivers.iter_mut() {
driver.reference_range = ReferenceRange::Avdd;
driver.data_rate = DataRate::Sps100;
Expand Down
2 changes: 1 addition & 1 deletion boards/argus/src/pressure/tasks/log_measurements.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,5 +73,5 @@ fn get_path_from_adc_and_channel(
adc_index: usize,
channel: usize,
) -> FileName {
format!("T_{}_{}.csv", adc_index, channel).unwrap() as FileName
format!("P_{}_{}.csv", adc_index, channel).unwrap() as FileName
}
5 changes: 5 additions & 0 deletions boards/argus/src/pressure/tasks/measure_pressure_sensors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use embassy_futures::yield_now;
use strum::EnumCount;

use crate::adc::types::AdcDevice;
use crate::led_indicator::service::LedIndicatorService;
use crate::pressure::service::{PressureService, PRESSURE_READING_QUEUE};
use crate::pressure::types::PressureChannel;
use crate::state_machine::service::StateMachineWorker;
Expand All @@ -15,6 +16,7 @@ use crate::utils::types::AsyncMutex;
pub async fn measure_pressure_sensors(
mut worker: StateMachineWorker,
pressure_service_mutex: &'static AsyncMutex<PressureService<{ AdcDevice::COUNT }>>,
led_indicator_service_mutex: &'static AsyncMutex<LedIndicatorService<2>>,
) {
worker
.run_while(&[States::Recording], async |_| -> Result<(), ()> {
Expand All @@ -36,6 +38,9 @@ pub async fn measure_pressure_sensors(
}
}

// Blink LED to indicate measurement cycle complete
led_indicator_service_mutex.lock().await.blink(1).await;

// Yield to allow other tasks to run, especially the NTC measurement task
yield_now().await;
Ok(())
Expand Down
8 changes: 7 additions & 1 deletion boards/argus/src/sd/task.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,22 @@
use defmt::{debug, error};

use crate::led_indicator::service::LedIndicatorService;
use crate::sd::service::{SDCardService, SD_CARD_WRITE_QUEUE};
use crate::utils::types::AsyncMutex;

#[embassy_executor::task]
pub async fn sd_card_task(sd_card_service_mutex: &'static AsyncMutex<SDCardService>) {
pub async fn sd_card_task(
sd_card_service_mutex: &'static AsyncMutex<SDCardService>,
led_indicator_service_mutex: &'static AsyncMutex<LedIndicatorService<2>>,
) {
debug!("Starting SD card write loop.");
loop {
let (scope, path, line) = SD_CARD_WRITE_QUEUE.receiver().receive().await;
if let Err(error) = sd_card_service_mutex.lock().await.write(scope, path, line) {
error!("Could not write to SD card: {}", error);
continue;
} else {
led_indicator_service_mutex.lock().await.blink(0).await;
}
}
}
3 changes: 3 additions & 0 deletions boards/argus/src/session/service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ use crate::sd::service::SDCardService;
use crate::sd::types::{FileName, Line, OperationScope, SdCardError};
use crate::utils::types::AsyncMutex;

/// Handles session management for data logging.
/// It reads the last session number from a session.txt file on the SD card, increments it,
/// and writes it back for the next boot. It also keeps track of the current session in memory.
pub struct SessionService {
pub current_session: Option<i32>,
sd_card_service: &'static AsyncMutex<SDCardService>,
Expand Down
5 changes: 4 additions & 1 deletion boards/argus/src/state_machine/service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,10 @@ impl StateMachineWorker {
where
Act: FnMut(&'static AsyncMutex<StateMachineOrchestrator>) -> Fut,
Fut: Future<Output = Result<(), Err>>, {
self.current_state.changed_and(|state| desired_states.contains(state)).await;
// Wait until we're in one of the desired states
if !desired_states.contains(&self.current_state.get().await) {
self.current_state.changed_and(|state| desired_states.contains(state)).await;
}
action(self.orchestrator).await
}

Expand Down
5 changes: 4 additions & 1 deletion boards/argus/src/strain/service.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use defmt::error;
use embassy_time::Instant;
use embassy_time::{Instant, Timer};
use strum::EnumCount;

use crate::adc::driver::types::{DataRate, Filter, Gain, ReferenceRange};
Expand Down Expand Up @@ -44,6 +44,9 @@ impl<const ADC_COUNT: usize> StrainService<ADC_COUNT> {
}

pub async fn setup(&mut self) -> Result<(), StrainServiceError> {
// Delay for 100ms to ensure ADCs are powered up
Timer::after_millis(100).await;

for driver in self.adc_service.lock().await.drivers.iter_mut() {
driver.reference_range = ReferenceRange::Avdd;
driver.data_rate = DataRate::Sps100;
Expand Down
5 changes: 5 additions & 0 deletions boards/argus/src/strain/tasks/measure_strain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use embassy_futures::yield_now;
use strum::EnumCount;

use crate::adc::types::AdcDevice;
use crate::led_indicator::service::LedIndicatorService;
use crate::state_machine::service::StateMachineWorker;
use crate::state_machine::types::States;
use crate::strain::service::{StrainService, STRAIN_READING_QUEUE};
Expand All @@ -15,6 +16,7 @@ use crate::utils::types::AsyncMutex;
pub async fn measure_strain(
mut worker: StateMachineWorker,
strain_service_mutex: &'static AsyncMutex<StrainService<{ AdcDevice::COUNT }>>,
led_indicator_service_mutex: &'static AsyncMutex<LedIndicatorService<2>>,
) {
worker
.run_while(&[States::Recording], async |_| -> Result<(), ()> {
Expand All @@ -36,6 +38,9 @@ pub async fn measure_strain(
}
}

// Blink LED to indicate measurement cycle complete
led_indicator_service_mutex.lock().await.blink(1).await;

// Yield to allow other tasks to run, especially the NTC measurement task
yield_now().await;
Ok(())
Expand Down
5 changes: 4 additions & 1 deletion boards/argus/src/temperature/service.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use defmt::{error, info};
use embassy_time::Instant;
use embassy_time::{Instant, Timer};
use strum::EnumCount;

use crate::adc::driver::types::{AnalogChannel, DataRate, Filter, Gain, ReferenceRange};
Expand Down Expand Up @@ -52,6 +52,9 @@ impl<const ADC_COUNT: usize> TemperatureService<ADC_COUNT> {
}

pub async fn setup(&mut self) -> Result<(), TemperatureServiceError> {
// Delay for 100ms to ensure ADCs are powered up
Timer::after_millis(100).await;

for driver in self.adc_service.lock().await.drivers.iter_mut() {
driver.reference_range = ReferenceRange::Avdd;
driver.data_rate = DataRate::Sps100;
Expand Down
5 changes: 5 additions & 0 deletions boards/argus/src/temperature/tasks/measure_thermocouples.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use embassy_futures::yield_now;
use strum::EnumCount;

use crate::adc::types::AdcDevice;
use crate::led_indicator::service::LedIndicatorService;
use crate::state_machine::service::StateMachineWorker;
use crate::state_machine::types::States;
use crate::temperature::service::{TemperatureService, THERMOCOUPLE_READING_QUEUE};
Expand All @@ -15,6 +16,7 @@ use crate::utils::types::AsyncMutex;
pub async fn measure_thermocouples(
mut worker: StateMachineWorker,
temperature_service_mutex: &'static AsyncMutex<TemperatureService<{ AdcDevice::COUNT }>>,
led_indicator_service_mutex: &'static AsyncMutex<LedIndicatorService<2>>,
) {
worker
.run_while(&[States::Recording], async |_| -> Result<(), ()> {
Expand All @@ -36,6 +38,9 @@ pub async fn measure_thermocouples(
}
}

// Blink LED to indicate measurement cycle complete
led_indicator_service_mutex.lock().await.blink(1).await;

// Yield to allow other tasks to run, especially the RTD measurement task
yield_now().await;
Ok(())
Expand Down
Loading