From 153acffb8684c9ca0de88f03a915d54479252193 Mon Sep 17 00:00:00 2001 From: rhetenor Date: Sat, 29 Aug 2026 21:09:09 +0000 Subject: [PATCH] display views: return error instead of unwrapping --- src/drivers/primary_lcd.rs | 22 +++++++++++++- src/views/card_view.rs | 21 +++++++------ src/views/flash_info_view.rs | 57 +++++++++++++++++++++++++++++++----- src/views/journal_view.rs | 8 +++-- src/views/main_menu.rs | 14 +++++---- src/views/menu_item.rs | 9 ++---- src/views/scan_menu.rs | 11 ++++--- src/views/settings_menu.rs | 10 +++++-- src/views/status_bar.rs | 2 -- 9 files changed, 114 insertions(+), 40 deletions(-) diff --git a/src/drivers/primary_lcd.rs b/src/drivers/primary_lcd.rs index 34a4a8c..c497274 100644 --- a/src/drivers/primary_lcd.rs +++ b/src/drivers/primary_lcd.rs @@ -1,3 +1,6 @@ +use core::error::Error; +use core::fmt::Debug; +use core::fmt::Display; use display_interface_spi::SPIInterface; use embedded_graphics::draw_target::DrawTarget; use embedded_graphics::pixelcolor::Rgb565; @@ -6,10 +9,27 @@ use embedded_hal_bus::spi::AtomicDevice; use embedded_hal_bus::util::AtomicCell; use esp_hal::delay::Delay; use esp_hal::gpio::Output; -use ili9341::{DisplaySize240x320, Ili9341, Orientation}; +use ili9341::{DisplayError, DisplaySize240x320, Ili9341, Orientation}; use crate::drivers::spi_bus::{DisplaySpiBus, SharedOutput}; +#[derive(Debug)] +pub struct PrimaryDisplayError(DisplayError); + +impl Display for PrimaryDisplayError { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + self.0.fmt(f) + } +} + +impl Error for PrimaryDisplayError {} + +impl From for PrimaryDisplayError { + fn from(value: DisplayError) -> Self { + Self(value) + } +} + type GenericPrimaryDisplay<'a, BUS, DC, RES> = Ili9341, Delay>, DC>, RES>; pub type PrimaryDisplay<'a> = diff --git a/src/views/card_view.rs b/src/views/card_view.rs index 65651b6..d67ff56 100644 --- a/src/views/card_view.rs +++ b/src/views/card_view.rs @@ -1,4 +1,5 @@ use crate::display::sprite::render_sprite_onto_ili9341; +use crate::drivers::primary_lcd::PrimaryDisplayError; use crate::navigation::navigation::NewState; use crate::navigation::outputs::Outputs; use crate::peripherals::Peripherals; @@ -35,7 +36,9 @@ impl Navigable for CardView { ) -> impl core::future::Future>> + Send { async move { let display = &mut outputs.primary_display; - display.clear(Rgb565::BLACK).unwrap(); + display + .clear(Rgb565::BLACK) + .map_err(PrimaryDisplayError::from)?; let background = Rectangle::new(Point::new(0, 0), Size::new(240, 320)); let bg_color = self.card.cardtype.clone().into(); @@ -49,56 +52,56 @@ impl Navigable for CardView { style, ) .draw(display) - .unwrap(); + .map_err(PrimaryDisplayError::from)?; Text::new( &format!("Type: {}", self.card.cardtype), Point::new(20, 250), style, ) .draw(display) - .unwrap(); + .map_err(PrimaryDisplayError::from)?; Text::new( &format!("Event: {}", self.card.event), Point::new(20, 260), style, ) .draw(display) - .unwrap(); + .map_err(PrimaryDisplayError::from)?; Text::new( &format!("UUID: {}", self.card.uuid), Point::new(20, 270), style, ) .draw(display) - .unwrap(); + .map_err(PrimaryDisplayError::from)?; Text::new( &format!("Trait1: {}", self.card.trait1), Point::new(20, 280), style, ) .draw(display) - .unwrap(); + .map_err(PrimaryDisplayError::from)?; Text::new( &format!("Trait2: {}", self.card.trait2), Point::new(20, 290), style, ) .draw(display) - .unwrap(); + .map_err(PrimaryDisplayError::from)?; Text::new( &format!("Trait3: {}", self.card.trait3), Point::new(20, 300), style, ) .draw(display) - .unwrap(); + .map_err(PrimaryDisplayError::from)?; Text::new( &format!("Secret: {}", self.card.secret), Point::new(20, 310), style, ) .draw(display) - .unwrap(); + .map_err(PrimaryDisplayError::from)?; let palette: Palette = self.card.cardtype.clone().into(); render_sprite_onto_ili9341(display, self.card.sprite.data.as_slice(), &palette); diff --git a/src/views/flash_info_view.rs b/src/views/flash_info_view.rs index 2299eb5..e9ccb02 100644 --- a/src/views/flash_info_view.rs +++ b/src/views/flash_info_view.rs @@ -1,21 +1,30 @@ +use crate::drivers::primary_lcd::PrimaryDisplayError; use crate::navigation::navigation::Action; use crate::navigation::navigation::Navigable; use crate::navigation::navigation::NewState; use crate::navigation::outputs::Outputs; use crate::peripherals::Peripherals; use crate::peripherals::storage::MAGIC_REGION; +use crate::peripherals::storage::cardstore::COUNT_REGION; use crate::views::view::View; use alloc::boxed::Box; use core::error; -use embedded_graphics::mono_font::MonoTextStyle; -use embedded_graphics::mono_font::ascii::FONT_10X20; -use embedded_graphics::pixelcolor::Rgb565; -use embedded_graphics::prelude::DrawTarget; -use embedded_graphics::prelude::RgbColor; -use embedded_graphics::text::Text; - use embedded_graphics::prelude::Point; +use embedded_graphics::{ + Drawable, + mono_font::{MonoTextStyle, ascii::FONT_10X20}, + pixelcolor::Rgb565, + prelude::*, + primitives::Rectangle, + text::Text, +}; +use alloc::format; +use embedded_text::{ + TextBox, + alignment::HorizontalAlignment, + style::{HeightMode, TextBoxStyleBuilder}, +}; #[derive(Debug, Clone)] pub struct FlashInfoView {} @@ -35,7 +44,39 @@ impl Navigable for FlashInfoView { .flash_store .read(MAGIC_REGION.offset, &mut magic_bytes) .await?; - Text::new("Flash Initialized: {:?}", Point::new(40, 40), style); + let mut card_count_bytes: [u8; COUNT_REGION.size] = [0; COUNT_REGION.size]; + peripherals + .store + .lock() + .await + .flash_store + .read(COUNT_REGION.offset, &mut card_count_bytes) + .await?; + + let style = MonoTextStyle::new(&FONT_10X20, Rgb565::WHITE); + let textbox_style = TextBoxStyleBuilder::new() + .height_mode(HeightMode::FitToText) + .alignment(HorizontalAlignment::Center) + .build(); + + let display_area = outputs.primary_display.bounding_box(); + let bounds = Rectangle::new(Point::new(0, 30), display_area.size); + + TextBox::with_textbox_style( + &format!( + " +Flash Init Magic: 0x{:x}\n +Card Count: {}\n +", + u32::from_le_bytes(magic_bytes), + u32::from_le_bytes(card_count_bytes) + ), + bounds, + style, + textbox_style, + ) + .draw(&mut outputs.primary_display) + .map_err(PrimaryDisplayError::from)?; Ok(()) } } diff --git a/src/views/journal_view.rs b/src/views/journal_view.rs index 61b6fcb..4b5dd4b 100644 --- a/src/views/journal_view.rs +++ b/src/views/journal_view.rs @@ -1,6 +1,7 @@ +use crate::drivers::primary_lcd::PrimaryDisplayError; +use crate::peripherals::Peripherals; use alloc::boxed::Box; use core::error; -use crate::peripherals::Peripherals; use core::future; use alloc::vec::Vec; @@ -31,7 +32,10 @@ impl Navigable for JournalView { _: &Peripherals, ) -> impl core::future::Future>> + Send { async move { - outputs.primary_display.clear(Rgb565::BLACK).unwrap(); + outputs + .primary_display + .clear(Rgb565::BLACK) + .map_err(PrimaryDisplayError::from)?; Ok(()) } } diff --git a/src/views/main_menu.rs b/src/views/main_menu.rs index 2c50eb6..2d562da 100644 --- a/src/views/main_menu.rs +++ b/src/views/main_menu.rs @@ -1,3 +1,4 @@ +use crate::drivers::primary_lcd::PrimaryDisplayError; use crate::peripherals::Peripherals; use alloc::boxed::Box; use alloc::vec; @@ -17,7 +18,6 @@ use embedded_graphics::pixelcolor::Rgb565; use embedded_graphics::prelude::RgbColor; use embedded_graphics_core::draw_target::DrawTarget; -use crate::peripherals::storage::cardstore::CardStoreError; pub const MAX_SELECTED: i32 = 4; #[derive(Debug, Clone)] @@ -35,10 +35,14 @@ impl Navigable for MainMenu { let display = &mut outputs.primary_display; display.clear(Rgb565::BLACK).unwrap(); - menu_item::show(display, "Scan card", 0, self.selected); - menu_item::show(display, "Last card", 1, self.selected); - menu_item::show(display, "Journal", 2, self.selected); - menu_item::show(display, "Settings", 3, self.selected); + menu_item::show(display, "Scan card", 0, self.selected) + .map_err(PrimaryDisplayError::from)?; + menu_item::show(display, "Last card", 1, self.selected) + .map_err(PrimaryDisplayError::from)?; + menu_item::show(display, "Journal", 2, self.selected) + .map_err(PrimaryDisplayError::from)?; + menu_item::show(display, "Settings", 3, self.selected) + .map_err(PrimaryDisplayError::from)?; Ok(()) } diff --git a/src/views/menu_item.rs b/src/views/menu_item.rs index 3a040f0..588e3b0 100644 --- a/src/views/menu_item.rs +++ b/src/views/menu_item.rs @@ -1,6 +1,3 @@ -use alloc::boxed::Box; -use core::error; -use crate::peripherals::Peripherals; use embedded_graphics::Drawable; use embedded_graphics::draw_target::DrawTarget; use embedded_graphics::mono_font::MonoTextStyle; @@ -10,7 +7,7 @@ use embedded_graphics::prelude::Point; use embedded_graphics::prelude::RgbColor; use embedded_graphics::text::Text; -pub fn show(display: &mut D, name: &str, position: i32, selected: i32) +pub fn show(display: &mut D, name: &str, position: i32, selected: i32) -> Result<(), D::Error> where D: DrawTarget, D::Error: core::fmt::Debug, @@ -27,6 +24,6 @@ where style }, ) - .draw(display) - .unwrap(); + .draw(display)?; + Ok(()) } diff --git a/src/views/scan_menu.rs b/src/views/scan_menu.rs index 1fe434f..1d6c3a3 100644 --- a/src/views/scan_menu.rs +++ b/src/views/scan_menu.rs @@ -1,3 +1,4 @@ +use crate::drivers::primary_lcd::PrimaryDisplayError; use crate::navigation::inputs::ButtonAction; use crate::navigation::navigation::CARD_DATA; use crate::navigation::navigation::NewState; @@ -44,13 +45,15 @@ impl Navigable for ScanMenu { async move { let display = &mut outputs.primary_display; let style = MonoTextStyle::new(&FONT_10X20, Rgb565::WHITE); - display.clear(Rgb565::BLACK).unwrap(); + display + .clear(Rgb565::BLACK) + .map_err(PrimaryDisplayError::from)?; let display_area = display.bounding_box(); Text::new("Scanning...", Point::new(20, 30), style) .draw(display) - .unwrap(); + .map_err(PrimaryDisplayError::from)?; // Create styles used by the drawing operations. let arc_stroke = PrimitiveStyleBuilder::new() @@ -80,13 +83,13 @@ impl Navigable for ScanMenu { ) .into_styled(arc_stroke) .draw(display) - .unwrap(); + .map_err(PrimaryDisplayError::from)?; // Draw centered text. let text = format!("{:.2}%", 100. * (self.progress as f32) / 255.); Text::with_text_style(&text, display_area.center(), character_style, text_style) .draw(display) - .unwrap(); + .map_err(PrimaryDisplayError::from)?; Ok(()) } } diff --git a/src/views/settings_menu.rs b/src/views/settings_menu.rs index 9bcf327..47ceee1 100644 --- a/src/views/settings_menu.rs +++ b/src/views/settings_menu.rs @@ -1,3 +1,4 @@ +use crate::drivers::primary_lcd::PrimaryDisplayError; use crate::navigation::navigation::{Action, Navigable, NewState}; use crate::navigation::outputs::Outputs; use crate::peripherals::Peripherals; @@ -27,9 +28,12 @@ impl Navigable for SettingsMenu { async move { let display = &mut outputs.primary_display; display.clear(Rgb565::BLACK).unwrap(); - menu_item::show(display, "System Inforation", 0, self.selected); - menu_item::show(display, "Wifi Information", 1, self.selected); - menu_item::show(display, "Flash Information", 2, self.selected); + menu_item::show(display, "System Inforation", 0, self.selected) + .map_err(PrimaryDisplayError::from)?; + menu_item::show(display, "Wifi Information", 1, self.selected) + .map_err(PrimaryDisplayError::from)?; + menu_item::show(display, "Flash Information", 2, self.selected) + .map_err(PrimaryDisplayError::from)?; Ok(()) } } diff --git a/src/views/status_bar.rs b/src/views/status_bar.rs index c274545..0233e40 100644 --- a/src/views/status_bar.rs +++ b/src/views/status_bar.rs @@ -1,3 +1 @@ -use alloc::boxed::Box; -use core::error; // Status bar view module -- 2.39.5