Moved primary lcd and navigation into dedicated files

This commit is contained in:
2026-08-02 14:59:11 +02:00
parent e287491906
commit 459ab8762c
4 changed files with 128 additions and 68 deletions
+18 -65
View File
@@ -8,29 +8,20 @@
#![deny(clippy::large_stack_frames)] #![deny(clippy::large_stack_frames)]
use creaturedex::card::mock::{MOCK_PAYLOAD, MOCK_PAYLOAD2}; 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::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 creaturedex::network::wifi::setup_wifi;
use embedded_graphics::draw_target::DrawTarget;
use display_interface_spi::SPIInterface;
use embassy_executor::Spawner; use embassy_executor::Spawner;
use embassy_time::Timer; use embassy_time::Timer;
use embedded_graphics::draw_target::DrawTarget;
use embedded_graphics::pixelcolor::Rgb565; use embedded_graphics::pixelcolor::Rgb565;
use embedded_graphics::prelude::RgbColor; use embedded_graphics::prelude::RgbColor;
use embedded_hal_bus::spi::ExclusiveDevice;
use esp_hal::clock::CpuClock; use esp_hal::clock::CpuClock;
use esp_hal::delay::Delay; 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 esp_hal::timer::timg::TimerGroup;
use ili9341::Ili9341; use log::error;
use ili9341::Orientation;
use log::{error, info};
#[panic_handler] #[panic_handler]
fn panic(panic_info: &core::panic::PanicInfo) -> ! { fn panic(panic_info: &core::panic::PanicInfo) -> ! {
@@ -50,21 +41,12 @@ esp_bootloader_esp_idf::esp_app_desc!();
)] )]
#[esp_rtos::main] #[esp_rtos::main]
async fn main(spawner: Spawner) { 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(); esp_println::logger::init_logger_from_env();
let config = esp_hal::Config::default().with_cpu_clock(CpuClock::max()); let config = esp_hal::Config::default().with_cpu_clock(CpuClock::max());
let peripherals = esp_hal::init(config); let peripherals = esp_hal::init(config);
// The following pins are used to bootstrap the chip. They are available // The following GPIO pins are in use by some feature of the module and should not be used.
// 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.
let _ = peripherals.GPIO27; let _ = peripherals.GPIO27;
let _ = peripherals.GPIO28; let _ = peripherals.GPIO28;
let _ = peripherals.GPIO29; let _ = peripherals.GPIO29;
@@ -73,75 +55,46 @@ async fn main(spawner: Spawner) {
let _ = peripherals.GPIO32; let _ = peripherals.GPIO32;
let _ = peripherals.GPIO33; let _ = peripherals.GPIO33;
let _ = peripherals.GPIO34; let _ = peripherals.GPIO34;
let _ = peripherals.GPIO35;
let _ = peripherals.GPIO36;
let _ = peripherals.GPIO37;
esp_alloc::heap_allocator!(#[esp_hal::ram(reclaimed)] size: 73744); esp_alloc::heap_allocator!(#[esp_hal::ram(reclaimed)] size: 73744);
let button_config = InputConfig::default().with_pull(Pull::Up); let mut delay = Delay::new();
let button1 = Input::new(peripherals.GPIO38, button_config); let button1 = init_navigation_button(peripherals.GPIO38);
let timg0 = TimerGroup::new(peripherals.TIMG0); let timg0 = TimerGroup::new(peripherals.TIMG0);
let sw_interrupt = let sw_interrupt =
esp_hal::interrupt::software::SoftwareInterruptControl::new(peripherals.SW_INTERRUPT); esp_hal::interrupt::software::SoftwareInterruptControl::new(peripherals.SW_INTERRUPT);
esp_rtos::start(timg0.timer0, sw_interrupt.software_interrupt0); esp_rtos::start(timg0.timer0, sw_interrupt.software_interrupt0);
let freq = Rate::from_khz(60_000); let mut display = init_primary_lcd(
info!("Display freq: {freq}");
let spi_bus = Spi::new(
peripherals.SPI2, peripherals.SPI2,
Config::default().with_frequency(freq).with_mode(Mode::_0), peripherals.GPIO36,
) peripherals.GPIO35,
.unwrap() peripherals.GPIO37,
.with_sck(peripherals.GPIO36) peripherals.GPIO11,
.with_mosi(peripherals.GPIO35) peripherals.GPIO10,
.with_miso(peripherals.GPIO37); peripherals.GPIO12,
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,
&mut delay, &mut delay,
Orientation::Portrait, );
ili9341::DisplaySize240x320,
)
.unwrap();
display.clear(Rgb565::BLACK).unwrap();
// setup_wifi(peripherals.WIFI, peripherals.FLASH, &spawner).await; // setup_wifi(peripherals.WIFI, peripherals.FLASH, &spawner).await;
log::info!("Setup complete, entering main loop"); log::info!("Setup complete, entering main loop");
let mut use_first_payload = true; let mut nav_state = NavigationState::new();
loop { loop {
if button1.is_low() { if button1.is_low() {
log::info!("Button pressed!"); log::info!("Button pressed!");
display.clear(Rgb565::BLACK).unwrap(); display.clear(Rgb565::BLACK).unwrap();
let payload = if use_first_payload { let payload = if nav_state.toggle_payload() {
&MOCK_PAYLOAD &MOCK_PAYLOAD
} else { } else {
&MOCK_PAYLOAD2 &MOCK_PAYLOAD2
}; };
render_nfc_payload(&mut display, payload); render_nfc_payload(&mut display, payload);
use_first_payload = !use_first_payload;
} }
// info!("Hello world!");
Timer::after_millis(10).await; 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
} }
+60 -1
View File
@@ -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<Spi<'a, esp_hal::Blocking>, 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
}
+15 -1
View File
@@ -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)
}
+35 -1
View File
@@ -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
}
}