From 3bd7ee8586722a4b025d75ad5a674a4d9e3e273a Mon Sep 17 00:00:00 2001 From: 4yn <4yn@users.noreply.github.com> Date: Fri, 18 Nov 2022 01:42:05 +0800 Subject: [PATCH] yubideck v3 firmware support --- README.md | 2 + src-slider_io/src/device/config.rs | 5 ++ src-slider_io/src/device/hid.rs | 88 ++++++++++++++++++++++++++++-- src-tauri/Cargo.lock | 2 +- src-tauri/Cargo.toml | 2 +- src-tauri/README.txt | 4 +- src-tauri/tauri.conf.json | 8 ++- src/App.svelte | 3 +- 8 files changed, 101 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index 7a34178..a4ac820 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,8 @@ Software adapter for various Chunithm slider controllers with a built-in Brokeni ## Changelog +- v0.5.0 + - Support for Yubideck 3.0 firmware - v0.4.3 - Make Yubideck USB reports more flexible when reading data - v0.4.2 diff --git a/src-slider_io/src/device/config.rs b/src-slider_io/src/device/config.rs index af3cfbf..3b294d8 100644 --- a/src-slider_io/src/device/config.rs +++ b/src-slider_io/src/device/config.rs @@ -6,6 +6,7 @@ pub enum HardwareSpec { TasollerTwo, Yuancon, Yubideck, + YubideckThree, } #[derive(Debug, Clone)] @@ -53,6 +54,10 @@ impl DeviceMode { spec: HardwareSpec::Yubideck, disable_air: v["disableAirStrings"].as_bool()?, }, + "yubideck-three" => DeviceMode::Hardware { + spec: HardwareSpec::YubideckThree, + disable_air: v["disableAirStrings"].as_bool()?, + }, "diva" => DeviceMode::DivaSlider { port: v["divaSerialPort"].as_str()?.to_string(), brightness: u8::try_from(v["divaBrightness"].as_i64()?).ok()?, diff --git a/src-slider_io/src/device/hid.rs b/src-slider_io/src/device/hid.rs index 4bed1ed..b439c35 100644 --- a/src-slider_io/src/device/hid.rs +++ b/src-slider_io/src/device/hid.rs @@ -18,7 +18,7 @@ use crate::{ use super::config::HardwareSpec; type HidReadCallback = fn(&Buffer, &mut SliderInput) -> (); -type HidLedCallback = fn(&mut Buffer, &SliderLights) -> (); +type HidLedCallback = fn(&mut Buffer, &mut Buffer, &SliderLights) -> (); enum WriteType { Bulk, @@ -41,6 +41,7 @@ pub struct HidJob { led_write_type: WriteType, led_callback: HidLedCallback, led_buf: Buffer, + led_buf_two: Buffer, handle: Option>, } @@ -70,6 +71,7 @@ impl HidJob { led_write_type: led_type, led_callback, led_buf: Buffer::new(), + led_buf_two: Buffer::new(), handle: None, } } @@ -102,7 +104,7 @@ impl HidJob { input.extra[0..2].copy_from_slice(&bits[26..28]); }, WriteType::Bulk, - |buf, lights| { + |buf, _, lights| { buf.len = 240; buf.data[0] = 'B' as u8; buf.data[1] = 'L' as u8; @@ -139,7 +141,7 @@ impl HidJob { input.extra[0..2].copy_from_slice(&bits[6..8]); }, WriteType::Bulk, - |buf, lights| { + |buf, _, lights| { buf.len = 240; buf.data[0] = 'B' as u8; buf.data[1] = 'L' as u8; @@ -190,7 +192,7 @@ impl HidJob { } }, WriteType::Interrupt, - |buf, lights| { + |buf, _, lights| { buf.len = 31 * 2; for (buf_chunk, state_chunk) in buf .data @@ -225,7 +227,7 @@ impl HidJob { } }, WriteType::Interrupt, - |buf, lights| { + |buf, _, lights| { buf.len = 62; let lights_nibbles: Vec = lights @@ -252,6 +254,56 @@ impl HidJob { } }, ), + HardwareSpec::YubideckThree => Self::new( + state.clone(), + 0x1973, + 0x2001, + 0x81, // Need to confirm + 0x02, // Need to confirm + *disable_air, + |buf, input| { + if buf.len != 45 && buf.len != 46 { + return; + } + + input.ground.copy_from_slice(&buf.data[2..34]); + input.flip_vert(); + for i in 0..6 { + input.air[i ^ 1] = (buf.data[0] >> i) & 1; + } + for i in 0..3 { + input.extra[2 - i] = (buf.data[1] >> i) & 1; + } + }, + 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]; + } + + buf_two.data[34..37].copy_from_slice(&lights.air_left[3..6]); + buf_two.data[37..40].copy_from_slice(&lights.air_right[3..6]); + }, + ), } } @@ -327,7 +379,11 @@ impl ThreadJob for HidJob { { let mut lights_handle = self.state.lights.lock(); if lights_handle.dirty { - (self.led_callback)(&mut self.led_buf, lights_handle.deref()); + (self.led_callback)( + &mut self.led_buf, + &mut self.led_buf_two, + lights_handle.deref(), + ); lights_handle.dirty = false; } } @@ -349,6 +405,26 @@ impl ThreadJob for HidJob { self.led_buf.len = 0; } } + + if self.led_buf_two.len != 0 { + let res = (match self.led_write_type { + WriteType::Bulk => { + handle.write_bulk(self.led_endpoint, self.led_buf_two.slice(), TIMEOUT) + } + WriteType::Interrupt => { + handle.write_interrupt(self.led_endpoint, &self.led_buf_two.slice(), TIMEOUT) + } + }) + .map_err(|e| { + // debug!("Device write error {}", e); + e + }) + .unwrap_or(0); + if res == self.led_buf_two.len + 1 { + // work = true; + self.led_buf_two.len = 0; + } + } } work diff --git a/src-tauri/Cargo.lock b/src-tauri/Cargo.lock index 26e66b1..1b5dd73 100644 --- a/src-tauri/Cargo.lock +++ b/src-tauri/Cargo.lock @@ -2996,7 +2996,7 @@ dependencies = [ [[package]] name = "slidershim" -version = "0.4.3" +version = "0.5.0" dependencies = [ "env_logger", "log", diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index db5cba1..64bc6a2 100644 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "slidershim" -version = "0.4.3" +version = "0.5.0" description = "slidershim" authors = ["4yn"] license = "" diff --git a/src-tauri/README.txt b/src-tauri/README.txt index b01761c..26b638f 100644 --- a/src-tauri/README.txt +++ b/src-tauri/README.txt @@ -2,13 +2,15 @@ ___| (_) __| | ___ _ __ ___| |__ (_)_ __ ___ / __| | |/ _` |/ _ \ '__/ __| '_ \| | '_ ` _ \ \__ \ | | (_| | __/ | \__ \ | | | | | | | | | -|___/_|_|\__,_|\___|_| |___/_| |_|_|_| |_| |_| v0.4.3 +|___/_|_|\__,_|\___|_| |___/_| |_|_|_| |_| |_| v0.5.0 =============================================== https://github.com/4yn/slidershim # Changelog +- v0.5.0 + - Support for Yubideck 3.0 firmware - v0.4.3 - Make Yubideck USB reports more flexible when reading data - v0.4.2 diff --git a/src-tauri/tauri.conf.json b/src-tauri/tauri.conf.json index e4c4cde..dde1beb 100644 --- a/src-tauri/tauri.conf.json +++ b/src-tauri/tauri.conf.json @@ -1,7 +1,7 @@ { "package": { "productName": "slidershim", - "version": "0.4.3" + "version": "0.5.0" }, "build": { "distDir": "../public", @@ -21,7 +21,9 @@ "icons/icon.icns", "icons/icon.ico" ], - "resources": ["./README.txt"], + "resources": [ + "./README.txt" + ], "externalBin": [], "copyright": "© 4yn 2022", "category": "DeveloperTool", @@ -74,4 +76,4 @@ "iconAsTemplate": true } } -} +} \ No newline at end of file diff --git a/src/App.svelte b/src/App.svelte index 5da1df8..465d59d 100644 --- a/src/App.svelte +++ b/src/App.svelte @@ -196,7 +196,8 @@ - + +