This commit is contained in:
Jakub Hlusička 2026-01-05 04:16:05 +01:00
parent bfe4839d83
commit 561be96f24
11 changed files with 2443 additions and 28 deletions

View file

@ -1,12 +1,13 @@
[target.'cfg(all(any(target_arch = "riscv32", target_arch = "xtensa"), target_os = "none"))'] [target.'cfg(all(any(target_arch = "riscv32", target_arch = "xtensa"), target_os = "none"))']
runner = "espflash flash --monitor" runner = "espflash flash --monitor"
# runner = "probe-rs run --chip esp32s3 --preverify"
[build] [build]
target = "xtensa-esp32s3-none-elf" target = "xtensa-esp32s3-none-elf"
rustflags = [ rustflags = [
# Required to obtain backtraces (e.g. when using the "esp-backtrace" crate.) # Required to obtain backtraces (e.g. when using the "esp-backtrace" crate.)
# NOTE: May negatively impact performance of produced code # NOTE: May negatively impact performance of produced code
"-C", "force-frame-pointers", "-C", "force-frame-pointers", "-C", "link-arg=-Wl,--wrap=strncmp",
] ]

61
firmware2/.vscode/launch.json vendored Normal file
View file

@ -0,0 +1,61 @@
{
"version": "0.2.0",
"configurations": [
{
"name": "probe-rs debug restart",
"type": "probe-rs-debug",
"request": "launch",
"probe": "303a:1001",
"chip": "esp32s3",
"coreConfigs": [
{
"programBinary": "target/xtensa-esp32s3-none-elf/debug/acid-firmware"
}
]
},
{
"name": "probe-rs release restart",
"type": "probe-rs-debug",
"request": "launch",
"probe": "303a:1001",
"chip": "esp32s3",
"coreConfigs": [
{
"programBinary": "target/xtensa-esp32s3-none-elf/release/acid-firmware"
}
]
},
{
"preLaunchTask": "rust: cargo build",
"name": "probe-rs debug",
"type": "probe-rs-debug",
"request": "launch",
"flashingConfig": {
"flashingEnabled": true,
},
"probe": "303a:1001",
"chip": "esp32s3",
"coreConfigs": [
{
"programBinary": "target/xtensa-esp32s3-none-elf/debug/acid-firmware"
}
]
},
{
"preLaunchTask": "rust: cargo build --release",
"name": "probe-rs release",
"type": "probe-rs-debug",
"request": "launch",
"flashingConfig": {
"flashingEnabled": true,
},
"probe": "303a:1001",
"chip": "esp32s3",
"coreConfigs": [
{
"programBinary": "target/xtensa-esp32s3-none-elf/release/acid-firmware"
}
]
}
]
}

35
firmware2/.vscode/tasks.json vendored Normal file
View file

@ -0,0 +1,35 @@
{
"version": "2.0.0",
"tasks": [
{
"label": "rust: cargo build",
"type": "cargo",
"command": "build",
"args": [
"--no-default-features", "--features=probe,info"
],
"problemMatcher": [
"$rustc"
],
"group": {
"kind": "build",
"isDefault": true
},
},
{
"label": "rust: cargo build --release",
"type": "cargo",
"command": "build",
"args": [
"--release", "--no-default-features", "--features=probe,info"
],
"problemMatcher": [
"$rustc"
],
"group": {
"kind": "build",
"isDefault": true
},
}
]
}

53
firmware2/Cargo.lock generated
View file

@ -33,12 +33,16 @@ dependencies = [
"json", "json",
"lazy_static", "lazy_static",
"log", "log",
"mutually_exclusive_features",
"panic-rtt-target",
"paste", "paste",
"rand_core 0.6.4", "rand_core 0.6.4",
"rmk", "rmk",
"rtt-target",
"slint", "slint",
"slint-build", "slint-build",
"static_cell", "static_cell",
"xkbcommon 0.9.0",
"xz2", "xz2",
] ]
@ -3722,7 +3726,7 @@ dependencies = [
"input", "input",
"memmap2", "memmap2",
"nix", "nix",
"xkbcommon", "xkbcommon 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]] [[package]]
@ -4660,6 +4664,12 @@ dependencies = [
"windows-sys 0.60.2", "windows-sys 0.60.2",
] ]
[[package]]
name = "mutually_exclusive_features"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e94e1e6445d314f972ff7395df2de295fe51b71821694f0b0e1e79c4f12c8577"
[[package]] [[package]]
name = "nb" name = "nb"
version = "0.1.3" version = "0.1.3"
@ -5240,6 +5250,17 @@ dependencies = [
"primeorder", "primeorder",
] ]
[[package]]
name = "panic-rtt-target"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a8116ffce1f89818647b84fba66d16cfdf3c0bee3c9320e606588d3e7415ce7"
dependencies = [
"critical-section",
"portable-atomic",
"rtt-target",
]
[[package]] [[package]]
name = "parking" name = "parking"
version = "2.2.1" version = "2.2.1"
@ -6077,6 +6098,19 @@ version = "0.20.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6c20b6793b5c2fa6553b250154b78d6d0db37e72700ae35fad9387a46f487c97" checksum = "6c20b6793b5c2fa6553b250154b78d6d0db37e72700ae35fad9387a46f487c97"
[[package]]
name = "rtt-target"
version = "0.6.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e7afed1f4302eeba88c601636cf2c554c45e1cbb464bab44c6012bab0e71473c"
dependencies = [
"critical-section",
"log",
"once_cell",
"portable-atomic",
"ufmt-write",
]
[[package]] [[package]]
name = "rust-ini" name = "rust-ini"
version = "0.21.3" version = "0.21.3"
@ -6879,6 +6913,15 @@ dependencies = [
"strict-num", "strict-num",
] ]
[[package]]
name = "tinyrlibc"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5d07d242693682e46801cb0186c583858bce022f698401b3f04bbd729c9a87e7"
dependencies = [
"cc",
]
[[package]] [[package]]
name = "tinystr" name = "tinystr"
version = "0.8.2" version = "0.8.2"
@ -8119,6 +8162,14 @@ dependencies = [
"rustix 1.1.3", "rustix 1.1.3",
] ]
[[package]]
name = "xkbcommon"
version = "0.9.0"
dependencies = [
"tinyrlibc",
"xkeysym",
]
[[package]] [[package]]
name = "xkbcommon" name = "xkbcommon"
version = "0.9.0" version = "0.9.0"

View file

@ -9,8 +9,9 @@ edition = "2024"
[features] [features]
default = ["usb-log", "limit-fps", "warn"] default = ["usb-log", "limit-fps", "warn"]
develop = ["limit-fps", "alt-log"] # Make RMK not to use USB
no-usb = ["rmk/_no_usb"] no-usb = ["rmk/_no_usb"]
# Let RMK use BLE
ble = ["rmk/esp32s3_ble"] ble = ["rmk/esp32s3_ble"]
# Use alternative logging via GPIO5 as RX and GPIO12 as TX. # Use alternative logging via GPIO5 as RX and GPIO12 as TX.
# Disables default logging via USB. # Disables default logging via USB.
@ -18,13 +19,23 @@ ble = ["rmk/esp32s3_ble"]
alt-log = [] alt-log = []
# Standard logging implementation over USB. # Standard logging implementation over USB.
usb-log = ["esp-backtrace/panic-handler"] usb-log = ["esp-backtrace/panic-handler"]
# RTT (+ logging) for probe-rs
rtt-log = ["dep:rtt-target", "dep:panic-rtt-target"]
# Block the main core while it is driving the LCD.
# This prevents the main core from accessing PSRAM while the LCD is being driven,
# which causes the LCD to glitch. To prevent the main core from spending all its
# execution time on just driving the LCD, it will be limited.
limit-fps = [] limit-fps = []
# Log levels (lower takes precedence) # Log levels (lower takes precedence) TODO: Use env vars
error = [] error = []
warn = [] warn = []
info = [] info = []
debug = [] debug = []
trace = [] trace = []
# Development profiles
develop = ["limit-fps", "alt-log"]
develop-usb = ["limit-fps", "usb-log", "no-usb"]
probe = ["limit-fps", "rtt-log", "no-usb"]
[dependencies] [dependencies]
rmk = { version = "0.8.2", default-features = false, features = [ rmk = { version = "0.8.2", default-features = false, features = [
@ -60,10 +71,14 @@ bytemuck = "1.24.0"
slint = { version = "1.14.1", default-features = false, features = ["compat-1-2", "libm", "log", "unsafe-single-threaded", "renderer-software"]} slint = { version = "1.14.1", default-features = false, features = ["compat-1-2", "libm", "log", "unsafe-single-threaded", "renderer-software"]}
critical-section = "1.2.0" critical-section = "1.2.0"
cfg-if = "1.0.4" cfg-if = "1.0.4"
xkbcommon = { path = "../../../rust/xkbcommon-rs-ffi", default-features = false, features = ["tinyrlibc"] }
rtt-target = { version = "0.6.2", features = ["log"], optional = true }
panic-rtt-target = { version = "0.2.0", optional = true }
# Crates for serial UART CLI # Crates for serial UART CLI
embedded-cli = { version = "0.2.1", default-features = false, features = ["help", "macros"] } embedded-cli = { version = "0.2.1", default-features = false, features = ["help", "macros"] }
embedded-io = "0.6.1" embedded-io = "0.6.1"
mutually_exclusive_features = "0.1.0"
[build-dependencies] [build-dependencies]
xz2 = "0.1.7" xz2 = "0.1.7"
@ -83,20 +98,48 @@ bench = false
inherits = "release" inherits = "release"
debug = true debug = true
[profile.dev.package.esp-storage] [profile.dev.package.esp-storage]
opt-level = 3 opt-level = 3
# btuuid fails to compile with `opt-level = "s"`
[profile.dev.package.btuuid]
opt-level = 0
# Optimize dependencies
[profile.dev.package."*"]
opt-level = 3
# [profile.dev.package.xtensa-lx]
# opt-level = 0
# [profile.dev.package.esp-sync]
# opt-level = 0
# [profile.dev.package.esp-alloc]
# opt-level = 0
[profile.dev] [profile.dev]
# Rust debug is too slow. # Rust debug is too slow.
# For debug builds always builds with some optimization # For debug builds always builds with some optimization
opt-level = "s" # opt-level = "s"
opt-level = 0
lto = false
[profile.release.package."*"]
opt-level = 3
# btuuid fails to compile with `opt-level = "3"`
[profile.release.package.btuuid]
opt-level = 0
[profile.release] [profile.release]
codegen-units = 1 # LLVM can perform better optimizations using a single thread codegen-units = 1 # LLVM can perform better optimizations using a single thread
debug = 2 debug = 2
debug-assertions = false debug-assertions = false
incremental = false incremental = false
lto = 'thin' # lto = 'thin'
opt-level = 3 lto = false
# opt-level = 3
opt-level = 0
overflow-checks = false overflow-checks = false

View file

@ -1,6 +1,6 @@
use std::fs::{File, OpenOptions}; use std::fs::{File, OpenOptions};
use std::io::{Read, Write}; use std::io::{Read, Write};
use std::path::Path; use std::path::{Path, PathBuf};
use std::env; use std::env;
use const_gen::*; use const_gen::*;
@ -29,6 +29,17 @@ fn main() {
// Set the extra linker script from defmt // Set the extra linker script from defmt
// println!("cargo:rustc-link-arg=-Tdefmt.x"); // println!("cargo:rustc-link-arg=-Tdefmt.x");
// 1. Tell cargo where to find the library
// let lib_path = PathBuf::from(manifest_dir).join("libs");
// println!(r#"cargo:rustc-link-search=native={}"#, lib_path.display());
println!(r#"cargo:rustc-link-search=native=C:\Users\Limeth\workspace\c\libxkbcommon-linux\build-debug"#);
// 2. Link the static library (strip the 'lib' prefix and '.a' extension)
println!("cargo:rustc-link-lib=static=xkbcommon");
// 3. Re-run if build.rs or the library changes
println!(r#"cargo:rerun-if-changed=C:\Users\Limeth\workspace\c\libxkbcommon-linux\build-debug\libxkbcommon.a"#);
let slint_config = CompilerConfiguration::new() let slint_config = CompilerConfiguration::new()
// .with_scale_factor(4.0) // .with_scale_factor(4.0)
.with_style("cosmic-dark".to_string()) .with_style("cosmic-dark".to_string())

1914
firmware2/keymaps/cz.xkb Normal file

File diff suppressed because it is too large Load diff

241
firmware2/src/ffi.rs Normal file
View file

@ -0,0 +1,241 @@
#![allow(unused)]
use core::{ffi::{CStr, VaList, c_char, c_int, c_long, c_longlong, c_size_t, c_uchar, c_void}, ptr::{null, null_mut}};
unsafe extern "C" {
fn malloc(size: c_size_t) -> *mut c_void;
}
#[unsafe(no_mangle)]
unsafe extern "C" fn strpbrk(s: *const c_char, accept: *const c_char) -> *mut c_char {
todo!()
}
#[allow(non_camel_case_types)]
type c_intmax_t = c_longlong;
#[unsafe(no_mangle)]
unsafe extern "C" fn imaxabs(j: c_intmax_t) -> c_intmax_t {
todo!()
}
#[unsafe(no_mangle)]
unsafe extern "C" fn eaccess(pathname: *const c_char, mode: c_int ) -> c_int {
todo!()
}
#[unsafe(no_mangle)]
unsafe extern "C" fn vasprintf(strp: *mut *mut c_char, fmt: *const c_char, ap: VaList) -> c_int {
todo!()
}
#[allow(non_camel_case_types)]
type stat = c_void; // Not implemented
#[unsafe(no_mangle)]
unsafe extern "C" fn stat(path: *const c_char, buf: *mut stat) -> c_int {
todo!()
}
#[unsafe(no_mangle)]
unsafe extern "C" fn __errno() -> *mut c_int {
todo!()
}
#[unsafe(no_mangle)]
unsafe extern "C" fn strerror(errnum: c_int) -> *mut c_char {
todo!()
}
#[allow(non_camel_case_types)]
type DIR = c_void; // Not implemented
#[allow(non_camel_case_types)]
type dirent = c_void; // Not implemented
#[unsafe(no_mangle)]
unsafe extern "C" fn opendir(name: *const c_char) -> *mut DIR {
todo!()
}
#[unsafe(no_mangle)]
unsafe extern "C" fn readdir(dirp: *mut DIR) -> *mut dirent {
todo!()
}
#[unsafe(no_mangle)]
unsafe extern "C" fn closedir(dirp: *mut DIR) -> c_int {
todo!()
}
#[unsafe(no_mangle)]
unsafe extern "C" fn qsort(
base: *mut c_void,
num: c_size_t,
size: c_size_t,
compar: Option<unsafe extern "C" fn(*const c_void, *const c_void) -> c_int>,
) {
todo!()
}
#[unsafe(no_mangle)]
unsafe extern "C" fn __getreent() -> *mut c_void /*struct _reent*/ {
todo!()
}
#[allow(non_camel_case_types)]
#[allow(clippy::upper_case_acronyms)]
enum FILE {}
#[unsafe(no_mangle)]
unsafe extern "C" fn fprintf(
stream: *mut FILE,
format: *const c_char,
...
) -> c_int {
todo!()
}
#[unsafe(no_mangle)]
unsafe extern "C" fn vfprintf(stream: *mut FILE, format: *const c_char, ap: VaList) -> c_int {
todo!()
}
#[unsafe(no_mangle)]
unsafe extern "C" fn strtol(nptr: *const c_char, endptr: *mut *mut c_char, base: c_int) -> c_long {
todo!()
}
#[unsafe(no_mangle)]
unsafe extern "C" fn secure_getenv(name: *const c_char) -> *mut c_char {
unsafe { getenv(name) }
}
#[unsafe(no_mangle)]
unsafe extern "C" fn getenv(name: *const c_char) -> *mut c_char {
null_mut()
}
#[unsafe(no_mangle)]
unsafe extern "C" fn fseek(
stream: *mut FILE,
offset: c_long,
whence: c_int,
) -> c_int {
todo!()
}
#[unsafe(no_mangle)]
unsafe extern "C" fn ftell(stream: *mut FILE) -> c_long {
todo!()
}
#[unsafe(no_mangle)]
unsafe extern "C" fn fread(
ptr: *mut c_void,
size: c_size_t,
nobj: c_size_t,
stream: *mut FILE,
) -> c_size_t {
todo!()
}
#[unsafe(no_mangle)]
unsafe extern "C" fn open(
path: *const c_char,
oflag: c_int,
...
) -> c_int {
todo!()
}
#[unsafe(no_mangle)]
unsafe extern "C" fn fstat(fildes: c_int, buf: *mut stat) -> c_int {
todo!()
}
#[unsafe(no_mangle)]
unsafe extern "C" fn close(fd: c_int) -> c_int {
todo!()
}
#[unsafe(no_mangle)]
unsafe extern "C" fn fdopen(
fd: c_int,
mode: *const c_char,
) -> *mut FILE {
todo!()
}
#[unsafe(no_mangle)]
unsafe extern "C" fn strndup(
s: *const c_char,
n: c_size_t,
) -> *mut c_char {
let len = unsafe { strnlen(s, n) };
let new = unsafe { malloc(len + 1) } as *mut c_char;
if new.is_null() {
return null_mut();
}
unsafe {
*new.add(len) = b'\0';
memcpy(new as *mut c_void, s as *const c_void, len) as *mut c_char
}
}
#[unsafe(no_mangle)]
unsafe extern "C" fn labs(i: c_long) -> c_long {
i.abs()
}
#[unsafe(no_mangle)]
unsafe extern "C" fn memcpy(dest: *mut c_void, src: *const c_void, n: c_size_t) -> *mut c_void {
todo!()
}
#[unsafe(no_mangle)]
unsafe extern "C" fn strnlen(s: *const c_char, maxlen: c_size_t) -> c_size_t {
let found: *const c_char = unsafe { memchr(s as *const c_void, b'\0' as c_int, maxlen) } as *const c_char;
if !found.is_null() { unsafe { found.offset_from(s) as c_size_t } } else { maxlen }
}
#[unsafe(no_mangle)]
unsafe extern "C" fn memchr(s: *const c_void, c: c_int, n: c_size_t) -> *mut c_void {
let mut s = s as *const c_uchar;
let c = c as c_uchar;
for _ in 0..n {
unsafe {
if *s == c {
return s as *mut c_void;
}
s = s.add(1);
}
}
null_mut()
}
#[unsafe(no_mangle)]
unsafe extern "C" fn __wrap_strncmp(
s1: *const c_char,
s2: *const c_char,
n: c_size_t,
) -> c_int {
unsafe {
for i in 0..n as isize {
let s1_i = s1.offset(i);
let s2_i = s2.offset(i);
let val = *s1_i as c_int - *s2_i as c_int;
if val != 0 || *s1_i == 0 {
return val;
}
}
0
}
}

View file

@ -43,6 +43,10 @@ const YELLOW: &str = "\u{001B}[33m";
const BLUE: &str = "\u{001B}[34m"; const BLUE: &str = "\u{001B}[34m";
const CYAN: &str = "\u{001B}[35m"; const CYAN: &str = "\u{001B}[35m";
#[cfg(feature = "rtt-log")]
#[allow(unused)]
use ::rtt_target::{rprint as print, rprintln as println};
#[cfg(feature = "alt-log")] #[cfg(feature = "alt-log")]
#[allow(unused)] #[allow(unused)]
macro_rules! println { macro_rules! println {
@ -78,7 +82,10 @@ fn print_log_record(uart: &mut UartTx<'_, Blocking>, record: &log::Record) {
uart.flush().unwrap(); uart.flush().unwrap();
} }
#[cfg(not(feature = "usb-log"))] #[cfg(feature = "rtt-log")]
use panic_rtt_target as _;
#[cfg(feature = "alt-log")]
#[panic_handler] #[panic_handler]
fn panic_handler(info: &core::panic::PanicInfo) -> ! { fn panic_handler(info: &core::panic::PanicInfo) -> ! {
use esp_backtrace::Backtrace; use esp_backtrace::Backtrace;

View file

@ -9,12 +9,16 @@
#![no_std] #![no_std]
#![no_main] #![no_main]
#![feature(macro_metavar_expr)] #![feature(macro_metavar_expr)]
#![feature(c_variadic)]
#![feature(c_size_t)]
extern crate alloc; extern crate alloc;
use core::alloc::Layout; use core::alloc::Layout;
use core::cell::RefCell; use core::cell::RefCell;
use core::ffi::CStr;
use alloc::string::ToString;
use alloc::boxed::Box; use alloc::boxed::Box;
use alloc::vec; use alloc::vec;
use bt_hci::controller::ExternalController; use bt_hci::controller::ExternalController;
@ -23,7 +27,7 @@ use embassy_executor::Spawner;
use embassy_sync::blocking_mutex::raw::{CriticalSectionRawMutex}; use embassy_sync::blocking_mutex::raw::{CriticalSectionRawMutex};
use embassy_sync::channel::Channel; use embassy_sync::channel::Channel;
use embassy_sync::signal::Signal; use embassy_sync::signal::Signal;
use embassy_time::Duration; use embassy_time::{Duration, Timer};
use esp_alloc::{HeapRegion, MemoryCapability}; use esp_alloc::{HeapRegion, MemoryCapability};
use esp_hal::clock::CpuClock; use esp_hal::clock::CpuClock;
use esp_hal::dma::{BurstConfig, DmaDescriptor, DmaTxBuf, ExternalBurstConfig}; use esp_hal::dma::{BurstConfig, DmaDescriptor, DmaTxBuf, ExternalBurstConfig};
@ -62,6 +66,7 @@ use slint::platform::software_renderer::Rgb565Pixel;
use slint::ComponentHandle; use slint::ComponentHandle;
use static_cell::StaticCell; use static_cell::StaticCell;
use ui::AppWindow; use ui::AppWindow;
use xkbcommon::xkb::{self, Keymap};
use {esp_alloc as _, esp_backtrace as _}; use {esp_alloc as _, esp_backtrace as _};
use crate::matrix::IoeMatrix; use crate::matrix::IoeMatrix;
@ -69,12 +74,15 @@ use crate::peripherals::st7701s::St7701s;
use crate::ui::backend::{FramebufferPtr, SlintBackend}; use crate::ui::backend::{FramebufferPtr, SlintBackend};
use crate::vial::{VIAL_KEYBOARD_DEF, VIAL_KEYBOARD_ID, CustomKeycodes}; use crate::vial::{VIAL_KEYBOARD_DEF, VIAL_KEYBOARD_ID, CustomKeycodes};
mutually_exclusive_features::none_or_one_of!["usb-log", "alt-log", "rtt-log"];
mod keymap; mod keymap;
mod matrix; mod matrix;
mod peripherals; mod peripherals;
mod vial; mod vial;
mod ui; mod ui;
mod logging; mod logging;
mod ffi;
#[cfg(feature = "alt-log")] #[cfg(feature = "alt-log")]
mod console; mod console;
@ -111,12 +119,14 @@ static SIGNAL_UI_RENDER: Signal<CriticalSectionRawMutex, ()> = Signal::new();
#[esp_rtos::main] #[esp_rtos::main]
async fn main(_spawner: Spawner) { async fn main(_spawner: Spawner) {
#[cfg(not(feature = "alt-log"))] #[cfg(feature = "usb-log")]
let alt_uart_rx_task = { {
esp_println::logger::init_logger(LOG_LEVEL_FILTER); esp_println::logger::init_logger(LOG_LEVEL_FILTER);
info!("Logger initialized!"); info!("Logger initialized!");
async {} }
};
#[cfg(feature = "rtt-log")]
rtt_target::rtt_init_log!(LOG_LEVEL_FILTER);
let config = esp_hal::Config::default() let config = esp_hal::Config::default()
.with_cpu_clock(CpuClock::max()) .with_cpu_clock(CpuClock::max())
@ -139,6 +149,9 @@ async fn main(_spawner: Spawner) {
console::run_console(uart_rx.into_async()) console::run_console(uart_rx.into_async())
}; };
#[cfg(not(feature = "alt-log"))]
let alt_uart_rx_task = async {};
// Use the internal DRAM as the heap. // Use the internal DRAM as the heap.
esp_alloc::heap_allocator!(#[unsafe(link_section = ".dram2_uninit")] size: 64 * 1024); esp_alloc::heap_allocator!(#[unsafe(link_section = ".dram2_uninit")] size: 64 * 1024);
info!("Heap initialized! {:#?}", esp_alloc::HEAP.stats()); info!("Heap initialized! {:#?}", esp_alloc::HEAP.stats());
@ -155,8 +168,12 @@ async fn main(_spawner: Spawner) {
} }
} }
let mut io = Io::new(peripherals.IO_MUX); info!("PSRAM allocator initialized!");
io.set_interrupt_handler(interrupt_handler);
// let mut io = Io::new(peripherals.IO_MUX);
// io.set_interrupt_handler(interrupt_handler);
// info!("IO Mux initialized!");
// Enable pull-up on GPIO0 to prevent booting into download mode. // Enable pull-up on GPIO0 to prevent booting into download mode.
let gpio0 = Output::new( let gpio0 = Output::new(
@ -181,6 +198,8 @@ async fn main(_spawner: Spawner) {
timg0.timer0, /*, software_interrupt.software_interrupt0 */ timg0.timer0, /*, software_interrupt.software_interrupt0 */
); );
info!("ESP-RTOS started!");
#[cfg(feature = "ble")] #[cfg(feature = "ble")]
let mut host_resources = rmk::HostResources::new(); let mut host_resources = rmk::HostResources::new();
#[cfg(feature = "ble")] #[cfg(feature = "ble")]
@ -194,8 +213,11 @@ async fn main(_spawner: Spawner) {
let connector = BleConnector::new(radio, bluetooth, Default::default()).unwrap(); let connector = BleConnector::new(radio, bluetooth, Default::default()).unwrap();
let controller: ExternalController<_, 20> = ExternalController::new(connector); let controller: ExternalController<_, 20> = ExternalController::new(connector);
let central_addr = [0x18, 0xe2, 0x21, 0x80, 0xc0, 0xc7]; let central_addr = [0x18, 0xe2, 0x21, 0x80, 0xc0, 0xc7];
let ble_stack = rmk::ble::build_ble_stack(controller, central_addr, &mut rng, &mut host_resources).await;
rmk::ble::build_ble_stack(controller, central_addr, &mut rng, &mut host_resources).await info!("BLE stack for RMK built!");
ble_stack
}; };
// Initialize USB // Initialize USB
@ -209,7 +231,11 @@ async fn main(_spawner: Spawner) {
let usb = Usb::new(peripherals.USB0, peripherals.GPIO20, peripherals.GPIO19); let usb = Usb::new(peripherals.USB0, peripherals.GPIO20, peripherals.GPIO19);
// Create the driver, from the HAL. // Create the driver, from the HAL.
let config = Config::default(); let config = Config::default();
Driver::new(usb, unsafe { &mut *addr_of_mut!(EP_MEMORY) }, config) let driver = Driver::new(usb, unsafe { &mut *addr_of_mut!(EP_MEMORY) }, config);
info!("USB driver for RMK built!");
driver
}; };
// Initialize the flash // Initialize the flash
@ -224,6 +250,8 @@ async fn main(_spawner: Spawner) {
.multicore_auto_park(); .multicore_auto_park();
let flash = async_flash_wrapper(flash); let flash = async_flash_wrapper(flash);
info!("Flash memory configured!");
let sck = Output::new(peripherals.GPIO36, Level::High, OutputConfig::default()); let sck = Output::new(peripherals.GPIO36, Level::High, OutputConfig::default());
let mosi = Flex::new(peripherals.GPIO35); let mosi = Flex::new(peripherals.GPIO35);
let cs = Output::new(peripherals.GPIO6, Level::High, OutputConfig::default()); let cs = Output::new(peripherals.GPIO6, Level::High, OutputConfig::default());
@ -261,6 +289,8 @@ async fn main(_spawner: Spawner) {
let st7701s = St7701s::new(sck, mosi, cs, unconfigured_dpi).await; let st7701s = St7701s::new(sck, mosi, cs, unconfigured_dpi).await;
info!("ST7701S-based LCD display initialized!");
// RMK config // RMK config
let vial_config = VialConfig::new(VIAL_KEYBOARD_ID, VIAL_KEYBOARD_DEF, &[(0, 0), (1, 1)]); let vial_config = VialConfig::new(VIAL_KEYBOARD_ID, VIAL_KEYBOARD_DEF, &[(0, 0), (1, 1)]);
let storage_config = StorageConfig { let storage_config = StorageConfig {
@ -288,6 +318,8 @@ async fn main(_spawner: Spawner) {
) )
.await; .await;
info!("Initialized keymap and storage for RMK!");
// Initialize the matrix and keyboard // Initialize the matrix and keyboard
const I2C_ADDR_MATRIX_LEFT: I2cAddress = I2cAddress::SevenBit(0b0100000); const I2C_ADDR_MATRIX_LEFT: I2cAddress = I2cAddress::SevenBit(0b0100000);
const I2C_ADDR_MATRIX_RIGHT: I2cAddress = I2cAddress::SevenBit(0b0100001); const I2C_ADDR_MATRIX_RIGHT: I2cAddress = I2cAddress::SevenBit(0b0100001);
@ -308,12 +340,16 @@ async fn main(_spawner: Spawner) {
.await; .await;
let mut keyboard = Keyboard::new(&keymap); // Initialize the light controller let mut keyboard = Keyboard::new(&keymap); // Initialize the light controller
info!("Keyboard initialized!");
static FRAMEBUFFER: StaticCell<Framebuffer> = StaticCell::new(); static FRAMEBUFFER: StaticCell<Framebuffer> = StaticCell::new();
let framebuffer = FRAMEBUFFER.init(Framebuffer::new( let framebuffer = FRAMEBUFFER.init(Framebuffer::new(
360 + /* TODO: Figure out why more bytes are needed: */ 8, 360 + /* TODO: Figure out why more bytes are needed: */ 8,
960, 960,
)); ));
info!("Framebuffer created!");
// let window_size = [framebuffer.width, framebuffer.height]; // let window_size = [framebuffer.width, framebuffer.height];
let window_size = [framebuffer.height, framebuffer.width]; let window_size = [framebuffer.height, framebuffer.width];
let framebuffer_ptr = FramebufferPtr(framebuffer.as_target_pixels() as _); let framebuffer_ptr = FramebufferPtr(framebuffer.as_target_pixels() as _);
@ -346,6 +382,8 @@ async fn main(_spawner: Spawner) {
}, },
); );
info!("Second core started!");
let hid_report_proxy_task = { let hid_report_proxy_task = {
static KEYBOARD_REPORT_PROXY: Channel<CriticalSectionRawMutex, Report, 16> = Channel::new(); static KEYBOARD_REPORT_PROXY: Channel<CriticalSectionRawMutex, Report, 16> = Channel::new();
@ -353,6 +391,16 @@ async fn main(_spawner: Spawner) {
*rmk::channel::KEYBOARD_REPORT_SENDER.write().await = &KEYBOARD_REPORT_PROXY; *rmk::channel::KEYBOARD_REPORT_SENDER.write().await = &KEYBOARD_REPORT_PROXY;
} }
info!("HID Report Proxy Task: Waiting 1 sec...");
Timer::after_secs(1).await;
info!("HID Report Proxy Task: Done waiting.");
const KEYMAP_STRING: &str = include_str!("../keymaps/cz.xkb");
info!("HID Report Proxy Task: test");
let context = xkb::Context::new(xkb::CONTEXT_NO_FLAGS);
info!("HID Report Proxy Task: foo");
let keymap = Keymap::new_from_string(&context, KEYMAP_STRING, xkb::KEYMAP_FORMAT_TEXT_V1, xkb::KEYMAP_COMPILE_NO_FLAGS).unwrap();
info!("HID Report Proxy Task: bar");
async { async {
loop { loop {
let report = KEYBOARD_REPORT_PROXY.receive().await; let report = KEYBOARD_REPORT_PROXY.receive().await;
@ -365,6 +413,8 @@ async fn main(_spawner: Spawner) {
let mut user_controller = UserController::new(); let mut user_controller = UserController::new();
info!("Awaiting on all tasks...");
// TODO: Probably want to select! instead and re-try. // TODO: Probably want to select! instead and re-try.
join_all![ join_all![
// We currently send the framebuffer data using the main core, which does not seem to slow // We currently send the framebuffer data using the main core, which does not seem to slow
@ -546,11 +596,12 @@ async fn run_lcd(mut st7701s: St7701s<'static, Blocking>, framebuffer: &'static
} }
} }
#[handler] // // TODO: Not needed currently. If it is ever enabled, don't forget to register it in Io.
#[ram] // TODO: Is this necessary? // #[handler]
fn interrupt_handler() { // #[ram] // TODO: Is this necessary?
esp_println::println!( // fn interrupt_handler() {
"GPIO Interrupt with priority {}", // // esp_println::println!(
esp_hal::xtensa_lx::interrupt::get_level() // // "GPIO Interrupt with priority {}",
); // // esp_hal::xtensa_lx::interrupt::get_level()
} // // );
// }

View file

@ -3,7 +3,7 @@ use core::{cell::RefCell, time::Duration};
use alloc::rc::Rc; use alloc::rc::Rc;
use esp_hal::{time::Instant}; use esp_hal::{time::Instant};
use log::info; use log::info;
use slint::{PhysicalSize, WindowSize, platform::software_renderer::{RenderingRotation, RepaintBufferType, Rgb565Pixel, SoftwareRenderer}}; use slint::{PhysicalSize, WindowSize, platform::{Key, software_renderer::{RenderingRotation, RepaintBufferType, Rgb565Pixel, SoftwareRenderer}}};
use super::window_adapter::SoftwareWindowAdapter; use super::window_adapter::SoftwareWindowAdapter;