From 459ab8762cf771f0a806d370b555afe085972809 Mon Sep 17 00:00:00 2001 From: lukas Date: Sun, 2 Aug 2026 14:59:11 +0200 Subject: [PATCH] Moved primary lcd and navigation into dedicated files --- src/bin/main.rs | 83 +++++++++----------------------------- src/display/primary_lcd.rs | 61 +++++++++++++++++++++++++++- src/navigation/input.rs | 16 +++++++- src/navigation/state.rs | 36 ++++++++++++++++- 4 files changed, 128 insertions(+), 68 deletions(-) diff --git a/src/bin/main.rs b/src/bin/main.rs index 8467582..8a9feec 100644 --- a/src/bin/main.rs +++ b/src/bin/main.rs @@ -8,29 +8,20 @@ #![deny(clippy::large_stack_frames)] use creaturedex::card::mock::{MOCK_PAYLOAD, MOCK_PAYLOAD2}; +use creaturedex::display::primary_lcd::init_primary_lcd; use creaturedex::display::views::card_view::render_nfc_payload; +use creaturedex::navigation::input::init_navigation_button; +use creaturedex::navigation::state::NavigationState; use creaturedex::network::wifi::setup_wifi; -use embedded_graphics::draw_target::DrawTarget; -use display_interface_spi::SPIInterface; use embassy_executor::Spawner; use embassy_time::Timer; +use embedded_graphics::draw_target::DrawTarget; use embedded_graphics::pixelcolor::Rgb565; use embedded_graphics::prelude::RgbColor; -use embedded_hal_bus::spi::ExclusiveDevice; use esp_hal::clock::CpuClock; use esp_hal::delay::Delay; -use esp_hal::gpio::Level; -use esp_hal::gpio::{Input, Output, Pull}; -use esp_hal::gpio::{InputConfig, OutputConfig}; -use esp_hal::spi::{ - Mode, - master::{Config, Spi}, -}; -use esp_hal::time::Rate; use esp_hal::timer::timg::TimerGroup; -use ili9341::Ili9341; -use ili9341::Orientation; -use log::{error, info}; +use log::error; #[panic_handler] fn panic(panic_info: &core::panic::PanicInfo) -> ! { @@ -50,21 +41,12 @@ esp_bootloader_esp_idf::esp_app_desc!(); )] #[esp_rtos::main] async fn main(spawner: Spawner) { - // generator version: 1.3.0 - // generator parameters: --chip esp32s3 -o esp32s3-wroom-1-octal-psram -o unstable-hal -o alloc -o wifi -o log -o wokwi -o neovim -o vscode -o esp - esp_println::logger::init_logger_from_env(); let config = esp_hal::Config::default().with_cpu_clock(CpuClock::max()); let peripherals = esp_hal::init(config); - // The following pins are used to bootstrap the chip. They are available - // for use, but check the datasheet of the module for more information on them. - // - GPIO0 - // - GPIO3 - // - GPIO45 - // - GPIO46 - // These GPIO pins are in use by some feature of the module and should not be used. + // The following GPIO pins are in use by some feature of the module and should not be used. let _ = peripherals.GPIO27; let _ = peripherals.GPIO28; let _ = peripherals.GPIO29; @@ -73,75 +55,46 @@ async fn main(spawner: Spawner) { let _ = peripherals.GPIO32; let _ = peripherals.GPIO33; let _ = peripherals.GPIO34; - let _ = peripherals.GPIO35; - let _ = peripherals.GPIO36; - let _ = peripherals.GPIO37; esp_alloc::heap_allocator!(#[esp_hal::ram(reclaimed)] size: 73744); - let button_config = InputConfig::default().with_pull(Pull::Up); - let button1 = Input::new(peripherals.GPIO38, button_config); + let mut delay = Delay::new(); + let button1 = init_navigation_button(peripherals.GPIO38); let timg0 = TimerGroup::new(peripherals.TIMG0); let sw_interrupt = esp_hal::interrupt::software::SoftwareInterruptControl::new(peripherals.SW_INTERRUPT); esp_rtos::start(timg0.timer0, sw_interrupt.software_interrupt0); - let freq = Rate::from_khz(60_000); - info!("Display freq: {freq}"); - - let spi_bus = Spi::new( + let mut display = init_primary_lcd( peripherals.SPI2, - Config::default().with_frequency(freq).with_mode(Mode::_0), - ) - .unwrap() - .with_sck(peripherals.GPIO36) - .with_mosi(peripherals.GPIO35) - .with_miso(peripherals.GPIO37); - - let cs_main = Output::new(peripherals.GPIO11, Level::High, OutputConfig::default()); - - let mut delay = Delay::new(); - let spi_dev = ExclusiveDevice::new(spi_bus, cs_main, delay).unwrap(); - let reset_main = Output::new(peripherals.GPIO10, Level::High, OutputConfig::default()); - let spi_dc = Output::new(peripherals.GPIO12, Level::High, OutputConfig::default()); - let iface = SPIInterface::new(spi_dev, spi_dc); - - let mut display = Ili9341::new( - iface, - reset_main, + peripherals.GPIO36, + peripherals.GPIO35, + peripherals.GPIO37, + peripherals.GPIO11, + peripherals.GPIO10, + peripherals.GPIO12, &mut delay, - Orientation::Portrait, - ili9341::DisplaySize240x320, - ) - .unwrap(); - - display.clear(Rgb565::BLACK).unwrap(); - - + ); // setup_wifi(peripherals.WIFI, peripherals.FLASH, &spawner).await; log::info!("Setup complete, entering main loop"); - let mut use_first_payload = true; + let mut nav_state = NavigationState::new(); loop { if button1.is_low() { log::info!("Button pressed!"); display.clear(Rgb565::BLACK).unwrap(); - let payload = if use_first_payload { + let payload = if nav_state.toggle_payload() { &MOCK_PAYLOAD } else { &MOCK_PAYLOAD2 }; render_nfc_payload(&mut display, payload); - use_first_payload = !use_first_payload; } - // info!("Hello world!"); Timer::after_millis(10).await; } - - // for inspiration have a look at the examples at https://github.com/esp-rs/esp-hal/tree/esp-hal-v1.1.0/examples } diff --git a/src/display/primary_lcd.rs b/src/display/primary_lcd.rs index 8c0bf35..efebe50 100644 --- a/src/display/primary_lcd.rs +++ b/src/display/primary_lcd.rs @@ -1 +1,60 @@ -// Primary LCD module +use display_interface_spi::SPIInterface; +use embedded_graphics::draw_target::DrawTarget; +use embedded_graphics::pixelcolor::Rgb565; +use embedded_graphics::prelude::RgbColor; +use embedded_hal_bus::spi::ExclusiveDevice; +use esp_hal::delay::Delay; +use esp_hal::gpio::{Level, Output, OutputConfig}; +use esp_hal::peripherals::{GPIO10, GPIO11, GPIO12, GPIO35, GPIO36, GPIO37, SPI2}; +use esp_hal::spi::{master::{Config, Spi}, Mode}; +use esp_hal::time::Rate; +use ili9341::{DisplaySize240x320, Ili9341, Orientation}; + +pub type PrimaryLcdDisplay<'a> = Ili9341< + SPIInterface< + ExclusiveDevice, Output<'a>, Delay>, + Output<'a>, + >, + Output<'a>, +>; + +pub fn init_primary_lcd( + spi2: SPI2<'static>, + sck: GPIO36<'static>, + mosi: GPIO35<'static>, + miso: GPIO37<'static>, + cs: GPIO11<'static>, + reset: GPIO10<'static>, + dc: GPIO12<'static>, + delay: &mut Delay, +) -> PrimaryLcdDisplay<'static> { + let freq = Rate::from_khz(60_000); + log::info!("Display freq: {freq}"); + + let spi_bus = Spi::new( + spi2, + Config::default().with_frequency(freq).with_mode(Mode::_0), + ) + .unwrap() + .with_sck(sck) + .with_mosi(mosi) + .with_miso(miso); + + let cs_main = Output::new(cs, Level::High, OutputConfig::default()); + let spi_dev = ExclusiveDevice::new(spi_bus, cs_main, *delay).unwrap(); + let reset_main = Output::new(reset, Level::High, OutputConfig::default()); + let spi_dc = Output::new(dc, Level::High, OutputConfig::default()); + let iface = SPIInterface::new(spi_dev, spi_dc); + + let mut display = Ili9341::new( + iface, + reset_main, + delay, + Orientation::Portrait, + DisplaySize240x320, + ) + .unwrap(); + + display.clear(Rgb565::BLACK).unwrap(); + display +} diff --git a/src/navigation/input.rs b/src/navigation/input.rs index 5320702..07f5426 100644 --- a/src/navigation/input.rs +++ b/src/navigation/input.rs @@ -1 +1,15 @@ -// Navigation input module +use esp_hal::gpio::{Input, InputConfig, Pull}; +use esp_hal::peripherals::GPIO38; + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum NavCommand { + NextCard, + PrevCard, + Select, + ScanTag, +} + +pub fn init_navigation_button(pin: GPIO38<'static>) -> Input<'static> { + let button_config = InputConfig::default().with_pull(Pull::Up); + Input::new(pin, button_config) +} diff --git a/src/navigation/state.rs b/src/navigation/state.rs index b0feb62..71e9548 100644 --- a/src/navigation/state.rs +++ b/src/navigation/state.rs @@ -1 +1,35 @@ -// Navigation state module +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum ScreenMode { + CardDetail, + DexGrid, + Settings, +} + +#[derive(Debug, Clone, Copy)] +pub struct NavigationState { + pub current_screen: ScreenMode, + pub card_index: usize, + pub use_first_payload: bool, +} + +impl Default for NavigationState { + fn default() -> Self { + Self { + current_screen: ScreenMode::CardDetail, + card_index: 0, + use_first_payload: true, + } + } +} + +impl NavigationState { + pub fn new() -> Self { + Self::default() + } + + pub fn toggle_payload(&mut self) -> bool { + let current = self.use_first_payload; + self.use_first_payload = !self.use_first_payload; + current + } +}