make all syscalls ffi compat
This commit is contained in:
@@ -25,11 +25,12 @@ pub fn get_key() -> KeyEvent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub mod display {
|
pub mod display {
|
||||||
|
use abi_sys::CPixel;
|
||||||
use embedded_graphics::{
|
use embedded_graphics::{
|
||||||
Pixel,
|
Pixel,
|
||||||
geometry::{Dimensions, Point},
|
geometry::{Dimensions, Point},
|
||||||
pixelcolor::{Rgb565, RgbColor},
|
pixelcolor::{Rgb565, RgbColor},
|
||||||
prelude::{DrawTarget, Size},
|
prelude::{DrawTarget, IntoStorage, Size},
|
||||||
primitives::Rectangle,
|
primitives::Rectangle,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -42,8 +43,27 @@ pub mod display {
|
|||||||
abi_sys::lock_display(lock);
|
abi_sys::lock_display(lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const BUF_SIZE: usize = 1024; // tune this for performance
|
||||||
|
|
||||||
fn draw_iter(pixels: &[Pixel<Rgb565>]) {
|
fn draw_iter(pixels: &[Pixel<Rgb565>]) {
|
||||||
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;
|
pub struct Display;
|
||||||
@@ -68,7 +88,6 @@ pub mod display {
|
|||||||
where
|
where
|
||||||
I: IntoIterator<Item = Pixel<Self::Color>>,
|
I: IntoIterator<Item = Pixel<Self::Color>>,
|
||||||
{
|
{
|
||||||
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 buf: [Pixel565; BUF_SIZE] = [Pixel(Point::new(0, 0), Rgb565::BLACK); BUF_SIZE];
|
||||||
|
|
||||||
let mut count = 0;
|
let mut count = 0;
|
||||||
|
|||||||
@@ -1,10 +1,16 @@
|
|||||||
#![no_std]
|
#![no_std]
|
||||||
|
|
||||||
use embedded_graphics::{Pixel, pixelcolor::Rgb565};
|
use embedded_graphics::{
|
||||||
|
Pixel,
|
||||||
|
pixelcolor::Rgb565,
|
||||||
|
prelude::{IntoStorage, Point},
|
||||||
|
};
|
||||||
use embedded_sdmmc::DirEntry;
|
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)]
|
#[repr(u8)]
|
||||||
pub enum CallAbiTable {
|
pub enum CallAbiTable {
|
||||||
PrintString = 0,
|
PrintString = 0,
|
||||||
@@ -17,11 +23,12 @@ pub enum CallAbiTable {
|
|||||||
ReadFile = 7,
|
ReadFile = 7,
|
||||||
FileLen = 8,
|
FileLen = 8,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type EntryFn = fn();
|
pub type EntryFn = fn();
|
||||||
|
|
||||||
#[unsafe(no_mangle)]
|
#[unsafe(no_mangle)]
|
||||||
#[unsafe(link_section = ".syscall_table")]
|
#[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);
|
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);
|
f(lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type DrawIterAbi = extern "C" fn(ptr: *const Pixel<Rgb565>, len: usize);
|
#[repr(C)]
|
||||||
|
#[derive(Copy, Clone)]
|
||||||
|
pub struct CPixel {
|
||||||
|
pub x: i32,
|
||||||
|
pub y: i32,
|
||||||
|
pub color: u16,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Into<CPixel> for Pixel<Rgb565> {
|
||||||
|
fn into(self) -> CPixel {
|
||||||
|
CPixel {
|
||||||
|
x: self.0.x,
|
||||||
|
y: self.0.y,
|
||||||
|
color: self.1.into_storage(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Into<Pixel<Rgb565>> for CPixel {
|
||||||
|
fn into(self) -> Pixel<Rgb565> {
|
||||||
|
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)]
|
#[unsafe(no_mangle)]
|
||||||
pub extern "C" fn draw_iter(ptr: *const Pixel<Rgb565>, len: usize) {
|
pub extern "C" fn draw_iter(ptr: *const CPixel, len: usize) {
|
||||||
let f: DrawIterAbi =
|
let f: DrawIterAbi =
|
||||||
unsafe { core::mem::transmute(CALL_ABI_TABLE[CallAbiTable::DrawIter as usize]) };
|
unsafe { core::mem::transmute(CALL_ABI_TABLE[CallAbiTable::DrawIter as usize]) };
|
||||||
f(ptr, len);
|
f(ptr, len);
|
||||||
|
|||||||
4
cbindgen.toml
Normal file
4
cbindgen.toml
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
language = "C"
|
||||||
|
|
||||||
|
[macro_expansion]
|
||||||
|
bitflags = true
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
use abi_sys::{
|
use abi_sys::{
|
||||||
DrawIterAbi, FileLen, GenRand, ListDir, LockDisplay, PrintAbi, ReadFile, RngRequest, SleepAbi,
|
CPixel, DrawIterAbi, FileLen, GenRand, ListDir, LockDisplay, PrintAbi, ReadFile, RngRequest,
|
||||||
keyboard::*,
|
SleepAbi, keyboard::*,
|
||||||
};
|
};
|
||||||
use alloc::{string::ToString, vec::Vec};
|
use alloc::{string::ToString, vec::Vec};
|
||||||
use core::sync::atomic::Ordering;
|
use core::sync::atomic::Ordering;
|
||||||
@@ -43,10 +43,12 @@ pub extern "C" fn lock_display(lock: bool) {
|
|||||||
|
|
||||||
const _: DrawIterAbi = draw_iter;
|
const _: DrawIterAbi = draw_iter;
|
||||||
// TODO: maybe return result
|
// TODO: maybe return result
|
||||||
pub extern "C" fn draw_iter(pixels: *const Pixel<Rgb565>, len: usize) {
|
pub extern "C" fn draw_iter(cpixels: *const CPixel, len: usize) {
|
||||||
// SAFETY: caller guarantees `ptr` is valid for `len` bytes
|
// SAFETY: caller guarantees `ptr` is valid for `len` bytes
|
||||||
let pixels = unsafe { core::slice::from_raw_parts(pixels, len) };
|
let cpixels = unsafe { core::slice::from_raw_parts(cpixels, len) };
|
||||||
unsafe { FRAMEBUFFER.draw_iter(pixels.iter().copied()).unwrap() }
|
|
||||||
|
let iter = cpixels.iter().copied().map(|c: CPixel| c.into());
|
||||||
|
unsafe { FRAMEBUFFER.draw_iter(iter).unwrap() }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub static mut KEY_CACHE: Queue<KeyEvent, 32> = Queue::new();
|
pub static mut KEY_CACHE: Queue<KeyEvent, 32> = Queue::new();
|
||||||
|
|||||||
Reference in New Issue
Block a user