From 0a1f5f2dfb80770e44066bf437d3f3d75757f150 Mon Sep 17 00:00:00 2001 From: "Sebastian H. Gabrielli" Date: Sat, 28 Dec 2024 21:14:14 +0100 Subject: [PATCH] Implement interactivity --- src/main.rs | 57 +++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 53 insertions(+), 4 deletions(-) diff --git a/src/main.rs b/src/main.rs index 8e1cef0..7bb8e9b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -2,16 +2,17 @@ #![no_main] use core::cell::RefCell; -use defmt::info; +use defmt::{error, info}; use display_interface_spi::SPIInterface; use embassy_embedded_hal::shared_bus::blocking::spi::SpiDevice; use embassy_executor::Spawner; use embassy_nrf::{ bind_interrupts, - gpio::{AnyPin, Level, Output, OutputDrive, Pin}, + gpio::{AnyPin, Input, Level, Output, OutputDrive, Pin}, peripherals, spim, }; -use embassy_sync::blocking_mutex::Mutex; +use embassy_sync::blocking_mutex::{raw::ThreadModeRawMutex, Mutex}; +use embassy_sync::channel::{Channel, Sender}; use embassy_time::{Duration, Timer}; use ili9341::Ili9341; use {defmt_rtt as _, panic_probe as _}; @@ -51,6 +52,8 @@ async fn blink(pin: AnyPin, blink_delay: Duration) -> ! { } } +static GUI_CHANNEL: Channel = Channel::new(); + #[embassy_executor::task] async fn gui_task( peripheral: embassy_nrf::peripherals::SERIAL3, @@ -108,10 +111,40 @@ async fn gui_task( .unwrap(); let mut gui = Gui::new(display); + gui.draw().expect("Failed to draw GUI"); loop { + info!("Waiting for GUI event"); + // Wait to receive a GUI event + let gui_action = GUI_CHANNEL.receive().await; + // Re-render the GUI + info!("Received event, calculating new screen"); + gui = gui.action(gui_action); + + // Clear the screen + info!("Clearing screen"); + gui.fill_black().expect("Failed to clear screen"); + // Draw the GUI + info!("Drawing screen"); gui.draw().expect("Failed to draw GUI"); - info!("Finished drawing GUI"); + } +} + +#[embassy_executor::task(pool_size = 2)] +async fn input_controller( + control: Sender<'static, ThreadModeRawMutex, gui::GuiAction, 8>, + pin: AnyPin, + action: gui::GuiAction, +) -> ! { + let mut button = Input::new(pin, embassy_nrf::gpio::Pull::Up); + + loop { + // Wait for the button to be pressed + button.wait_for_falling_edge().await; + // Send the event + if let Err(_e) = control.try_send(action) { + error!("Failed to send input action with error"); + } } } @@ -150,6 +183,22 @@ async fn main(spawner: Spawner) { )) .expect("Failed to spawn GUI task"); + // Create the GUI controllers + spawner + .spawn(input_controller( + GUI_CHANNEL.sender(), + p.P0_06.degrade(), + gui::GuiAction::Down, + )) + .expect("Failed tp spawn DOWN input controller"); + spawner + .spawn(input_controller( + GUI_CHANNEL.sender(), + p.P0_07.degrade(), + gui::GuiAction::Select, + )) + .expect("Failed tp spawn Select input controller"); + // Now loop, re-running the demo every second loop { info!("Hello, world!");