mirror of
https://gitlab.com/asus-linux/asusctl.git
synced 2026-02-06 00:15:04 +01:00
Adjust how thread exit is handled for anime controller
This commit is contained in:
1
Cargo.lock
generated
1
Cargo.lock
generated
@@ -1022,6 +1022,7 @@ version = "1.3.3"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"gif",
|
"gif",
|
||||||
"glam",
|
"glam",
|
||||||
|
"log",
|
||||||
"pix",
|
"pix",
|
||||||
"png_pong",
|
"png_pong",
|
||||||
"serde",
|
"serde",
|
||||||
|
|||||||
@@ -59,7 +59,10 @@ pub struct LedModeCommand {
|
|||||||
help = "set the keyboard LED suspend animation to enabled while the device is suspended"
|
help = "set the keyboard LED suspend animation to enabled while the device is suspended"
|
||||||
)]
|
)]
|
||||||
pub sleep_enable: Option<bool>,
|
pub sleep_enable: Option<bool>,
|
||||||
#[options(meta = "", help = "set the full keyboard LEDs (keys and side) to enabled")]
|
#[options(
|
||||||
|
meta = "",
|
||||||
|
help = "set the full keyboard LEDs (keys and side) to enabled"
|
||||||
|
)]
|
||||||
pub all_leds_enable: Option<bool>,
|
pub all_leds_enable: Option<bool>,
|
||||||
#[options(meta = "", help = "set the keyboard keys LEDs to enabled")]
|
#[options(meta = "", help = "set the keyboard keys LEDs to enabled")]
|
||||||
pub keys_leds_enable: Option<bool>,
|
pub keys_leds_enable: Option<bool>,
|
||||||
|
|||||||
@@ -365,8 +365,7 @@ fn handle_led_mode(
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if supported.multizone_led_mode && command.trim().starts_with("multi")
|
if supported.multizone_led_mode && command.trim().starts_with("multi") {
|
||||||
{
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
false
|
false
|
||||||
|
|||||||
@@ -91,12 +91,16 @@ impl<'a> CtrlAnimeInner<'static> {
|
|||||||
for action in self.sequences.iter() {
|
for action in self.sequences.iter() {
|
||||||
match action {
|
match action {
|
||||||
ActionData::Animation(frames) => {
|
ActionData::Animation(frames) => {
|
||||||
rog_anime::run_animation(frames, self.do_early_return.clone(), &|output| {
|
rog_anime::run_animation(frames, &|output| {
|
||||||
|
if self.do_early_return.load(Ordering::Acquire) {
|
||||||
|
return Ok(true); // Do safe exit
|
||||||
|
}
|
||||||
self.client
|
self.client
|
||||||
.proxies()
|
.proxies()
|
||||||
.anime()
|
.anime()
|
||||||
.write(output)
|
.write(output)
|
||||||
.map_err(|e| AnimeError::Dbus(format!("{}", e)))
|
.map_err(|e| AnimeError::Dbus(format!("{}", e)))
|
||||||
|
.map(|_| false)
|
||||||
})?;
|
})?;
|
||||||
}
|
}
|
||||||
ActionData::Image(image) => {
|
ActionData::Image(image) => {
|
||||||
|
|||||||
@@ -141,6 +141,7 @@ impl CtrlAnime {
|
|||||||
warn!("AniMe system actions was empty");
|
warn!("AniMe system actions was empty");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Loop rules:
|
// Loop rules:
|
||||||
// - Lock the mutex **only when required**. That is, the lock must be held for the shortest duration possible.
|
// - Lock the mutex **only when required**. That is, the lock must be held for the shortest duration possible.
|
||||||
// - An AtomicBool used for thread exit should be checked in every loop, including nested
|
// - An AtomicBool used for thread exit should be checked in every loop, including nested
|
||||||
@@ -150,55 +151,54 @@ impl CtrlAnime {
|
|||||||
std::thread::Builder::new()
|
std::thread::Builder::new()
|
||||||
.name("AniMe system thread start".into())
|
.name("AniMe system thread start".into())
|
||||||
.spawn(move || {
|
.spawn(move || {
|
||||||
info!("AniMe system thread started");
|
info!("AniMe new system thread started");
|
||||||
// Getting copies of these Atomics is done *in* the thread to ensure
|
// Getting copies of these Atomics is done *in* the thread to ensure
|
||||||
// we don't block other threads/main
|
// we don't block other threads/main
|
||||||
let thread_exit;
|
let thread_exit;
|
||||||
let thread_running;
|
let thread_running;
|
||||||
// First two loops are to ensure we *do* aquire a lock on the mutex
|
|
||||||
// The reason the loop is required is because the USB writes can block
|
|
||||||
// for up to 10ms. We can't fail to get the atomics.
|
|
||||||
loop {
|
loop {
|
||||||
if let Ok(lock) = inner.try_lock() {
|
if let Ok(lock) = inner.try_lock() {
|
||||||
thread_exit = lock.thread_exit.clone();
|
thread_exit = lock.thread_exit.clone();
|
||||||
thread_running = lock.thread_running.clone();
|
thread_running = lock.thread_running.clone();
|
||||||
// Make any running loop exit first
|
|
||||||
thread_exit.store(true, Ordering::SeqCst);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// First two loops are to ensure we *do* aquire a lock on the mutex
|
||||||
loop {
|
// The reason the loop is required is because the USB writes can block
|
||||||
// wait for other threads to set not running so we know they exited
|
// for up to 10ms. We can't fail to get the atomics.
|
||||||
if !thread_running.load(Ordering::SeqCst) {
|
while thread_running.load(Ordering::SeqCst) {
|
||||||
info!("AniMe forced a thread to exit");
|
// Make any running loop exit first
|
||||||
break;
|
thread_exit.store(true, Ordering::SeqCst);
|
||||||
}
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
info!("AniMe no previous system thread running (now)");
|
||||||
thread_exit.store(false, Ordering::SeqCst);
|
thread_exit.store(false, Ordering::SeqCst);
|
||||||
thread_running.store(true, Ordering::SeqCst);
|
|
||||||
|
|
||||||
'main: loop {
|
'main: loop {
|
||||||
|
thread_running.store(true, Ordering::SeqCst);
|
||||||
for action in actions.iter() {
|
for action in actions.iter() {
|
||||||
if thread_exit.load(Ordering::SeqCst) {
|
if thread_exit.load(Ordering::SeqCst) {
|
||||||
break 'main;
|
break 'main;
|
||||||
}
|
}
|
||||||
match action {
|
match action {
|
||||||
ActionData::Animation(frames) => {
|
ActionData::Animation(frames) => {
|
||||||
if let Err(err) = rog_anime::run_animation(
|
if let Err(err) = rog_anime::run_animation(frames, &|frame| {
|
||||||
frames,
|
if thread_exit.load(Ordering::Acquire) {
|
||||||
thread_exit.clone(),
|
info!("rog-anime: frame-loop was asked to exit");
|
||||||
&|frame| {
|
return Ok(true); // Do safe exit
|
||||||
inner
|
}
|
||||||
.try_lock()
|
inner
|
||||||
.map(|lock| lock.write_data_buffer(frame))
|
.try_lock()
|
||||||
.map_err(|err| {
|
.map(|lock| {
|
||||||
warn!("rog_anime::run_animation:callback {}", err);
|
lock.write_data_buffer(frame);
|
||||||
AnimeError::NoFrames
|
false // Don't exit yet
|
||||||
})
|
})
|
||||||
},
|
.map_err(|err| {
|
||||||
) {
|
warn!("rog_anime::run_animation:callback {}", err);
|
||||||
|
AnimeError::NoFrames
|
||||||
|
})
|
||||||
|
}) {
|
||||||
warn!("rog_anime::run_animation:Animation {}", err);
|
warn!("rog_anime::run_animation:Animation {}", err);
|
||||||
break 'main;
|
break 'main;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -83,7 +83,6 @@ impl AuraConfigV407 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#[derive(Deserialize, Serialize)]
|
#[derive(Deserialize, Serialize)]
|
||||||
pub struct AuraConfig {
|
pub struct AuraConfig {
|
||||||
pub brightness: LedBrightness,
|
pub brightness: LedBrightness,
|
||||||
@@ -94,7 +93,7 @@ pub struct AuraConfig {
|
|||||||
pub sleep_anim_enabled: bool,
|
pub sleep_anim_enabled: bool,
|
||||||
pub all_leds_enabled: bool,
|
pub all_leds_enabled: bool,
|
||||||
pub keys_leds_enabled: bool,
|
pub keys_leds_enabled: bool,
|
||||||
pub side_leds_enabled: bool
|
pub side_leds_enabled: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for AuraConfig {
|
impl Default for AuraConfig {
|
||||||
|
|||||||
@@ -9,10 +9,9 @@ use crate::{
|
|||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use log::{error, info, warn};
|
use log::{error, info, warn};
|
||||||
use logind_zbus::manager::ManagerProxy;
|
use logind_zbus::manager::ManagerProxy;
|
||||||
|
use rog_aura::usb::leds_message;
|
||||||
use rog_aura::{
|
use rog_aura::{
|
||||||
usb::{
|
usb::{LED_APPLY, LED_SET},
|
||||||
LED_APPLY, LED_SET
|
|
||||||
},
|
|
||||||
AuraEffect, LedBrightness, LED_MSG_LEN,
|
AuraEffect, LedBrightness, LED_MSG_LEN,
|
||||||
};
|
};
|
||||||
use rog_supported::LedSupportedFunctions;
|
use rog_supported::LedSupportedFunctions;
|
||||||
@@ -23,14 +22,11 @@ use std::path::Path;
|
|||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::sync::Mutex;
|
use std::sync::Mutex;
|
||||||
use zbus::Connection;
|
use zbus::Connection;
|
||||||
use rog_aura::usb::leds_message;
|
|
||||||
|
|
||||||
use crate::GetSupported;
|
use crate::GetSupported;
|
||||||
|
|
||||||
use super::config::AuraConfig;
|
use super::config::AuraConfig;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
impl GetSupported for CtrlKbdLed {
|
impl GetSupported for CtrlKbdLed {
|
||||||
type A = LedSupportedFunctions;
|
type A = LedSupportedFunctions;
|
||||||
|
|
||||||
@@ -281,20 +277,19 @@ impl CtrlKbdLed {
|
|||||||
self.set_brightness(self.config.brightness)
|
self.set_brightness(self.config.brightness)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// Set combination state for boot animation/sleep animation/all leds/keys leds/side leds LED active
|
/// Set combination state for boot animation/sleep animation/all leds/keys leds/side leds LED active
|
||||||
pub(super) fn set_power_states(&self, config: &AuraConfig) -> Result<(), RogError> {
|
pub(super) fn set_power_states(&self, config: &AuraConfig) -> Result<(), RogError> {
|
||||||
|
let bytes = leds_message(
|
||||||
let bytes = leds_message(config.boot_anim_enabled,
|
config.boot_anim_enabled,
|
||||||
config.sleep_anim_enabled,
|
config.sleep_anim_enabled,
|
||||||
config.all_leds_enabled,
|
config.all_leds_enabled,
|
||||||
config.keys_leds_enabled,
|
config.keys_leds_enabled,
|
||||||
config.side_leds_enabled);
|
config.side_leds_enabled,
|
||||||
|
);
|
||||||
|
|
||||||
// Quite ugly, must be a more idiomatic way to do
|
// Quite ugly, must be a more idiomatic way to do
|
||||||
let message = [
|
let message = [
|
||||||
0x5d, 0xbd, 0x01, bytes[0], bytes[1], bytes[2], 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
0x5d, 0xbd, 0x01, bytes[0], bytes[1], bytes[2], 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
];
|
];
|
||||||
|
|
||||||
self.write_bytes(&message)?;
|
self.write_bytes(&message)?;
|
||||||
|
|||||||
@@ -38,15 +38,15 @@ impl CtrlKbdLedZbus {
|
|||||||
ctrl.config.write();
|
ctrl.config.write();
|
||||||
|
|
||||||
ctrl.set_power_states(&ctrl.config)
|
ctrl.set_power_states(&ctrl.config)
|
||||||
.map_err(|err| warn!("{}", err))
|
.map_err(|err| warn!("{}", err))
|
||||||
.ok();
|
.ok();
|
||||||
|
|
||||||
states = Some(LedPowerStates {
|
states = Some(LedPowerStates {
|
||||||
boot_anim: ctrl.config.boot_anim_enabled,
|
boot_anim: ctrl.config.boot_anim_enabled,
|
||||||
sleep_anim: ctrl.config.sleep_anim_enabled,
|
sleep_anim: ctrl.config.sleep_anim_enabled,
|
||||||
all_leds: ctrl.config.all_leds_enabled,
|
all_leds: ctrl.config.all_leds_enabled,
|
||||||
keys_leds: ctrl.config.keys_leds_enabled,
|
keys_leds: ctrl.config.keys_leds_enabled,
|
||||||
side_leds: ctrl.config.side_leds_enabled
|
side_leds: ctrl.config.side_leds_enabled,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
// Need to pull state out like this due to MutexGuard
|
// Need to pull state out like this due to MutexGuard
|
||||||
@@ -69,15 +69,15 @@ impl CtrlKbdLedZbus {
|
|||||||
ctrl.config.write();
|
ctrl.config.write();
|
||||||
|
|
||||||
ctrl.set_power_states(&ctrl.config)
|
ctrl.set_power_states(&ctrl.config)
|
||||||
.map_err(|err| warn!("{}", err))
|
.map_err(|err| warn!("{}", err))
|
||||||
.ok();
|
.ok();
|
||||||
|
|
||||||
states = Some(LedPowerStates {
|
states = Some(LedPowerStates {
|
||||||
boot_anim: ctrl.config.boot_anim_enabled,
|
boot_anim: ctrl.config.boot_anim_enabled,
|
||||||
sleep_anim: ctrl.config.sleep_anim_enabled,
|
sleep_anim: ctrl.config.sleep_anim_enabled,
|
||||||
all_leds: ctrl.config.all_leds_enabled,
|
all_leds: ctrl.config.all_leds_enabled,
|
||||||
keys_leds: ctrl.config.keys_leds_enabled,
|
keys_leds: ctrl.config.keys_leds_enabled,
|
||||||
side_leds: ctrl.config.side_leds_enabled
|
side_leds: ctrl.config.side_leds_enabled,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if let Some(states) = states {
|
if let Some(states) = states {
|
||||||
@@ -109,7 +109,7 @@ impl CtrlKbdLedZbus {
|
|||||||
sleep_anim: ctrl.config.sleep_anim_enabled,
|
sleep_anim: ctrl.config.sleep_anim_enabled,
|
||||||
all_leds: ctrl.config.all_leds_enabled,
|
all_leds: ctrl.config.all_leds_enabled,
|
||||||
keys_leds: ctrl.config.keys_leds_enabled,
|
keys_leds: ctrl.config.keys_leds_enabled,
|
||||||
side_leds: ctrl.config.side_leds_enabled
|
side_leds: ctrl.config.side_leds_enabled,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
// Need to pull state out like this due to MutexGuard
|
// Need to pull state out like this due to MutexGuard
|
||||||
@@ -140,7 +140,7 @@ impl CtrlKbdLedZbus {
|
|||||||
sleep_anim: ctrl.config.sleep_anim_enabled,
|
sleep_anim: ctrl.config.sleep_anim_enabled,
|
||||||
all_leds: ctrl.config.all_leds_enabled,
|
all_leds: ctrl.config.all_leds_enabled,
|
||||||
keys_leds: ctrl.config.keys_leds_enabled,
|
keys_leds: ctrl.config.keys_leds_enabled,
|
||||||
side_leds: ctrl.config.side_leds_enabled
|
side_leds: ctrl.config.side_leds_enabled,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
// Need to pull state out like this due to MutexGuard
|
// Need to pull state out like this due to MutexGuard
|
||||||
@@ -171,7 +171,7 @@ impl CtrlKbdLedZbus {
|
|||||||
sleep_anim: ctrl.config.sleep_anim_enabled,
|
sleep_anim: ctrl.config.sleep_anim_enabled,
|
||||||
all_leds: ctrl.config.all_leds_enabled,
|
all_leds: ctrl.config.all_leds_enabled,
|
||||||
keys_leds: ctrl.config.keys_leds_enabled,
|
keys_leds: ctrl.config.keys_leds_enabled,
|
||||||
side_leds: ctrl.config.side_leds_enabled
|
side_leds: ctrl.config.side_leds_enabled,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
// Need to pull state out like this due to MutexGuard
|
// Need to pull state out like this due to MutexGuard
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ dbus = ["zvariant"]
|
|||||||
png_pong = "^0.8.0"
|
png_pong = "^0.8.0"
|
||||||
pix = "0.13"
|
pix = "0.13"
|
||||||
gif = "^0.11.2"
|
gif = "^0.11.2"
|
||||||
|
log = "*"
|
||||||
|
|
||||||
serde = "^1.0"
|
serde = "^1.0"
|
||||||
serde_derive = "^1.0"
|
serde_derive = "^1.0"
|
||||||
|
|||||||
@@ -1,12 +1,9 @@
|
|||||||
use std::{
|
use std::{
|
||||||
sync::{
|
|
||||||
atomic::{AtomicBool, Ordering},
|
|
||||||
Arc,
|
|
||||||
},
|
|
||||||
thread::sleep,
|
thread::sleep,
|
||||||
time::{Duration, Instant},
|
time::{Duration, Instant},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use log::info;
|
||||||
use serde_derive::{Deserialize, Serialize};
|
use serde_derive::{Deserialize, Serialize};
|
||||||
#[cfg(feature = "dbus")]
|
#[cfg(feature = "dbus")]
|
||||||
use zvariant::Type;
|
use zvariant::Type;
|
||||||
@@ -92,10 +89,11 @@ impl From<AnimeDataBuffer> for AnimePacketType {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// This runs the animations as a blocking loop by using the `callback` to write data
|
/// This runs the animations as a blocking loop by using the `callback` to write data
|
||||||
|
///
|
||||||
|
/// If `callback` is `Ok(true)` then `run_animation` will exit the animation loop early.
|
||||||
pub fn run_animation(
|
pub fn run_animation(
|
||||||
frames: &AnimeGif,
|
frames: &AnimeGif,
|
||||||
do_early_return: Arc<AtomicBool>,
|
callback: &dyn Fn(AnimeDataBuffer) -> Result<bool, AnimeError>,
|
||||||
callback: &dyn Fn(AnimeDataBuffer) -> Result<(), AnimeError>,
|
|
||||||
) -> Result<(), AnimeError> {
|
) -> Result<(), AnimeError> {
|
||||||
let mut count = 0;
|
let mut count = 0;
|
||||||
let start = Instant::now();
|
let start = Instant::now();
|
||||||
@@ -140,9 +138,6 @@ pub fn run_animation(
|
|||||||
'animation: loop {
|
'animation: loop {
|
||||||
for frame in frames.frames() {
|
for frame in frames.frames() {
|
||||||
let frame_start = Instant::now();
|
let frame_start = Instant::now();
|
||||||
if do_early_return.load(Ordering::SeqCst) {
|
|
||||||
return Ok(());
|
|
||||||
}
|
|
||||||
let mut output = frame.frame().clone();
|
let mut output = frame.frame().clone();
|
||||||
|
|
||||||
if let AnimTime::Fade(_) = frames.duration() {
|
if let AnimTime::Fade(_) = frames.duration() {
|
||||||
@@ -164,12 +159,14 @@ pub fn run_animation(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
callback(output).ok();
|
if matches!(callback(output), Ok(true)) {
|
||||||
|
info!("rog-anime: frame-loop callback asked to exit early");
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
|
||||||
if timed && Instant::now().duration_since(start) > run_time {
|
if timed && Instant::now().duration_since(start) > run_time {
|
||||||
break 'animation;
|
break 'animation;
|
||||||
}
|
}
|
||||||
|
|
||||||
sleep(frame.delay());
|
sleep(frame.delay());
|
||||||
}
|
}
|
||||||
if let AnimTime::Count(times) = frames.duration() {
|
if let AnimTime::Count(times) = frames.duration() {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
|
use crate::usb::LedCfgState::{Off, On};
|
||||||
use std::convert::TryFrom;
|
use std::convert::TryFrom;
|
||||||
use std::ops::{BitAnd, BitOr};
|
use std::ops::{BitAnd, BitOr};
|
||||||
use crate::usb::LedCfgState::{Off, On};
|
|
||||||
|
|
||||||
pub const LED_INIT1: [u8; 2] = [0x5d, 0xb9];
|
pub const LED_INIT1: [u8; 2] = [0x5d, 0xb9];
|
||||||
pub const LED_INIT2: &str = "]ASUS Tech.Inc."; // ] == 0x5d
|
pub const LED_INIT2: &str = "]ASUS Tech.Inc."; // ] == 0x5d
|
||||||
@@ -12,12 +12,12 @@ pub const LED_INIT5: [u8; 6] = [0x5e, 0x05, 0x20, 0x31, 0, 0x08];
|
|||||||
pub const LED_APPLY: [u8; 17] = [0x5d, 0xb4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
|
pub const LED_APPLY: [u8; 17] = [0x5d, 0xb4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
|
||||||
pub const LED_SET: [u8; 17] = [0x5d, 0xb5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
|
pub const LED_SET: [u8; 17] = [0x5d, 0xb5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
|
||||||
|
|
||||||
pub const BOOT_MASK:i32 = 0xc31309;
|
pub const BOOT_MASK: i32 = 0xc31309;
|
||||||
pub const SLEEP_MASK:i32 = 0x300904;
|
pub const SLEEP_MASK: i32 = 0x300904;
|
||||||
pub const ALL_LEDS_MASK:i32 = 0x000002;
|
pub const ALL_LEDS_MASK: i32 = 0x000002;
|
||||||
pub const KBD_LEDS_MASK:i32 = 0x080000;
|
pub const KBD_LEDS_MASK: i32 = 0x080000;
|
||||||
pub const SIDE_LEDS_MASK:i32 = 0x040500;
|
pub const SIDE_LEDS_MASK: i32 = 0x040500;
|
||||||
pub const LEDS_STATE_MASK:i32 = ALL_LEDS_MASK | KBD_LEDS_MASK | SIDE_LEDS_MASK;
|
pub const LEDS_STATE_MASK: i32 = ALL_LEDS_MASK | KBD_LEDS_MASK | SIDE_LEDS_MASK;
|
||||||
|
|
||||||
/// Writes out the correct byte string for brightness
|
/// Writes out the correct byte string for brightness
|
||||||
pub const fn aura_brightness_bytes(brightness: u8) -> [u8; 17] {
|
pub const fn aura_brightness_bytes(brightness: u8) -> [u8; 17] {
|
||||||
@@ -29,7 +29,7 @@ pub const fn aura_brightness_bytes(brightness: u8) -> [u8; 17] {
|
|||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy)]
|
||||||
pub enum LedCfgState {
|
pub enum LedCfgState {
|
||||||
On = 0xffffff,
|
On = 0xffffff,
|
||||||
Off = 0x0
|
Off = 0x0,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<i32> for LedCfgState {
|
impl From<i32> for LedCfgState {
|
||||||
@@ -37,7 +37,7 @@ impl From<i32> for LedCfgState {
|
|||||||
match state {
|
match state {
|
||||||
0xffffff => On,
|
0xffffff => On,
|
||||||
0x0 => Off,
|
0x0 => Off,
|
||||||
_ => Off
|
_ => Off,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -46,19 +46,19 @@ impl From<bool> for LedCfgState {
|
|||||||
fn from(state: bool) -> Self {
|
fn from(state: bool) -> Self {
|
||||||
match state {
|
match state {
|
||||||
true => On,
|
true => On,
|
||||||
false => Off
|
false => Off,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TryFrom <[u8; 3]> for LedCfgState {
|
impl TryFrom<[u8; 3]> for LedCfgState {
|
||||||
type Error = &'static str;
|
type Error = &'static str;
|
||||||
|
|
||||||
fn try_from(value: [u8; 3]) -> Result<Self, Self::Error> {
|
fn try_from(value: [u8; 3]) -> Result<Self, Self::Error> {
|
||||||
match value {
|
match value {
|
||||||
[0xff, 0xff, 0xff] => Ok(On),
|
[0xff, 0xff, 0xff] => Ok(On),
|
||||||
[0, 0, 0] => Ok(Off),
|
[0, 0, 0] => Ok(Off),
|
||||||
_ => Err("Unconvertible value")
|
_ => Err("Unconvertible value"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -67,14 +67,14 @@ impl BitAnd<LedCfgState> for i32 {
|
|||||||
type Output = i32;
|
type Output = i32;
|
||||||
|
|
||||||
fn bitand(self, rhs: LedCfgState) -> i32 {
|
fn bitand(self, rhs: LedCfgState) -> i32 {
|
||||||
return self & rhs as i32
|
return self & rhs as i32;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl BitOr<LedCfgState> for i32 {
|
impl BitOr<LedCfgState> for i32 {
|
||||||
type Output = i32;
|
type Output = i32;
|
||||||
|
|
||||||
fn bitor(self, rhs: LedCfgState) -> Self::Output {
|
fn bitor(self, rhs: LedCfgState) -> Self::Output {
|
||||||
return self | rhs as i32
|
return self | rhs as i32;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -94,17 +94,38 @@ impl BitAnd<LedCfgState> for LedCfgState {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn leds_message (boot_state: bool, sleep_state: bool, all_leds_state: bool, kbd_leds_state: bool, side_leds_state: bool) -> [u8; 3] {
|
pub fn leds_message(
|
||||||
let raw_message = _leds_message(boot_state.into(), sleep_state.into(), all_leds_state.into(), kbd_leds_state.into(), side_leds_state.into());
|
boot_state: bool,
|
||||||
|
sleep_state: bool,
|
||||||
|
all_leds_state: bool,
|
||||||
|
kbd_leds_state: bool,
|
||||||
|
side_leds_state: bool,
|
||||||
|
) -> [u8; 3] {
|
||||||
|
let raw_message = _leds_message(
|
||||||
|
boot_state.into(),
|
||||||
|
sleep_state.into(),
|
||||||
|
all_leds_state.into(),
|
||||||
|
kbd_leds_state.into(),
|
||||||
|
side_leds_state.into(),
|
||||||
|
);
|
||||||
|
|
||||||
let [_, lows @ ..] = i32::to_be_bytes(raw_message);
|
let [_, lows @ ..] = i32::to_be_bytes(raw_message);
|
||||||
return lows;
|
return lows;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn _leds_message (boot_state: LedCfgState, sleep_state: LedCfgState, all_leds_state: LedCfgState, kbd_leds_state: LedCfgState, side_leds_state: LedCfgState) -> i32 {
|
fn _leds_message(
|
||||||
|
boot_state: LedCfgState,
|
||||||
|
sleep_state: LedCfgState,
|
||||||
|
all_leds_state: LedCfgState,
|
||||||
|
kbd_leds_state: LedCfgState,
|
||||||
|
side_leds_state: LedCfgState,
|
||||||
|
) -> i32 {
|
||||||
let full_leds_state = match all_leds_state {
|
let full_leds_state = match all_leds_state {
|
||||||
On => (ALL_LEDS_MASK & all_leds_state) | (KBD_LEDS_MASK & kbd_leds_state) | (SIDE_LEDS_MASK & side_leds_state),
|
On => {
|
||||||
|
(ALL_LEDS_MASK & all_leds_state)
|
||||||
|
| (KBD_LEDS_MASK & kbd_leds_state)
|
||||||
|
| (SIDE_LEDS_MASK & side_leds_state)
|
||||||
|
}
|
||||||
Off => 0x0100 & side_leds_state,
|
Off => 0x0100 & side_leds_state,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -112,6 +133,6 @@ fn _leds_message (boot_state: LedCfgState, sleep_state: LedCfgState, all_leds_st
|
|||||||
|
|
||||||
return match (all_leds_state | kbd_leds_state | side_leds_state).into() {
|
return match (all_leds_state | kbd_leds_state | side_leds_state).into() {
|
||||||
On => boot_xor_sleep ^ ((boot_xor_sleep ^ full_leds_state) & LEDS_STATE_MASK),
|
On => boot_xor_sleep ^ ((boot_xor_sleep ^ full_leds_state) & LEDS_STATE_MASK),
|
||||||
_ => boot_xor_sleep
|
_ => boot_xor_sleep,
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user