From f366aace7f74325237a975fc019bbab86176a6bf Mon Sep 17 00:00:00 2001 From: Empire Phoenix Date: Fri, 31 Oct 2025 23:22:40 +0100 Subject: [PATCH 1/3] esp-hal release wip --- Software/MainBoard/rust/.idea/vcs.xml | 3 +- Software/MainBoard/rust/Cargo.toml | 55 +++++---- Software/MainBoard/rust/src/fat_error.rs | 3 +- Software/MainBoard/rust/src/hal/esp.rs | 99 ++++++++--------- .../rust/src/hal/little_fs2storage_adapter.rs | 2 +- Software/MainBoard/rust/src/hal/mod.rs | 105 ++++++++---------- Software/MainBoard/rust/src/log/mod.rs | 15 ++- Software/MainBoard/rust/src/main.rs | 18 ++- 8 files changed, 140 insertions(+), 160 deletions(-) diff --git a/Software/MainBoard/rust/.idea/vcs.xml b/Software/MainBoard/rust/.idea/vcs.xml index a3c3c7c..c654893 100644 --- a/Software/MainBoard/rust/.idea/vcs.xml +++ b/Software/MainBoard/rust/.idea/vcs.xml @@ -1,7 +1,8 @@ + - + \ No newline at end of file diff --git a/Software/MainBoard/rust/Cargo.toml b/Software/MainBoard/rust/Cargo.toml index 0aa9409..e49a396 100644 --- a/Software/MainBoard/rust/Cargo.toml +++ b/Software/MainBoard/rust/Cargo.toml @@ -40,14 +40,14 @@ partition_table = "partitions.csv" # Shared CAN API canapi = { path = "../../Shared/canapi" } #ESP stuff -esp-bootloader-esp-idf = { version = "0.2.0", features = ["esp32c6"] } -esp-hal = { version = "=1.0.0-rc.0", features = [ +esp-bootloader-esp-idf = { version = "0.4.0", features = ["esp32c6"] } +esp-hal = { version = "1.0.0", features = [ "esp32c6", "log-04", "unstable", "rt" ] } -log = "0.4.27" +log = "0.4.28" embassy-net = { version = "0.7.1", default-features = false, features = [ "dhcpv4", @@ -58,35 +58,32 @@ embassy-net = { version = "0.7.1", default-features = false, features = [ "proto-ipv4", "dns" ] } -embedded-io = "0.6.1" -embedded-io-async = "0.6.1" +embedded-io = "0.7.1" +embedded-io-async = "0.7.0" esp-alloc = "0.8.0" -esp-backtrace = { version = "0.17.0", features = [ +esp-backtrace = { version = "0.18.1", features = [ "esp32c6", - "exception-handler", "panic-handler", "println", "colors", "custom-halt" ] } -esp-println = { version = "0.15.0", features = ["esp32c6", "log-04"] } +esp-println = { version = "0.16.1", features = ["esp32c6", "log-04"] } # for more networking protocol support see https://crates.io/crates/edge-net -embassy-executor = { version = "0.7.0", features = [ +embassy-executor = { version = "0.9.1", features = [ "log", - "task-arena-size-64", "nightly" ] } embassy-time = { version = "0.5.0", features = ["log"], default-features = false } -esp-hal-embassy = { version = "0.9.0", features = ["esp32c6", "log-04"] } -esp-storage = { version = "0.7.0", features = ["esp32c6"] } +esp-storage = { version = "0.8.1", features = ["esp32c6"] } -esp-wifi = { version = "0.15.0", features = [ - "builtin-scheduler", +esp-radio = { version = "0.17.0", features = [ "esp-alloc", "esp32c6", "log-04", "smoltcp", "wifi", + "unstable" ] } smoltcp = { version = "0.12.0", default-features = false, features = [ "alloc", @@ -112,22 +109,22 @@ embedded-hal-bus = { version = "0.3.0" } #bq34z100 = { version = "0.3.0", default-features = false } onewire = "0.4.0" #strum = { version = "0.27.0", default-feature = false, features = ["derive"] } -measurements = "0.11.0" -ds323x = "0.6.0" +measurements = "0.11.1" +ds323x = "0.7.0" #json -serde = { version = "1.0.219", features = ["derive", "alloc"], default-features = false } -serde_json = { version = "1.0.143", default-features = false, features = ["alloc"] } +serde = { version = "1.0.228", features = ["derive", "alloc"], default-features = false } +serde_json = { version = "1.0.145", default-features = false, features = ["alloc"] } chrono = { version = "0.4.42", default-features = false, features = ["iana-time-zone", "alloc", "serde"] } chrono-tz = { version = "0.10.4", default-features = false, features = ["filter-by-regex"] } eeprom24x = "0.7.2" -crc = "3.2.1" -strum_macros = "0.27.0" -unit-enum = "1.4.1" +crc = "3.3.0" +strum_macros = "0.27.2" +unit-enum = "1.4.3" pca9535 = { version = "2.0.0" } ina219 = { version = "0.2.0" } -embedded-storage = "=0.3.1" +embedded-storage = "0.3.1" portable-atomic = "1.11.1" embassy-sync = { version = "0.7.2", features = ["log"] } async-trait = "0.1.89" @@ -138,12 +135,12 @@ edge-nal-embassy = "0.6.0" static_cell = "2.1.1" edge-http = { version = "0.6.1", features = ["log"] } littlefs2 = { version = "0.6.1", features = ["c-stubs", "alloc"] } -littlefs2-core = "0.1.1" -bytemuck = { version = "1.23.2", features = ["derive", "min_const_generics", "pod_saturating", "extern_crate_alloc"] } -deranged = "0.5.3" +littlefs2-core = "0.1.2" +bytemuck = { version = "1.24.0", features = ["derive", "min_const_generics", "pod_saturating", "extern_crate_alloc"] } +deranged = "0.5.5" embassy-embedded-hal = "0.5.0" bincode = { version = "2.0.1", default-features = false, features = ["derive"] } -sntpc = { version = "0.6.0", default-features = false, features = ["log", "embassy-socket", "embassy-socket-ipv6"] } +sntpc = { version = "0.6.1", default-features = false, features = ["log", "embassy-socket", "embassy-socket-ipv6"] } option-lock = { version = "0.3.1", default-features = false } #stay in sync with mcutie version here! @@ -151,9 +148,7 @@ heapless = { version = "0.7.17", features = ["serde"] } mcutie = { version = "0.3.0", default-features = false, features = ["log", "homeassistant"] } nb = "1.1.0" embedded-can = "0.4.1" -no-panic = "0.1.35" -dont_panic = "0.1.0" - +esp-rtos = { version = "0.2.0", features = ["esp32c6", "embassy"] } [patch.crates-io] @@ -161,4 +156,4 @@ mcutie = { git = 'https://github.com/empirephoenix/mcutie.git' } #bq34z100 = { path = "../../bq34z100_rust" } [build-dependencies] -vergen = { version = "8.2.6", features = ["build", "git", "gitcl"] } +vergen = { version = "8.3.2", features = ["build", "git", "gitcl"] } diff --git a/Software/MainBoard/rust/src/fat_error.rs b/Software/MainBoard/rust/src/fat_error.rs index 838bbf4..f5b3306 100644 --- a/Software/MainBoard/rust/src/fat_error.rs +++ b/Software/MainBoard/rust/src/fat_error.rs @@ -10,7 +10,7 @@ use embedded_storage::nor_flash::NorFlashErrorKind; use esp_hal::i2c::master::ConfigError; use esp_hal::pcnt::unit::{InvalidHighLimit, InvalidLowLimit}; use esp_hal::twai::EspTwaiError; -use esp_wifi::wifi::WifiError; +use esp_radio::wifi::WifiError; use ina219::errors::{BusVoltageReadError, ShuntVoltageReadError}; use littlefs2_core::PathError; use onewire::Error; @@ -316,4 +316,3 @@ impl From for FatError { FatError::SNTPError { error: value } } } - diff --git a/Software/MainBoard/rust/src/hal/esp.rs b/Software/MainBoard/rust/src/hal/esp.rs index e6c254c..a69faad 100644 --- a/Software/MainBoard/rust/src/hal/esp.rs +++ b/Software/MainBoard/rust/src/hal/esp.rs @@ -22,8 +22,8 @@ use embassy_sync::once_lock::OnceLock; use embassy_time::{Duration, Timer, WithTimeout}; use embedded_storage::nor_flash::{check_erase, NorFlash, ReadNorFlash}; use esp_bootloader_esp_idf::ota::OtaImageState::Valid; -use esp_bootloader_esp_idf::ota::{Ota, OtaImageState, Slot}; -use esp_bootloader_esp_idf::partitions::FlashRegion; +use esp_bootloader_esp_idf::ota::{Ota, OtaImageState}; +use esp_bootloader_esp_idf::partitions::{AppPartitionSubType, FlashRegion}; use esp_hal::gpio::{Input, RtcPinWithResistors}; use esp_hal::rng::Rng; use esp_hal::rtc_cntl::{ @@ -32,11 +32,11 @@ use esp_hal::rtc_cntl::{ }; use esp_hal::system::software_reset; use esp_println::println; -use esp_storage::FlashStorage; -use esp_wifi::wifi::{ - AccessPointConfiguration, AccessPointInfo, AuthMethod, ClientConfiguration, Configuration, - ScanConfig, ScanTypeConfig, WifiController, WifiDevice, WifiState, +use esp_radio::wifi::{ + AccessPointConfig, AccessPointInfo, AuthMethod, ClientConfig, ModeConfig, ScanConfig, + ScanTypeConfig, WifiController, WifiDevice, WifiStaState, }; +use esp_storage::FlashStorage; use littlefs2::fs::Filesystem; use littlefs2_core::{FileType, PathBuf, SeekFrom}; use log::{info, warn}; @@ -49,13 +49,13 @@ use smoltcp::socket::udp::PacketMetadata; use smoltcp::wire::DnsQueryType; use sntpc::{get_time, NtpContext, NtpTimestampGenerator}; -#[esp_hal::ram(rtc_fast, persistent)] +#[esp_hal::ram(unstable(rtc_fast), unstable(persistent))] static mut LAST_WATERING_TIMESTAMP: [i64; PLANT_COUNT] = [0; PLANT_COUNT]; -#[esp_hal::ram(rtc_fast, persistent)] +#[esp_hal::ram(unstable(rtc_fast), unstable(persistent))] static mut CONSECUTIVE_WATERING_PLANT: [u32; PLANT_COUNT] = [0; PLANT_COUNT]; -#[esp_hal::ram(rtc_fast, persistent)] +#[esp_hal::ram(unstable(rtc_fast), unstable(persistent))] static mut LOW_VOLTAGE_DETECTED: i8 = 0; -#[esp_hal::ram(rtc_fast, persistent)] +#[esp_hal::ram(unstable(rtc_fast), unstable(persistent))] static mut RESTART_TO_CONF: i8 = 0; const CONFIG_FILE: &str = "config.json"; @@ -127,9 +127,9 @@ pub struct Esp<'a> { // RTC-capable GPIO used as external wake source (store the raw peripheral) pub wake_gpio1: esp_hal::peripherals::GPIO1<'static>, - pub ota: Ota<'static, FlashStorage>, - pub ota_target: &'static mut FlashRegion<'static, FlashStorage>, - pub current: Slot, + pub ota: Ota<'static, FlashStorage<'static>>, + pub ota_target: &'static mut FlashRegion<'static, FlashStorage<'static>>, + pub current: AppPartitionSubType, pub slot0_state: OtaImageState, pub slot1_state: OtaImageState, } @@ -236,13 +236,19 @@ impl Esp<'_> { } pub(crate) async fn finalize_ota(&mut self) -> Result<(), FatError> { - let current = self.ota.current_slot()?; - if self.ota.current_ota_state()? != OtaImageState::Valid { + let current = self.ota.current_app_partition()?; + if self.ota.current_ota_state()? != Valid { info!("Validating current slot {current:?} as it was able to ota"); self.ota.set_current_ota_state(Valid)?; } - - self.ota.set_current_slot(current.next())?; + let next = match current { + AppPartitionSubType::Ota0 => AppPartitionSubType::Ota1, + AppPartitionSubType::Ota1 => AppPartitionSubType::Ota0, + _ => { + bail!("Invalid current slot {current:?} for ota"); + } + }; + self.ota.set_current_app_partition(next)?; info!("switched slot"); self.ota.set_current_ota_state(OtaImageState::New)?; info!("switched state for new partition"); @@ -319,16 +325,10 @@ impl Esp<'_> { info!("start wifi scan"); let mut lock = self.controller.try_lock()?; info!("start wifi scan lock"); - let scan_config = ScanConfig { - ssid: None, - bssid: None, - channel: None, - show_hidden: false, - scan_type: ScanTypeConfig::Active { - min: Default::default(), - max: Default::default(), - }, - }; + let scan_config = ScanConfig::default().with_scan_type(ScanTypeConfig::Active { + min: Default::default(), + max: Default::default(), + }); let rv = lock.scan_with_config_async(scan_config).await?; info!("end wifi scan lock"); Ok(rv) @@ -378,14 +378,12 @@ impl Esp<'_> { } } - pub(crate) async fn wifi_ap(&mut self) -> FatResult> { + pub(crate) async fn wifi_ap(&mut self, spawner: Spawner) -> FatResult> { let ssid = match self.load_config().await { Ok(config) => config.network.ap_ssid.as_str().to_string(), Err(_) => "PlantCtrl Emergency Mode".to_string(), }; - let spawner = Spawner::for_current_executor().await; - let device = self.interface_ap.take().unwrap(); let gw_ip_addr_str = "192.168.71.1"; let gw_ip_addr = Ipv4Addr::from_str(gw_ip_addr_str).expect("failed to parse gateway ip"); @@ -408,15 +406,9 @@ impl Esp<'_> { ); let stack = mk_static!(Stack, stack); - let client_config = Configuration::AccessPoint(AccessPointConfiguration { - ssid: ssid.clone(), - ..Default::default() - }); - - self.controller - .lock() - .await - .set_configuration(&client_config)?; + let client_config = + ModeConfig::AccessPoint(AccessPointConfig::default().with_ssid(ssid.clone())); + self.controller.lock().await.set_config(&client_config)?; println!("start new"); self.controller.lock().await.start()?; @@ -445,8 +437,9 @@ impl Esp<'_> { pub(crate) async fn wifi( &mut self, network_config: &NetworkConfig, + spawner: Spawner, ) -> FatResult> { - esp_wifi::wifi_set_log_verbose(); + esp_radio::wifi_set_log_verbose(); let ssid = network_config.ssid.clone(); match &ssid { Some(ssid) => { @@ -466,8 +459,6 @@ impl Esp<'_> { }; let max_wait = network_config.max_wait; - let spawner = Spawner::for_current_executor().await; - let device = self.interface_sta.take().unwrap(); let config = embassy_net::Config::dhcpv4(DhcpConfig::default()); @@ -482,17 +473,15 @@ impl Esp<'_> { ); let stack = mk_static!(Stack, stack); - let client_config = Configuration::Client(ClientConfiguration { - ssid, - bssid: None, - auth_method: AuthMethod::WPA2Personal, //FIXME read from config, fill via scan - password, - channel: None, - }); + let client_config = ClientConfig::default() + .with_ssid(ssid) + .with_auth_method(AuthMethod::Wpa2Personal) + .with_password(password); + self.controller .lock() .await - .set_configuration(&client_config)?; + .set_config(&ModeConfig::Client(client_config))?; spawner.spawn(net_task(runner)).ok(); self.controller.lock().await.start_async().await?; @@ -501,8 +490,8 @@ impl Esp<'_> { guard.current_time_us() } + max_wait as u64 * 1000; loop { - let state = esp_wifi::wifi::sta_state(); - if state == WifiState::StaStarted { + let state = esp_radio::wifi::sta_state(); + if state == WifiStaState::Started { self.controller.lock().await.connect()?; break; } @@ -520,8 +509,8 @@ impl Esp<'_> { guard.current_time_us() } + max_wait as u64 * 1000; loop { - let state = esp_wifi::wifi::sta_state(); - if state == WifiState::StaConnected { + let state = esp_radio::wifi::sta_state(); + if state == WifiStaState::Connected { break; } if { @@ -699,6 +688,7 @@ impl Esp<'_> { &mut self, network_config: &'static NetworkConfig, stack: Stack<'static>, + spawner: Spawner, ) -> FatResult<()> { let base_topic = network_config .base_topic @@ -751,7 +741,6 @@ impl Esp<'_> { let keep_alive = Duration::from_secs(60 * 60 * 2).as_secs() as u16; let (receiver, task) = builder.build(keep_alive); - let spawner = Spawner::for_current_executor().await; spawner.spawn(mqtt_incoming_task( receiver, round_trip_topic.clone(), diff --git a/Software/MainBoard/rust/src/hal/little_fs2storage_adapter.rs b/Software/MainBoard/rust/src/hal/little_fs2storage_adapter.rs index d103b26..78cf032 100644 --- a/Software/MainBoard/rust/src/hal/little_fs2storage_adapter.rs +++ b/Software/MainBoard/rust/src/hal/little_fs2storage_adapter.rs @@ -9,7 +9,7 @@ use littlefs2::io::Result as lfs2Result; use log::error; pub struct LittleFs2Filesystem { - pub(crate) storage: &'static mut FlashRegion<'static, FlashStorage>, + pub(crate) storage: &'static mut FlashRegion<'static, FlashStorage<'static>>, } impl lfs2Storage for LittleFs2Filesystem { diff --git a/Software/MainBoard/rust/src/hal/mod.rs b/Software/MainBoard/rust/src/hal/mod.rs index 564ce20..4a8d8a9 100644 --- a/Software/MainBoard/rust/src/hal/mod.rs +++ b/Software/MainBoard/rust/src/hal/mod.rs @@ -27,14 +27,8 @@ use esp_hal::peripherals::GPIO2; use esp_hal::peripherals::GPIO21; use esp_hal::peripherals::GPIO22; use esp_hal::peripherals::GPIO23; -use esp_hal::peripherals::GPIO24; -use esp_hal::peripherals::GPIO25; -use esp_hal::peripherals::GPIO26; use esp_hal::peripherals::GPIO27; -use esp_hal::peripherals::GPIO28; -use esp_hal::peripherals::GPIO29; use esp_hal::peripherals::GPIO3; -use esp_hal::peripherals::GPIO30; use esp_hal::peripherals::GPIO4; use esp_hal::peripherals::GPIO5; use esp_hal::peripherals::GPIO6; @@ -89,9 +83,9 @@ use embedded_storage::nor_flash::ReadNorFlash; use esp_alloc as _; use esp_backtrace as _; use esp_bootloader_esp_idf::ota::{Ota, OtaImageState}; -use esp_bootloader_esp_idf::ota::{Slot as ota_slot, Slot}; use esp_hal::delay::Delay; use esp_hal::i2c::master::{BusTimeout, Config, I2c}; +use esp_hal::interrupt::software::SoftwareInterruptControl; use esp_hal::pcnt::unit::Unit; use esp_hal::pcnt::Pcnt; use esp_hal::rng::Rng; @@ -100,8 +94,8 @@ use esp_hal::system::reset_reason; use esp_hal::time::Rate; use esp_hal::timer::timg::TimerGroup; use esp_hal::Blocking; +use esp_radio::{init, Controller}; use esp_storage::FlashStorage; -use esp_wifi::{init, EspWifiController}; use littlefs2::fs::{Allocation, Filesystem as lfs2Filesystem}; use littlefs2::object_safe::DynStorage; use log::{error, info, warn}; @@ -221,13 +215,7 @@ pub struct FreePeripherals<'a> { pub gpio21: GPIO21<'a>, pub gpio22: GPIO22<'a>, pub gpio23: GPIO23<'a>, - pub gpio24: GPIO24<'a>, - pub gpio25: GPIO25<'a>, - pub gpio26: GPIO26<'a>, pub gpio27: GPIO27<'a>, - pub gpio28: GPIO28<'a>, - pub gpio29: GPIO29<'a>, - pub gpio30: GPIO30<'a>, pub twai: TWAI0<'a>, pub pcnt0: Unit<'a, 0>, pub pcnt1: Unit<'a, 1>, @@ -258,7 +246,9 @@ impl PlantHal { error: "Init error rct".to_string(), })?; - let systimer = SystemTimer::new(peripherals.SYSTIMER); + let timg0 = TimerGroup::new(peripherals.TIMG0); + let sw_int = SoftwareInterruptControl::new(peripherals.SW_INTERRUPT); + esp_rtos::start(timg0.timer0, sw_int.software_interrupt0); let boot_button = Input::new( peripherals.GPIO9, @@ -268,21 +258,15 @@ impl PlantHal { // Reserve GPIO1 for deep sleep wake (configured just before entering sleep) let wake_gpio1 = peripherals.GPIO1; - let rng = Rng::new(peripherals.RNG); - let timg0 = TimerGroup::new(peripherals.TIMG0); + let rng = Rng::new(); let esp_wifi_ctrl = &*mk_static!( - EspWifiController<'static>, - init(timg0.timer0, rng).expect("Could not init wifi controller") + Controller<'static>, + init().expect("Could not init wifi controller") ); let (controller, interfaces) = - esp_wifi::wifi::new(esp_wifi_ctrl, peripherals.WIFI).expect("Could not init wifi"); - - use esp_hal::timer::systimer::SystemTimer; - esp_hal_embassy::init(systimer.alarm0); - - //let mut adc1 = Adc::new(peripherals.ADC1, adc1_config); - // + esp_radio::wifi::new(esp_wifi_ctrl, peripherals.WIFI, Default::default()) + .expect("Could not init wifi"); let pcnt_module = Pcnt::new(peripherals.PCNT); @@ -311,13 +295,7 @@ impl PlantHal { gpio21: peripherals.GPIO21, gpio22: peripherals.GPIO22, gpio23: peripherals.GPIO23, - gpio24: peripherals.GPIO24, - gpio25: peripherals.GPIO25, - gpio26: peripherals.GPIO26, gpio27: peripherals.GPIO27, - gpio28: peripherals.GPIO28, - gpio29: peripherals.GPIO29, - gpio30: peripherals.GPIO30, twai: peripherals.TWAI0, pcnt0: pcnt_module.unit0, pcnt1: pcnt_module.unit1, @@ -328,9 +306,10 @@ impl PlantHal { [u8; esp_bootloader_esp_idf::partitions::PARTITION_TABLE_MAX_LEN], [0u8; esp_bootloader_esp_idf::partitions::PARTITION_TABLE_MAX_LEN] ); - let storage_ota = mk_static!(FlashStorage, FlashStorage::new()); + let flash_storage = mk_static!(FlashStorage, FlashStorage::new(peripherals.FLASH)); + let pt = - esp_bootloader_esp_idf::partitions::read_partition_table(storage_ota, tablebuffer)?; + esp_bootloader_esp_idf::partitions::read_partition_table(flash_storage, tablebuffer)?; let ota_data = mk_static!( PartitionEntry, @@ -342,14 +321,14 @@ impl PlantHal { let ota_data = mk_static!( FlashRegion, - ota_data.as_embedded_storage(storage_ota) + ota_data.as_embedded_storage(flash_storage) ); - let state_0 = ota_state(ota_slot::Slot0, ota_data); - let state_1 = ota_state(ota_slot::Slot1, ota_data); - let mut ota = Ota::new(ota_data)?; + let state_0 = ota_state(AppPartitionSubType::Ota0, ota_data); + let state_1 = ota_state(AppPartitionSubType::Ota1, ota_data); + let mut ota = Ota::new(ota_data, 2)?; let running = get_current_slot_and_fix_ota_data(&mut ota, state_0, state_1)?; - let target = running.next(); + let target = next_partition(running)?; info!("Currently running OTA slot: {running:?}"); info!("Slot0 state: {state_0:?}"); @@ -357,26 +336,25 @@ impl PlantHal { //obtain current_state and next_state here! let ota_target = match target { - Slot::None => { - panic!("No OTA slot active?"); - } - Slot::Slot0 => pt + AppPartitionSubType::Ota0 => pt .find_partition(esp_bootloader_esp_idf::partitions::PartitionType::App( AppPartitionSubType::Ota0, ))? .context("Partition table invalid no ota0")?, - Slot::Slot1 => pt + AppPartitionSubType::Ota1 => pt .find_partition(esp_bootloader_esp_idf::partitions::PartitionType::App( AppPartitionSubType::Ota1, ))? .context("Partition table invalid no ota1")?, + _ => { + bail!("Invalid target partition"); + } }; let ota_target = mk_static!(PartitionEntry, ota_target); - let storage_ota = mk_static!(FlashStorage, FlashStorage::new()); let ota_target = mk_static!( FlashRegion, - ota_target.as_embedded_storage(storage_ota) + ota_target.as_embedded_storage(flash_storage) ); let data_partition = pt @@ -386,10 +364,9 @@ impl PlantHal { .expect("Data partition with littlefs not found"); let data_partition = mk_static!(PartitionEntry, data_partition); - let storage_data = mk_static!(FlashStorage, FlashStorage::new()); let data = mk_static!( FlashRegion, - data_partition.as_embedded_storage(storage_data) + data_partition.as_embedded_storage(flash_storage) ); let lfs2filesystem = mk_static!(LittleFs2Filesystem, LittleFs2Filesystem { storage: data }); let alloc = mk_static!(Allocation, lfs2Filesystem::allocate()); @@ -607,15 +584,12 @@ impl PlantHal { } } -fn ota_state(slot: ota_slot, ota_data: &mut FlashRegion) -> OtaImageState { +fn ota_state(slot: AppPartitionSubType, ota_data: &mut FlashRegion) -> OtaImageState { // Read and log OTA states for both slots before constructing Ota // Each OTA select entry is 32 bytes: [seq:4][label:20][state:4][crc:4] // Offsets within the OTA data partition: slot0 @ 0x0000, slot1 @ 0x1000 - if slot == ota_slot::None { - return OtaImageState::Undefined; - } let mut slot_buf = [0u8; 32]; - if slot == ota_slot::Slot0 { + if slot == AppPartitionSubType::Ota0 { let _ = ota_data.read(0x0000, &mut slot_buf); } else { let _ = ota_data.read(0x1000, &mut slot_buf); @@ -629,7 +603,7 @@ fn get_current_slot_and_fix_ota_data( ota: &mut Ota, state0: OtaImageState, state1: OtaImageState, -) -> Result { +) -> Result { let state = ota.current_ota_state().unwrap_or_default(); let swap = match state { OtaImageState::Invalid => true, @@ -640,11 +614,11 @@ fn get_current_slot_and_fix_ota_data( } _ => false, }; - let current = ota.current_slot()?; + let current = ota.current_app_partition()?; if swap { let other = match current { - ota_slot::Slot0 => state1, - ota_slot::Slot1 => state0, + AppPartitionSubType::Ota0 => state1, + AppPartitionSubType::Ota1 => state0, _ => OtaImageState::Invalid, }; @@ -668,13 +642,26 @@ fn get_current_slot_and_fix_ota_data( _ => {} } info!("Current slot has state {state:?} other state has {other:?} swapping"); - ota.set_current_slot(current.next())?; + let next = next_partition(current)?; + ota.set_current_app_partition(next)?; + //we actually booted other slot, than partition table assumes - return Ok(ota.current_slot()?); + return Ok(ota.current_app_partition()?); }; Ok(current) } +pub fn next_partition(current: AppPartitionSubType) -> FatResult { + let next = match current { + AppPartitionSubType::Ota0 => AppPartitionSubType::Ota1, + AppPartitionSubType::Ota1 => AppPartitionSubType::Ota0, + _ => { + bail!("Current slot is not ota0 or ota1"); + } + }; + Ok(next) +} + pub async fn esp_time() -> DateTime { let guard = TIME_ACCESS.get().await.lock().await; DateTime::from_timestamp_micros(guard.current_time_us() as i64).unwrap() diff --git a/Software/MainBoard/rust/src/log/mod.rs b/Software/MainBoard/rust/src/log/mod.rs index ccbb164..881fb4b 100644 --- a/Software/MainBoard/rust/src/log/mod.rs +++ b/Software/MainBoard/rust/src/log/mod.rs @@ -14,7 +14,7 @@ use unit_enum::UnitEnum; const LOG_ARRAY_SIZE: u8 = 220; const MAX_LOG_ARRAY_INDEX: u8 = LOG_ARRAY_SIZE - 1; -#[esp_hal::ram(rtc_fast, persistent)] +#[esp_hal::ram(unstable(rtc_fast), unstable(persistent))] static mut LOG_ARRAY: LogArray = LogArray { buffer: [LogEntryInner { timestamp: 0, @@ -159,7 +159,6 @@ impl LogArray { } } - fn limit_length(input: &str, target: &mut heapless::String) { for char in input.chars() { match target.push(char) { @@ -171,16 +170,20 @@ fn limit_length(input: &str, target: &mut heapless::String {} Err(_) => { - warn!("Error pushin . to limit {LIMIT} current value {target} input {input}") + warn!( + "Error pushin . to limit {LIMIT} current value {target} input {input}" + ) } } - match target.push('.'){ + match target.push('.') { Ok(_) => {} Err(_) => { - warn!("Error pushin . to limit {LIMIT} current value {target} input {input}") + warn!( + "Error pushin . to limit {LIMIT} current value {target} input {input}" + ) } } return; diff --git a/Software/MainBoard/rust/src/main.rs b/Software/MainBoard/rust/src/main.rs index 77ecb50..f558886 100644 --- a/Software/MainBoard/rust/src/main.rs +++ b/Software/MainBoard/rust/src/main.rs @@ -233,7 +233,7 @@ async fn safe_main(spawner: Spawner) -> FatResult<()> { { info!("No wifi configured, starting initial config mode"); - let stack = board.board_hal.get_esp().wifi_ap().await?; + let stack = board.board_hal.get_esp().wifi_ap(spawner).await?; let reboot_now = Arc::new(AtomicBool::new(false)); println!("starting webserver"); @@ -244,7 +244,7 @@ async fn safe_main(spawner: Spawner) -> FatResult<()> { let mut stack: OptionLock = OptionLock::empty(); let network_mode = if board.board_hal.get_config().network.ssid.is_some() { - try_connect_wifi_sntp_mqtt(&mut board, &mut stack).await + try_connect_wifi_sntp_mqtt(&mut board, &mut stack, spawner).await } else { info!("No wifi configured"); //the current sensors require this amount to stabilize, in the case of Wi-Fi this is already handled due to connect timings; @@ -257,7 +257,7 @@ async fn safe_main(spawner: Spawner) -> FatResult<()> { let res = { let esp = board.board_hal.get_esp(); - esp.wifi_ap().await + esp.wifi_ap(spawner).await }; match res { Ok(ap_stack) => { @@ -839,9 +839,10 @@ macro_rules! mk_static { async fn try_connect_wifi_sntp_mqtt( board: &mut MutexGuard<'static, CriticalSectionRawMutex, HAL<'static>>, stack_store: &mut OptionLock>, + spawner: Spawner, ) -> NetworkMode { let nw_conf = &board.board_hal.get_config().network.clone(); - match board.board_hal.get_esp().wifi(nw_conf).await { + match board.board_hal.get_esp().wifi(nw_conf, spawner).await { Ok(stack) => { stack_store.replace(stack); @@ -865,7 +866,12 @@ async fn try_connect_wifi_sntp_mqtt( let mqtt_connected = if board.board_hal.get_config().network.mqtt_url.is_some() { let nw_config = board.board_hal.get_config().network.clone(); let nw_config = mk_static!(NetworkConfig, nw_config); - match board.board_hal.get_esp().mqtt(nw_config, stack).await { + match board + .board_hal + .get_esp() + .mqtt(nw_config, stack, spawner) + .await + { Ok(_) => { info!("Mqtt connection ready"); true @@ -1052,7 +1058,7 @@ async fn wait_infinity( } } -#[esp_hal_embassy::main] +#[esp_rtos::main] async fn main(spawner: Spawner) -> ! { // intialize embassy logger::init_logger_from_env(); From 0519ca3efe60b2c2191382cf7387753e263aa494 Mon Sep 17 00:00:00 2001 From: Empire Phoenix Date: Fri, 31 Oct 2025 23:39:10 +0100 Subject: [PATCH 2/3] read and write to nal --- Software/MainBoard/rust/src/webserver/backup_manager.rs | 2 +- Software/MainBoard/rust/src/webserver/file_manager.rs | 2 +- Software/MainBoard/rust/src/webserver/get_json.rs | 2 +- Software/MainBoard/rust/src/webserver/get_log.rs | 2 +- Software/MainBoard/rust/src/webserver/get_static.rs | 2 +- Software/MainBoard/rust/src/webserver/mod.rs | 4 ++-- Software/MainBoard/rust/src/webserver/ota.rs | 2 +- Software/MainBoard/rust/src/webserver/post_json.rs | 2 +- 8 files changed, 9 insertions(+), 9 deletions(-) diff --git a/Software/MainBoard/rust/src/webserver/backup_manager.rs b/Software/MainBoard/rust/src/webserver/backup_manager.rs index 8143b33..ef6c4b0 100644 --- a/Software/MainBoard/rust/src/webserver/backup_manager.rs +++ b/Software/MainBoard/rust/src/webserver/backup_manager.rs @@ -6,7 +6,7 @@ use alloc::format; use alloc::string::{String, ToString}; use chrono::DateTime; use edge_http::io::server::Connection; -use embedded_io_async::{Read, Write}; +use edge_nal::io::{Read, Write}; use log::info; use serde::{Deserialize, Serialize}; diff --git a/Software/MainBoard/rust/src/webserver/file_manager.rs b/Software/MainBoard/rust/src/webserver/file_manager.rs index ddf7c16..03304ae 100644 --- a/Software/MainBoard/rust/src/webserver/file_manager.rs +++ b/Software/MainBoard/rust/src/webserver/file_manager.rs @@ -6,7 +6,7 @@ use alloc::format; use alloc::string::String; use edge_http::io::server::Connection; use edge_http::Method; -use embedded_io_async::{Read, Write}; +use edge_nal::io::{Read, Write}; use log::info; pub(crate) async fn list_files( diff --git a/Software/MainBoard/rust/src/webserver/get_json.rs b/Software/MainBoard/rust/src/webserver/get_json.rs index a23cb04..553e9e4 100644 --- a/Software/MainBoard/rust/src/webserver/get_json.rs +++ b/Software/MainBoard/rust/src/webserver/get_json.rs @@ -10,7 +10,7 @@ use alloc::vec::Vec; use chrono_tz::Tz; use core::str::FromStr; use edge_http::io::server::Connection; -use embedded_io_async::{Read, Write}; +use edge_nal::io::{Read, Write}; use log::info; use serde::Serialize; diff --git a/Software/MainBoard/rust/src/webserver/get_log.rs b/Software/MainBoard/rust/src/webserver/get_log.rs index 4cc5331..0f403a0 100644 --- a/Software/MainBoard/rust/src/webserver/get_log.rs +++ b/Software/MainBoard/rust/src/webserver/get_log.rs @@ -1,7 +1,7 @@ use crate::fat_error::FatResult; use crate::log::LOG_ACCESS; use edge_http::io::server::Connection; -use embedded_io_async::{Read, Write}; +use edge_nal::io::{Read, Write}; pub(crate) async fn get_log( conn: &mut Connection<'_, T, N>, diff --git a/Software/MainBoard/rust/src/webserver/get_static.rs b/Software/MainBoard/rust/src/webserver/get_static.rs index 26b1947..1db5be8 100644 --- a/Software/MainBoard/rust/src/webserver/get_static.rs +++ b/Software/MainBoard/rust/src/webserver/get_static.rs @@ -1,6 +1,6 @@ use crate::fat_error::FatError; use edge_http::io::server::Connection; -use embedded_io_async::{Read, Write}; +use edge_nal::io::{Read, Write}; pub(crate) async fn serve_favicon( conn: &mut Connection<'_, T, { N }>, diff --git a/Software/MainBoard/rust/src/webserver/mod.rs b/Software/MainBoard/rust/src/webserver/mod.rs index eb43111..de78ac6 100644 --- a/Software/MainBoard/rust/src/webserver/mod.rs +++ b/Software/MainBoard/rust/src/webserver/mod.rs @@ -32,11 +32,11 @@ use core::result::Result::Ok; use core::sync::atomic::{AtomicBool, Ordering}; use edge_http::io::server::{Connection, Handler, Server}; use edge_http::Method; +use edge_nal::io::{Read, Write}; use edge_nal::TcpBind; use edge_nal_embassy::{Tcp, TcpBuffers}; use embassy_net::Stack; use embassy_time::Instant; -use embedded_io_async::{Read, Write}; use log::{error, info}; struct HTTPRequestRouter { @@ -203,7 +203,7 @@ async fn handle_json<'a, T, const N: usize>( ) -> FatResult where T: Read + Write, - ::Error: Debug, + ::Error: Debug, { match chain { Ok(answer) => match answer { diff --git a/Software/MainBoard/rust/src/webserver/ota.rs b/Software/MainBoard/rust/src/webserver/ota.rs index 5744153..c8195df 100644 --- a/Software/MainBoard/rust/src/webserver/ota.rs +++ b/Software/MainBoard/rust/src/webserver/ota.rs @@ -3,7 +3,7 @@ use crate::webserver::read_up_to_bytes_from_request; use crate::BOARD_ACCESS; use edge_http::io::server::Connection; use edge_http::Method; -use embedded_io_async::{Read, Write}; +use edge_nal::io::{Read, Write}; use log::info; pub(crate) async fn ota_operations( diff --git a/Software/MainBoard/rust/src/webserver/post_json.rs b/Software/MainBoard/rust/src/webserver/post_json.rs index 50ac3e8..87c747f 100644 --- a/Software/MainBoard/rust/src/webserver/post_json.rs +++ b/Software/MainBoard/rust/src/webserver/post_json.rs @@ -7,7 +7,7 @@ use alloc::string::{String, ToString}; use alloc::vec::Vec; use chrono::DateTime; use edge_http::io::server::Connection; -use embedded_io_async::{Read, Write}; +use edge_nal::io::{Read, Write}; use log::info; use serde::{Deserialize, Serialize}; From 8cd9e08e93f02324d4d7664046f99ebd9c22b9da Mon Sep 17 00:00:00 2001 From: Empire Phoenix Date: Sun, 2 Nov 2025 02:30:21 +0100 Subject: [PATCH 3/3] shared flash test --- Software/MainBoard/rust/src/hal/esp.rs | 6 +- .../rust/src/hal/little_fs2storage_adapter.rs | 4 +- Software/MainBoard/rust/src/hal/mod.rs | 36 +++++++---- .../MainBoard/rust/src/hal/shared_flash.rs | 63 +++++++++++++++++++ Software/MainBoard/rust/src/hal/v4_sensor.rs | 12 ++-- Software/MainBoard/rust/src/plant_state.rs | 24 +++++-- 6 files changed, 117 insertions(+), 28 deletions(-) create mode 100644 Software/MainBoard/rust/src/hal/shared_flash.rs diff --git a/Software/MainBoard/rust/src/hal/esp.rs b/Software/MainBoard/rust/src/hal/esp.rs index a69faad..4985e1a 100644 --- a/Software/MainBoard/rust/src/hal/esp.rs +++ b/Software/MainBoard/rust/src/hal/esp.rs @@ -7,6 +7,7 @@ use serde::Serialize; use crate::fat_error::{ContextExt, FatError, FatResult}; use crate::hal::little_fs2storage_adapter::LittleFs2Filesystem; +use crate::hal::shared_flash::MutexFlashStorage; use alloc::string::ToString; use alloc::sync::Arc; use alloc::{format, string::String, vec, vec::Vec}; @@ -36,7 +37,6 @@ use esp_radio::wifi::{ AccessPointConfig, AccessPointInfo, AuthMethod, ClientConfig, ModeConfig, ScanConfig, ScanTypeConfig, WifiController, WifiDevice, WifiStaState, }; -use esp_storage::FlashStorage; use littlefs2::fs::Filesystem; use littlefs2_core::{FileType, PathBuf, SeekFrom}; use log::{info, warn}; @@ -127,8 +127,8 @@ pub struct Esp<'a> { // RTC-capable GPIO used as external wake source (store the raw peripheral) pub wake_gpio1: esp_hal::peripherals::GPIO1<'static>, - pub ota: Ota<'static, FlashStorage<'static>>, - pub ota_target: &'static mut FlashRegion<'static, FlashStorage<'static>>, + pub ota: Ota<'static, MutexFlashStorage>, + pub ota_target: &'static mut FlashRegion<'static, MutexFlashStorage>, pub current: AppPartitionSubType, pub slot0_state: OtaImageState, pub slot1_state: OtaImageState, diff --git a/Software/MainBoard/rust/src/hal/little_fs2storage_adapter.rs b/Software/MainBoard/rust/src/hal/little_fs2storage_adapter.rs index 78cf032..987a7b7 100644 --- a/Software/MainBoard/rust/src/hal/little_fs2storage_adapter.rs +++ b/Software/MainBoard/rust/src/hal/little_fs2storage_adapter.rs @@ -1,6 +1,6 @@ +use crate::hal::shared_flash::MutexFlashStorage; use embedded_storage::nor_flash::{check_erase, NorFlash, ReadNorFlash}; use esp_bootloader_esp_idf::partitions::FlashRegion; -use esp_storage::FlashStorage; use littlefs2::consts::U4096 as lfsCache; use littlefs2::consts::U512 as lfsLookahead; use littlefs2::driver::Storage as lfs2Storage; @@ -9,7 +9,7 @@ use littlefs2::io::Result as lfs2Result; use log::error; pub struct LittleFs2Filesystem { - pub(crate) storage: &'static mut FlashRegion<'static, FlashStorage<'static>>, + pub(crate) storage: &'static mut FlashRegion<'static, MutexFlashStorage>, } impl lfs2Storage for LittleFs2Filesystem { diff --git a/Software/MainBoard/rust/src/hal/mod.rs b/Software/MainBoard/rust/src/hal/mod.rs index 4a8d8a9..c995dcf 100644 --- a/Software/MainBoard/rust/src/hal/mod.rs +++ b/Software/MainBoard/rust/src/hal/mod.rs @@ -4,11 +4,13 @@ pub mod esp; mod initial_hal; mod little_fs2storage_adapter; pub(crate) mod rtc; +mod shared_flash; mod v3_hal; mod v3_shift_register; mod v4_hal; pub(crate) mod v4_sensor; mod water; + use crate::alloc::string::ToString; use crate::hal::rtc::{DS3231Module, RTCModuleInteraction}; use esp_hal::peripherals::Peripherals; @@ -79,7 +81,7 @@ use crate::hal::water::TankSensor; use crate::log::LOG_ACCESS; use embassy_sync::mutex::Mutex; use embassy_sync::once_lock::OnceLock; -use embedded_storage::nor_flash::ReadNorFlash; +use embedded_storage::ReadStorage; use esp_alloc as _; use esp_backtrace as _; use esp_bootloader_esp_idf::ota::{Ota, OtaImageState}; @@ -101,6 +103,7 @@ use littlefs2::object_safe::DynStorage; use log::{error, info, warn}; use portable_atomic::AtomicBool; use serde::Serialize; +use shared_flash::MutexFlashStorage; pub static TIME_ACCESS: OnceLock> = OnceLock::new(); @@ -306,7 +309,15 @@ impl PlantHal { [u8; esp_bootloader_esp_idf::partitions::PARTITION_TABLE_MAX_LEN], [0u8; esp_bootloader_esp_idf::partitions::PARTITION_TABLE_MAX_LEN] ); - let flash_storage = mk_static!(FlashStorage, FlashStorage::new(peripherals.FLASH)); + + let bullshit = MutexFlashStorage { + inner: Arc::new(CriticalSectionMutex::new(RefCell::new(FlashStorage::new( + peripherals.FLASH, + )))), + }; + let flash_storage = mk_static!(MutexFlashStorage, bullshit.clone()); + let flash_storage_2 = mk_static!(MutexFlashStorage, bullshit.clone()); + let flash_storage_3 = mk_static!(MutexFlashStorage, bullshit.clone()); let pt = esp_bootloader_esp_idf::partitions::read_partition_table(flash_storage, tablebuffer)?; @@ -320,8 +331,8 @@ impl PlantHal { ); let ota_data = mk_static!( - FlashRegion, - ota_data.as_embedded_storage(flash_storage) + FlashRegion, + ota_data.as_embedded_storage(flash_storage_2) ); let state_0 = ota_state(AppPartitionSubType::Ota0, ota_data); @@ -353,7 +364,7 @@ impl PlantHal { let ota_target = mk_static!(PartitionEntry, ota_target); let ota_target = mk_static!( - FlashRegion, + FlashRegion, ota_target.as_embedded_storage(flash_storage) ); @@ -365,8 +376,8 @@ impl PlantHal { let data_partition = mk_static!(PartitionEntry, data_partition); let data = mk_static!( - FlashRegion, - data_partition.as_embedded_storage(flash_storage) + FlashRegion, + data_partition.as_embedded_storage(flash_storage_3) ); let lfs2filesystem = mk_static!(LittleFs2Filesystem, LittleFs2Filesystem { storage: data }); let alloc = mk_static!(Allocation, lfs2Filesystem::allocate()); @@ -584,15 +595,18 @@ impl PlantHal { } } -fn ota_state(slot: AppPartitionSubType, ota_data: &mut FlashRegion) -> OtaImageState { +fn ota_state( + slot: AppPartitionSubType, + ota_data: &mut FlashRegion, +) -> OtaImageState { // Read and log OTA states for both slots before constructing Ota // Each OTA select entry is 32 bytes: [seq:4][label:20][state:4][crc:4] // Offsets within the OTA data partition: slot0 @ 0x0000, slot1 @ 0x1000 let mut slot_buf = [0u8; 32]; if slot == AppPartitionSubType::Ota0 { - let _ = ota_data.read(0x0000, &mut slot_buf); + let _ = ReadStorage::read(ota_data, 0x0000, &mut slot_buf); } else { - let _ = ota_data.read(0x1000, &mut slot_buf); + let _ = ReadStorage::read(ota_data, 0x1000, &mut slot_buf); } let raw_state = u32::from_le_bytes(slot_buf[24..28].try_into().unwrap_or([0xff; 4])); @@ -600,7 +614,7 @@ fn ota_state(slot: AppPartitionSubType, ota_data: &mut FlashRegion } fn get_current_slot_and_fix_ota_data( - ota: &mut Ota, + ota: &mut Ota, state0: OtaImageState, state1: OtaImageState, ) -> Result { diff --git a/Software/MainBoard/rust/src/hal/shared_flash.rs b/Software/MainBoard/rust/src/hal/shared_flash.rs new file mode 100644 index 0000000..69bd76e --- /dev/null +++ b/Software/MainBoard/rust/src/hal/shared_flash.rs @@ -0,0 +1,63 @@ +use alloc::sync::Arc; +use core::cell::RefCell; +use core::ops::{Deref, DerefMut}; +use embassy_sync::blocking_mutex::CriticalSectionMutex; +use embedded_storage::nor_flash::{ErrorType, NorFlash, ReadNorFlash}; +use embedded_storage::ReadStorage; +use esp_storage::{FlashStorage, FlashStorageError}; + +#[derive(Clone)] +pub struct MutexFlashStorage { + pub(crate) inner: Arc>>>, +} + +impl ReadStorage for MutexFlashStorage { + type Error = FlashStorageError; + + fn read(&mut self, offset: u32, bytes: &mut [u8]) -> Result<(), FlashStorageError> { + self.inner + .lock(|f| ReadStorage::read(f.borrow_mut().deref_mut(), offset, bytes)) + } + + fn capacity(&self) -> usize { + self.inner + .lock(|f| ReadStorage::capacity(f.borrow().deref())) + } +} + +impl embedded_storage::Storage for MutexFlashStorage { + fn write(&mut self, offset: u32, bytes: &[u8]) -> Result<(), Self::Error> { + NorFlash::write(self, offset, bytes) + } +} + +impl ErrorType for MutexFlashStorage { + type Error = FlashStorageError; +} + +impl ReadNorFlash for MutexFlashStorage { + const READ_SIZE: usize = 0; + + fn read(&mut self, offset: u32, bytes: &mut [u8]) -> Result<(), Self::Error> { + ReadStorage::read(self, offset, bytes) + } + + fn capacity(&self) -> usize { + ReadStorage::capacity(self) + } +} + +impl NorFlash for MutexFlashStorage { + const WRITE_SIZE: usize = 0; + const ERASE_SIZE: usize = 0; + + fn erase(&mut self, from: u32, to: u32) -> Result<(), Self::Error> { + self.inner + .lock(|f| NorFlash::erase(f.borrow_mut().deref_mut(), from, to)) + } + + fn write(&mut self, offset: u32, bytes: &[u8]) -> Result<(), Self::Error> { + self.inner + .lock(|f| NorFlash::write(f.borrow_mut().deref_mut(), offset, bytes)) + } +} diff --git a/Software/MainBoard/rust/src/hal/v4_sensor.rs b/Software/MainBoard/rust/src/hal/v4_sensor.rs index d618616..f38a47b 100644 --- a/Software/MainBoard/rust/src/hal/v4_sensor.rs +++ b/Software/MainBoard/rust/src/hal/v4_sensor.rs @@ -101,8 +101,9 @@ impl SensorInteraction for SensorImpl { Timer::after_millis(10).await; let mut moistures = Moistures::default(); - let _ = Self::wait_for_can_measurements(&mut twai, &mut moistures).with_timeout(Duration::from_millis(5000)).await; - + let _ = Self::wait_for_can_measurements(&mut twai, &mut moistures) + .with_timeout(Duration::from_millis(5000)) + .await; can_power.set_low(); @@ -170,7 +171,7 @@ impl SensorImpl { can_power.set_low(); twai_config.replace(config); - let result= moistures.into(); + let result = moistures.into(); info!("Autodetection result: {result:?}"); Ok(result) @@ -182,7 +183,6 @@ impl SensorImpl { as_async: &mut Twai<'_, Async>, moistures: &mut Moistures, ) -> FatResult<()> { - loop { match as_async.receive_async().await { Ok(can_frame) => match can_frame.id() { @@ -200,7 +200,7 @@ impl SensorImpl { let plant = msg.1 as usize; let sensor = msg.2; let data = can_frame.data(); - + match sensor { SensorSlot::A => { moistures.sensor_a_hz[plant] = data[0] as f32; @@ -319,4 +319,4 @@ impl From for DetectionResult { } result } -} \ No newline at end of file +} diff --git a/Software/MainBoard/rust/src/plant_state.rs b/Software/MainBoard/rust/src/plant_state.rs index b4d2cca..87649c6 100644 --- a/Software/MainBoard/rust/src/plant_state.rs +++ b/Software/MainBoard/rust/src/plant_state.rs @@ -120,8 +120,12 @@ impl PlantState { let raw = moistures.sensor_a_hz[plant_id]; match map_range_moisture( raw, - board.board_hal.get_config().plants[plant_id].moisture_sensor_min_frequency.map(|a| a as f32), - board.board_hal.get_config().plants[plant_id].moisture_sensor_max_frequency.map(|b| b as f32), + board.board_hal.get_config().plants[plant_id] + .moisture_sensor_min_frequency + .map(|a| a as f32), + board.board_hal.get_config().plants[plant_id] + .moisture_sensor_max_frequency + .map(|b| b as f32), ) { Ok(moisture_percent) => MoistureSensorState::MoistureValue { raw_hz: raw, @@ -137,8 +141,12 @@ impl PlantState { let raw = moistures.sensor_b_hz[plant_id]; match map_range_moisture( raw, - board.board_hal.get_config().plants[plant_id].moisture_sensor_min_frequency.map(|a| a as f32), - board.board_hal.get_config().plants[plant_id].moisture_sensor_max_frequency.map(|b| b as f32) + board.board_hal.get_config().plants[plant_id] + .moisture_sensor_min_frequency + .map(|a| a as f32), + board.board_hal.get_config().plants[plant_id] + .moisture_sensor_max_frequency + .map(|b| b as f32), ) { Ok(moisture_percent) => MoistureSensorState::MoistureValue { raw_hz: raw, @@ -196,8 +204,12 @@ impl PlantState { (Some(moisture_a), Some(moisture_b)) => { (Some(((moisture_a + moisture_b) / 2.) as u8), (None, None)) } - (Some(moisture_percent), _) => (Some(moisture_percent as u8), (None, self.sensor_b.is_err())), - (_, Some(moisture_percent)) => (Some(moisture_percent as u8), (self.sensor_a.is_err(), None)), + (Some(moisture_percent), _) => { + (Some(moisture_percent as u8), (None, self.sensor_b.is_err())) + } + (_, Some(moisture_percent)) => { + (Some(moisture_percent as u8), (self.sensor_a.is_err(), None)) + } _ => (None, (self.sensor_a.is_err(), self.sensor_b.is_err())), } }