mirror of
https://github.com/LegitCamper/picocalc-os-rs.git
synced 2025-12-27 15:55:25 +00:00
fix framebuffer crash
This commit is contained in:
@@ -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() }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user