probably working serial output

This commit is contained in:
Megurine Luka 2024-04-25 16:08:08 -05:00
parent 28b541d8d5
commit aaf305d9bf
2 changed files with 68 additions and 5 deletions

View File

@ -324,7 +324,10 @@ pub extern "C" fn chuni_io_led_init() -> HRESULT {
#[no_mangle]
#[cfg(any(chuni, chusanapp))]
pub extern "C" fn chuni_io_led_init() -> HRESULT {
serial::serial_led_init()
// If this fails, it is not a failure for the YubiDeck LEDs
serial::serial_led_init();
S_OK
}
#[no_mangle]

View File

@ -1,10 +1,70 @@
use winapi::shared::winerror::S_OK;
use winapi::um::winnt::HRESULT;
use std::io::Write;
use std::sync::Mutex;
use std::time::Duration;
use lazy_static::lazy_static;
use log::error;
use serialport::{SerialPort};
pub fn serial_led_init() -> HRESULT {
S_OK
lazy_static! {
static ref SERIAL_PORT: Option<Mutex<Box<dyn SerialPort>>> = open_port();
}
const BOARD_0_LEDS: i32 = 53 * 3;
const BOARD_1_LEDS: i32 = 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) => 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 mut serial = port.lock().unwrap();
if serial.write(escaped.as_slice()).is_err() {
error!("error writing serial led data: {e:#?}");
}
}
fn escape_data(board: u8, rgb: *const u8) -> Result<Vec<u8>, &'static str> {
let mut escaped = vec![ESCAPE_BYTE, board];
let len = match board {
0 => BOARD_0_LEDS,
1 => BOARD_1_LEDS,
_ => return Err("invalid board id"),
};
for i in 0..len {
let mut byte = rgb[i];
if byte == ESCAPE_BYTE || byte == FRAMING_BYTE {
escaped.push(ESCAPE_BYTE);
byte -= 1;
}
escaped.push(byte);
}
Ok(escaped)
}