diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index d8efaac..8c9aca1 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -24,6 +24,7 @@ jobs: - stm32h7b0vb - esp32c3 - esp32c6 + - esp32h2 steps: - uses: cargo-bins/cargo-binstall@main - uses: actions/checkout@v3 @@ -50,6 +51,7 @@ jobs: - pico_w - esp32c3 - esp32c6 + - esp32h2 steps: - uses: cargo-bins/cargo-binstall@main - uses: actions/checkout@v3 diff --git a/esp32h2/.cargo/config.toml b/esp32h2/.cargo/config.toml new file mode 100644 index 0000000..3f2f5ea --- /dev/null +++ b/esp32h2/.cargo/config.toml @@ -0,0 +1,14 @@ +[target.'cfg(all(any(target_arch = "riscv32", target_arch = "xtensa"), target_os = "none"))'] +runner = "espflash flash --monitor" + +[build] +target = "riscv32imac-unknown-none-elf" +rustflags = [ + # Required to obtain backtraces (e.g. when using the "esp-backtrace" crate.) + # NOTE: May negatively impact performance of produced code + "-C", "force-frame-pointers", +] + +[env] +ESP_LOG = "info" +KEYBOARD_TOML_PATH = { value = "keyboard.toml", relative = true } diff --git a/esp32h2/.gitignore b/esp32h2/.gitignore new file mode 100644 index 0000000..406c95c --- /dev/null +++ b/esp32h2/.gitignore @@ -0,0 +1,8 @@ +target + +*.bin +*.elf +*.hex +*.uf2 + +.DS_Store diff --git a/esp32h2/Cargo.toml b/esp32h2/Cargo.toml new file mode 100644 index 0000000..93687a2 --- /dev/null +++ b/esp32h2/Cargo.toml @@ -0,0 +1,76 @@ +[package] +name = "{{ project_name }}" +version = "0.1.0" +authors = ["Haobo Gu "] +description = "Keyboard firmware written in Rust" +homepage = "https://github.com/haobogu/rmk" +repository = "https://github.com/haobogu/rmk" +readme = "README.md" +edition = "2024" +license = "MIT OR Apache-2.0" + +[dependencies] +# TODO: switch to crates-io version when it's released. +rmk = { git = "https://github.com/HaoboGu/rmk", rev = "9a740762d80b208c2180cfd2dbde7ed889339d3e", default-features = false, features = [ + "esp32h2_ble", + "log", + "storage", + "vial", +] } +embassy-executor = { version = "0.10" } +esp-backtrace = { version = "0.19", features = [ + "esp32h2", + "panic-handler", + "println", +] } +esp-storage = { version = "0.9", features = ["esp32h2"] } +esp-hal = { version = "1.1", features = ["esp32h2", "unstable"] } +esp-alloc = { version = "0.10" } +esp-println = { version = "0.17", features = ["esp32h2", "log-04"] } +esp-radio = { version = "0.18", features = ["esp32h2", "unstable", "ble"] } +esp-rtos = { version = "0.3", features = ["esp32h2", "esp-radio", "embassy"] } +esp-bootloader-esp-idf = { version = "0.5", features = ["esp32h2", "log-04"] } +bt-hci = { version = "0.9" } + +[build-dependencies] +xz2 = "0.1.7" +json = "0.12" +const-gen = "1.6" +embuild = "0.33" +cc = "1.2.9" + +[[bin]] +name = "{{ project_name }}" +test = false +bench = false + +[profile.dev.package.esp-storage] +opt-level = 3 + +[profile.dev] +# Rust debug is too slow. +# For debug builds always builds with some optimization +opt-level = "s" + +[profile.release] +codegen-units = 1 # LLVM can perform better optimizations using a single thread +debug = 2 +debug-assertions = false +incremental = false +lto = 'thin' +opt-level = 3 +overflow-checks = false + +# esp-radio (crates.io 0.18) still pins bt-hci 0.8, but rmk/trouble-host need bt-hci 0.9. +# Pin the esp-hal graph to the embassy-rs/esp-hal fork (esp-radio 0.18 + bt-hci 0.9) — +# the same rev trouble's own esp CI uses. Drop once esp-radio ships bt-hci 0.9. +[patch.crates-io] +esp-alloc = { git = "https://github.com/embassy-rs/esp-hal.git", rev = "b7eec0fe94aa62d49dfc12d3bf87ca038a8d119f" } +esp-backtrace = { git = "https://github.com/embassy-rs/esp-hal.git", rev = "b7eec0fe94aa62d49dfc12d3bf87ca038a8d119f" } +esp-bootloader-esp-idf = { git = "https://github.com/embassy-rs/esp-hal.git", rev = "b7eec0fe94aa62d49dfc12d3bf87ca038a8d119f" } +esp-hal = { git = "https://github.com/embassy-rs/esp-hal.git", rev = "b7eec0fe94aa62d49dfc12d3bf87ca038a8d119f" } +esp-println = { git = "https://github.com/embassy-rs/esp-hal.git", rev = "b7eec0fe94aa62d49dfc12d3bf87ca038a8d119f" } +esp-radio = { git = "https://github.com/embassy-rs/esp-hal.git", rev = "b7eec0fe94aa62d49dfc12d3bf87ca038a8d119f" } +esp-rtos = { git = "https://github.com/embassy-rs/esp-hal.git", rev = "b7eec0fe94aa62d49dfc12d3bf87ca038a8d119f" } +esp-storage = { git = "https://github.com/embassy-rs/esp-hal.git", rev = "b7eec0fe94aa62d49dfc12d3bf87ca038a8d119f" } +embassy-executor = { git = "https://github.com/embassy-rs/embassy.git", rev = "1d3c3dec8edbf37450d0174b312f8d3d6cc0bf12" } diff --git a/esp32h2/Makefile.toml b/esp32h2/Makefile.toml new file mode 100644 index 0000000..0e8ab96 --- /dev/null +++ b/esp32h2/Makefile.toml @@ -0,0 +1,12 @@ +[tasks.build] +command = "cargo" +args = ["build", "--release"] + +[tasks.uf2] +install_crate = { crate_name = "cargo-espflash", binary = "cargo", test_arg = [ + "espflash", + "--help", +] } +command = "cargo" +args = ["espflash", "save-image", "--release", "--chip", "esp32h2", "--merge", "{{ project_name }}.bin"] +dependencies = ["build"] diff --git a/esp32h2/README.md b/esp32h2/README.md new file mode 100644 index 0000000..c5084c0 --- /dev/null +++ b/esp32h2/README.md @@ -0,0 +1,68 @@ +# RMK + +RMK is a feature-rich and easy-to-use keyboard firmware. + +## Use the template + +To run this firmware, you should have latest Rust installed. The full instruction of installing esp Rust toolchain can be found [here](https://docs.esp-rs.org/book/installation/index.html). + +[`espflash`](https://github.com/esp-rs/espflash) should also be installed: + +``` +cargo install cargo-espflash espflash +``` + +After having everything installed, use the following command to run the example: + +``` +cargo run --release +``` + +If everything is good, you'll see the log as the following: + +```shell +cargo run --release + Compiling ... + ... + ... + Finished `release` profile [optimized + debuginfo] target(s) in 11.70s + Running `espflash flash --monitor --port /dev/cu.usbmodem211401 target/riscv32imac-unknown-none-elf/release/{{ project_name }}` +[2025-04-10T10:01:23Z INFO ] Serial port: '/dev/cu.usbmodem211401' +[2025-04-10T10:01:23Z INFO ] Connecting... +[2025-04-10T10:01:23Z INFO ] Using flash stub +Chip type: esp32h2 (revision v0.1) +Crystal frequency: 32 MHz +Flash size: 4MB +Features: BLE 5, IEEE 802.15.4 +MAC address: 40:4c:ca:5b:c7:dc +App/part. size: 768,944/4,128,768 bytes, 18.62% +[2025-04-10T10:01:23Z INFO ] Segment at address '0x0' has not changed, skipping write +[2025-04-10T10:01:23Z INFO ] Segment at address '0x8000' has not changed, skipping write +[00:00:06] [========================================] 411/411 0x10000 [2025-04-10T10:01:31Z INFO ] Flashing has completed! +``` + +If espflash reports the following error: + +``` +Error: espflash::connection_failed + + × Error while connecting to device + ╰─▶ Serial port not found +``` + +You should to identify which serial port are connected to your esp board, and use `--port` to specify the used serial port: + +``` +# Suppose that the esp board are connected to /dev/cu.usbmodem211401 +cargo run --release -- --port /dev/cu.usbmodem211401 +``` + +If you want to get some insight of segments of your binary, [`espsegs`](https://github.com/bjoernQ/espsegs) would help: + +``` +# Install it first +cargo install --git https://github.com/bjoernQ/espsegs + +# Check all segments +espsegs target/riscv32imac-unknown-none-elf/release/{{ project_name }} --chip esp32h2 +``` \ No newline at end of file diff --git a/esp32h2/build.rs b/esp32h2/build.rs new file mode 100644 index 0000000..147d1e0 --- /dev/null +++ b/esp32h2/build.rs @@ -0,0 +1,49 @@ +use std::fs::File; +use std::io::Read; +use std::path::Path; +use std::{env, fs}; + +use const_gen::*; +use xz2::read::XzEncoder; + +fn main() { + println!("cargo:rerun-if-changed=keyboard.toml"); + + // Generate vial config at the root of project + println!("cargo:rerun-if-changed=vial.json"); + generate_vial_config(); + + println!("cargo:rustc-link-arg-bins=-Tlinkall.x"); + + // Set the extra linker script from defmt + // println!("cargo:rustc-link-arg=-Tdefmt.x"); +} + +fn generate_vial_config() { + // Generated vial config file + let out_file = Path::new(&env::var_os("OUT_DIR").unwrap()).join("config_generated.rs"); + + let p = Path::new("vial.json"); + let mut content = String::new(); + match File::open(p) { + Ok(mut file) => { + file.read_to_string(&mut content).expect("Cannot read vial.json"); + } + Err(e) => println!("Cannot find vial.json {:?}: {}", p, e), + }; + + let vial_cfg = json::stringify(json::parse(&content).unwrap()); + let mut keyboard_def_compressed: Vec = Vec::new(); + XzEncoder::new(vial_cfg.as_bytes(), 6) + .read_to_end(&mut keyboard_def_compressed) + .unwrap(); + + let keyboard_id: Vec = vec![0xB9, 0xBC, 0x09, 0xB2, 0x9D, 0x37, 0x4C, 0xEA]; + let const_declarations = [ + const_declaration!(pub VIAL_KEYBOARD_DEF = keyboard_def_compressed), + const_declaration!(pub VIAL_KEYBOARD_ID = keyboard_id), + ] + .map(|s| "#[allow(clippy::redundant_static_lifetimes)]\n".to_owned() + s.as_str()) + .join("\n"); + fs::write(out_file, const_declarations).unwrap(); +} diff --git a/esp32h2/keyboard.toml b/esp32h2/keyboard.toml new file mode 100644 index 0000000..33fadba --- /dev/null +++ b/esp32h2/keyboard.toml @@ -0,0 +1,53 @@ +[keyboard] +name = "{{ project_name }}" +product_name = "{{ project_name }}" +vendor_id = 0x4c4b +product_id = 0x4643 +manufacturer = "RMK" +chip = "esp32h2" +usb_enable = false + +[matrix] +# Row and col pins are mandatory +# Note: esp32h2 exposes GPIO0-15 and GPIO22-27 (GPIO16-21 don't exist) +row_pins = ["GPIO6", "GPIO7", "GPIO10", "GPIO11"] +col_pins = ["GPIO3", "GPIO4", "GPIO5"] + +# RMK uses col2row as the default matrix diode direction, if you want to use a row2col matrix, add `row2col = true` +# row2col = true + +[layout] +rows = 4 +cols = 3 +layers = 2 +keymap = [ + [ + ["A", "B", "C"], + ["Kc1", "Kc2", "Kc3"], + ["LCtrl", "MO(1)", "LShift"], + ["OSL(1)", "LT(2, Kc9)", "LM(1, LShift | LGui)"] + ], + [ + ["_", "TT(1)", "TG(2)"], + ["_", "_", "_"], + ["_", "_", "_"], + ["_", "_", "_"] + ], +] + +[light] +# All light pins are high-active by default, uncomment if you want it to be low-active +# capslock.pin = "GPIO12" +# capslock.low_active = true +# scrolllock.pin = "GPIO13" +# scrolllock.low_active = true +# Just ignore if no light pin is used for it +# numslock.pin = "GPIO14" +# numslock.low_active = true + +[storage] +# Storage feature is enabled by default +# enabled = false + +[ble] +enabled = true diff --git a/esp32h2/rust-toolchain.toml b/esp32h2/rust-toolchain.toml new file mode 100644 index 0000000..e11abcb --- /dev/null +++ b/esp32h2/rust-toolchain.toml @@ -0,0 +1,6 @@ +[toolchain] +channel = "stable" +components = ["rust-src", "rustfmt", "llvm-tools"] +targets = [ + "riscv32imac-unknown-none-elf", +] diff --git a/esp32h2/src/main.rs b/esp32h2/src/main.rs new file mode 100644 index 0000000..c3bc882 --- /dev/null +++ b/esp32h2/src/main.rs @@ -0,0 +1,9 @@ +#![no_std] +#![no_main] + +use rmk::macros::rmk_keyboard; + +// Vial config is automatically generated by `build.rs`, according to `vial.json` +// Please put `vial.json` at your project's root +#[rmk_keyboard] +mod keyboard {} diff --git a/esp32h2/vial.json b/esp32h2/vial.json new file mode 100644 index 0000000..809c81f --- /dev/null +++ b/esp32h2/vial.json @@ -0,0 +1,74 @@ +{ + "name": "{{ project_name }}", + "vendorId": "0x4C4B", + "productId": "0x4643", + "lighting": "none", + "matrix": { + "rows": 4, + "cols": 3 + }, + "customKeycodes": [ + { + "name": "BT0", + "title": "Bluetooth Channel 0", + "shortName": "BT0" + }, + { + "name": "BT1", + "title": "Bluetooth Channel 1", + "shortName": "BT1" + }, + { + "name": "BT2", + "title": "Bluetooth Channel 2", + "shortName": "BT2" + }, + { + "name": "NEXT_BT", + "title": "Switch to the next Bluetooth channel", + "shortName": "Next\nBT" + }, + { + "name": "PREV_BT", + "title": "Switch to the previous Bluetooth channel", + "shortName": "Prev\nBT" + }, + { + "name": "CLR_BT", + "title": "Clear bond info for current channel", + "shortName": "Clear\nBT" + }, + { + "name": "SWITCH", + "title": "Switch default output mode between USB/BLE", + "shortName": "Switch\nOutput" + } + ], + "layouts": { + "keymap": [ + [ + "0,0", + "0,1", + "0,2" + ], + [ + "1,0", + "1,1", + "1,2" + ], + [ + "2,0", + "2,1", + "2,2" + ], + [ + { + "y": -2, + "x": 4 + }, + "3,0", + "3,2" + ] + ] + } +} \ No newline at end of file diff --git a/esp32h2_split/.cargo/config.toml b/esp32h2_split/.cargo/config.toml new file mode 100644 index 0000000..3f2f5ea --- /dev/null +++ b/esp32h2_split/.cargo/config.toml @@ -0,0 +1,14 @@ +[target.'cfg(all(any(target_arch = "riscv32", target_arch = "xtensa"), target_os = "none"))'] +runner = "espflash flash --monitor" + +[build] +target = "riscv32imac-unknown-none-elf" +rustflags = [ + # Required to obtain backtraces (e.g. when using the "esp-backtrace" crate.) + # NOTE: May negatively impact performance of produced code + "-C", "force-frame-pointers", +] + +[env] +ESP_LOG = "info" +KEYBOARD_TOML_PATH = { value = "keyboard.toml", relative = true } diff --git a/esp32h2_split/.gitignore b/esp32h2_split/.gitignore new file mode 100644 index 0000000..406c95c --- /dev/null +++ b/esp32h2_split/.gitignore @@ -0,0 +1,8 @@ +target + +*.bin +*.elf +*.hex +*.uf2 + +.DS_Store diff --git a/esp32h2_split/Cargo.toml b/esp32h2_split/Cargo.toml new file mode 100644 index 0000000..b124785 --- /dev/null +++ b/esp32h2_split/Cargo.toml @@ -0,0 +1,86 @@ +[package] +name = "{{ project_name }}" +version = "0.1.0" +authors = ["Haobo Gu "] +description = "Keyboard firmware written in Rust" +homepage = "https://github.com/haobogu/rmk" +repository = "https://github.com/haobogu/rmk" +readme = "README.md" +edition = "2024" +license = "MIT OR Apache-2.0" + +[dependencies] +# TODO: switch to crates-io version when it's released. +rmk = { git = "https://github.com/HaoboGu/rmk", rev = "9a740762d80b208c2180cfd2dbde7ed889339d3e", default-features = false, features = [ + "esp32h2_ble", + "log", + "split", + "async_matrix", + "storage", + "vial", +] } +embassy-executor = { version = "0.10" } +esp-backtrace = { version = "0.19", features = [ + "esp32h2", + "panic-handler", + "println", +] } +esp-storage = { version = "0.9", features = ["esp32h2"] } +esp-hal = { version = "1.1", features = ["esp32h2", "unstable"] } +esp-alloc = { version = "0.10" } +esp-println = { version = "0.17", features = ["esp32h2", "log-04"] } +esp-radio = { version = "0.18", features = ["esp32h2", "unstable", "ble"] } +esp-rtos = { version = "0.3", features = ["esp32h2", "esp-radio", "embassy"] } +esp-bootloader-esp-idf = { version = "0.5", features = ["esp32h2", "log-04"] } +bt-hci = { version = "0.9" } + +[build-dependencies] +xz2 = "0.1.7" +json = "0.12" +const-gen = "1.6" +embuild = "0.33" +cc = "1.2.9" + +# Split keyboard example +[[bin]] +name = "central" +path = "src/central.rs" +test = false +bench = false + +[[bin]] +name = "peripheral" +path = "src/peripheral.rs" +test = false +bench = false + +[profile.dev.package.esp-storage] +opt-level = 3 + +[profile.dev] +# Rust debug is too slow. +# For debug builds always builds with some optimization +opt-level = "s" + +[profile.release] +codegen-units = 1 # LLVM can perform better optimizations using a single thread +debug = 2 +debug-assertions = false +incremental = false +lto = 'thin' +opt-level = 3 +overflow-checks = false + +# esp-radio (crates.io 0.18) still pins bt-hci 0.8, but rmk/trouble-host need bt-hci 0.9. +# Pin the esp-hal graph to the embassy-rs/esp-hal fork (esp-radio 0.18 + bt-hci 0.9) — +# the same rev trouble's own esp CI uses. Drop once esp-radio ships bt-hci 0.9. +[patch.crates-io] +esp-alloc = { git = "https://github.com/embassy-rs/esp-hal.git", rev = "b7eec0fe94aa62d49dfc12d3bf87ca038a8d119f" } +esp-backtrace = { git = "https://github.com/embassy-rs/esp-hal.git", rev = "b7eec0fe94aa62d49dfc12d3bf87ca038a8d119f" } +esp-bootloader-esp-idf = { git = "https://github.com/embassy-rs/esp-hal.git", rev = "b7eec0fe94aa62d49dfc12d3bf87ca038a8d119f" } +esp-hal = { git = "https://github.com/embassy-rs/esp-hal.git", rev = "b7eec0fe94aa62d49dfc12d3bf87ca038a8d119f" } +esp-println = { git = "https://github.com/embassy-rs/esp-hal.git", rev = "b7eec0fe94aa62d49dfc12d3bf87ca038a8d119f" } +esp-radio = { git = "https://github.com/embassy-rs/esp-hal.git", rev = "b7eec0fe94aa62d49dfc12d3bf87ca038a8d119f" } +esp-rtos = { git = "https://github.com/embassy-rs/esp-hal.git", rev = "b7eec0fe94aa62d49dfc12d3bf87ca038a8d119f" } +esp-storage = { git = "https://github.com/embassy-rs/esp-hal.git", rev = "b7eec0fe94aa62d49dfc12d3bf87ca038a8d119f" } +embassy-executor = { git = "https://github.com/embassy-rs/embassy.git", rev = "1d3c3dec8edbf37450d0174b312f8d3d6cc0bf12" } diff --git a/esp32h2_split/Makefile.toml b/esp32h2_split/Makefile.toml new file mode 100644 index 0000000..0a56e76 --- /dev/null +++ b/esp32h2_split/Makefile.toml @@ -0,0 +1,25 @@ +[tasks.build] +command = "cargo" +args = ["build", "--release"] + +[tasks.save-image-central] +install_crate = { crate_name = "cargo-espflash", binary = "cargo", test_arg = [ + "espflash", + "--help", +] } +command = "cargo" +args = ["espflash", "save-image", "--release", "--bin", "central", "--chip", "esp32h2", "--merge", "central.bin"] +dependencies = ["build"] + +[tasks.save-image-peripheral] +install_crate = { crate_name = "cargo-espflash", binary = "cargo", test_arg = [ + "espflash", + "--help", +] } +command = "cargo" +args = ["espflash", "save-image", "--release", "--bin", "peripheral", "--chip", "esp32h2", "--merge", "peripheral.bin"] +dependencies = ["build"] + +[tasks.uf2] +dependencies = ["save-image-central", "save-image-peripheral"] + diff --git a/esp32h2_split/README.md b/esp32h2_split/README.md new file mode 100644 index 0000000..8d184ce --- /dev/null +++ b/esp32h2_split/README.md @@ -0,0 +1,74 @@ +# RMK + +RMK is a feature-rich and easy-to-use keyboard firmware. + +## Use the template + +To run this firmware, you should have latest Rust installed. The full instruction of installing esp Rust toolchain can be found [here](https://docs.esp-rs.org/book/installation/index.html). + +[`espflash`](https://github.com/esp-rs/espflash) should also be installed: + +``` +cargo install cargo-espflash espflash +``` + +After having everything installed, use the following command to run the split central: + +``` +cargo run --release --bin central +``` + +For peripheral, run + +``` +cargo run --release --bin peripheral +``` + +If everything is good, you'll see the log as the following: + +```shell +cargo run --release --bin central + Compiling ... + ... + ... + Finished `release` profile [optimized + debuginfo] target(s) in 11.70s + Running `espflash flash --monitor --port /dev/cu.usbmodem211401 target/riscv32imac-unknown-none-elf/release/central` +[2025-04-10T10:01:23Z INFO ] Serial port: '/dev/cu.usbmodem211401' +[2025-04-10T10:01:23Z INFO ] Connecting... +[2025-04-10T10:01:23Z INFO ] Using flash stub +Chip type: esp32h2 (revision v0.1) +Crystal frequency: 32 MHz +Flash size: 4MB +Features: BLE 5, IEEE 802.15.4 +MAC address: 40:4c:ca:5b:c7:dc +App/part. size: 768,944/4,128,768 bytes, 18.62% +[2025-04-10T10:01:23Z INFO ] Segment at address '0x0' has not changed, skipping write +[2025-04-10T10:01:23Z INFO ] Segment at address '0x8000' has not changed, skipping write +[00:00:06] [========================================] 411/411 0x10000 [2025-04-10T10:01:31Z INFO ] Flashing has completed! +``` + +If espflash reports the following error: + +``` +Error: espflash::connection_failed + + × Error while connecting to device + ╰─▶ Serial port not found +``` + +You should to identify which serial port are connected to your esp board, and use `--port` to specify the used serial port: + +``` +# Suppose that the esp board are connected to /dev/cu.usbmodem211401 +cargo run --release --bin central -- --port /dev/cu.usbmodem211401 +``` + +If you want to get some insight of segments of your binary, [`espsegs`](https://github.com/bjoernQ/espsegs) would help: + +``` +# Install it first +cargo install --git https://github.com/bjoernQ/espsegs + +# Check all segments +espsegs target/riscv32imac-unknown-none-elf/release/central --chip esp32h2 +``` \ No newline at end of file diff --git a/esp32h2_split/build.rs b/esp32h2_split/build.rs new file mode 100644 index 0000000..147d1e0 --- /dev/null +++ b/esp32h2_split/build.rs @@ -0,0 +1,49 @@ +use std::fs::File; +use std::io::Read; +use std::path::Path; +use std::{env, fs}; + +use const_gen::*; +use xz2::read::XzEncoder; + +fn main() { + println!("cargo:rerun-if-changed=keyboard.toml"); + + // Generate vial config at the root of project + println!("cargo:rerun-if-changed=vial.json"); + generate_vial_config(); + + println!("cargo:rustc-link-arg-bins=-Tlinkall.x"); + + // Set the extra linker script from defmt + // println!("cargo:rustc-link-arg=-Tdefmt.x"); +} + +fn generate_vial_config() { + // Generated vial config file + let out_file = Path::new(&env::var_os("OUT_DIR").unwrap()).join("config_generated.rs"); + + let p = Path::new("vial.json"); + let mut content = String::new(); + match File::open(p) { + Ok(mut file) => { + file.read_to_string(&mut content).expect("Cannot read vial.json"); + } + Err(e) => println!("Cannot find vial.json {:?}: {}", p, e), + }; + + let vial_cfg = json::stringify(json::parse(&content).unwrap()); + let mut keyboard_def_compressed: Vec = Vec::new(); + XzEncoder::new(vial_cfg.as_bytes(), 6) + .read_to_end(&mut keyboard_def_compressed) + .unwrap(); + + let keyboard_id: Vec = vec![0xB9, 0xBC, 0x09, 0xB2, 0x9D, 0x37, 0x4C, 0xEA]; + let const_declarations = [ + const_declaration!(pub VIAL_KEYBOARD_DEF = keyboard_def_compressed), + const_declaration!(pub VIAL_KEYBOARD_ID = keyboard_id), + ] + .map(|s| "#[allow(clippy::redundant_static_lifetimes)]\n".to_owned() + s.as_str()) + .join("\n"); + fs::write(out_file, const_declarations).unwrap(); +} diff --git a/esp32h2_split/keyboard.toml b/esp32h2_split/keyboard.toml new file mode 100644 index 0000000..701ca5b --- /dev/null +++ b/esp32h2_split/keyboard.toml @@ -0,0 +1,59 @@ +[keyboard] +name = "{{ project_name }}" +product_name = "{{ project_name }}" +vendor_id = 0x4c4b +product_id = 0x4643 +manufacturer = "RMK" +chip = "esp32h2" +usb_enable = false + +[layout] +rows = 4 +cols = 3 +layers = 2 +keymap = [ + [ + ["A", "B", "C"], + ["Kc1", "Kc2", "Kc3"], + ["LCtrl", "MO(1)", "LShift"], + ["OSL(1)", "LT(2, Kc9)", "LM(1, LShift | LGui)"] + ], + [ + ["_", "TT(1)", "TG(2)"], + ["_", "_", "_"], + ["_", "_", "_"], + ["_", "_", "_"] + ], +] + +[split] +connection = "ble" + +[split.central] +rows = 2 +cols = 2 +row_offset = 0 +col_offset = 0 + +[split.central.matrix] +# Note: esp32h2 exposes GPIO0-15 and GPIO22-27 (GPIO16-21 don't exist) +row_pins = ["GPIO6", "GPIO7"] +col_pins = ["GPIO3", "GPIO4"] +# RMK uses col2row as the default matrix diode direction, if you want to use a row2col matrix, add `row2col = true` +# row2col = true + +[[split.peripheral]] +rows = 2 +cols = 1 +row_offset = 2 +col_offset = 2 + +[split.peripheral.matrix] +row_pins = ["GPIO6", "GPIO7"] +col_pins = ["GPIO3"] + +[ble] +enabled = true + +[rmk] +split_peripherals_num = 1 \ No newline at end of file diff --git a/esp32h2_split/rust-toolchain.toml b/esp32h2_split/rust-toolchain.toml new file mode 100644 index 0000000..e11abcb --- /dev/null +++ b/esp32h2_split/rust-toolchain.toml @@ -0,0 +1,6 @@ +[toolchain] +channel = "stable" +components = ["rust-src", "rustfmt", "llvm-tools"] +targets = [ + "riscv32imac-unknown-none-elf", +] diff --git a/esp32h2_split/src/central.rs b/esp32h2_split/src/central.rs new file mode 100644 index 0000000..db41ba4 --- /dev/null +++ b/esp32h2_split/src/central.rs @@ -0,0 +1,7 @@ +#![no_main] +#![no_std] + +use rmk::macros::rmk_central; + +#[rmk_central] +mod keyboard_central {} diff --git a/esp32h2_split/src/peripheral.rs b/esp32h2_split/src/peripheral.rs new file mode 100644 index 0000000..36c4a32 --- /dev/null +++ b/esp32h2_split/src/peripheral.rs @@ -0,0 +1,7 @@ +#![no_main] +#![no_std] + +use rmk::macros::rmk_peripheral; + +#[rmk_peripheral(id = 0)] +mod keyboard_peripheral {} diff --git a/esp32h2_split/vial.json b/esp32h2_split/vial.json new file mode 100644 index 0000000..809c81f --- /dev/null +++ b/esp32h2_split/vial.json @@ -0,0 +1,74 @@ +{ + "name": "{{ project_name }}", + "vendorId": "0x4C4B", + "productId": "0x4643", + "lighting": "none", + "matrix": { + "rows": 4, + "cols": 3 + }, + "customKeycodes": [ + { + "name": "BT0", + "title": "Bluetooth Channel 0", + "shortName": "BT0" + }, + { + "name": "BT1", + "title": "Bluetooth Channel 1", + "shortName": "BT1" + }, + { + "name": "BT2", + "title": "Bluetooth Channel 2", + "shortName": "BT2" + }, + { + "name": "NEXT_BT", + "title": "Switch to the next Bluetooth channel", + "shortName": "Next\nBT" + }, + { + "name": "PREV_BT", + "title": "Switch to the previous Bluetooth channel", + "shortName": "Prev\nBT" + }, + { + "name": "CLR_BT", + "title": "Clear bond info for current channel", + "shortName": "Clear\nBT" + }, + { + "name": "SWITCH", + "title": "Switch default output mode between USB/BLE", + "shortName": "Switch\nOutput" + } + ], + "layouts": { + "keymap": [ + [ + "0,0", + "0,1", + "0,2" + ], + [ + "1,0", + "1,1", + "1,2" + ], + [ + "2,0", + "2,1", + "2,2" + ], + [ + { + "y": -2, + "x": 4 + }, + "3,0", + "3,2" + ] + ] + } +} \ No newline at end of file