Skip to content

Commit 6bd34fc

Browse files
committed
feat(rynk): add host-side client implementation
Add a runtime-free host client crate for the Rynk protocol, plus native serial and BLE transport crates. Extend firmware-side Rynk protocol handling for host clients and cover the wire format, loopback path, hardware validation example, and host CI checks. Signed-off-by: Haobo Gu <haobogu@outlook.com>
1 parent 89bfd45 commit 6bd34fc

68 files changed

Lines changed: 5562 additions & 1248 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/ci/_lib.sh

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,17 +33,27 @@ log_section() {
3333
}
3434

3535
# Feature-set matrix for rmk check/clippy/test. An empty entry means
36-
# `--no-default-features` with no extra features on top. Kept here so
37-
# check.sh and test.sh stay in lockstep — a set added for check is also
38-
# exercised by tests, and vice versa.
36+
# `--no-default-features` with no extra features on top. This is the single
37+
# source of truth: check.sh, test.sh, and scripts/test_all.sh all consume it,
38+
# so a set added here is checked, clippy'd, and tested everywhere.
3939
RMK_FEATURESETS=(
4040
""
4141
"log,std"
4242
"storage"
4343
"async_matrix,storage"
44+
"vial,storage"
45+
"vial,_ble"
46+
"split,async_matrix"
47+
"split,async_matrix,_ble"
48+
"split,vial,async_matrix"
49+
"split,vial,async_matrix,_ble"
4450
"split,vial,storage"
4551
"passkey_entry"
4652
"split,vial,storage,passkey_entry"
53+
"vial,storage,steno"
54+
"split,vial,storage,async_matrix,_ble,steno"
55+
"rynk,bulk,_ble,split,storage,async_matrix"
56+
"rynk,storage"
4757
)
4858

4959
# Examples auto-discovery skiplist. Reasons:

.github/ci/format.sh

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@ for crate in rmk rmk-config rmk-macro rmk-types; do
88
cargo +nightly fmt --manifest-path "$crate/Cargo.toml" --check
99
done
1010

11+
log_section "Formatting host tooling"
12+
cargo +nightly fmt --manifest-path rynk/Cargo.toml --all --check
13+
1114
log_section "Formatting examples"
1215
while IFS= read -r manifest; do
1316
cargo +nightly fmt --manifest-path "$manifest" --check

.github/ci/host.sh

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
#!/bin/bash
2+
set -euo pipefail
3+
# shellcheck source=_lib.sh
4+
source "$(dirname "${BASH_SOURCE[0]}")/_lib.sh"
5+
6+
# The host tooling is its own cargo workspace.
7+
cd "$repo_root/rynk"
8+
9+
export CARGO_TERM_COLOR=always
10+
export CARGO_TARGET_DIR="${CARGO_TARGET_DIR:-$target_root/host}"
11+
mkdir -p "$CARGO_TARGET_DIR"
12+
13+
log_section "Tests"
14+
cargo +stable test --workspace --lib --tests
15+
16+
log_section "Wasm smoke check"
17+
cargo +stable check -p rynk --lib --target wasm32-unknown-unknown
18+
19+
log_section "Clippy"
20+
cargo +stable clippy --workspace --lib --tests --examples -- -D warnings

.github/ci/test.sh

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,9 @@ nx=(nextest run --config-file "$nextest_cfg" --profile ci)
1616
log_section "Running tests"
1717
cargo +stable "${nx[@]}" --manifest-path rmk-config/Cargo.toml
1818
cargo +stable "${nx[@]}" --manifest-path rmk-types/Cargo.toml
19-
# Exercise the rmk_protocol module (gated behind `rmk_protocol`) so the wire-format
20-
# snapshot tests under rmk-types/src/protocol/rmk/snapshots/ run in CI. `host`
21-
# enables rmk_protocol + bulk + _ble + split, covering every snapshot.
19+
# Exercise the rynk protocol module (gated behind `rynk`).
2220
cargo +stable "${nx[@]}" --manifest-path rmk-types/Cargo.toml --features host
21+
cargo +stable "${nx[@]}" --manifest-path rmk-types/Cargo.toml --features steno
2322
cargo +stable "${nx[@]}" --manifest-path rmk-macro/Cargo.toml
2423
for feats in "${RMK_FEATURESETS[@]}"; do
2524
if [[ -z "$feats" ]]; then

.github/workflows/ci.yml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,22 @@ jobs:
7878
run: cargo install --locked cargo-expand
7979
- run: .github/ci/test.sh
8080

81+
# Host tooling lives in its own workspace, so it gets its own job.
82+
host:
83+
runs-on: ubuntu-latest
84+
steps:
85+
- uses: actions/checkout@v6
86+
- uses: dtolnay/rust-toolchain@stable
87+
with:
88+
components: clippy
89+
targets: wasm32-unknown-unknown
90+
- uses: Swatinem/rust-cache@v2
91+
with:
92+
shared-key: ci-host
93+
cache-directories: |
94+
target/ci
95+
- run: .github/ci/host.sh
96+
8197
# Discover buildable examples for the matrix
8298
discover:
8399
runs-on: ubuntu-latest

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ rmk/Cargo.lock
1515
rmk-macro/Cargo.lock
1616
rmk-config/Cargo.lock
1717
rmk-types/Cargo.lock
18+
rynk/Cargo.lock
1819

1920
# esp idf build files
2021
.embuild

examples/use_rust/nrf54lm20_ble/Cargo.toml

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,14 @@ edition = "2024"
1010
license = "MIT OR Apache-2.0"
1111

1212
[dependencies]
13-
rmk = { path = "../../../rmk", features = ["async_matrix", "nrf54lm20_ble"] }
13+
rmk = { path = "../../../rmk", default-features = false, features = [
14+
"rynk",
15+
"async_matrix",
16+
"nrf54lm20_ble",
17+
"storage",
18+
"defmt",
19+
"watchdog",
20+
] }
1421
nrf-sdc = { git = "https://github.com/alexmoon/nrf-sdc", rev = "131ff2088ed2bb4f6e50ba49e4976aced21fe7ba", default-features = false, features = [
1522
"defmt",
1623
"peripheral",

examples/use_rust/nrf54lm20_ble/src/main.rs

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
#![no_std]
22
#![no_main]
33

4-
mod vial;
54
#[macro_use]
65
mod macros;
76
mod keymap;
@@ -23,7 +22,7 @@ use panic_probe as _;
2322
use rand_chacha::ChaCha12Rng;
2423
use rand_core::SeedableRng;
2524
use rmk::ble::{BleTransport, build_ble_stack};
26-
use rmk::config::{BehaviorConfig, DeviceConfig, PositionalConfig, RmkConfig, StorageConfig, VialConfig};
25+
use rmk::config::{BehaviorConfig, DeviceConfig, PositionalConfig, RmkConfig, StorageConfig};
2726
use rmk::debounce::default_debouncer::DefaultDebouncer;
2827
use rmk::host::HostService;
2928
use rmk::keyboard::Keyboard;
@@ -32,7 +31,6 @@ use rmk::processor::builtin::wpm::WpmProcessor;
3231
use rmk::usb::UsbTransport;
3332
use rmk::{DefaultPacketPool, HostResources, KeymapData, PacketPool, initialize_keymap_and_storage, run_all};
3433
use static_cell::StaticCell;
35-
use vial::{VIAL_KEYBOARD_DEF, VIAL_KEYBOARD_ID};
3634

3735
type RandomSource = cracen::Cracen<'static, Blocking>;
3836

@@ -58,8 +56,6 @@ const FLASH_SECTORS: u8 = 6;
5856
const L2CAP_TXQ: u8 = 4;
5957
const L2CAP_RXQ: u8 = 4;
6058

61-
const UNLOCK_KEYS: &[(u8, u8)] = &[(0, 0), (0, 1)];
62-
6359
fn build_sdc<'d, const N: usize>(
6460
p: nrf_sdc::Peripherals<'d>,
6561
rng: &'d mut RandomSource,
@@ -189,15 +185,13 @@ async fn main(spawner: Spawner) {
189185
product_name: "RMK nRF54LM20A",
190186
serial_number: "vial:f64c2b3c:000054",
191187
};
192-
let vial_config = VialConfig::new(VIAL_KEYBOARD_ID, VIAL_KEYBOARD_DEF, UNLOCK_KEYS);
193188
let storage_config = StorageConfig {
194189
start_addr: FLASH_START_ADDR,
195190
num_sectors: FLASH_SECTORS,
196191
..Default::default()
197192
};
198193
let rmk_config = RmkConfig {
199194
device_config: keyboard_device_config,
200-
vial_config,
201195
storage_config,
202196
..Default::default()
203197
};

rmk-config/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1172,7 +1172,7 @@ mod tests {
11721172

11731173
assert_eq!(config.led_indicator.channel_size, 2);
11741174
assert_eq!(config.led_indicator.pubs, 2);
1175-
assert_eq!(config.led_indicator.subs, 3);
1175+
assert_eq!(config.led_indicator.subs, 4);
11761176

11771177
assert_eq!(config.pointing.channel_size, 8);
11781178
assert_eq!(config.pointing.subs, 2);

rmk-types/Cargo.toml

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,8 @@ rynk = []
3838
# Enables multi-element bulk keymap/combo/morse endpoints and BULK_SIZE constant.
3939
bulk = ["rynk"]
4040
# Host tool: uses protocol ceiling values for Vec capacities.
41-
# Enables all optional endpoint groups so the host can talk to any firmware.
42-
host = ["rynk", "bulk", "_ble", "split"]
41+
host = ["rynk", "bulk", "_ble", "split", "steno"]
4342
# Build-time only features: forwarded from rmk to control constant generation in build.rs.
44-
# Also used as `#[cfg(feature = "...")]` guards for protocol endpoint/topic gating.
4543
_ble = []
4644
split = []
4745
display = []

0 commit comments

Comments
 (0)