remove screen tearing

This commit is contained in:
2025-09-18 19:20:20 -06:00
parent 9468ceab51
commit e628c47e4b
8 changed files with 53 additions and 25 deletions

View File

@@ -1,13 +1,19 @@
use abi_sys::{DrawIterAbi, GetKeyAbi, PrintAbi, SleepAbi};
use core::sync::atomic::Ordering;
use abi_sys::{DrawIterAbi, GetKeyAbi, LockDisplay, PrintAbi, SleepAbi};
use embassy_rp::clocks::clk_sys_freq;
use embedded_graphics::{Pixel, draw_target::DrawTarget, pixelcolor::Rgb565};
use shared::keyboard::KeyEvent;
use crate::{KEY_CACHE, display::FRAMEBUFFER};
use crate::{
KEY_CACHE,
display::{FB_PAUSED, FRAMEBUFFER},
};
// ensure the abi and the kernel fn signatures are the same
const _: PrintAbi = print;
const _: SleepAbi = sleep;
const _: LockDisplay = lock_display;
const _: DrawIterAbi = draw_iter;
const _: GetKeyAbi = get_key;
@@ -24,6 +30,10 @@ pub extern "Rust" fn sleep(ms: u64) {
}
}
pub extern "Rust" fn lock_display(lock: bool) {
FB_PAUSED.store(lock, Ordering::Relaxed);
}
// TODO: maybe return result
pub extern "Rust" fn draw_iter(pixels: &[Pixel<Rgb565>]) {
unsafe { FRAMEBUFFER.draw_iter(pixels.iter().copied()).unwrap() }

View File

@@ -1,3 +1,5 @@
use core::sync::atomic::{AtomicBool, Ordering};
use crate::framebuffer::AtomicFrameBuffer;
use embassy_rp::{
Peri,
@@ -24,6 +26,7 @@ pub const SCREEN_WIDTH: usize = 320;
pub const SCREEN_HEIGHT: usize = 320;
pub static mut FRAMEBUFFER: AtomicFrameBuffer = AtomicFrameBuffer::new();
pub static FB_PAUSED: AtomicBool = AtomicBool::new(false);
pub async fn init_display(
spi: Spi<'static, SPI1, Async>,
@@ -48,20 +51,16 @@ pub async fn init_display(
display
}
pub fn clear_fb() {
unsafe {
FRAMEBUFFER.clear(Rgb565::WHITE).unwrap();
}
}
#[embassy_executor::task]
pub async fn display_handler(mut display: DISPLAY) {
loop {
unsafe {
FRAMEBUFFER
.partial_draw_batched(&mut display)
.await
.unwrap()
if !FB_PAUSED.load(Ordering::Acquire) {
unsafe {
FRAMEBUFFER
.partial_draw_batched(&mut display)
.await
.unwrap()
}
}
Timer::after_millis(32).await; // 30 fps

View File

@@ -54,6 +54,7 @@ pub async unsafe fn load_binary(name: &ShortFileName) -> Result<EntryFn, &str> {
let entries: &[(CallAbiTable, usize)] = &[
(CallAbiTable::Print, abi::print as usize),
(CallAbiTable::Sleep, abi::sleep as usize),
(CallAbiTable::LockDisplay, abi::lock_display as usize),
(CallAbiTable::DrawIter, abi::draw_iter as usize),
(CallAbiTable::GetKey, abi::get_key as usize),
];

View File

@@ -29,7 +29,6 @@ use crate::{
ui::{SELECTIONS, clear_selection, ui_handler},
};
use abi_sys::EntryFn;
use alloc::string::String;
use embedded_graphics::{
pixelcolor::Rgb565,
prelude::{DrawTarget, RgbColor},

View File

@@ -1,15 +1,16 @@
use crate::{
BINARY_CH, display::FRAMEBUFFER, elf::load_binary, peripherals::keyboard, storage::FileName,
BINARY_CH,
display::{FB_PAUSED, FRAMEBUFFER},
elf::load_binary,
peripherals::keyboard,
storage::FileName,
};
use alloc::{str::FromStr, string::String, vec::Vec};
use core::sync::atomic::Ordering;
use embassy_sync::{blocking_mutex::raw::CriticalSectionRawMutex, mutex::Mutex};
use embassy_time::Timer;
use embedded_graphics::{
Drawable,
mono_font::{
MonoTextStyle,
ascii::{FONT_9X15, FONT_10X20},
},
mono_font::{MonoTextStyle, ascii::FONT_10X20},
pixelcolor::Rgb565,
prelude::{Dimensions, Point, Primitive, RgbColor, Size},
primitives::{PrimitiveStyle, Rectangle},
@@ -81,6 +82,8 @@ async fn draw_selection() {
const NO_BINS: &str = "No Programs found on SD Card. Ensure programs end with '.bin', and are located in the root directory";
let no_bins = String::from_str(NO_BINS).unwrap();
FB_PAUSED.store(true, Ordering::Release); // ensure all elements show up at once
if file_names.is_empty() {
TextBox::new(
&no_bins,
@@ -124,6 +127,7 @@ async fn draw_selection() {
}
guard.changed = false;
FB_PAUSED.store(false, Ordering::Release); // ensure all elements show up at once
}
#[derive(Clone)]