diff --git a/kernel/src/main.rs b/kernel/src/main.rs index c3ea02e..ac5151c 100644 --- a/kernel/src/main.rs +++ b/kernel/src/main.rs @@ -39,9 +39,7 @@ use crate::{ ui::{clear_screen, ui_handler}, usb::usb_handler, }; -use core::sync::atomic::{AtomicBool, Ordering}; use embassy_executor::{Executor, Spawner}; -use embassy_futures::select::select; use embassy_rp::{ Peri, gpio::{Input, Level, Output, Pull}, @@ -107,9 +105,6 @@ async fn watchdog_task(mut watchdog: Watchdog) { } } -static ENABLE_UI: AtomicBool = AtomicBool::new(true); -static UI_CHANGE: Signal = Signal::new(); - #[embassy_executor::main] async fn main(_spawner: Spawner) { let p = embassy_rp::init(Default::default()); @@ -177,24 +172,15 @@ async fn userland_task() { let name = recv.receive().await; let (entry, _bump) = unsafe { load_binary(&name).await.expect("unable to load binary") }; - // disable kernel ui - { - ENABLE_UI.store(false, Ordering::Release); - UI_CHANGE.signal(()); - clear_screen().await; - } + clear_screen().await; unsafe { MS_SINCE_LAUNCH = Some(Instant::now()) }; #[cfg(feature = "defmt")] defmt::info!("Executing Binary"); entry(); - // enable kernel ui - { - ENABLE_UI.store(true, Ordering::Release); - UI_CHANGE.signal(()); - clear_screen().await; - } + STOP_KEY_HANDLER.signal(()); + clear_screen().await; } } @@ -336,18 +322,25 @@ async fn kernel_task( let usb_driver = embassy_rp_usb::Driver::new(usb, Irqs); spawner.spawn(usb_handler(usb_driver)).unwrap(); + let mut ui_enabled = true; loop { - let ui_enabled = ENABLE_UI.load(Ordering::Relaxed); if ui_enabled { - select(ui_handler(), UI_CHANGE.wait()).await; + ui_handler().await; } else { - select(key_handler(), UI_CHANGE.wait()).await; + key_handler().await; } + ui_enabled ^= true // flip bool } } +static STOP_KEY_HANDLER: Signal = Signal::new(); + async fn key_handler() { loop { + if STOP_KEY_HANDLER.try_take().is_some() { + break; + } + if let Some(event) = read_keyboard_fifo().await { if let KeyState::Pressed = event.state { unsafe { diff --git a/kernel/src/scsi/mod.rs b/kernel/src/scsi/mod.rs index fa4d593..e077f9d 100644 --- a/kernel/src/scsi/mod.rs +++ b/kernel/src/scsi/mod.rs @@ -23,7 +23,7 @@ pub static SCSI_HALT: AtomicBool = AtomicBool::new(false); // number of blocks to read from sd at once // higher is better, but is larger. Size is BLOCKS * 512 bytes -const BLOCKS: usize = 5; +const BLOCKS: usize = 10; static mut BLOCK_BUF: LazyLock<[Block; BLOCKS]> = LazyLock::new(|| core::array::from_fn(|_| Block::new())); diff --git a/kernel/src/ui.rs b/kernel/src/ui.rs index 859c213..288de8d 100644 --- a/kernel/src/ui.rs +++ b/kernel/src/ui.rs @@ -1,7 +1,6 @@ use crate::{ BINARY_CH, display::FRAMEBUFFER, - elf::load_binary, framebuffer::FB_PAUSED, peripherals::keyboard, storage::{FileName, SDCARD}, @@ -10,7 +9,6 @@ use crate::{ use abi_sys::keyboard::{KeyCode, KeyState}; use alloc::{str::FromStr, string::String, vec::Vec}; use core::sync::atomic::Ordering; -use embassy_futures::yield_now; use embassy_sync::{blocking_mutex::raw::CriticalSectionRawMutex, mutex::Mutex}; use embassy_time::Timer; use embedded_graphics::{ @@ -43,7 +41,10 @@ pub async fn ui_handler() { update_selections().await; loop { - input_handler(&mut ui, &mut menu, &mut scsi).await; + if input_handler(&mut ui, &mut menu, &mut scsi).await { + overlay.clear().await; + return; + } match ui.page { UiPage::Menu => menu.draw().await, UiPage::Scsi => scsi.draw().await, @@ -53,7 +54,7 @@ pub async fn ui_handler() { } } -async fn input_handler(ui: &mut UiState, menu: &mut MenuPage, scsi: &mut ScsiPage) { +async fn input_handler(ui: &mut UiState, menu: &mut MenuPage, scsi: &mut ScsiPage) -> bool { if let Some(event) = keyboard::read_keyboard_fifo().await { if event.state == KeyState::Pressed { match (&mut ui.page, event.key) { @@ -68,11 +69,12 @@ async fn input_handler(ui: &mut UiState, menu: &mut MenuPage, scsi: &mut ScsiPag ui.page = UiPage::Menu; update_selections().await; } - (UiPage::Menu, _) => menu.handle_input(event.key).await, - (UiPage::Scsi, _) => scsi.handle_input(event.key).await, + (UiPage::Menu, _) => return menu.handle_input(event.key).await, + (UiPage::Scsi, _) => return scsi.handle_input(event.key).await, } } } + false } struct Overlay { @@ -103,6 +105,12 @@ impl Overlay { self.last_bounds = Some(text.bounds()); text.draw(fb).unwrap(); } + + async fn clear(&mut self) { + if let Some(rect) = self.last_bounds { + clear_rect(rect).await + } + } } enum UiPage { @@ -116,7 +124,7 @@ struct UiState { trait Page { async fn draw(&mut self); - async fn handle_input(&mut self, key: KeyCode); + async fn handle_input(&mut self, key: KeyCode) -> bool; async fn clear(&mut self); } @@ -131,7 +139,7 @@ impl Page for ScsiPage { let bounds = fb.bounding_box(); Text::with_alignment( - "Mass storage over usb enabled", + "Usb Mass storage enabled", bounds.center(), text_style, Alignment::Center, @@ -140,8 +148,8 @@ impl Page for ScsiPage { .unwrap(); } - async fn handle_input(&mut self, _key: KeyCode) { - () + async fn handle_input(&mut self, _key: KeyCode) -> bool { + false } async fn clear(&mut self) { @@ -240,17 +248,15 @@ impl Page for MenuPage { FB_PAUSED.store(false, Ordering::Release); // ensure all elements show up at once } - async fn handle_input(&mut self, key: KeyCode) { + async fn handle_input(&mut self, key: KeyCode) -> bool { match key { KeyCode::Enter | KeyCode::Right => { let selections = SELECTIONS.lock().await; let selection = selections[self.selection].clone(); - BINARY_CH.send(selection.short_name).await; self.clear().await; - loop { - yield_now().await; - } + BINARY_CH.send(selection.short_name).await; + return true; } KeyCode::Up => { if self.selection > 0 { @@ -272,6 +278,7 @@ impl Page for MenuPage { _ => (), } self.changed = true; + false } async fn clear(&mut self) {