Compare commits

...

4 Commits

Author SHA1 Message Date
NoxiousOtter 2ac1506229 working serial output 2024-04-25 17:26:32 -05:00
NoxiousOtter 52e387d01d oops remove stale code 2024-04-25 16:09:02 -05:00
NoxiousOtter db57f69bdb probably working serial output 2024-04-25 16:08:08 -05:00
NoxiousOtter 73332a7163 add deps and make file 2024-04-25 14:20:31 -05:00
4 changed files with 192 additions and 0 deletions

110
Cargo.lock generated
View File

@ -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"

View File

@ -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"

View File

@ -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
View 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)
}