wip: add flash info view
This commit was merged in pull request #45.
This commit is contained in:
@@ -1,4 +1,6 @@
|
||||
use crate::storage::cardstore::CardStore;
|
||||
use embedded_hal_bus::i2c::AtomicDevice;
|
||||
use esp_hal::rtc_cntl::Rtc;
|
||||
use esp_hal::{Blocking, i2c::master::I2c, time::Instant};
|
||||
|
||||
use crate::{
|
||||
@@ -14,6 +16,8 @@ use crate::{
|
||||
)]
|
||||
pub async fn nfc_scanner(
|
||||
mut nfc_driver: NfcPn532Driver<AtomicDevice<'static, I2c<'static, Blocking>>>,
|
||||
mut card_store: CardStore,
|
||||
rtc: Rtc<'static>,
|
||||
) {
|
||||
loop {
|
||||
while CARD_DATA.lock().await.is_none() {
|
||||
@@ -24,10 +28,22 @@ pub async fn nfc_scanner(
|
||||
log::error!("Failed to split NFC card data");
|
||||
continue;
|
||||
};
|
||||
CARD_DATA
|
||||
.lock()
|
||||
.await
|
||||
.replace(Card::try_from(split_data).unwrap());
|
||||
let card = match Card::try_from(split_data) {
|
||||
Ok(card) => card,
|
||||
Err(err) => {
|
||||
log::error!("Invalid card data: {err}");
|
||||
continue;
|
||||
}
|
||||
};
|
||||
CARD_DATA.lock().await.replace(card);
|
||||
|
||||
match card_store.save_raw_card(split_data, rtc.current_time_us()) {
|
||||
Ok(()) => {}
|
||||
Err(error) => {
|
||||
log::error!("Error storing card in flash: {:?}", error)
|
||||
}
|
||||
}
|
||||
|
||||
let elapsed_ms = start.elapsed().as_millis();
|
||||
log::info!(
|
||||
"NFC read duration: {} ms, card data length: {}",
|
||||
@@ -35,8 +51,8 @@ pub async fn nfc_scanner(
|
||||
card_data.len()
|
||||
);
|
||||
}
|
||||
Err(e) => {
|
||||
log::error!("NFC read failed: {e}");
|
||||
Err(_) => {
|
||||
log::info!("No NFC card found");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+6
-4
@@ -22,7 +22,6 @@ use creaturedex::network::wifi::setup_wifi;
|
||||
use creaturedex::storage::cardstore::CardStore;
|
||||
use creaturedex::storage::store::Store;
|
||||
use embassy_executor::Spawner;
|
||||
use embassy_time::Instant;
|
||||
use embedded_graphics::pixelcolor::BinaryColor;
|
||||
use embedded_graphics::{
|
||||
mono_font::{MonoTextStyle, ascii::FONT_6X10},
|
||||
@@ -30,13 +29,13 @@ use embedded_graphics::{
|
||||
text::Text,
|
||||
};
|
||||
use embedded_hal_bus::i2c::AtomicDevice;
|
||||
use embedded_hal_bus::util::AtomicCell;
|
||||
use esp_hal::Blocking;
|
||||
use esp_hal::clock::CpuClock;
|
||||
use esp_hal::gpio::{Input, InputConfig, Pull};
|
||||
use esp_hal::timer::timg::TimerGroup;
|
||||
use log::error;
|
||||
|
||||
use esp_hal::rtc_cntl::Rtc;
|
||||
|
||||
#[panic_handler]
|
||||
fn panic(panic_info: &core::panic::PanicInfo) -> ! {
|
||||
error!("{}", panic_info);
|
||||
@@ -148,7 +147,10 @@ async fn main(spawner: Spawner) {
|
||||
|
||||
log::info!("Setup complete, entering main loop");
|
||||
spawner.spawn(navigation::run(inputs, outputs).expect("run task failed"));
|
||||
spawner.spawn(background_tasks::nfc_scanner(nfc_driver).expect("nfc scanner task failed"));
|
||||
spawner.spawn(
|
||||
background_tasks::nfc_scanner(nfc_driver, card_store, rtc)
|
||||
.expect("nfc scanner task failed"),
|
||||
);
|
||||
}
|
||||
|
||||
fn display_shit(oled: &mut SecondaryDisplay<'static>, text: &str) {
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
pub mod card_view;
|
||||
pub mod flash_info_view;
|
||||
pub mod journal_view;
|
||||
pub mod main_menu;
|
||||
pub mod menu_item;
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
use crate::navigation::inputs::ButtonAction;
|
||||
use crate::navigation::navigation::Action;
|
||||
use crate::navigation::navigation::Navigable;
|
||||
use crate::navigation::navigation::NewState;
|
||||
use crate::navigation::outputs::Outputs;
|
||||
use crate::views::view::View;
|
||||
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;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct FlashInfoView {}
|
||||
|
||||
impl Navigable for FlashInfoView {
|
||||
fn display(&self, outputs: &mut Outputs) -> impl core::future::Future<Output = ()> + Send {
|
||||
let style = MonoTextStyle::new(&FONT_10X20, Rgb565::WHITE);
|
||||
Text::new("Flash Initialized: {:?}", Point::new(40, 40), style);
|
||||
|
||||
core::future::ready(())
|
||||
}
|
||||
|
||||
fn handle_input(&self, input: Action) -> impl core::future::Future<Output = NewState> + Send {
|
||||
async move {
|
||||
let Action::Button(input) = input else {
|
||||
// Skip timer inputs
|
||||
return NewState {
|
||||
view: View::FlashInfo(self.clone()),
|
||||
replace_view: true,
|
||||
redraw: false,
|
||||
};
|
||||
};
|
||||
|
||||
let new_menu = match input {
|
||||
_ => View::FlashInfo(self.clone()),
|
||||
};
|
||||
|
||||
NewState {
|
||||
replace_view: matches!(new_menu, View::FlashInfo(_)),
|
||||
view: new_menu,
|
||||
redraw: true,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,11 +1,14 @@
|
||||
use crate::navigation::navigation::{Action, Navigable, NewState};
|
||||
use crate::navigation::outputs::Outputs;
|
||||
use crate::views::{menu_item, view::View};
|
||||
use crate::views::{flash_info_view::FlashInfoView, menu_item, view::View};
|
||||
|
||||
use crate::navigation::inputs::ButtonAction;
|
||||
|
||||
use embedded_graphics::pixelcolor::Rgb565;
|
||||
use embedded_graphics::prelude::RgbColor;
|
||||
use embedded_graphics_core::draw_target::DrawTarget;
|
||||
pub const MAX_SELECTED: i8 = 2;
|
||||
|
||||
pub const MAX_SELECTED: i32 = 2;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct SettingsMenu {
|
||||
@@ -18,16 +21,50 @@ impl Navigable for SettingsMenu {
|
||||
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);
|
||||
|
||||
core::future::ready(())
|
||||
}
|
||||
|
||||
fn handle_input(&self, input: Action) -> impl core::future::Future<Output = NewState> + Send {
|
||||
async move {
|
||||
NewState {
|
||||
view: View::Settings(SettingsMenu { selected: 0 }),
|
||||
let Action::Button(input) = input else {
|
||||
// Skip timer inputs
|
||||
return NewState {
|
||||
view: View::Settings(self.clone()),
|
||||
replace_view: true,
|
||||
redraw: !matches!(input, Action::Timer),
|
||||
redraw: false,
|
||||
};
|
||||
};
|
||||
|
||||
let new_menu = match input {
|
||||
ButtonAction::Up => {
|
||||
let new_selected = if (self.selected - 1) < 0 {
|
||||
MAX_SELECTED - 1
|
||||
} else {
|
||||
self.selected - 1
|
||||
};
|
||||
View::Settings(SettingsMenu {
|
||||
selected: new_selected,
|
||||
})
|
||||
}
|
||||
ButtonAction::Down => {
|
||||
let new_selected = self.selected.wrapping_add(1) % MAX_SELECTED;
|
||||
View::Settings(SettingsMenu {
|
||||
selected: new_selected,
|
||||
})
|
||||
}
|
||||
ButtonAction::Ok => match self.selected {
|
||||
2 => View::FlashInfo(FlashInfoView {}),
|
||||
_ => View::Settings(self.clone()),
|
||||
},
|
||||
_ => View::Settings(self.clone()),
|
||||
};
|
||||
|
||||
NewState {
|
||||
replace_view: matches!(new_menu, View::Settings(_)),
|
||||
view: new_menu,
|
||||
redraw: true,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+5
-2
@@ -1,8 +1,8 @@
|
||||
use crate::navigation::outputs::Outputs;
|
||||
use crate::views::card_view::CardView;
|
||||
use crate::views::{
|
||||
journal_view::JournalView, main_menu::MainMenu, scan_menu::ScanMenu,
|
||||
settings_menu::SettingsMenu,
|
||||
flash_info_view::FlashInfoView, journal_view::JournalView, main_menu::MainMenu,
|
||||
scan_menu::ScanMenu, settings_menu::SettingsMenu,
|
||||
};
|
||||
|
||||
use crate::navigation::navigation::{Navigable, NewState};
|
||||
@@ -14,6 +14,7 @@ pub enum View {
|
||||
Settings(SettingsMenu),
|
||||
Journal(JournalView),
|
||||
Card(CardView),
|
||||
FlashInfo(FlashInfoView),
|
||||
}
|
||||
|
||||
impl Navigable for View {
|
||||
@@ -25,6 +26,7 @@ impl Navigable for View {
|
||||
View::Settings(settings_menu) => settings_menu.display(outputs).await,
|
||||
View::Journal(journal_view) => journal_view.display(outputs).await,
|
||||
View::Card(card_view) => card_view.display(outputs).await,
|
||||
View::FlashInfo(flash_info_view) => flash_info_view.display(outputs).await,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -40,6 +42,7 @@ impl Navigable for View {
|
||||
View::Settings(settings_menu) => settings_menu.handle_input(input).await,
|
||||
View::Journal(journal_view) => journal_view.handle_input(input).await,
|
||||
View::Card(card_view) => card_view.handle_input(input).await,
|
||||
View::FlashInfo(flash_info_view) => flash_info_view.handle_input(input).await,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user