From 3c657045caa26f5c88f5610eb9e0e29341da0302 Mon Sep 17 00:00:00 2001 From: rhetenor Date: Sun, 30 Aug 2026 08:53:37 +0000 Subject: [PATCH] pass outputs and state to nfc task so that they can show errors on their own --- src/background_tasks/nfc.rs | 18 +++++- src/bin/main.rs | 11 ++-- src/navigation/navigation.rs | 86 ++++++++++++++++---------- src/peripherals/storage/flash_store.rs | 5 +- src/views/error_view.rs | 2 +- 5 files changed, 79 insertions(+), 43 deletions(-) diff --git a/src/background_tasks/nfc.rs b/src/background_tasks/nfc.rs index e659aaf..5aed664 100644 --- a/src/background_tasks/nfc.rs +++ b/src/background_tasks/nfc.rs @@ -1,4 +1,9 @@ -use crate::peripherals::Peripherals; +use crate::navigation::navigation::display_error; +use crate::{ + navigation::{navigation::Mutex, outputs::Outputs, state::NavigationState}, + peripherals::Peripherals, +}; +use alloc::string::ToString; use embedded_hal_bus::i2c::AtomicDevice; use esp_hal::{Blocking, i2c::master::I2c, time::Instant}; @@ -15,7 +20,9 @@ use crate::{ )] pub async fn nfc_scanner( mut nfc_driver: NfcPn532Driver>>, + outputs: &'static Mutex, peripherals: &'static Peripherals, + navigation_state: &'static Mutex, ) { loop { while CARD_DATA.lock().await.is_none() { @@ -45,7 +52,14 @@ pub async fn nfc_scanner( { Ok(()) => {} Err(error) => { - log::error!("Error storing card in flash: {:?}", error) + log::error!("Error storing card in flash: {:?}", error); + display_error( + error.to_string(), + navigation_state, + outputs, + peripherals, + ) + .await; } } diff --git a/src/bin/main.rs b/src/bin/main.rs index f001eee..e833a09 100644 --- a/src/bin/main.rs +++ b/src/bin/main.rs @@ -20,6 +20,7 @@ use creaturedex::drivers::tertiary_lcd::{ use creaturedex::navigation::navigation::Mutex; use creaturedex::navigation::inputs::Inputs; use creaturedex::navigation::navigation::{self}; +use creaturedex::navigation::state::NavigationState; use creaturedex::navigation::outputs::Outputs; use creaturedex::peripherals::Peripherals; use creaturedex::peripherals::storage::cardstore::CardStore; @@ -163,7 +164,7 @@ async fn main(spawner: Spawner) { display_shit(&mut secondaries[2], "baz 1"); display_shit_prim(&mut primary, "Hello World"); - let outputs = { + let outputs = Box::leak(Box::new(Mutex::new({ let [sec_1, sec_2, sec_3] = secondaries; Outputs { primary_display: primary, @@ -173,12 +174,14 @@ async fn main(spawner: Spawner) { tertiary_display: lcd, _led_a: (), } - }; + }))); + + let navigation_state = Box::leak(Box::new(Mutex::new(NavigationState::new()))); log::info!("Setup complete, entering main loop"); - spawner.spawn(navigation::run(inputs, outputs, peripherals).expect("run task failed")); + spawner.spawn(navigation::run(inputs, outputs, peripherals, navigation_state).expect("run task failed")); spawner.spawn( - background_tasks::nfc_scanner(nfc_driver, peripherals).expect("nfc scanner task failed"), + background_tasks::nfc_scanner(nfc_driver, outputs, peripherals, navigation_state).expect("nfc scanner task failed"), ); core::future::pending::<()>().await } diff --git a/src/navigation/navigation.rs b/src/navigation/navigation.rs index b7aa9e0..f05febf 100644 --- a/src/navigation/navigation.rs +++ b/src/navigation/navigation.rs @@ -41,43 +41,56 @@ pub trait Navigable { fn handle_input(&self, input: Action) -> impl core::future::Future + Send; } -#[embassy_executor::task] -pub async fn run(mut inputs: Inputs, mut outputs: Outputs, peripherals: &'static Peripherals) { - async fn display_error( - error: String, - state: &mut NavigationState, - outputs: &mut Outputs, - peripherals: &Peripherals, - ) -> () { - let error_view = ErrorView { - error: error.to_string(), - }; - state.screens.push(View::Error(error_view)); - state - .screens - .last() - // Unwrap: we just pushed the state - .unwrap() - .display(outputs, peripherals) - .await - // Unwrap: display will panic on error in error view - .unwrap(); - } - - log::info!("starting navigation"); - - let mut state = NavigationState::new(); - if let Err(error) = state +pub async fn display_error( + error: String, + navigation_state: &Mutex, + outputs: &Mutex, + peripherals: &Peripherals, +) -> () { + let error_view = ErrorView { + error: error.to_string(), + }; + let mut state = navigation_state.lock().await; + state.screens.push(View::Error(error_view)); + let mut outs = outputs.lock().await; + state .screens .last() + // Unwrap: we just pushed the state .unwrap() - .display(&mut outputs, peripherals) + .display(&mut outs, peripherals) .await + // Unwrap: display will panic on error in error view + .unwrap(); +} + +#[embassy_executor::task] +pub async fn run( + mut inputs: Inputs, + mut outputs: &'static Mutex, + peripherals: &'static Peripherals, + navigation_state: &'static Mutex, +) { + log::info!("starting navigation"); + { - display_error(error.to_string(), &mut state, &mut outputs, peripherals).await; - }; + let mut outs = outputs.lock().await; + if let Err(error) = navigation_state + .lock() + .await + .screens + .last() + .unwrap() + .display(&mut outs, peripherals) + .await + { + display_error(error.to_string(), &navigation_state, &outputs, peripherals).await; + }; + } loop { + Timer::after(Duration::from_millis(DEBOUNCE_DURATION_MILLIS)).await; + let mut state = navigation_state.lock().await; let selection = select( inputs.wait_for_press(), Timer::after(Duration::from_millis(DEBOUNCE_DURATION_MILLIS)), @@ -120,17 +133,22 @@ pub async fn run(mut inputs: Inputs, mut outputs: Outputs, peripherals: &'static } state.screens.push(new_state.view); + let mut outs = outputs.lock().await; if (action != Action::Timer || new_state.redraw) && let Err(error) = state .screens .last() .unwrap() - .display(&mut outputs, peripherals) + .display(&mut outs, peripherals) .await { - display_error(error.to_string(), &mut state, &mut outputs, peripherals).await; + display_error( + error.to_string(), + &navigation_state, + &mut outputs, + peripherals, + ) + .await; } - - Timer::after(Duration::from_millis(DEBOUNCE_DURATION_MILLIS)).await; } } diff --git a/src/peripherals/storage/flash_store.rs b/src/peripherals/storage/flash_store.rs index e99d99f..1bbb564 100644 --- a/src/peripherals/storage/flash_store.rs +++ b/src/peripherals/storage/flash_store.rs @@ -21,8 +21,9 @@ impl Error for FlashStoreError {} impl Display for FlashStoreError { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - use core::fmt::Debug; - self.0.fmt(f) + match self { + err => write!(f, "FlashStoreError:\n{:?}", err.0), + } } } diff --git a/src/views/error_view.rs b/src/views/error_view.rs index cac0274..2524f69 100644 --- a/src/views/error_view.rs +++ b/src/views/error_view.rs @@ -64,7 +64,7 @@ impl Navigable for ErrorView { .alignment(HorizontalAlignment::Center) .build(); - let bounds = Rectangle::new(Point::new(0, 30), display_area.size); + let bounds = Rectangle::new(Point::new(0, 50), display_area.size); TextBox::with_textbox_style(&self.error.to_string(), bounds, style, textbox_style) .draw(&mut outputs.primary_display)