cbindgen abi_sys

This commit is contained in:
2025-10-05 17:14:38 -06:00
parent f2a5801284
commit af238b2847
17 changed files with 590 additions and 305 deletions

1
.gitignore vendored
View File

@@ -1,2 +1,3 @@
/target
*.uf2
abi_sys.h

249
Cargo.lock generated
View File

@@ -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"

View File

@@ -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" }

View File

@@ -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<spin::Mutex<()>, 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<Rgb565>;
pub fn lock_display(lock: bool) {
abi_sys::lock_display(lock);
}
fn draw_iter(pixels: &[Pixel<Rgb565>]) {
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<DirEntry>]) -> 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())
}
}

View File

@@ -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"

View File

@@ -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<Rgb565>, len: usize);
#[allow(unused)]
pub fn draw_iter(pixels: &[Pixel<Rgb565>]) {
#[unsafe(no_mangle)]
pub extern "C" fn draw_iter(ptr: *const Pixel<Rgb565>, 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 {
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<KeyEvent> 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<KeyEventC> 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<u8> 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<u8> 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<u8> 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<DirEntry>]) -> usize {
#[unsafe(no_mangle)]
pub extern "C" fn list_dir(
str: *const u8,
len: usize,
files: *mut Option<DirEntry>,
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)
}
}

View File

@@ -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

View File

@@ -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",

View File

@@ -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()

View File

@@ -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;

View File

@@ -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;

View File

@@ -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<CriticalSectionRawMutex, SelectionList> =
Mutex::new(SelectionList::new());

View File

@@ -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 }

View File

@@ -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<KeyEvent> 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<KeyEventC> 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<u8> 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<u8> 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<u8> 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),
},
}
}
}
}

View File

@@ -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::{

View File

@@ -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;

View File

@@ -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;