Compare commits
4 Commits
trunk
...
serial-led
Author | SHA1 | Date | |
---|---|---|---|
25b26ece1c | |||
a64ba411d0 | |||
aaf305d9bf | |||
28b541d8d5 |
110
Cargo.lock
generated
110
Cargo.lock
generated
@ -97,6 +97,7 @@ dependencies = [
|
||||
"lazy_static",
|
||||
"log",
|
||||
"rusb",
|
||||
"serialport",
|
||||
"shared_memory",
|
||||
"winapi",
|
||||
"yubideck-common",
|
||||
@ -141,6 +142,12 @@ dependencies = [
|
||||
"os_str_bytes",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "core-foundation-sys"
|
||||
version = "0.8.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f"
|
||||
|
||||
[[package]]
|
||||
name = "env_logger"
|
||||
version = "0.10.1"
|
||||
@ -227,6 +234,16 @@ dependencies = [
|
||||
"hashbrown",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "io-kit-sys"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "617ee6cf8e3f66f3b4ea67a4058564628cde41901316e19f559e14c7c72c5e7b"
|
||||
dependencies = [
|
||||
"core-foundation-sys",
|
||||
"mach2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "is-terminal"
|
||||
version = "0.4.10"
|
||||
@ -250,6 +267,26 @@ version = "0.2.151"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "302d7ab3130588088d277783b1e2d2e10c9e9e4a16dd9050e6ec93fb3e7048f4"
|
||||
|
||||
[[package]]
|
||||
name = "libudev"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "78b324152da65df7bb95acfcaab55e3097ceaab02fb19b228a9eb74d55f135e0"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"libudev-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libudev-sys"
|
||||
version = "0.1.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3c8469b4a23b962c1396b9b451dda50ef5b283e8dd309d69033475fa9b334324"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"pkg-config",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libusb1-sys"
|
||||
version = "0.6.4"
|
||||
@ -274,6 +311,15 @@ version = "0.4.20"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f"
|
||||
|
||||
[[package]]
|
||||
name = "mach2"
|
||||
version = "0.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "19b955cdeb2a02b9117f121ce63aa52d08ade45de53e48fe6a38b39c10f6f709"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.7.1"
|
||||
@ -302,6 +348,17 @@ dependencies = [
|
||||
"memoffset",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nix"
|
||||
version = "0.26.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "598beaf3cc6fdd9a5dfb1630c2800c7acd31df7aaf0f565796fba2b53ca1af1b"
|
||||
dependencies = [
|
||||
"bitflags 1.3.2",
|
||||
"cfg-if 1.0.0",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nix"
|
||||
version = "0.27.1"
|
||||
@ -474,6 +531,12 @@ dependencies = [
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "scopeguard"
|
||||
version = "1.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.193"
|
||||
@ -494,6 +557,24 @@ dependencies = [
|
||||
"syn 2.0.45",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serialport"
|
||||
version = "4.3.1-alpha.0"
|
||||
source = "git+https://github.com/serialport/serialport-rs.git?rev=954a622#954a62297db09bf190d485bb5d165687cc6af671"
|
||||
dependencies = [
|
||||
"bitflags 2.4.1",
|
||||
"cfg-if 1.0.0",
|
||||
"core-foundation-sys",
|
||||
"io-kit-sys",
|
||||
"libudev",
|
||||
"mach2",
|
||||
"nix 0.26.4",
|
||||
"regex",
|
||||
"scopeguard",
|
||||
"unescaper",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "shared_memory"
|
||||
version = "0.12.4-chuniio"
|
||||
@ -551,6 +632,35 @@ version = "0.16.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "222a222a5bfe1bba4a77b45ec488a741b3cb8872e5e499451fd7d0129c9c7c3d"
|
||||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "1.0.55"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6e3de26b0965292219b4287ff031fcba86837900fe9cd2b34ea8ad893c0953d2"
|
||||
dependencies = [
|
||||
"thiserror-impl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror-impl"
|
||||
version = "1.0.55"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "268026685b2be38d7103e9e507c938a1fcb3d7e6eb15e87870b617bf37b6d581"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.45",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unescaper"
|
||||
version = "0.1.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0adf6ad32eb5b3cadff915f7b770faaac8f7ff0476633aa29eb0d9584d889d34"
|
||||
dependencies = [
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.12"
|
||||
|
@ -19,6 +19,9 @@ rusb = "0.9.3"
|
||||
shared_memory = { workspace = true }
|
||||
yubideck-common = { path = "../common" }
|
||||
winapi = { workspace = true, features = ["minwindef", "winnt", "winerror", "winbase", "winuser"] }
|
||||
# Use this version of serialport because it fixes write being blocking in Windows
|
||||
# As of version 4.3.0, it is not in a stable release
|
||||
serialport = { git = "https://github.com/serialport/serialport-rs.git", rev = "954a622" }
|
||||
|
||||
[build-dependencies]
|
||||
cfg_aliases = "0.2.0"
|
||||
|
@ -1,6 +1,7 @@
|
||||
#![allow(clippy::missing_safety_doc)]
|
||||
|
||||
mod configuration;
|
||||
mod serial;
|
||||
|
||||
use std::{
|
||||
ffi::c_void,
|
||||
@ -11,6 +12,7 @@ use std::{
|
||||
},
|
||||
time::Duration,
|
||||
};
|
||||
use std::mem::offset_of;
|
||||
|
||||
use ::log::error;
|
||||
use shared_memory::Shmem;
|
||||
@ -321,6 +323,7 @@ pub extern "C" fn chuni_io_led_init() -> HRESULT {
|
||||
#[no_mangle]
|
||||
#[cfg(any(chuni, chusanapp))]
|
||||
pub unsafe extern "C" fn chuni_io_led_set_colors(board: u8, rgb: *const u8) {
|
||||
serial::serial_led_set(board, rgb);
|
||||
let device_rg = DEVICE.read().unwrap();
|
||||
let Some(device) = device_rg.as_ref().map(|z| z) else { return };
|
||||
let Some(out_shmem) = &OUTPUT_SHMEM else {
|
||||
|
76
chuniio/src/serial.rs
Normal file
76
chuniio/src/serial.rs
Normal file
@ -0,0 +1,76 @@
|
||||
use lazy_static::lazy_static;
|
||||
use log::{error, info};
|
||||
use serialport::SerialPort;
|
||||
use std::io::Write;
|
||||
use std::ptr;
|
||||
use std::sync::Mutex;
|
||||
use std::time::Duration;
|
||||
|
||||
lazy_static! {
|
||||
static ref SERIAL_PORT: Option<Mutex<Box<dyn SerialPort>>> = open_port();
|
||||
}
|
||||
|
||||
const BOARD_0_LEDS: usize = 53 * 3;
|
||||
const BOARD_1_LEDS: usize = 63 * 3;
|
||||
|
||||
const FRAMING_BYTE: u8 = 0xE0;
|
||||
const ESCAPE_BYTE: u8 = 0xD0;
|
||||
|
||||
fn open_port() -> Option<Mutex<Box<dyn SerialPort>>> {
|
||||
let builder = serialport::new("COM10", 921600).timeout(Duration::from_secs(0));
|
||||
|
||||
match builder.open() {
|
||||
Ok(port) => {
|
||||
info!("Successfully bound to the serial device");
|
||||
Some(Mutex::new(port))
|
||||
}
|
||||
Err(e) => {
|
||||
error!("error opening serial port for LED output: {e:#?}");
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn serial_led_set(board: u8, rgb: *const u8) {
|
||||
let port = match &*SERIAL_PORT {
|
||||
None => return,
|
||||
Some(p) => p,
|
||||
};
|
||||
|
||||
// We need to escape the data, the same as how segatools does it
|
||||
let escaped = match escape_data(board, rgb) {
|
||||
Ok(data) => data,
|
||||
Err(e) => return,
|
||||
};
|
||||
|
||||
let len = escaped.len();
|
||||
let mut serial = port.lock().unwrap();
|
||||
if let Err(e) = serial.write(escaped.as_slice()) {
|
||||
error!("error writing serial led data: {e:#?}");
|
||||
}
|
||||
}
|
||||
|
||||
fn escape_data(board: u8, rgb: *const u8) -> Result<Vec<u8>, &'static str> {
|
||||
let mut escaped = vec![FRAMING_BYTE, board];
|
||||
|
||||
let len = match board {
|
||||
0 => BOARD_0_LEDS,
|
||||
1 => BOARD_1_LEDS,
|
||||
_ => return Err("invalid board id"),
|
||||
};
|
||||
|
||||
let rgb_data = unsafe { std::slice::from_raw_parts(rgb, len) };
|
||||
|
||||
for byte in rgb_data.iter() {
|
||||
let mut byte_to_write = *byte;
|
||||
|
||||
if byte_to_write == ESCAPE_BYTE || byte_to_write == FRAMING_BYTE {
|
||||
escaped.push(ESCAPE_BYTE);
|
||||
byte_to_write -= 1;
|
||||
}
|
||||
|
||||
escaped.push(byte_to_write);
|
||||
}
|
||||
|
||||
Ok(escaped)
|
||||
}
|
Loading…
Reference in New Issue
Block a user