fix framebuffer crash

This commit is contained in:
2025-09-04 18:33:43 -06:00
parent 5d0a3608d1
commit ec25ee8601
4 changed files with 34 additions and 40 deletions

View File

@@ -24,17 +24,23 @@ pub extern "Rust" fn print(msg: &str) {
defmt::info!("{:?}", msg); defmt::info!("{:?}", msg);
} }
// TODO: maybe return result
pub extern "Rust" fn draw_iter(pixels: &[Pixel<Rgb565>]) { pub extern "Rust" fn draw_iter(pixels: &[Pixel<Rgb565>]) {
let framebuffer = block_on(FRAMEBUFFER.lock()); for _ in 0..10 {
framebuffer if let Some(mut framebuffer) = FRAMEBUFFER.try_lock().ok() {
.borrow_mut() for _ in 0..10 {
.as_mut() // kernel takes() framebuffer
.unwrap() if let Some(framebuffer) = framebuffer.as_mut() {
.draw_iter(pixels.iter().copied()) framebuffer.draw_iter(pixels.iter().copied()).unwrap();
.unwrap(); }
break;
}
break;
}
cortex_m::asm::nop();
}
} }
pub extern "Rust" fn get_key() -> Option<KeyEvent> { pub extern "Rust" fn get_key() -> Option<KeyEvent> {
defmt::info!("get key called");
unsafe { KEY_CACHE.dequeue() } unsafe { KEY_CACHE.dequeue() }
} }

View File

@@ -1,10 +1,9 @@
use core::cell::RefCell;
use embassy_rp::{ use embassy_rp::{
gpio::{Level, Output}, gpio::{Level, Output},
peripherals::{PIN_13, PIN_14, PIN_15, SPI1}, peripherals::{PIN_13, PIN_14, PIN_15, SPI1},
spi::{Async, Spi}, spi::{Async, Spi},
}; };
use embassy_sync::{blocking_mutex::raw::ThreadModeRawMutex, mutex::Mutex}; use embassy_sync::{blocking_mutex::raw::CriticalSectionRawMutex, mutex::Mutex};
use embassy_time::{Delay, Timer}; use embassy_time::{Delay, Timer};
use embedded_hal_bus::spi::ExclusiveDevice; use embedded_hal_bus::spi::ExclusiveDevice;
use st7365p_lcd::{FrameBuffer, ST7365P}; use st7365p_lcd::{FrameBuffer, ST7365P};
@@ -22,8 +21,7 @@ pub const SCREEN_HEIGHT: usize = 320;
type FB = FrameBuffer<SCREEN_WIDTH, SCREEN_HEIGHT, { SCREEN_WIDTH * SCREEN_HEIGHT }>; type FB = FrameBuffer<SCREEN_WIDTH, SCREEN_HEIGHT, { SCREEN_WIDTH * SCREEN_HEIGHT }>;
static FRAMEBUFFER_CELL: StaticCell<FB> = StaticCell::new(); static FRAMEBUFFER_CELL: StaticCell<FB> = StaticCell::new();
pub static FRAMEBUFFER: Mutex<ThreadModeRawMutex, RefCell<Option<&'static mut FB>>> = pub static FRAMEBUFFER: Mutex<CriticalSectionRawMutex, Option<&'static mut FB>> = Mutex::new(None);
Mutex::new(RefCell::new(None));
pub async fn init_display( pub async fn init_display(
spi: Spi<'static, SPI1, Async>, spi: Spi<'static, SPI1, Async>,
@@ -45,25 +43,23 @@ pub async fn init_display(
display.set_custom_orientation(0x40).await.unwrap(); display.set_custom_orientation(0x40).await.unwrap();
framebuffer.draw(&mut display).await.unwrap(); framebuffer.draw(&mut display).await.unwrap();
display.set_on().await.unwrap(); display.set_on().await.unwrap();
FRAMEBUFFER FRAMEBUFFER.lock().await.replace(framebuffer);
.lock()
.await
.swap(&RefCell::new(Some(framebuffer)));
display display
} }
pub async fn display_handler(mut display: DISPLAY) { pub async fn display_handler(mut display: DISPLAY) {
loop { loop {
FRAMEBUFFER let fb: &mut FB = {
.lock() let mut guard = FRAMEBUFFER.lock().await;
.await guard.take().unwrap() // take ownership
.borrow_mut() }; // guard dropped
.as_mut()
.unwrap() fb.partial_draw_batched(&mut display).await.unwrap();
.partial_draw_batched(&mut display)
.await // Put it back
.unwrap(); FRAMEBUFFER.lock().await.replace(fb);
Timer::after_millis(32).await; // 30 fps Timer::after_millis(32).await; // 30 fps
} }
} }

View File

@@ -181,8 +181,6 @@ async fn kernel_task(display: Display, sd: Sd, mcu: Mcu, usb: USB) {
); );
let display = init_display(spi, display.cs, display.data, display.reset).await; let display = init_display(spi, display.cs, display.data, display.reset).await;
DRIVERS_READY.signal(());
let display_fut = display_handler(display); let display_fut = display_handler(display);
{ {
@@ -204,6 +202,7 @@ async fn kernel_task(display: Display, sd: Sd, mcu: Mcu, usb: USB) {
let usb_fut = usb_handler(usb); let usb_fut = usb_handler(usb);
ENABLE_SCSI.store(true, core::sync::atomic::Ordering::Relaxed); ENABLE_SCSI.store(true, core::sync::atomic::Ordering::Relaxed);
DRIVERS_READY.signal(());
join3(usb_fut, display_fut, async { join3(usb_fut, display_fut, async {
loop { loop {
Timer::after_millis(100).await; Timer::after_millis(100).await;

View File

@@ -51,6 +51,9 @@ impl<const MAX_SELECTIONS: usize, const MAX_STR_LEN: usize> UI<MAX_SELECTIONS, M
} }
async fn draw_selection(&mut self) { async fn draw_selection(&mut self) {
let mut fb_lock = FRAMEBUFFER.lock().await;
let fb = fb_lock.as_mut().unwrap();
let text_style = MonoTextStyle::new(&FONT_9X15, Rgb565::WHITE); let text_style = MonoTextStyle::new(&FONT_9X15, Rgb565::WHITE);
let selection = Rectangle::new( let selection = Rectangle::new(
@@ -62,7 +65,7 @@ impl<const MAX_SELECTIONS: usize, const MAX_STR_LEN: usize> UI<MAX_SELECTIONS, M
let Some(first) = file_names.next() else { 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", Text::new("No Programs found on SD Card\nEnsure programs end with '.bin',\nand are located in the root directory",
Point::zero(), text_style).draw(*FRAMEBUFFER.lock().await.borrow_mut().as_mut().unwrap()).unwrap(); Point::zero(), text_style).draw(*fb).unwrap();
return; return;
}; };
@@ -72,18 +75,8 @@ impl<const MAX_SELECTIONS: usize, const MAX_STR_LEN: usize> UI<MAX_SELECTIONS, M
LinearLayout::vertical(chain) LinearLayout::vertical(chain)
.with_alignment(horizontal::Center) .with_alignment(horizontal::Center)
.arrange() .arrange()
.align_to( .align_to(&fb.bounding_box(), horizontal::Center, vertical::Center)
&FRAMEBUFFER .draw(*fb)
.lock()
.await
.borrow_mut()
.as_mut()
.unwrap()
.bounding_box(),
horizontal::Center,
vertical::Center,
)
.draw(*FRAMEBUFFER.lock().await.borrow_mut().as_mut().unwrap())
.unwrap(); .unwrap();
} }
} }