Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 9 additions & 21 deletions rmk/src/host/context.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//! Shared context for host-facing services (Vial today, Rynk next).
//! Shared context for the Vial and Rynk host services.

use embassy_time::Duration;
use rmk_types::action::{EncoderAction, KeyAction};
Expand Down Expand Up @@ -107,26 +107,14 @@ impl<'a> KeyboardContext<'a> {
self.keymap.num_encoders()
}

pub async fn set_encoder_clockwise(&self, layer: u8, idx: u8, action: KeyAction) {
let updated = self.keymap.set_encoder_clockwise(layer as usize, idx as usize, action);
#[cfg(feature = "storage")]
if let Some(encoder) = updated {
FLASH_CHANNEL
.send(FlashOperationMessage::Encoder {
idx,
layer,
action: encoder,
})
.await;
}
#[cfg(not(feature = "storage"))]
let _ = updated;
}

pub async fn set_encoder_counter_clockwise(&self, layer: u8, idx: u8, action: KeyAction) {
let updated = self
.keymap
.set_encoder_counter_clockwise(layer as usize, idx as usize, action);
/// Write one encoder direction and persist the updated pair.
pub async fn set_encoder_direction(&self, layer: u8, idx: u8, clockwise: bool, action: KeyAction) {
let updated = if clockwise {
self.keymap.set_encoder_clockwise(layer as usize, idx as usize, action)
} else {
self.keymap
.set_encoder_counter_clockwise(layer as usize, idx as usize, action)
};
#[cfg(feature = "storage")]
if let Some(encoder) = updated {
FLASH_CHANNEL
Expand Down
9 changes: 2 additions & 7 deletions rmk/src/host/via/vial.rs
Original file line number Diff line number Diff line change
Expand Up @@ -405,13 +405,8 @@ pub(crate) async fn process_vial<'a>(
);
let keycode = BigEndian::read_u16(&report.output_data[5..7]);
let action = from_via_keycode(keycode);
if clockwise == 1 {
info!("Setting clockwise action: {:?}", action);
ctx.set_encoder_clockwise(layer, index, action).await;
} else {
info!("Setting counter-clockwise action: {:?}", action);
ctx.set_encoder_counter_clockwise(layer, index, action).await;
}
info!("Setting encoder action (clockwise: {}): {:?}", clockwise, action);
ctx.set_encoder_direction(layer, index, clockwise == 1, action).await;
}
_ => (),
}
Expand Down
28 changes: 3 additions & 25 deletions rmk/tests/common/rynk_hid_link.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! HID-framed variant of [`super::rynk_link`]: interposes the fixed 32-byte HID
//! report framing (firmware `RynkHidService`, de-framed at the `ble::rynk` seam
//! via `drop_report_padding` and reply-framed by `RynkBleTx`) between the host
//! via `RynkHidFrameTracker` and reply-framed by `RynkBleTx`) between the host
//! client and `run_session`, so the framing round-trips through the *real*
//! dispatcher.
//!
Expand All @@ -19,6 +19,7 @@ use rmk_types::protocol::rynk::{Cmd, RYNK_HEADER_SIZE, RYNK_HID_REPORT_SIZE, Ryn
use serde::Serialize;
use serde::de::DeserializeOwned;

use super::rynk_link::Frame;
use super::test_block_on::test_block_on;

/// One direction of the link, carrying whole HID reports.
Expand All @@ -34,32 +35,9 @@ async fn write_framed(link: &Link, data: &[u8]) {
}
}

/// A frame read off the wire, decoded only as far as its header.
pub struct Frame {
pub header: RynkHeader,
pub payload: Vec<u8>,
}

impl Frame {
/// Decode the payload as a `Result<T, RynkError>` envelope, strictly.
pub fn envelope<T: DeserializeOwned>(&self) -> Result<T, RynkError> {
let (env, rest) = postcard::take_from_bytes::<Result<T, RynkError>>(&self.payload)
.expect("response payload must decode as an envelope");
assert!(rest.is_empty(), "response payload has {} trailing byte(s)", rest.len());
env
}

/// Decode the payload as a bare `T` — topic frames are not enveloped.
pub fn raw<T: DeserializeOwned>(&self) -> T {
let (value, rest) = postcard::take_from_bytes::<T>(&self.payload).expect("topic payload must decode");
assert!(rest.is_empty(), "topic payload has {} trailing byte(s)", rest.len());
value
}
}

/// Device-side Rx: reads whole reports off the pipe and de-frames them into the
/// byte stream `run_session` reads. Mirrors the firmware de-frame (`ble::rynk`'s
/// `drop_report_padding` feeding `RYNK_BLE_RX_PIPE`), with `pending`/`pos` standing
/// `RynkHidFrameTracker` feeding `RYNK_BLE_RX_PIPE`), with `pending`/`pos` standing
/// in for the pipe's buffering and `remaining` tracking the in-flight frame.
struct HidRx<'p> {
link: &'p Link,
Expand Down
4 changes: 2 additions & 2 deletions rmk/tests/common/rynk_link.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,8 @@ use super::test_block_on::test_block_on;
/// been polled yet.
pub type Link = Pipe<NoopRawMutex, RYNK_BUFFER_SIZE>;

/// A frame read off the wire, decoded only as far as its header.
///
/// A frame read off the wire, decoded only as far as its header. Shared with
/// the HID-framed harness ([`super::rynk_hid_link`]).
pub struct Frame {
pub header: RynkHeader,
pub payload: Vec<u8>,
Expand Down
2 changes: 1 addition & 1 deletion rmk/tests/rynk_hid_loopback.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//! HID-framed loopback: the same production [`RynkService::run_session`] as
//! `rynk_loopback.rs`, but every exchange crosses the fixed 32-byte HID report
//! framing (firmware `RynkHidService`; de-framed at the `ble::rynk` seam via
//! `drop_report_padding`, reply-framed by `ble::rynk::RynkBleTx`). Proves the
//! `RynkHidFrameTracker`, reply-framed by `ble::rynk::RynkBleTx`). Proves the
//! framing round-trips through the real dispatcher: single-report frames,
//! multi-report reassembly (`GetCapabilities` > 32 B), a pipelined two-request
//! session, and a server→host topic push.
Expand Down