use crate::hardware::channelization::{MCP23017_A_LED, MCP23017_B_LED}; use crate::hardware::initialize; use crate::hardware::mcp23017::Mcp23017OutputPin; use crate::hardware::mcp23017::{Mcp23017, Mcp23017Task}; use crate::hardware::Hardware; use crate::logger::setup_logger; use crate::on_drop::on_drop; use anyhow::Result; use embedded_hal::digital::PinState; use log::info; use std::sync::atomic::{AtomicBool, Ordering}; use std::thread; use std::thread::sleep; use std::time::Duration; mod hardware; mod logger; pub fn run() -> Result<()> { setup_logger()?; info!( "Project Nautilus Flight Software {}", env!("CARGO_PKG_VERSION") ); let hal = initialize()?; let mut mcp23017_a = hal.new_mcp23017_a()?; let mut mcp23017_b = hal.new_mcp23017_b()?; info!("Battery Voltage: {}", hal.get_battery_voltage()?); mcp23017_a.init()?; mcp23017_b.init()?; let running = AtomicBool::new(true); thread::scope(|scope| { // This will automatically set running to false when it drops // This means that if the main thread exits this scope, we will // shut down any side branches let _shutdown_threads = on_drop(|| running.store(false, Ordering::Relaxed)); Mcp23017Task::new(&mcp23017_a, "mcp23017-a".into()) .start(scope, &running, 10)?; Mcp23017Task::new(&mcp23017_b, "mcp23017-b".into()) .start(scope, &running, 10)?; let mut led_pin_a = mcp23017_a.new_output_pin(MCP23017_A_LED)?; led_pin_a.set_state_on_drop(PinState::Low); let mut led_pin_b = mcp23017_b.new_output_pin(MCP23017_B_LED)?; led_pin_b.set_state_on_drop(PinState::Low); led_pin_a.set_state(PinState::High); sleep(Duration::from_secs(1)); led_pin_b.set_state(PinState::High); sleep(Duration::from_secs(1)); anyhow::Ok(()) })?; info!("Shutting Down"); // Explicitly drop these to allow the borrow checker to be sure that // dropping the hal is safe drop(mcp23017_a); drop(mcp23017_b); drop(hal); Ok(()) } #[cfg(test)] mod test_utils; mod data; mod on_drop;