diff --git a/.gitignore b/.gitignore index 84faace..f73c1bf 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ /target *.uf2 +abi_sys.h diff --git a/Cargo.lock b/Cargo.lock index d5cafc5..21df7c7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -18,6 +18,7 @@ version = "0.1.0" dependencies = [ "abi_sys", "embedded-graphics", + "embedded-sdmmc", "rand_core 0.9.3", "shared", "spin", @@ -28,10 +29,11 @@ dependencies = [ name = "abi_sys" version = "0.1.0" dependencies = [ + "bitflags 2.9.4", + "cbindgen", "defmt 0.3.100", "embedded-graphics", "embedded-sdmmc", - "shared", "strum", ] @@ -95,6 +97,17 @@ dependencies = [ "critical-section", ] +[[package]] +name = "atty" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" +dependencies = [ + "hermit-abi 0.1.19", + "libc", + "winapi", +] + [[package]] name = "autocfg" version = "1.5.0" @@ -239,12 +252,55 @@ dependencies = [ "embedded-layout", ] +[[package]] +name = "cbindgen" +version = "0.24.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b922faaf31122819ec80c4047cc684c6979a087366c069611e33649bf98e18d" +dependencies = [ + "clap", + "heck 0.4.1", + "indexmap 1.9.3", + "log", + "proc-macro2", + "quote", + "serde", + "serde_json", + "syn 1.0.109", + "tempfile", + "toml", +] + [[package]] name = "cfg-if" version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2fd1289c04a9ea8cb22300a459a72a385d7c73d3259e2ed7dcb2af674838cfa9" +[[package]] +name = "clap" +version = "3.2.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ea181bf566f71cb9a5d17a59e1871af638180a18fb0035c92ae62b705207123" +dependencies = [ + "atty", + "bitflags 1.3.2", + "clap_lex", + "indexmap 1.9.3", + "strsim 0.10.0", + "termcolor", + "textwrap", +] + +[[package]] +name = "clap_lex" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2850f2f5a82cbf437dd5af4d49848fbdfc27c157c3d010345776f952765261c5" +dependencies = [ + "os_str_bytes", +] + [[package]] name = "codespan-reporting" version = "0.11.1" @@ -380,7 +436,7 @@ dependencies = [ "ident_case", "proc-macro2", "quote", - "strsim", + "strsim 0.11.1", "syn 2.0.106", ] @@ -1015,6 +1071,22 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" +[[package]] +name = "errno" +version = "0.3.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" +dependencies = [ + "libc", + "windows-sys 0.61.0", +] + +[[package]] +name = "fastrand" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" + [[package]] name = "fixed" version = "1.29.0" @@ -1176,7 +1248,19 @@ checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592" dependencies = [ "cfg-if", "libc", - "wasi", + "wasi 0.11.1+wasi-snapshot-preview1", +] + +[[package]] +name = "getrandom" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26145e563e54f2cadc477553f1ec5ee650b00862f0a58bcd12cbdc5f0ea2d2f4" +dependencies = [ + "cfg-if", + "libc", + "r-efi", + "wasi 0.14.7+wasi-0.2.4", ] [[package]] @@ -1208,6 +1292,12 @@ dependencies = [ "byteorder", ] +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" + [[package]] name = "hashbrown" version = "0.13.2" @@ -1234,12 +1324,27 @@ dependencies = [ "stable_deref_trait", ] +[[package]] +name = "heck" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" + [[package]] name = "heck" version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" +[[package]] +name = "hermit-abi" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" +dependencies = [ + "libc", +] + [[package]] name = "hermit-abi" version = "0.5.2" @@ -1252,6 +1357,16 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" +[[package]] +name = "indexmap" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" +dependencies = [ + "autocfg", + "hashbrown 0.12.3", +] + [[package]] name = "indexmap" version = "2.11.4" @@ -1268,7 +1383,7 @@ version = "0.4.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e04d7f318608d35d4b61ddd75cbdaee86b023ebe2bd5a66ee0915f0bf93095a9" dependencies = [ - "hermit-abi", + "hermit-abi 0.5.2", "libc", "windows-sys 0.59.0", ] @@ -1291,6 +1406,12 @@ dependencies = [ "either", ] +[[package]] +name = "itoa" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" + [[package]] name = "js-sys" version = "0.3.80" @@ -1454,6 +1575,12 @@ dependencies = [ "libc", ] +[[package]] +name = "linux-raw-sys" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df1d3c3b53da64cf5760482273a98e575c651a67eec7f77df96b5b642de8f039" + [[package]] name = "litrs" version = "0.4.2" @@ -1571,6 +1698,12 @@ version = "1.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" +[[package]] +name = "os_str_bytes" +version = "6.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2355d85b9a3786f481747ced0e0ff2ba35213a1f9bd406ed906554d7af805a1" + [[package]] name = "panic-probe" version = "0.3.2" @@ -1617,7 +1750,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b4c5cc86750666a3ed20bdaf5ca2a0344f9c67674cae0515bec2da16fbaa47db" dependencies = [ "fixedbitset 0.4.2", - "indexmap", + "indexmap 2.11.4", ] [[package]] @@ -1627,7 +1760,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3672b37090dbd86368a4145bc067582552b29c27377cad4e0a306c97f9bd7772" dependencies = [ "fixedbitset 0.5.7", - "indexmap", + "indexmap 2.11.4", ] [[package]] @@ -1830,6 +1963,12 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "r-efi" +version = "5.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" + [[package]] name = "radium" version = "0.7.0" @@ -1872,7 +2011,7 @@ version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ba009ff324d1fc1b900bd1fdb31564febe58a8ccc8a6fdbb93b543d33b13ca43" dependencies = [ - "getrandom", + "getrandom 0.2.16", "libredox", "thiserror 1.0.69", ] @@ -1949,12 +2088,31 @@ dependencies = [ "semver", ] +[[package]] +name = "rustix" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd15f8a2c5551a84d56efdc1cd049089e409ac19a3072d5037a17fd70719ff3e" +dependencies = [ + "bitflags 2.9.4", + "errno", + "libc", + "linux-raw-sys", + "windows-sys 0.61.0", +] + [[package]] name = "rustversion" version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" +[[package]] +name = "ryu" +version = "1.0.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" + [[package]] name = "same-file" version = "1.0.6" @@ -1998,6 +2156,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fd6c24dee235d0da097043389623fb913daddf92c76e9f5a1db88607a0bcbd1d" dependencies = [ "serde_core", + "serde_derive", ] [[package]] @@ -2020,6 +2179,19 @@ dependencies = [ "syn 2.0.106", ] +[[package]] +name = "serde_json" +version = "1.0.145" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "402a6f66d8c709116cf22f558eab210f5a50187f702eb4d7e5ef38d9a7f1c79c" +dependencies = [ + "itoa", + "memchr", + "ryu", + "serde", + "serde_core", +] + [[package]] name = "sha2-const-stable" version = "0.1.0" @@ -2040,8 +2212,9 @@ dependencies = [ name = "shared" version = "0.1.0" dependencies = [ + "abi_sys", "bitflags 2.9.4", - "defmt 1.0.1", + "defmt 0.3.100", ] [[package]] @@ -2149,6 +2322,12 @@ dependencies = [ "precomputed-hash", ] +[[package]] +name = "strsim" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" + [[package]] name = "strsim" version = "0.11.1" @@ -2170,7 +2349,7 @@ version = "0.27.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7695ce3845ea4b33927c055a39dc438a45b059f7c1b3d91d38d10355fb8cbca7" dependencies = [ - "heck", + "heck 0.5.0", "proc-macro2", "quote", "syn 2.0.106", @@ -2213,6 +2392,19 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" +[[package]] +name = "tempfile" +version = "3.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d31c77bdf42a745371d260a26ca7163f1e0924b64afa0b688e61b5a9fa02f16" +dependencies = [ + "fastrand", + "getrandom 0.3.3", + "once_cell", + "rustix", + "windows-sys 0.61.0", +] + [[package]] name = "term" version = "0.7.0" @@ -2242,6 +2434,12 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "textwrap" +version = "0.16.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c13547615a44dc9c452a8a534638acdf07120d4b6847c8178705da06306a3057" + [[package]] name = "thiserror" version = "1.0.69" @@ -2300,6 +2498,15 @@ dependencies = [ "embedded-graphics", ] +[[package]] +name = "toml" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234" +dependencies = [ + "serde", +] + [[package]] name = "trouble-host" version = "0.1.0" @@ -2457,6 +2664,24 @@ version = "0.11.1+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" +[[package]] +name = "wasi" +version = "0.14.7+wasi-0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "883478de20367e224c0090af9cf5f9fa85bed63a95c1abf3afc5c083ebc06e8c" +dependencies = [ + "wasip2", +] + +[[package]] +name = "wasip2" +version = "1.0.1+wasi-0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0562428422c63773dad2c345a1882263bbf4d65cf3f42e90921f787ef5ad58e7" +dependencies = [ + "wit-bindgen", +] + [[package]] name = "wasm-bindgen" version = "0.2.103" @@ -2635,6 +2860,12 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" +[[package]] +name = "wit-bindgen" +version = "0.46.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f17a85883d4e6d00e8a97c586de764dabcc06133f7f1d55dce5cdc070ad7fe59" + [[package]] name = "wyz" version = "0.5.1" diff --git a/abi/Cargo.toml b/abi/Cargo.toml index 3d46683..bb7337f 100644 --- a/abi/Cargo.toml +++ b/abi/Cargo.toml @@ -4,6 +4,7 @@ version = "0.1.0" edition = "2024" [dependencies] +embedded-sdmmc = { version = "0.9.0", default-features = false } embedded-graphics = "0.8.1" shared = { path = "../shared" } abi_sys = { path = "../abi_sys" } diff --git a/abi/src/lib.rs b/abi/src/lib.rs index 271c445..e8daf7c 100644 --- a/abi/src/lib.rs +++ b/abi/src/lib.rs @@ -1,9 +1,8 @@ #![no_std] -use abi_sys::{RngRequest, draw_iter, gen_rand}; -pub use abi_sys::{file_len, list_dir, lock_display, print, read_file, sleep}; +pub use abi_sys::keyboard; +use abi_sys::{RngRequest, keyboard::KeyEvent}; use rand_core::RngCore; -pub use shared::keyboard::{KeyCode, KeyEvent, KeyState, Modifiers}; use talc::*; static mut ARENA: [u8; 10000] = [0; 10000]; @@ -13,12 +12,19 @@ static ALLOCATOR: Talck, ClaimOnOom> = Talc::new(unsafe { ClaimOnOom::new(Span::from_array(core::ptr::addr_of!(ARENA).cast_mut())) }) .lock(); +pub fn print(msg: &str) { + abi_sys::print(msg.as_ptr(), msg.len()); +} + +pub fn sleep(ms: u64) { + abi_sys::sleep(ms); +} + pub fn get_key() -> KeyEvent { - abi_sys::get_key().into() + abi_sys::keyboard::get_key().into() } pub mod display { - use crate::draw_iter; use embedded_graphics::{ Pixel, geometry::{Dimensions, Point}, @@ -32,6 +38,14 @@ pub mod display { pub type Pixel565 = Pixel; + pub fn lock_display(lock: bool) { + abi_sys::lock_display(lock); + } + + fn draw_iter(pixels: &[Pixel]) { + abi_sys::draw_iter(pixels.as_ptr(), pixels.len()) + } + pub struct Display; impl Dimensions for Display { @@ -77,6 +91,10 @@ pub mod display { } } +fn gen_rand(req: &mut RngRequest) { + abi_sys::gen_rand(req); +} + pub struct Rng; impl RngCore for Rng { @@ -105,3 +123,25 @@ impl RngCore for Rng { gen_rand(&mut req); } } + +pub mod fs { + use embedded_sdmmc::DirEntry; + + pub fn read_file(file: &str, read_from: usize, buf: &mut [u8]) -> usize { + abi_sys::read_file( + file.as_ptr(), + file.len(), + read_from, + buf.as_mut_ptr(), + buf.len(), + ) + } + + pub fn list_dir(path: &str, files: &mut [Option]) -> usize { + abi_sys::list_dir(path.as_ptr(), path.len(), files.as_mut_ptr(), files.len()) + } + + pub fn file_len(str: &str) -> usize { + abi_sys::file_len(str.as_ptr(), str.len()) + } +} diff --git a/abi_sys/Cargo.toml b/abi_sys/Cargo.toml index ee7bad7..a64b5e5 100644 --- a/abi_sys/Cargo.toml +++ b/abi_sys/Cargo.toml @@ -4,11 +4,15 @@ version = "0.1.0" edition = "2024" [features] +default = [] defmt = ["dep:defmt"] [dependencies] -embedded-graphics = "0.8.1" strum = { version = "0.27.2", default-features = false, features = ["derive"] } -defmt = { version = "0.3", optional = true } -shared = { path = "../shared" } +bitflags = "2.9.4" +embedded-graphics = "0.8.1" embedded-sdmmc = { version = "0.9.0", default-features = false } +defmt = { version = "0.3", optional = true } + +[build-dependencies] +cbindgen = "0.24.0" diff --git a/abi_sys/src/lib.rs b/abi_sys/src/lib.rs index fb6c084..89c0427 100644 --- a/abi_sys/src/lib.rs +++ b/abi_sys/src/lib.rs @@ -1,27 +1,11 @@ #![no_std] -extern crate alloc; - -#[allow(unused)] -use embedded_graphics::{ - Pixel, - geometry::Point, - pixelcolor::{Rgb565, RgbColor}, -}; +use embedded_graphics::{Pixel, pixelcolor::Rgb565}; use embedded_sdmmc::DirEntry; -use shared::keyboard::KeyEventC; -pub use shared::keyboard::{KeyCode, KeyEvent, KeyState, Modifiers}; use strum::{EnumCount, EnumIter}; -pub type EntryFn = fn(); - -#[unsafe(no_mangle)] -#[unsafe(link_section = ".syscall_table")] -pub static mut CALL_ABI_TABLE: [usize; CallAbiTable::COUNT] = [0; CallAbiTable::COUNT]; - -#[repr(usize)] #[derive(Clone, Copy, EnumIter, EnumCount)] -#[cfg_attr(feature = "defmt", derive(defmt::Format))] +#[repr(u8)] pub enum CallAbiTable { PrintString = 0, SleepMs = 1, @@ -33,20 +17,25 @@ 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 type PrintAbi = extern "C" fn(ptr: *const u8, len: usize); -#[allow(unused)] -pub fn print(msg: &str) { +#[unsafe(no_mangle)] +pub extern "C" fn print(ptr: *const u8, len: usize) { let f: PrintAbi = unsafe { core::mem::transmute(CALL_ABI_TABLE[CallAbiTable::PrintString as usize]) }; - f(msg.as_ptr(), msg.len()); + f(ptr, len); } pub type SleepAbi = extern "C" fn(ms: u64); -#[allow(unused)] -pub fn sleep(ms: u64) { +#[unsafe(no_mangle)] +pub extern "C" fn sleep(ms: u64) { let f: SleepAbi = unsafe { core::mem::transmute(CALL_ABI_TABLE[CallAbiTable::SleepMs as usize]) }; f(ms); @@ -54,8 +43,8 @@ pub fn sleep(ms: u64) { pub type LockDisplay = extern "C" fn(lock: bool); -#[allow(unused)] -pub fn lock_display(lock: bool) { +#[unsafe(no_mangle)] +pub extern "C" fn lock_display(lock: bool) { let f: LockDisplay = unsafe { core::mem::transmute(CALL_ABI_TABLE[CallAbiTable::LockDisplay as usize]) }; f(lock); @@ -63,20 +52,240 @@ pub fn lock_display(lock: bool) { pub type DrawIterAbi = extern "C" fn(ptr: *const Pixel, len: usize); -#[allow(unused)] -pub fn draw_iter(pixels: &[Pixel]) { +#[unsafe(no_mangle)] +pub extern "C" fn draw_iter(ptr: *const Pixel, len: usize) { let f: DrawIterAbi = unsafe { core::mem::transmute(CALL_ABI_TABLE[CallAbiTable::DrawIter as usize]) }; - f(pixels.as_ptr(), pixels.len()); + f(ptr, len); } -pub type GetKeyAbi = extern "C" fn() -> KeyEventC; +pub mod keyboard { + use crate::{CALL_ABI_TABLE, CallAbiTable}; -#[allow(unused)] -pub fn get_key() -> KeyEventC { - let f: GetKeyAbi = - unsafe { core::mem::transmute(CALL_ABI_TABLE[CallAbiTable::GetKey as usize]) }; - f() + bitflags::bitflags! { + #[derive(Default, Debug, PartialEq, Eq, Clone, Copy)] + #[repr(C)] + pub struct Modifiers: u8 { + const NONE = 0; + const CTRL = 1; + const ALT = 2; + const LSHIFT = 4; + const RSHIFT = 8; + const SYM = 16; + } + } + + #[repr(C)] + pub struct KeyEventC { + pub key: u8, + pub state: KeyState, + pub mods: Modifiers, + } + + impl Into for KeyEventC { + fn into(self) -> KeyEvent { + KeyEvent { + key: self.key.into(), + state: self.state, + mods: self.mods, + } + } + } + + #[derive(Debug)] + pub struct KeyEvent { + pub key: KeyCode, + pub state: KeyState, + pub mods: Modifiers, + } + + impl Into for KeyEvent { + fn into(self) -> KeyEventC { + KeyEventC { + key: self.key.into(), + state: self.state, + mods: self.mods, + } + } + } + + #[cfg_attr(feature = "defmt", derive(defmt::Format))] + #[derive(Debug, Clone, Copy, PartialEq, Eq)] + #[repr(C)] + pub enum KeyState { + Idle = 0, + Pressed = 1, + Hold = 2, + Released = 3, + } + + impl From for KeyState { + fn from(value: u8) -> Self { + match value { + 1 => KeyState::Pressed, + 2 => KeyState::Hold, + 3 => KeyState::Released, + 0 | _ => KeyState::Idle, + } + } + } + + #[cfg_attr(feature = "defmt", derive(defmt::Format))] + #[derive(Debug, Clone, Copy, PartialEq, Eq)] + #[repr(u8)] + pub enum KeyCode { + JoyUp = 0x01, + JoyDown = 0x02, + JoyLeft = 0x03, + JoyRight = 0x04, + JoyCenter = 0x05, + BtnLeft1 = 0x06, + BtnRight1 = 0x07, + BtnLeft2 = 0x11, + BtnRight2 = 0x12, + Backspace = 0x08, + Tab = 0x09, + Enter = 0x0A, + ModAlt = 0xA1, + ModShiftLeft = 0xA2, + ModShiftRight = 0xA3, + ModSym = 0xA4, + ModCtrl = 0xA5, + Esc = 0xB1, + Left = 0xB4, + Up = 0xB5, + Down = 0xB6, + Right = 0xB7, + Break = 0xD0, + Insert = 0xD1, + Home = 0xD2, + Del = 0xD4, + End = 0xD5, + PageUp = 0xD6, + PageDown = 0xD7, + CapsLock = 0xC1, + F1 = 0x81, + F2 = 0x82, + F3 = 0x83, + F4 = 0x84, + F5 = 0x85, + F6 = 0x86, + F7 = 0x87, + F8 = 0x88, + F9 = 0x89, + F10 = 0x90, + Char(char), + Unknown(u8), + } + + impl Into for KeyCode { + fn into(self) -> u8 { + match self { + KeyCode::JoyUp => 0x01, + KeyCode::JoyDown => 0x02, + KeyCode::JoyLeft => 0x03, + KeyCode::JoyRight => 0x04, + KeyCode::JoyCenter => 0x05, + KeyCode::BtnLeft1 => 0x06, + KeyCode::BtnRight1 => 0x07, + KeyCode::BtnLeft2 => 0x11, + KeyCode::BtnRight2 => 0x12, + KeyCode::Backspace => 0x08, + KeyCode::Tab => 0x09, + KeyCode::Enter => 0x0A, + KeyCode::ModAlt => 0xA1, + KeyCode::ModShiftLeft => 0xA2, + KeyCode::ModShiftRight => 0xA3, + KeyCode::ModSym => 0xA4, + KeyCode::ModCtrl => 0xA5, + KeyCode::Esc => 0xB1, + KeyCode::Left => 0xB4, + KeyCode::Up => 0xB5, + KeyCode::Down => 0xB6, + KeyCode::Right => 0xB7, + KeyCode::Break => 0xD0, + KeyCode::Insert => 0xD1, + KeyCode::Home => 0xD2, + KeyCode::Del => 0xD4, + KeyCode::End => 0xD5, + KeyCode::PageUp => 0xD6, + KeyCode::PageDown => 0xD7, + KeyCode::CapsLock => 0xC1, + KeyCode::F1 => 0x81, + KeyCode::F2 => 0x82, + KeyCode::F3 => 0x83, + KeyCode::F4 => 0x84, + KeyCode::F5 => 0x85, + KeyCode::F6 => 0x86, + KeyCode::F7 => 0x87, + KeyCode::F8 => 0x88, + KeyCode::F9 => 0x89, + KeyCode::F10 => 0x90, + KeyCode::Char(char) => char as u8, + KeyCode::Unknown(i) => i, + } + } + } + + impl From for KeyCode { + fn from(value: u8) -> Self { + match value { + 0x01 => Self::JoyUp, + 0x02 => Self::JoyDown, + 0x03 => Self::JoyLeft, + 0x04 => Self::JoyRight, + 0x05 => Self::JoyCenter, + 0x06 => Self::BtnLeft1, + 0x07 => Self::BtnRight1, + 0x08 => Self::Backspace, + 0x09 => Self::Tab, + 0x0A => Self::Enter, + 0x11 => Self::BtnLeft2, + 0x12 => Self::BtnRight2, + 0xA1 => Self::ModAlt, + 0xA2 => Self::ModShiftLeft, + 0xA3 => Self::ModShiftRight, + 0xA4 => Self::ModSym, + 0xA5 => Self::ModCtrl, + 0xB1 => Self::Esc, + 0xB4 => Self::Left, + 0xB5 => Self::Up, + 0xB6 => Self::Down, + 0xB7 => Self::Right, + 0xC1 => Self::CapsLock, + 0xD0 => Self::Break, + 0xD1 => Self::Insert, + 0xD2 => Self::Home, + 0xD4 => Self::Del, + 0xD5 => Self::End, + 0xD6 => Self::PageUp, + 0xD7 => Self::PageDown, + 0x81 => Self::F1, + 0x82 => Self::F2, + 0x83 => Self::F3, + 0x84 => Self::F4, + 0x85 => Self::F5, + 0x86 => Self::F6, + 0x87 => Self::F7, + 0x88 => Self::F8, + 0x89 => Self::F9, + 0x90 => Self::F10, + _ => match char::from_u32(value as u32) { + Some(c) => Self::Char(c), + None => Self::Unknown(value), + }, + } + } + } + + pub type GetKeyAbi = extern "C" fn() -> KeyEventC; + + #[unsafe(no_mangle)] + pub extern "C" fn get_key() -> KeyEventC { + let f: GetKeyAbi = + unsafe { core::mem::transmute(CALL_ABI_TABLE[CallAbiTable::GetKey as usize]) }; + f() + } } #[repr(C)] @@ -88,8 +297,8 @@ pub enum RngRequest { pub type GenRand = extern "C" fn(req: &mut RngRequest); -#[allow(unused)] -pub fn gen_rand(req: &mut RngRequest) { +#[unsafe(no_mangle)] +pub extern "C" fn gen_rand(req: &mut RngRequest) { unsafe { let ptr = CALL_ABI_TABLE[CallAbiTable::GenRand as usize]; let f: GenRand = core::mem::transmute(ptr); @@ -104,12 +313,17 @@ pub type ListDir = extern "C" fn( file_len: usize, ) -> usize; -#[allow(unused)] -pub fn list_dir(path: &str, files: &mut [Option]) -> usize { +#[unsafe(no_mangle)] +pub extern "C" fn list_dir( + str: *const u8, + len: usize, + files: *mut Option, + file_len: usize, +) -> usize { unsafe { let ptr = CALL_ABI_TABLE[CallAbiTable::ListDir as usize]; let f: ListDir = core::mem::transmute(ptr); - f(path.as_ptr(), path.len(), files.as_mut_ptr(), files.len()) + f(str, len, files, file_len) } } @@ -121,28 +335,28 @@ pub type ReadFile = extern "C" fn( buf_len: usize, ) -> usize; -#[allow(unused)] -pub fn read_file(file: &str, read_from: usize, buf: &mut [u8]) -> usize { +#[unsafe(no_mangle)] +pub extern "C" fn read_file( + str: *const u8, + len: usize, + read_from: usize, + buf: *mut u8, + buf_len: usize, +) -> usize { unsafe { let ptr = CALL_ABI_TABLE[CallAbiTable::ReadFile as usize]; let f: ReadFile = core::mem::transmute(ptr); - f( - file.as_ptr(), - file.len(), - read_from, - buf.as_mut_ptr(), - buf.len(), - ) + f(str, len, read_from, buf, buf_len) } } pub type FileLen = extern "C" fn(str: *const u8, len: usize) -> usize; -#[allow(unused)] -pub fn file_len(file: &str) -> usize { +#[unsafe(no_mangle)] +pub extern "C" fn file_len(str: *const u8, len: usize) -> usize { unsafe { let ptr = CALL_ABI_TABLE[CallAbiTable::FileLen as usize]; let f: FileLen = core::mem::transmute(ptr); - f(file.as_ptr(), file.len()) + f(str, len) } } diff --git a/justfile b/justfile index d087935..0f1a419 100644 --- a/justfile +++ b/justfile @@ -6,10 +6,13 @@ kernel-release: binary-args := "RUSTFLAGS=\"-C link-arg=-pie -C relocation-model=pic\"" +cbindgen: + cbindgen abi_sys --output abi_sys.h -q + userapp app: {{binary-args}} cargo build --bin {{app}} --profile release-binary -userapps: +userapps: cbindgen just userapp calculator just userapp snake just userapp gallery diff --git a/kernel/Cargo.toml b/kernel/Cargo.toml index 4c582d3..13d4eef 100644 --- a/kernel/Cargo.toml +++ b/kernel/Cargo.toml @@ -18,7 +18,6 @@ trouble = ["dep:bt-hci", "dep:cyw43", "dep:cyw43-pio", "dep:trouble-host"] defmt = [ "dep:defmt", "shared/defmt", - "abi_sys/defmt", "panic-probe/print-defmt", "embassy-executor/defmt", "embassy-time/defmt", diff --git a/kernel/src/abi.rs b/kernel/src/abi.rs index 820af43..e61bc24 100644 --- a/kernel/src/abi.rs +++ b/kernel/src/abi.rs @@ -1,14 +1,13 @@ use abi_sys::{ - DrawIterAbi, FileLen, GenRand, GetKeyAbi, ListDir, LockDisplay, Modifiers, PrintAbi, ReadFile, - RngRequest, SleepAbi, + DrawIterAbi, FileLen, GenRand, ListDir, LockDisplay, PrintAbi, ReadFile, RngRequest, SleepAbi, + keyboard::*, }; use alloc::{string::ToString, vec::Vec}; use core::sync::atomic::Ordering; use embassy_rp::clocks::{RoscRng, clk_sys_freq}; use embedded_graphics::{Pixel, draw_target::DrawTarget, pixelcolor::Rgb565}; -use embedded_sdmmc::{DirEntry, LfnBuffer, ShortFileName}; +use embedded_sdmmc::{DirEntry, LfnBuffer}; use heapless::spsc::Queue; -use shared::keyboard::{KeyEvent, KeyEventC}; use crate::{ display::{FB_PAUSED, FRAMEBUFFER}, @@ -58,8 +57,8 @@ pub extern "C" fn get_key() -> KeyEventC { event.into() } else { KeyEvent { - key: abi_sys::KeyCode::Unknown(0), - state: abi_sys::KeyState::Idle, + key: KeyCode::Unknown(0), + state: KeyState::Idle, mods: Modifiers::empty(), } .into() diff --git a/kernel/src/elf.rs b/kernel/src/elf.rs index 488e11e..0bc6591 100644 --- a/kernel/src/elf.rs +++ b/kernel/src/elf.rs @@ -2,7 +2,8 @@ use crate::{ abi, storage::{File, SDCARD}, }; -use abi_sys::{CallAbiTable, EntryFn}; +use abi_sys::CallAbiTable; +use abi_sys::EntryFn; use alloc::{vec, vec::Vec}; use bumpalo::Bump; use core::ptr; diff --git a/kernel/src/peripherals/keyboard.rs b/kernel/src/peripherals/keyboard.rs index a9ef605..28b65e7 100644 --- a/kernel/src/peripherals/keyboard.rs +++ b/kernel/src/peripherals/keyboard.rs @@ -1,5 +1,5 @@ use crate::peripherals::PERIPHERAL_BUS; -pub use shared::keyboard::{KeyCode, KeyEvent, KeyState, Modifiers}; +pub use abi_sys::keyboard::{KeyCode, KeyEvent, KeyState, Modifiers}; const REG_ID_KEY: u8 = 0x04; const REG_ID_FIF: u8 = 0x09; diff --git a/kernel/src/ui.rs b/kernel/src/ui.rs index f4b9d85..1c91c40 100644 --- a/kernel/src/ui.rs +++ b/kernel/src/ui.rs @@ -5,6 +5,7 @@ use crate::{ peripherals::keyboard, storage::FileName, }; +use abi_sys::keyboard::{KeyCode, KeyState}; use alloc::{str::FromStr, string::String, vec::Vec}; use core::sync::atomic::Ordering; use embassy_sync::{blocking_mutex::raw::CriticalSectionRawMutex, mutex::Mutex}; @@ -22,7 +23,6 @@ use embedded_layout::{ prelude::*, }; use embedded_text::TextBox; -use shared::keyboard::{KeyCode, KeyState}; pub static SELECTIONS: Mutex = Mutex::new(SelectionList::new()); diff --git a/shared/Cargo.toml b/shared/Cargo.toml index 89519f1..8796b8a 100644 --- a/shared/Cargo.toml +++ b/shared/Cargo.toml @@ -8,5 +8,6 @@ default = [] defmt = ["dep:defmt"] [dependencies] +abi_sys = { path = "../abi_sys" } bitflags = "2.9.4" -defmt = { version = "1.0.1", optional = true } +defmt = { version = "0.3", optional = true } diff --git a/shared/src/lib.rs b/shared/src/lib.rs index 874213e..0c9ac1a 100644 --- a/shared/src/lib.rs +++ b/shared/src/lib.rs @@ -1,219 +1 @@ #![no_std] - -pub mod keyboard { - bitflags::bitflags! { - #[derive(Default, Debug, PartialEq, Eq, Clone, Copy)] - #[repr(C)] - pub struct Modifiers: u8 { - const NONE = 0; - const CTRL = 1; - const ALT = 2; - const LSHIFT = 4; - const RSHIFT = 8; - const SYM = 16; - } - } - - #[repr(C)] - pub struct KeyEventC { - pub key: u8, - pub state: KeyState, - pub mods: Modifiers, - } - - impl Into for KeyEventC { - fn into(self) -> KeyEvent { - KeyEvent { - key: self.key.into(), - state: self.state, - mods: self.mods, - } - } - } - - #[derive(Debug)] - pub struct KeyEvent { - pub key: KeyCode, - pub state: KeyState, - pub mods: Modifiers, - } - - impl Into for KeyEvent { - fn into(self) -> KeyEventC { - KeyEventC { - key: self.key.into(), - state: self.state, - mods: self.mods, - } - } - } - - #[cfg_attr(feature = "defmt", derive(defmt::Format))] - #[derive(Debug, Clone, Copy, PartialEq, Eq)] - #[repr(C)] - pub enum KeyState { - Idle = 0, - Pressed = 1, - Hold = 2, - Released = 3, - } - - impl From for KeyState { - fn from(value: u8) -> Self { - match value { - 1 => KeyState::Pressed, - 2 => KeyState::Hold, - 3 => KeyState::Released, - 0 | _ => KeyState::Idle, - } - } - } - - #[cfg_attr(feature = "defmt", derive(defmt::Format))] - #[derive(Debug, Clone, Copy, PartialEq, Eq)] - #[repr(u8)] - pub enum KeyCode { - JoyUp = 0x01, - JoyDown = 0x02, - JoyLeft = 0x03, - JoyRight = 0x04, - JoyCenter = 0x05, - BtnLeft1 = 0x06, - BtnRight1 = 0x07, - BtnLeft2 = 0x11, - BtnRight2 = 0x12, - Backspace = 0x08, - Tab = 0x09, - Enter = 0x0A, - ModAlt = 0xA1, - ModShiftLeft = 0xA2, - ModShiftRight = 0xA3, - ModSym = 0xA4, - ModCtrl = 0xA5, - Esc = 0xB1, - Left = 0xB4, - Up = 0xB5, - Down = 0xB6, - Right = 0xB7, - Break = 0xD0, - Insert = 0xD1, - Home = 0xD2, - Del = 0xD4, - End = 0xD5, - PageUp = 0xD6, - PageDown = 0xD7, - CapsLock = 0xC1, - F1 = 0x81, - F2 = 0x82, - F3 = 0x83, - F4 = 0x84, - F5 = 0x85, - F6 = 0x86, - F7 = 0x87, - F8 = 0x88, - F9 = 0x89, - F10 = 0x90, - Char(char), - Unknown(u8), - } - - impl Into for KeyCode { - fn into(self) -> u8 { - match self { - KeyCode::JoyUp => 0x01, - KeyCode::JoyDown => 0x02, - KeyCode::JoyLeft => 0x03, - KeyCode::JoyRight => 0x04, - KeyCode::JoyCenter => 0x05, - KeyCode::BtnLeft1 => 0x06, - KeyCode::BtnRight1 => 0x07, - KeyCode::BtnLeft2 => 0x11, - KeyCode::BtnRight2 => 0x12, - KeyCode::Backspace => 0x08, - KeyCode::Tab => 0x09, - KeyCode::Enter => 0x0A, - KeyCode::ModAlt => 0xA1, - KeyCode::ModShiftLeft => 0xA2, - KeyCode::ModShiftRight => 0xA3, - KeyCode::ModSym => 0xA4, - KeyCode::ModCtrl => 0xA5, - KeyCode::Esc => 0xB1, - KeyCode::Left => 0xB4, - KeyCode::Up => 0xB5, - KeyCode::Down => 0xB6, - KeyCode::Right => 0xB7, - KeyCode::Break => 0xD0, - KeyCode::Insert => 0xD1, - KeyCode::Home => 0xD2, - KeyCode::Del => 0xD4, - KeyCode::End => 0xD5, - KeyCode::PageUp => 0xD6, - KeyCode::PageDown => 0xD7, - KeyCode::CapsLock => 0xC1, - KeyCode::F1 => 0x81, - KeyCode::F2 => 0x82, - KeyCode::F3 => 0x83, - KeyCode::F4 => 0x84, - KeyCode::F5 => 0x85, - KeyCode::F6 => 0x86, - KeyCode::F7 => 0x87, - KeyCode::F8 => 0x88, - KeyCode::F9 => 0x89, - KeyCode::F10 => 0x90, - KeyCode::Char(char) => char as u8, - KeyCode::Unknown(i) => i, - } - } - } - - impl From for KeyCode { - fn from(value: u8) -> Self { - match value { - 0x01 => Self::JoyUp, - 0x02 => Self::JoyDown, - 0x03 => Self::JoyLeft, - 0x04 => Self::JoyRight, - 0x05 => Self::JoyCenter, - 0x06 => Self::BtnLeft1, - 0x07 => Self::BtnRight1, - 0x08 => Self::Backspace, - 0x09 => Self::Tab, - 0x0A => Self::Enter, - 0x11 => Self::BtnLeft2, - 0x12 => Self::BtnRight2, - 0xA1 => Self::ModAlt, - 0xA2 => Self::ModShiftLeft, - 0xA3 => Self::ModShiftRight, - 0xA4 => Self::ModSym, - 0xA5 => Self::ModCtrl, - 0xB1 => Self::Esc, - 0xB4 => Self::Left, - 0xB5 => Self::Up, - 0xB6 => Self::Down, - 0xB7 => Self::Right, - 0xC1 => Self::CapsLock, - 0xD0 => Self::Break, - 0xD1 => Self::Insert, - 0xD2 => Self::Home, - 0xD4 => Self::Del, - 0xD5 => Self::End, - 0xD6 => Self::PageUp, - 0xD7 => Self::PageDown, - 0x81 => Self::F1, - 0x82 => Self::F2, - 0x83 => Self::F3, - 0x84 => Self::F4, - 0x85 => Self::F5, - 0x86 => Self::F6, - 0x87 => Self::F7, - 0x88 => Self::F8, - 0x89 => Self::F9, - 0x90 => Self::F10, - _ => match char::from_u32(value as u32) { - Some(c) => Self::Char(c), - None => Self::Unknown(value), - }, - } - } - } -} diff --git a/user-apps/calculator/src/main.rs b/user-apps/calculator/src/main.rs index 54b9cbb..2e0bfec 100644 --- a/user-apps/calculator/src/main.rs +++ b/user-apps/calculator/src/main.rs @@ -2,7 +2,12 @@ #![no_main] extern crate alloc; -use abi::{KeyCode, KeyState, display::Display, get_key, lock_display, print}; +use abi::{ + display::{Display, lock_display}, + get_key, + keyboard::{KeyCode, KeyState}, + print, +}; use alloc::{format, string::String, vec, vec::Vec}; use core::panic::PanicInfo; use embedded_graphics::{ diff --git a/user-apps/gallery/src/main.rs b/user-apps/gallery/src/main.rs index a896070..be73636 100644 --- a/user-apps/gallery/src/main.rs +++ b/user-apps/gallery/src/main.rs @@ -4,9 +4,11 @@ extern crate alloc; use abi::{ - KeyCode, KeyState, - display::{Display, SCREEN_HEIGHT, SCREEN_WIDTH}, - get_key, list_dir, lock_display, print, read_file, + display::{Display, SCREEN_HEIGHT, SCREEN_WIDTH, lock_display}, + fs::{list_dir, read_file}, + get_key, + keyboard::{KeyCode, KeyState}, + print, }; use alloc::{format, string::ToString}; use core::panic::PanicInfo; diff --git a/user-apps/snake/src/main.rs b/user-apps/snake/src/main.rs index 78d9451..a979b33 100644 --- a/user-apps/snake/src/main.rs +++ b/user-apps/snake/src/main.rs @@ -3,9 +3,11 @@ extern crate alloc; use abi::{ - KeyCode, KeyState, Rng, - display::{Display, SCREEN_HEIGHT, SCREEN_WIDTH}, - get_key, lock_display, print, sleep, + Rng, + display::{Display, SCREEN_HEIGHT, SCREEN_WIDTH, lock_display}, + get_key, + keyboard::{KeyCode, KeyState}, + print, sleep, }; use alloc::format; use core::panic::PanicInfo;