From 7b63ff3a1a665a8d9221e8f9d2c8cb1d090f0b7e Mon Sep 17 00:00:00 2001 From: sr1canskhsia Date: Sat, 22 Mar 2025 00:27:46 -0400 Subject: [PATCH] Add Laverita v3 support --- src-slider_io/src/device/config.rs | 5 +++ src-slider_io/src/device/hid.rs | 56 +++++++++++++++++++++++++++++- src/App.svelte | 1 + 3 files changed, 61 insertions(+), 1 deletion(-) diff --git a/src-slider_io/src/device/config.rs b/src-slider_io/src/device/config.rs index 3b294d8..efd902e 100644 --- a/src-slider_io/src/device/config.rs +++ b/src-slider_io/src/device/config.rs @@ -5,6 +5,7 @@ pub enum HardwareSpec { TasollerOne, TasollerTwo, Yuancon, + YuanconThree, Yubideck, YubideckThree, } @@ -50,6 +51,10 @@ impl DeviceMode { spec: HardwareSpec::Yuancon, disable_air: v["disableAirStrings"].as_bool()?, }, + "yuancon-three" => DeviceMode::Hardware { + spec: HardwareSpec::YuanconThree, + disable_air: v["disableAirStrings"].as_bool()?, + }, "yubideck" => DeviceMode::Hardware { spec: HardwareSpec::Yubideck, disable_air: v["disableAirStrings"].as_bool()?, diff --git a/src-slider_io/src/device/hid.rs b/src-slider_io/src/device/hid.rs index b439c35..89dc8bc 100644 --- a/src-slider_io/src/device/hid.rs +++ b/src-slider_io/src/device/hid.rs @@ -205,6 +205,53 @@ impl HidJob { } }, ), + HardwareSpec::YuanconThree => Self::new( + state.clone(), + 0x0518, + 0x2022, + 0x83, + 0x03, + *disable_air, + |buf, input| { + if buf.len != 46 { // real length is 46 but last 12 bytes are unused + return; + } + + input.ground.copy_from_slice(&buf.data[2..34]); + input.flip_vert(); + + let bits: Vec = (0..8).map(|x| (buf.data[0] >> x) & 1).collect(); + for i in 0..6 { + input.air[i ^ 1] = bits[i]; + } + input.extra[0..2].copy_from_slice(&bits[6..8]); + }, + WriteType::Interrupt, + |buf, buf_two, lights| { + buf.len = 61; + buf.data[0] = 0; + buf_two.len = 61; + buf_two.data[0] = 1; + + for (buf_chunk, state_chunk) in buf.data[1..61] + .chunks_mut(3) + .zip(lights.ground.chunks(3).skip(11).take(20).rev()) + { + buf_chunk[0] = state_chunk[0]; + buf_chunk[1] = state_chunk[1]; + buf_chunk[2] = state_chunk[2]; + } + + for (buf_chunk, state_chunk) in buf_two.data[1..34] + .chunks_mut(3) + .zip(lights.ground.chunks(3).take(11).rev()) + { + buf_chunk[0] = state_chunk[0]; + buf_chunk[1] = state_chunk[1]; + buf_chunk[2] = state_chunk[2]; + } + }, + ), HardwareSpec::Yubideck => Self::new( state.clone(), 0x1973, @@ -323,8 +370,15 @@ impl HidJob { } info!("Device setting configuration"); handle.set_active_configuration(1)?; + + // A bit janky but Laverita v3 seems to require interface 3 info!("Device claiming interface"); - handle.claim_interface(0)?; + if self.vid == 0x0518 && self.pid == 0x2022 { + handle.claim_interface(3)?; + } else { + handle.claim_interface(0)?; + } + self.handle = Some(handle); Ok(()) } diff --git a/src/App.svelte b/src/App.svelte index 465d59d..14a5d6a 100644 --- a/src/App.svelte +++ b/src/App.svelte @@ -196,6 +196,7 @@ +