From 078e1f6931843b17f5d35fdc587cdac97196627f Mon Sep 17 00:00:00 2001 From: sawyer bristol Date: Wed, 30 Jul 2025 17:44:52 -0600 Subject: [PATCH] global access to framebuff --- kernel/src/abi.rs | 12 ++++++ kernel/src/display.rs | 51 ++++++++++++++++--------- kernel/src/main.rs | 89 ++++++++++++++++++++++++------------------- 3 files changed, 95 insertions(+), 57 deletions(-) create mode 100644 kernel/src/abi.rs diff --git a/kernel/src/abi.rs b/kernel/src/abi.rs new file mode 100644 index 0000000..833661d --- /dev/null +++ b/kernel/src/abi.rs @@ -0,0 +1,12 @@ +use abi::Syscall; + +#[unsafe(no_mangle)] +pub extern "C" fn syscall_dispatch(call: *const Syscall) -> usize { + let call = unsafe { &*call }; + match call { + Syscall::DrawPixels { x, y, color } => { + draw_pixel(*x, *y, *color); + 0 + } + } +} diff --git a/kernel/src/display.rs b/kernel/src/display.rs index 6766b8a..d284575 100644 --- a/kernel/src/display.rs +++ b/kernel/src/display.rs @@ -1,4 +1,4 @@ -use core::sync::atomic::Ordering; +use core::{cell::RefCell, sync::atomic::Ordering}; use defmt::info; use embassy_rp::{ @@ -6,7 +6,7 @@ use embassy_rp::{ peripherals::{PIN_13, PIN_14, PIN_15, SPI1}, spi::{Async, Spi}, }; -use embassy_sync::{blocking_mutex::raw::ThreadModeRawMutex, signal::Signal}; +use embassy_sync::{blocking_mutex::raw::ThreadModeRawMutex, mutex::Mutex, signal::Signal}; use embassy_time::{Delay, Instant, Timer}; use embedded_graphics::{ Drawable, @@ -20,19 +20,31 @@ use embedded_graphics::{ use embedded_hal_bus::spi::ExclusiveDevice; use portable_atomic::AtomicBool; use st7365p_lcd::{FrameBuffer, ST7365P}; +use static_cell::StaticCell; + +type DISPLAY = ST7365P< + ExclusiveDevice, Output<'static>, Delay>, + Output<'static>, + Output<'static>, + Delay, +>; const SCREEN_WIDTH: usize = 320; const SCREEN_HEIGHT: usize = 320; -pub static DISPLAY_SIGNAL: Signal = Signal::new(); +type FB = FrameBuffer; +static FRAMEBUFFER_CELL: StaticCell = StaticCell::new(); +pub static FRAMEBUFFER: Mutex>> = + Mutex::new(RefCell::new(None)); -pub async fn display_handler( +pub async fn init_display( spi: Spi<'static, SPI1, Async>, cs: PIN_13, data: PIN_14, reset: PIN_15, -) { +) -> DISPLAY { let spi_device = ExclusiveDevice::new(spi, Output::new(cs, Level::Low), Delay).unwrap(); + defmt::info!("spi made"); let mut display = ST7365P::new( spi_device, Output::new(data, Level::Low), @@ -41,28 +53,31 @@ pub async fn display_handler( true, Delay, ); - let mut framebuffer: FrameBuffer< - SCREEN_WIDTH, - SCREEN_HEIGHT, - { SCREEN_WIDTH * SCREEN_HEIGHT }, - > = FrameBuffer::new(); + let framebuffer = FRAMEBUFFER_CELL.init(FrameBuffer::new()); display.init().await.unwrap(); display.set_custom_orientation(0x40).await.unwrap(); framebuffer.draw(&mut display).await.unwrap(); display.set_on().await.unwrap(); + FRAMEBUFFER + .lock() + .await + .swap(&RefCell::new(Some(framebuffer))); - DISPLAY_SIGNAL.signal(()); + display +} +pub async fn display_handler(mut display: DISPLAY) { loop { - DISPLAY_SIGNAL.wait().await; - - // text.draw(&mut framebuffer).unwrap(); - - let start = Instant::now(); - framebuffer + defmt::info!("drawing"); + FRAMEBUFFER + .lock() + .await + .borrow_mut() + .as_mut() + .unwrap() .partial_draw_batched(&mut display) .await .unwrap(); - info!("Elapsed {}ms", start.elapsed().as_millis()); + Timer::after_millis(32).await; // 30 fps } } diff --git a/kernel/src/main.rs b/kernel/src/main.rs index cc25387..7b24eab 100644 --- a/kernel/src/main.rs +++ b/kernel/src/main.rs @@ -3,9 +3,19 @@ #![cfg_attr(not(test), no_std)] #![cfg_attr(not(test), no_main)] +mod display; +mod peripherals; +mod scsi; +mod storage; +mod usb; +mod utils; + use crate::{ - display::DISPLAY_SIGNAL, - peripherals::keyboard::{KeyCode, KeyState, read_keyboard_fifo}, + display::{FRAMEBUFFER, display_handler, init_display}, + peripherals::{ + conf_peripherals, + keyboard::{KeyCode, KeyState, read_keyboard_fifo}, + }, storage::SdCard, usb::usb_handler, }; @@ -14,7 +24,7 @@ use {defmt_rtt as _, panic_probe as _}; use core::cell::RefCell; use embassy_executor::Spawner; -use embassy_futures::join::join; +use embassy_futures::join::{join, join3}; use embassy_rp::{ gpio::{Input, Level, Output, Pull}, peripherals::{I2C1, USB}, @@ -25,20 +35,18 @@ use embassy_rp::{i2c, i2c::I2c, spi}; use embassy_sync::blocking_mutex::raw::ThreadModeRawMutex; use embassy_sync::mutex::Mutex; use embassy_time::{Delay, Timer}; -use embedded_graphics::primitives::Rectangle; +use embedded_graphics::{ + Drawable, + mono_font::{MonoTextStyle, ascii::FONT_6X10}, + pixelcolor::{BinaryColor, Rgb565}, + prelude::{Point, RgbColor}, + primitives::Rectangle, + text::{Text, TextStyle}, +}; use embedded_hal_bus::spi::ExclusiveDevice; use embedded_sdmmc::SdCard as SdmmcSdCard; use heapless::String; -mod peripherals; -use peripherals::conf_peripherals; -mod display; -use display::display_handler; -mod scsi; -mod storage; -mod usb; -mod utils; - embassy_rp::bind_interrupts!(struct Irqs { I2C1_IRQ => i2c::InterruptHandler; USBCTRL_IRQ => embassy_rp_usb::InterruptHandler; @@ -54,25 +62,30 @@ async fn main(_spawner: Spawner) { let i2c1 = I2c::new_async(p.I2C1, p.PIN_7, p.PIN_6, Irqs, config); conf_peripherals(i2c1).await; - // SPI1 bus display - let mut config = spi::Config::default(); - config.frequency = 16_000_000; - let spi1 = spi::Spi::new( - p.SPI1, p.PIN_10, p.PIN_11, p.PIN_12, p.DMA_CH0, p.DMA_CH1, config, - ); + Timer::after_millis(250).await; - let usb = embassy_rp_usb::Driver::new(p.USB, Irqs); + let display_fut = { + let mut config = spi::Config::default(); + config.frequency = 16_000_000; + let spi = Spi::new( + p.SPI1, p.PIN_10, p.PIN_11, p.PIN_12, p.DMA_CH0, p.DMA_CH1, config, + ); + let cs = p.PIN_13; + let data = p.PIN_14; + let reset = p.PIN_15; + + let display = init_display(spi, cs, data, reset).await; + display_handler(display) + }; + defmt::info!("ready"); let sdcard = { let mut config = spi::Config::default(); config.frequency = 400_000; - let spi = Spi::new_blocking( - p.SPI0, - p.PIN_18, // clk - p.PIN_19, // mosi - p.PIN_16, // miso - config.clone(), - ); + let clk = p.PIN_18; + let mosi = p.PIN_19; + let miso = p.PIN_16; + let spi = Spi::new_blocking(p.SPI0, clk, mosi, miso, config.clone()); let cs = Output::new(p.PIN_17, Level::High); let det = Input::new(p.PIN_22, Pull::None); @@ -84,18 +97,16 @@ async fn main(_spawner: Spawner) { SdCard::new(sdcard, det) }; - usb_handler(usb, sdcard).await; -} + let usb = embassy_rp_usb::Driver::new(p.USB, Irqs); + let usb_fut = usb_handler(usb, sdcard); -use abi::Syscall; + Text::new( + "Framebuffer works", + Point::new(100, 100), + MonoTextStyle::new(&FONT_6X10, Rgb565::GREEN), + ) + .draw(*FRAMEBUFFER.lock().await.get_mut().as_mut().unwrap()) + .unwrap(); -#[no_mangle] -pub extern "C" fn syscall_dispatch(call: *const Syscall) -> usize { - let call = unsafe { &*call }; - match call { - Syscall::DrawPixels { x, y, color } => { - draw_pixel(*x, *y, *color); - 0 - } - } + display_fut.await; }