Triple oled #37
Generated
+1
-2
@@ -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",
|
||||||
|
|||||||
@@ -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]
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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>,
|
||||||
@@ -10,3 +16,13 @@ pub struct Outputs {
|
|||||||
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
@@ -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 {
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|
||||||
|
|||||||
@@ -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
@@ -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,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user