From ce35df64c333b1b743e8d921641efd55aeaf9c52 Mon Sep 17 00:00:00 2001 From: sawyer bristol Date: Thu, 4 Sep 2025 19:32:47 -0600 Subject: [PATCH] WIP Binary Ui --- kernel/src/main.rs | 41 +++++++++++++---------- kernel/src/ui.rs | 83 +++++++++++++++++++++++++--------------------- 2 files changed, 69 insertions(+), 55 deletions(-) diff --git a/kernel/src/main.rs b/kernel/src/main.rs index 27451df..1f19627 100644 --- a/kernel/src/main.rs +++ b/kernel/src/main.rs @@ -25,6 +25,7 @@ use crate::{ keyboard::{KeyCode, KeyState, read_keyboard_fifo}, }, storage::{SDCARD, SdCard}, + ui::ui_handler, usb::{ENABLE_SCSI, usb_handler}, }; use alloc::vec::Vec; @@ -33,7 +34,7 @@ use {defmt_rtt as _, panic_probe as _}; use defmt::unwrap; use embassy_executor::{Executor, Spawner}; -use embassy_futures::join::{join, join3}; +use embassy_futures::join::{join, join3, join4}; use embassy_rp::{ gpio::{Input, Level, Output, Pull}, i2c::{self, I2c}, @@ -45,10 +46,7 @@ use embassy_rp::{ spi::{self, Spi}, usb as embassy_rp_usb, }; -use embassy_sync::{ - blocking_mutex::{Mutex, raw::CriticalSectionRawMutex}, - signal::Signal, -}; +use embassy_sync::{blocking_mutex::raw::CriticalSectionRawMutex, mutex::Mutex}; use embassy_time::{Delay, Timer}; use embedded_hal_bus::spi::ExclusiveDevice; use embedded_sdmmc::SdCard as SdmmcSdCard; @@ -73,7 +71,12 @@ static ALLOCATOR: Talck, ClaimOnOom> = Talc::new(unsafe { ClaimOnOom::new(Span::from_array(core::ptr::addr_of!(ARENA).cast_mut())) }) .lock(); -static DRIVERS_READY: Signal = Signal::new(); +static TASK_STATE: Mutex = Mutex::new(TaskState::Ui); + +enum TaskState { + Ui, + Kernel, +} #[embassy_executor::main] async fn main(_spawner: Spawner) { @@ -119,16 +122,16 @@ async fn main(_spawner: Spawner) { // runs dynamically loaded elf files #[embassy_executor::task] async fn userland_task() { - DRIVERS_READY.wait().await; + // DRIVERS_READY.wait().await; - defmt::info!("Loading binary"); - let binary_data: &[u8] = - include_bytes!("../../target/thumbv8m.main-none-eabihf/release/calculator"); + // defmt::info!("Loading binary"); + // let binary_data: &[u8] = + // include_bytes!("../../target/thumbv8m.main-none-eabihf/release/calculator"); - defmt::info!("Running binary"); - let entry = unsafe { load_binary(binary_data).unwrap() }; + // defmt::info!("Running binary"); + // let entry = unsafe { load_binary(binary_data).unwrap() }; - entry().await; + // entry().await; } struct Display { @@ -183,6 +186,8 @@ async fn kernel_task(display: Display, sd: Sd, mcu: Mcu, usb: USB) { let display_fut = display_handler(display); + let ui_fut = ui_handler(); + { let mut config = spi::Config::default(); config.frequency = 400_000; @@ -201,15 +206,15 @@ async fn kernel_task(display: Display, sd: Sd, mcu: Mcu, usb: USB) { let usb = embassy_rp_usb::Driver::new(usb, Irqs); let usb_fut = usb_handler(usb); - ENABLE_SCSI.store(true, core::sync::atomic::Ordering::Relaxed); - DRIVERS_READY.signal(()); - join3(usb_fut, display_fut, async { + let key_abi_fut = async { loop { Timer::after_millis(100).await; get_keys().await } - }) - .await; + }; + + ENABLE_SCSI.store(true, core::sync::atomic::Ordering::Relaxed); + join4(usb_fut, display_fut, key_abi_fut, ui_fut).await; } static mut KEY_CACHE: Queue = Queue::new(); diff --git a/kernel/src/ui.rs b/kernel/src/ui.rs index 18c8d1a..d90f7a8 100644 --- a/kernel/src/ui.rs +++ b/kernel/src/ui.rs @@ -1,7 +1,10 @@ use crate::{ + TASK_STATE, TaskState, display::{FRAMEBUFFER, SCREEN_HEIGHT, SCREEN_WIDTH}, format, + peripherals::keyboard, }; +use alloc::{string::String, vec::Vec}; use core::fmt::Debug; use defmt::info; use embassy_rp::{ @@ -9,6 +12,11 @@ use embassy_rp::{ peripherals::{PIN_13, PIN_14, PIN_15, SPI1}, spi::{Async, Spi}, }; +use embassy_sync::{ + blocking_mutex::raw::{CriticalSectionRawMutex, ThreadModeRawMutex}, + mutex::Mutex, + signal::Signal, +}; use embassy_time::{Delay, Timer}; use embedded_graphics::{ Drawable, @@ -30,38 +38,38 @@ use embedded_layout::{ object_chain::Chain, prelude::*, }; -use heapless::{String, Vec}; +use shared::keyboard::KeyCode; -pub struct UI { - pub selections_list: SelectionList, -} +static SELECTIONS: Mutex = + Mutex::new(SelectionList::new(Vec::new())); -impl UI { - pub fn new() -> Self { - Self { - selections_list: SelectionList::new(Vec::new()), +pub async fn ui_handler() { + loop { + let state = TASK_STATE.lock().await; + if let TaskState::Ui = *state { + let mut selections = SELECTIONS.lock().await; + if let Some(event) = keyboard::read_keyboard_fifo().await { + match event.key { + KeyCode::JoyUp => selections.up(), + KeyCode::JoyDown => selections.down(), + KeyCode::Enter | KeyCode::JoyRight => (), + _ => (), + } + } + + draw_selection().await; } } +} - pub async fn draw>(&mut self) - where - ::Error: Debug, - { - self.draw_selection().await; - } - - async fn draw_selection(&mut self) { - let mut fb_lock = FRAMEBUFFER.lock().await; - let fb = fb_lock.as_mut().unwrap(); - +async fn draw_selection() { + let mut fb_lock = FRAMEBUFFER.lock().await; + if let Some(fb) = fb_lock.as_mut() { + info!("UIINg"); let text_style = MonoTextStyle::new(&FONT_9X15, Rgb565::WHITE); - let selection = Rectangle::new( - Point::new(0, 0), - Size::new(SCREEN_WIDTH as u32 - 1, SCREEN_HEIGHT as u32 - 1), - ); - - let mut file_names = self.selections_list.selections.iter(); + let guard = SELECTIONS.lock().await; + let mut file_names = guard.selections.iter(); let Some(first) = file_names.next() else { Text::new("No Programs found on SD Card\nEnsure programs end with '.bin',\nand are located in the root directory", @@ -72,24 +80,25 @@ impl UI { +pub struct SelectionList { current_selection: u16, - selections: Vec, MAX_SELECTION>, + selections: Vec, } -impl - SelectionList -{ - pub fn new(selections: Vec, MAX_SELECTION>) -> Self { +impl SelectionList { + pub const fn new(selections: Vec) -> Self { Self { selections, current_selection: 0,