Triple oled #37

Merged
ede1998 merged 8 commits from triple-oled into main 2026-08-24 19:59:11 +02:00
10 changed files with 114 additions and 119 deletions
Showing only changes of commit dbbc93b528 - Show all commits
Generated
+1 -2
View File
@@ -1702,8 +1702,7 @@ checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
[[package]] [[package]]
name = "i2c-character-display" name = "i2c-character-display"
version = "0.5.1" version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "git+https://github.com/ede1998/i2c-character-display.git?rev=57aef1f49da183c120b8e995ef77549e3515d3c6#57aef1f49da183c120b8e995ef77549e3515d3c6"
checksum = "86a620ec16541e28c0e52ce21cd23d734a5d7efaae3d609b2a58694b0ef67739"
dependencies = [ dependencies = [
"bitfield 0.17.0", "bitfield 0.17.0",
"embedded-hal 1.0.0", "embedded-hal 1.0.0",
+1
View File
@@ -52,6 +52,7 @@ ch1115 = { version = "0.1.2", features = ["graphics"] }
[patch.crates-io] [patch.crates-io]
ch1115 = { git = "https://github.com/ede1998/ch1115.git", rev = "2d3a3ba38050efe012e6a210afe3e125ec280c37" } ch1115 = { git = "https://github.com/ede1998/ch1115.git", rev = "2d3a3ba38050efe012e6a210afe3e125ec280c37" }
i2c-character-display = { git = "https://github.com/ede1998/i2c-character-display.git", rev = "57aef1f49da183c120b8e995ef77549e3515d3c6" }
# For fine tuning these settings, please refer to https://doc.rust-lang.org/cargo/reference/profiles.html # For fine tuning these settings, please refer to https://doc.rust-lang.org/cargo/reference/profiles.html
[profile.dev] [profile.dev]
+3 -9
View File
@@ -8,8 +8,6 @@ use crate::views::view::View;
use embassy_futures::select::{Either, select}; use embassy_futures::select::{Either, select};
use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex; use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex;
use embassy_time::{Duration, Timer}; use embassy_time::{Duration, Timer};
use embedded_graphics::draw_target::DrawTarget;
use embedded_graphics::pixelcolor::Rgb565;
pub type Mutex<T> = embassy_sync::mutex::Mutex<CriticalSectionRawMutex, T>; pub type Mutex<T> = embassy_sync::mutex::Mutex<CriticalSectionRawMutex, T>;
pub type Signal<T> = embassy_sync::signal::Signal<CriticalSectionRawMutex, T>; pub type Signal<T> = embassy_sync::signal::Signal<CriticalSectionRawMutex, T>;
@@ -29,11 +27,7 @@ pub struct NewState {
} }
pub trait Navigable { pub trait Navigable {
fn display<D>(&self, display: &mut D) -> impl core::future::Future<Output = ()> + Send fn display(&self, outputs: &mut Outputs) -> impl core::future::Future<Output = ()> + Send;
where
D: DrawTarget<Color = Rgb565> + Send,
D::Error: core::fmt::Debug;
// fn display<D>(&self, outputs: &mut Outputs) -> impl core::future::Future<Output = ()> + Send;
fn handle_input(&self, input: Action) -> impl core::future::Future<Output = NewState> + Send; fn handle_input(&self, input: Action) -> impl core::future::Future<Output = NewState> + Send;
} }
@@ -42,7 +36,7 @@ pub async fn run(mut inputs: Inputs, mut outputs: Outputs) {
log::info!("starting navigation"); log::info!("starting navigation");
let mut state = NavigationState::new(); let mut state = NavigationState::new();
state.screens.last().unwrap().display(&mut outputs.primary_display).await; state.screens.last().unwrap().display(&mut outputs).await;
loop { loop {
let selection = select( let selection = select(
@@ -88,7 +82,7 @@ pub async fn run(mut inputs: Inputs, mut outputs: Outputs) {
state.screens.push(new_state.view); state.screens.push(new_state.view);
if action != Action::Timer || new_state.redraw { if action != Action::Timer || new_state.redraw {
state.screens.last().unwrap().display(&mut outputs.primary_display).await; state.screens.last().unwrap().display(&mut outputs).await;
} }
Timer::after(Duration::from_millis(DEBOUNCE_DURATION_MILLIS)).await; Timer::after(Duration::from_millis(DEBOUNCE_DURATION_MILLIS)).await;
+19 -3
View File
@@ -1,6 +1,12 @@
use crate::display::{shared_bus::{DualPrimaryDisplay, DualSecondaryDisplay}, tertiary_lcd::TertiaryI2cLcd}; use embedded_graphics::{
draw_target::DrawTarget as _,
pixelcolor::{Rgb565, RgbColor as _},
};
use crate::display::{
shared_bus::{DualPrimaryDisplay, DualSecondaryDisplay},
tertiary_lcd::TertiaryI2cLcd,
};
pub struct Outputs { pub struct Outputs {
pub primary_display: DualPrimaryDisplay<'static>, pub primary_display: DualPrimaryDisplay<'static>,
@@ -9,4 +15,14 @@ pub struct Outputs {
// pub secondary_display_3: DualSecondaryDisplay<'static>, // pub secondary_display_3: DualSecondaryDisplay<'static>,
pub tertiary_display: TertiaryI2cLcd<'static>, pub tertiary_display: TertiaryI2cLcd<'static>,
pub _led_a: (), pub _led_a: (),
} }
impl Outputs {
pub fn clear_screens(&mut self) {
self.primary_display.clear(Rgb565::BLACK).unwrap();
self.secondary_display_1.clear().unwrap();
// self.secondary_display_2.clear().unwrap();
// self.secondary_display_3.clear().unwrap();
self.tertiary_display.clear().unwrap();
}
}
+68 -70
View File
@@ -1,5 +1,6 @@
use crate::display::sprite::render_sprite_onto_ili9341; use crate::display::sprite::render_sprite_onto_ili9341;
use crate::navigation::navigation::NewState; use crate::navigation::navigation::NewState;
use crate::navigation::outputs::Outputs;
use alloc::format; use alloc::format;
use embedded_graphics::mono_font::MonoTextStyle; use embedded_graphics::mono_font::MonoTextStyle;
use embedded_graphics::mono_font::ascii::FONT_6X10; use embedded_graphics::mono_font::ascii::FONT_6X10;
@@ -24,80 +25,77 @@ pub struct CardView {
} }
impl Navigable for CardView { impl Navigable for CardView {
fn display<D>(&self, display: &mut D) -> impl core::future::Future<Output = ()> + Send fn display(&self, outputs: &mut Outputs) -> impl core::future::Future<Output = ()> + Send {
where async move {
D: DrawTarget<Color = Rgb565>, let display = &mut outputs.primary_display;
D::Error: core::fmt::Debug, display.clear(Rgb565::BLACK).unwrap();
{
display.clear(Rgb565::BLACK).unwrap();
let background = Rectangle::new(Point::new(0, 0), Size::new(240, 320)); let background = Rectangle::new(Point::new(0, 0), Size::new(240, 320));
let bg_color = self.card.cardtype.clone().into(); let bg_color = self.card.cardtype.clone().into();
let _ = display.fill_solid(&background, bg_color); let _ = display.fill_solid(&background, bg_color);
let style = MonoTextStyle::new(&FONT_6X10, Rgb565::WHITE); let style = MonoTextStyle::new(&FONT_6X10, Rgb565::WHITE);
Text::new( Text::new(
&format!("Name: {}", self.card.name), &format!("Name: {}", self.card.name),
Point::new(20, 240), Point::new(20, 240),
style, style,
) )
.draw(display) .draw(display)
.unwrap(); .unwrap();
Text::new( Text::new(
&format!("Type: {}", self.card.cardtype), &format!("Type: {}", self.card.cardtype),
Point::new(20, 250), Point::new(20, 250),
style, style,
) )
.draw(display) .draw(display)
.unwrap(); .unwrap();
Text::new( Text::new(
&format!("Event: {}", self.card.event), &format!("Event: {}", self.card.event),
Point::new(20, 260), Point::new(20, 260),
style, style,
) )
.draw(display) .draw(display)
.unwrap(); .unwrap();
Text::new( Text::new(
&format!("UUID: {}", self.card.uuid), &format!("UUID: {}", self.card.uuid),
Point::new(20, 270), Point::new(20, 270),
style, style,
) )
.draw(display) .draw(display)
.unwrap(); .unwrap();
Text::new( Text::new(
&format!("Trait1: {}", self.card.trait1), &format!("Trait1: {}", self.card.trait1),
Point::new(20, 280), Point::new(20, 280),
style, style,
) )
.draw(display) .draw(display)
.unwrap(); .unwrap();
Text::new( Text::new(
&format!("Trait2: {}", self.card.trait2), &format!("Trait2: {}", self.card.trait2),
Point::new(20, 290), Point::new(20, 290),
style, style,
) )
.draw(display) .draw(display)
.unwrap(); .unwrap();
Text::new( Text::new(
&format!("Trait3: {}", self.card.trait3), &format!("Trait3: {}", self.card.trait3),
Point::new(20, 300), Point::new(20, 300),
style, style,
) )
.draw(display) .draw(display)
.unwrap(); .unwrap();
Text::new( Text::new(
&format!("Secret: {}", self.card.secret), &format!("Secret: {}", self.card.secret),
Point::new(20, 310), Point::new(20, 310),
style, style,
) )
.draw(display) .draw(display)
.unwrap(); .unwrap();
let palette: Palette = self.card.cardtype.clone().into(); let palette: Palette = self.card.cardtype.clone().into();
render_sprite_onto_ili9341(display, self.card.sprite.data.as_slice(), &palette); render_sprite_onto_ili9341(display, self.card.sprite.data.as_slice(), &palette);
}
core::future::ready(())
} }
fn handle_input(&self, input: Action) -> impl core::future::Future<Output = NewState> + Send { fn handle_input(&self, input: Action) -> impl core::future::Future<Output = NewState> + Send {
+5 -11
View File
@@ -7,9 +7,7 @@ use embedded_graphics::prelude::RgbColor;
use embedded_graphics_core::draw_target::DrawTarget; use embedded_graphics_core::draw_target::DrawTarget;
use crate::{ use crate::{
card::model::Card, card::model::Card, navigation::{navigation::{Action, Navigable, NewState}, outputs::Outputs}, views::view::View,
navigation::navigation::{Action, Navigable, NewState},
views::view::View,
}; };
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
@@ -19,14 +17,10 @@ pub struct JournalView {
} }
impl Navigable for JournalView { impl Navigable for JournalView {
fn display<D>(&self, display: &mut D) -> impl core::future::Future<Output = ()> + Send fn display(&self, outputs: &mut Outputs) -> impl core::future::Future<Output = ()> + Send {
where async move {
D: DrawTarget<Color = Rgb565>, outputs.primary_display.clear(Rgb565::BLACK).unwrap();
D::Error: core::fmt::Debug, }
{
display.clear(Rgb565::BLACK).unwrap();
core::future::ready(())
} }
fn handle_input(&self, input: Action) -> impl core::future::Future<Output = NewState> + Send { fn handle_input(&self, input: Action) -> impl core::future::Future<Output = NewState> + Send {
+3 -4
View File
@@ -4,6 +4,7 @@ use crate::card::model::Card;
use crate::card::{decoder::split_nfc_hex, mock::*}; use crate::card::{decoder::split_nfc_hex, mock::*};
use crate::navigation::inputs::ButtonAction; use crate::navigation::inputs::ButtonAction;
use crate::navigation::outputs::Outputs;
use crate::views::card_view::CardView; use crate::views::card_view::CardView;
use crate::views::journal_view::JournalView; use crate::views::journal_view::JournalView;
use crate::views::{menu_item, settings_menu::SettingsMenu, view::View}; use crate::views::{menu_item, settings_menu::SettingsMenu, view::View};
@@ -21,11 +22,9 @@ pub struct MainMenu {
} }
impl Navigable for MainMenu { impl Navigable for MainMenu {
fn display<D>(&self, display: &mut D) -> impl core::future::Future<Output = ()> + Send fn display(&self, outputs: &mut Outputs) -> impl core::future::Future<Output = ()> + Send
where
D: DrawTarget<Color = Rgb565>,
D::Error: core::fmt::Debug,
{ {
let display = &mut outputs.primary_display;
display.clear(Rgb565::BLACK).unwrap(); display.clear(Rgb565::BLACK).unwrap();
menu_item::show(display, "Scan card", 0, self.selected); menu_item::show(display, "Scan card", 0, self.selected);
+4 -4
View File
@@ -1,10 +1,12 @@
use crate::navigation::inputs::ButtonAction; use crate::navigation::inputs::ButtonAction;
use crate::navigation::navigation::CARD_DATA; use crate::navigation::navigation::CARD_DATA;
use crate::navigation::navigation::NewState; use crate::navigation::navigation::NewState;
use crate::navigation::outputs::Outputs;
use alloc::format; use alloc::format;
use embedded_graphics::Drawable; use embedded_graphics::Drawable;
use embedded_graphics::geometry::AngleUnit as _; use embedded_graphics::geometry::AngleUnit as _;
use embedded_graphics::geometry::Dimensions as _;
use embedded_graphics::geometry::Size; use embedded_graphics::geometry::Size;
use embedded_graphics::mono_font::MonoTextStyle; use embedded_graphics::mono_font::MonoTextStyle;
use embedded_graphics::mono_font::ascii::FONT_10X20; use embedded_graphics::mono_font::ascii::FONT_10X20;
@@ -31,11 +33,9 @@ pub struct ScanMenu {
} }
impl Navigable for ScanMenu { impl Navigable for ScanMenu {
fn display<D>(&self, display: &mut D) -> impl core::future::Future<Output = ()> + Send fn display(&self, outputs: &mut Outputs) -> impl core::future::Future<Output = ()> + Send
where
D: DrawTarget<Color = Rgb565>,
D::Error: core::fmt::Debug,
{ {
let display = &mut outputs.primary_display;
let style = MonoTextStyle::new(&FONT_10X20, Rgb565::WHITE); let style = MonoTextStyle::new(&FONT_10X20, Rgb565::WHITE);
display.clear(Rgb565::BLACK).unwrap(); display.clear(Rgb565::BLACK).unwrap();
+3 -5
View File
@@ -1,4 +1,5 @@
use crate::navigation::navigation::{Action, Navigable, NewState}; use crate::navigation::navigation::{Action, Navigable, NewState};
use crate::navigation::outputs::Outputs;
use crate::views::{menu_item, view::View}; use crate::views::{menu_item, view::View};
use embedded_graphics::pixelcolor::Rgb565; use embedded_graphics::pixelcolor::Rgb565;
@@ -12,11 +13,8 @@ pub struct SettingsMenu {
} }
impl Navigable for SettingsMenu { impl Navigable for SettingsMenu {
fn display<D>(&self, display: &mut D) -> impl core::future::Future<Output = ()> + Send fn display(&self, outputs: &mut Outputs) -> impl core::future::Future<Output = ()> + Send {
where let display = &mut outputs.primary_display;
D: DrawTarget<Color = Rgb565>,
D::Error: core::fmt::Debug,
{
display.clear(Rgb565::BLACK).unwrap(); display.clear(Rgb565::BLACK).unwrap();
menu_item::show(display, "System Inforation", 0, self.selected); menu_item::show(display, "System Inforation", 0, self.selected);
menu_item::show(display, "Wifi Information", 1, self.selected); menu_item::show(display, "Wifi Information", 1, self.selected);
+7 -11
View File
@@ -1,6 +1,5 @@
use embedded_graphics::draw_target::DrawTarget;
use embedded_graphics::pixelcolor::Rgb565;
use crate::navigation::outputs::Outputs;
use crate::views::card_view::CardView; use crate::views::card_view::CardView;
use crate::views::{ use crate::views::{
journal_view::JournalView, main_menu::MainMenu, scan_menu::ScanMenu, journal_view::JournalView, main_menu::MainMenu, scan_menu::ScanMenu,
@@ -19,18 +18,15 @@ pub enum View {
} }
impl Navigable for View { impl Navigable for View {
fn display<D>(&self, display: &mut D) -> impl core::future::Future<Output = ()> + Send fn display(&self, outputs: &mut Outputs) -> impl core::future::Future<Output = ()> + Send
where
D: DrawTarget<Color = Rgb565> + Send,
D::Error: core::fmt::Debug,
{ {
async move { async move {
match self { match self {
View::Main(main_menu) => main_menu.display(display).await, View::Main(main_menu) => main_menu.display(outputs).await,
View::Scan(scan_menu) => scan_menu.display(display).await, View::Scan(scan_menu) => scan_menu.display(outputs).await,
View::Settings(settings_menu) => settings_menu.display(display).await, View::Settings(settings_menu) => settings_menu.display(outputs).await,
View::Journal(journal_view) => journal_view.display(display).await, View::Journal(journal_view) => journal_view.display(outputs).await,
View::Card(card_view) => card_view.display(display).await, View::Card(card_view) => card_view.display(outputs).await,
} }
} }
} }