diff --git a/abi/src/lib.rs b/abi/src/lib.rs index e8daf7c..efbb865 100644 --- a/abi/src/lib.rs +++ b/abi/src/lib.rs @@ -25,11 +25,12 @@ pub fn get_key() -> KeyEvent { } pub mod display { + use abi_sys::CPixel; use embedded_graphics::{ Pixel, geometry::{Dimensions, Point}, pixelcolor::{Rgb565, RgbColor}, - prelude::{DrawTarget, Size}, + prelude::{DrawTarget, IntoStorage, Size}, primitives::Rectangle, }; @@ -42,8 +43,27 @@ pub mod display { abi_sys::lock_display(lock); } + const BUF_SIZE: usize = 1024; // tune this for performance + fn draw_iter(pixels: &[Pixel]) { - abi_sys::draw_iter(pixels.as_ptr(), pixels.len()) + let mut cpixels: [CPixel; BUF_SIZE] = [const { + CPixel { + x: 0, + y: 0, + color: 0, + } + }; BUF_SIZE]; + for (px, cpx) in pixels.iter().zip(cpixels.iter_mut()) { + let Pixel(pos, color) = px; + let color: u16 = color.into_storage(); // convert Rgb565 -> u16 + *cpx = CPixel { + x: pos.x, + y: pos.y, + color, + }; + } + + abi_sys::draw_iter(cpixels.as_ptr(), cpixels.len()) } pub struct Display; @@ -68,7 +88,6 @@ pub mod display { where I: IntoIterator>, { - const BUF_SIZE: usize = 1024; // tune this for performance let mut buf: [Pixel565; BUF_SIZE] = [Pixel(Point::new(0, 0), Rgb565::BLACK); BUF_SIZE]; let mut count = 0; diff --git a/abi_sys/src/lib.rs b/abi_sys/src/lib.rs index 89c0427..5f0aa78 100644 --- a/abi_sys/src/lib.rs +++ b/abi_sys/src/lib.rs @@ -1,10 +1,16 @@ #![no_std] -use embedded_graphics::{Pixel, pixelcolor::Rgb565}; +use embedded_graphics::{ + Pixel, + pixelcolor::Rgb565, + prelude::{IntoStorage, Point}, +}; use embedded_sdmmc::DirEntry; -use strum::{EnumCount, EnumIter}; +use strum::EnumIter; -#[derive(Clone, Copy, EnumIter, EnumCount)] +pub const ABI_CALL_TABLE_COUNT: usize = 9; + +#[derive(Clone, Copy, EnumIter)] #[repr(u8)] pub enum CallAbiTable { PrintString = 0, @@ -17,11 +23,12 @@ pub enum CallAbiTable { ReadFile = 7, FileLen = 8, } + pub type EntryFn = fn(); #[unsafe(no_mangle)] #[unsafe(link_section = ".syscall_table")] -pub static mut CALL_ABI_TABLE: [usize; CallAbiTable::COUNT] = [0; CallAbiTable::COUNT]; +pub static mut CALL_ABI_TABLE: [usize; ABI_CALL_TABLE_COUNT] = [0; ABI_CALL_TABLE_COUNT]; pub type PrintAbi = extern "C" fn(ptr: *const u8, len: usize); @@ -50,10 +57,37 @@ pub extern "C" fn lock_display(lock: bool) { f(lock); } -pub type DrawIterAbi = extern "C" fn(ptr: *const Pixel, len: usize); +#[repr(C)] +#[derive(Copy, Clone)] +pub struct CPixel { + pub x: i32, + pub y: i32, + pub color: u16, +} + +impl Into for Pixel { + fn into(self) -> CPixel { + CPixel { + x: self.0.x, + y: self.0.y, + color: self.1.into_storage(), + } + } +} + +impl Into> for CPixel { + fn into(self) -> Pixel { + let r5 = ((self.color >> 11) & 0x1F) as u8; + let g6 = ((self.color >> 5) & 0x3F) as u8; + let b5 = (self.color & 0x1F) as u8; + Pixel(Point::new(self.x, self.y), Rgb565::new(r5, g6, b5)) + } +} + +pub type DrawIterAbi = extern "C" fn(ptr: *const CPixel, len: usize); #[unsafe(no_mangle)] -pub extern "C" fn draw_iter(ptr: *const Pixel, len: usize) { +pub extern "C" fn draw_iter(ptr: *const CPixel, len: usize) { let f: DrawIterAbi = unsafe { core::mem::transmute(CALL_ABI_TABLE[CallAbiTable::DrawIter as usize]) }; f(ptr, len); diff --git a/cbindgen.toml b/cbindgen.toml new file mode 100644 index 0000000..56fe889 --- /dev/null +++ b/cbindgen.toml @@ -0,0 +1,4 @@ +language = "C" + +[macro_expansion] +bitflags = true diff --git a/kernel/src/abi.rs b/kernel/src/abi.rs index e61bc24..9f1a607 100644 --- a/kernel/src/abi.rs +++ b/kernel/src/abi.rs @@ -1,6 +1,6 @@ use abi_sys::{ - DrawIterAbi, FileLen, GenRand, ListDir, LockDisplay, PrintAbi, ReadFile, RngRequest, SleepAbi, - keyboard::*, + CPixel, DrawIterAbi, FileLen, GenRand, ListDir, LockDisplay, PrintAbi, ReadFile, RngRequest, + SleepAbi, keyboard::*, }; use alloc::{string::ToString, vec::Vec}; use core::sync::atomic::Ordering; @@ -43,10 +43,12 @@ pub extern "C" fn lock_display(lock: bool) { const _: DrawIterAbi = draw_iter; // TODO: maybe return result -pub extern "C" fn draw_iter(pixels: *const Pixel, len: usize) { +pub extern "C" fn draw_iter(cpixels: *const CPixel, len: usize) { // SAFETY: caller guarantees `ptr` is valid for `len` bytes - let pixels = unsafe { core::slice::from_raw_parts(pixels, len) }; - unsafe { FRAMEBUFFER.draw_iter(pixels.iter().copied()).unwrap() } + let cpixels = unsafe { core::slice::from_raw_parts(cpixels, len) }; + + let iter = cpixels.iter().copied().map(|c: CPixel| c.into()); + unsafe { FRAMEBUFFER.draw_iter(iter).unwrap() } } pub static mut KEY_CACHE: Queue = Queue::new();