Added working implementation of the G14 Slash ledstrip

This commit is contained in:
jochen@g14
2024-03-30 18:41:31 +01:00
parent cdc9ca7b58
commit 8cdc9773c9
20 changed files with 663 additions and 746 deletions

View File

@@ -17,6 +17,7 @@ use crate::ctrl_aura::trait_impls::{CtrlAuraZbus, AURA_ZBUS_NAME, AURA_ZBUS_PATH
use crate::ctrl_fancurves::{CtrlFanCurveZbus, FAN_CURVE_ZBUS_NAME, FAN_CURVE_ZBUS_PATH};
use crate::error::RogError;
use crate::{task_watch_item, task_watch_item_notify, CtrlTask, ReloadAndNotify};
use crate::ctrl_slash::trait_impls::{CtrlSlashZbus, SLASH_ZBUS_NAME, SLASH_ZBUS_PATH};
const PLATFORM_ZBUS_NAME: &str = "Platform";
const PLATFORM_ZBUS_PATH: &str = "/org/asuslinux";
@@ -350,6 +351,13 @@ impl CtrlPlatform {
{
interfaces.push(PLATFORM_ZBUS_NAME.to_owned());
}
if server
.interface::<_, CtrlSlashZbus>(SLASH_ZBUS_PATH)
.await
.is_ok()
{
interfaces.push(SLASH_ZBUS_NAME.to_owned());
}
interfaces
}

View File

@@ -1,7 +1,6 @@
use serde_derive::{Deserialize, Serialize};
use config_traits::{StdConfig, StdConfigLoad, StdConfigLoad2};
use config_traits::{StdConfig, StdConfigLoad};
use rog_slash::{DeviceState, SlashMode};
use crate::ctrl_anime::config::{AnimeConfig, AnimeConfigV460, AnimeConfigV472};
const CONFIG_FILE: &str = "slash.ron";
@@ -11,7 +10,7 @@ pub struct SlashConfig {
pub slash_enabled: bool,
pub slash_brightness: u8,
pub slash_interval: u8,
pub slash_mode: u8,
pub slash_mode: SlashMode,
}
impl Default for SlashConfig {
@@ -20,7 +19,7 @@ impl Default for SlashConfig {
slash_enabled: true,
slash_brightness: 255,
slash_interval: 0,
slash_mode: SlashMode::Bounce as u8,
slash_mode: SlashMode::Bounce,
}
}
}

View File

@@ -3,8 +3,9 @@ pub mod trait_impls;
use rog_platform::hid_raw::HidRaw;
use rog_platform::usb_raw::USBRaw;
use rog_slash::{SlashMode};
use rog_slash::usb::{pkt_set_mode, pkt_set_options, pkts_for_init};
use rog_slash::{SlashMode, SlashType};
use rog_slash::error::SlashError;
use rog_slash::usb::{get_slash_type, pkt_set_mode, pkt_set_options, pkts_for_init};
use crate::ctrl_slash::config::SlashConfig;
use crate::error::RogError;
@@ -36,12 +37,11 @@ impl Node {
// }
}
#[derive(Clone)]
pub struct CtrlSlash {
// node: HidRaw,
node: Node,
config: SlashConfig,
// slash_type: SlashType,
slash_type: SlashType,
// // set to force thread to exit
// thread_exit: Arc<AtomicBool>,
// // Set to false when the thread exits
@@ -62,12 +62,15 @@ impl CtrlSlash {
};
// Maybe, detecting the slash-type may become necessary
// let slash_type = get_slash_type()?;
let slash_type = get_slash_type()?;
if slash_type == SlashType::Unknown {
return Err(RogError::Slash(SlashError::NoDevice));
}
let ctrl = CtrlSlash {
node,
config,
// slash_type,
slash_type,
// thread_exit: Arc::new(AtomicBool::new(false)),
// thread_running: Arc::new(AtomicBool::new(false)),
};
@@ -92,7 +95,7 @@ impl CtrlSlash {
}
pub fn set_slash_mode(&self, slash_mode: SlashMode) -> Result<(), RogError> {
let command_packets = pkt_set_mode(slash_mode as u8);
let command_packets = pkt_set_mode(slash_mode);
self.node.write_bytes(&command_packets[0])?;
self.node.write_bytes(&command_packets[1])?;
Ok(())

View File

@@ -1,11 +1,12 @@
use std::sync::Arc;
use log::warn;
use zbus::{Connection, interface};
use zbus::{Connection, interface, SignalContext};
use zbus::export::futures_util::lock::Mutex;
use config_traits::StdConfig;
use rog_slash::DeviceState;
use rog_slash::usb::pkt_set_options;
use rog_slash::{DeviceState, SlashMode};
use rog_slash::usb::{pkt_set_mode, pkt_set_options};
use crate::ctrl_slash::CtrlSlash;
use crate::error::RogError;
pub const SLASH_ZBUS_NAME: &str = "Slash";
@@ -14,41 +15,47 @@ pub const SLASH_ZBUS_PATH: &str = "/org/asuslinux";
#[derive(Clone)]
pub struct CtrlSlashZbus(pub Arc<Mutex<CtrlSlash>>);
/// The struct with the main dbus methods requires this trait
impl crate::ZbusRun for CtrlSlashZbus {
async fn add_to_server(self, server: &mut Connection) {
Self::add_to_server_helper(self, SLASH_ZBUS_NAME, server).await;
Self::add_to_server_helper(self, SLASH_ZBUS_PATH, server).await;
}
}
// None of these calls can be guarnateed to succeed unless we loop until okay
// If the try_lock *does* succeed then any other thread trying to lock will not
// grab it until we finish.
#[interface(name = "org.asuslinux.Slash")]
impl CtrlSlashZbus {
// /// Writes a data stream of length. Will force system thread to exit until
// /// it is restarted
// async fn write(&self, input: AnimeDataBuffer) -> zbus::fdo::Result<()> {
// let lock = self.0.lock().await;
// lock.thread_exit.store(true, Ordering::SeqCst);
// lock.write_data_buffer(input).map_err(|err| {
// warn!("ctrl_anime::run_animation:callback {}", err);
// err
// })?;
// Ok(())
// }
/// Set base brightness level
/// Get enabled or not
#[zbus(property)]
async fn enabled(&self) -> bool {
let lock = self.0.lock().await;
lock.config.slash_enabled
}
/// Set enabled true or false
async fn set_enabled(&self, enabled: bool) {
let mut lock = self.0.lock().await;
let brightness = if enabled && lock.config.slash_brightness == 0 { 0x88 } else { lock.config.slash_brightness };
lock.node
.write_bytes(&pkt_set_options(enabled, brightness, lock.config.slash_interval))
.map_err(|err| {
warn!("ctrl_slash::set_options {}", err);
})
.ok();
lock.config.slash_enabled = enabled;
lock.config.slash_brightness = brightness;
lock.config.write();
}
/// Get brightness level
#[zbus(property)]
async fn brightness(&self) -> u8 {
let lock = self.0.lock().await;
lock.config.slash_brightness
}
/// Set base brightness level
#[zbus(property)]
/// Set brightness level
async fn set_brightness(&self, brightness: u8) {
let mut lock = self.0.lock().await;
let enabled = brightness > 0;
@@ -65,23 +72,51 @@ impl CtrlSlashZbus {
}
#[zbus(property)]
async fn enable_display(&self) -> bool {
async fn interval(&self) -> u8 {
let lock = self.0.lock().await;
lock.config.slash_enabled
lock.config.slash_interval
}
/// Set whether the AniMe is enabled at all
#[zbus(property)]
async fn set_enable_display(&self, enabled: bool) {
/// Set interval between slash animations (0-255)
async fn set_interval(&self, interval: u8) {
let mut lock = self.0.lock().await;
lock.node
.write_bytes(&pkt_set_options(enabled, lock.config.slash_brightness, lock.config.slash_interval))
.write_bytes(&pkt_set_options(lock.config.slash_enabled, lock.config.slash_brightness, interval))
.map_err(|err| {
warn!("ctrl_slash::set_options {}", err);
})
.ok();
lock.config.slash_enabled = enabled;
lock.config.slash_interval = interval;
lock.config.write();
}
#[zbus(property)]
async fn slash_mode(&self) -> u8 {
let lock = self.0.lock().await;
lock.config.slash_interval
}
/// Set interval between slash animations (0-255)
async fn set_slash_mode(&self, slash_mode: SlashMode) {
let mut lock = self.0.lock().await;
let command_packets = pkt_set_mode(slash_mode);
lock.node
.write_bytes(&command_packets[0])
.map_err(|err| {
warn!("ctrl_slash::set_options {}", err);
})
.ok();
lock.node
.write_bytes(&command_packets[1])
.map_err(|err| {
warn!("ctrl_slash::set_options {}", err);
})
.ok();
lock.config.slash_mode = slash_mode;
lock.config.write();
}
@@ -91,4 +126,20 @@ impl CtrlSlashZbus {
let lock = self.0.lock().await;
DeviceState::from(&lock.config)
}
}
impl crate::CtrlTask for CtrlSlashZbus {
fn zbus_path() -> &'static str {
SLASH_ZBUS_PATH
}
async fn create_tasks(&self, _: SignalContext<'static>) -> Result<(), RogError> {
Ok(())
}
}
impl crate::Reloadable for CtrlSlashZbus {
async fn reload(&mut self) -> Result<(), RogError> {
Ok(())
}
}

View File

@@ -110,11 +110,15 @@ async fn start_daemon() -> Result<(), Box<dyn Error>> {
match CtrlSlash::new(SlashConfig::new().load()) {
Ok(ctrl) => {
let sig_ctx = CtrlPlatform::signal_context(&connection)?;
start_tasks(ctrl, &mut connection, sig_ctx).await?;
let zbus = CtrlSlashZbus(Arc::new(Mutex::new(ctrl)));
// Currently, the Slash has no need for a loop watching power events, however,
// it could be cool to have the slash do some power-on/off animation
// (It has a built-in power on animation which plays when u plug in the power supply)
let sig_ctx = CtrlSlashZbus::signal_context(&connection)?;
start_tasks(zbus, &mut connection, sig_ctx).await?;
}
Err(err) => {
info!("Slash control: {}", err);
info!("AniMe control: {}", err);
}
}

View File

@@ -5,6 +5,7 @@ use config_traits::ron;
use rog_anime::error::AnimeError;
use rog_platform::error::PlatformError;
use rog_profiles::error::ProfileError;
use rog_slash::error::SlashError;
#[derive(Debug)]
pub enum RogError {
@@ -31,6 +32,7 @@ pub enum RogError {
NoAuraKeyboard,
NoAuraNode,
Anime(AnimeError),
Slash(SlashError),
Platform(PlatformError),
SystemdUnitAction(String),
SystemdUnitWaitTimeout(String),
@@ -72,6 +74,7 @@ impl fmt::Display for RogError {
RogError::NoAuraKeyboard => write!(f, "No supported Aura keyboard"),
RogError::NoAuraNode => write!(f, "No Aura keyboard node found"),
RogError::Anime(deets) => write!(f, "AniMe Matrix error: {}", deets),
RogError::Slash(deets) => write!(f, "Slash error: {}", deets),
RogError::Platform(deets) => write!(f, "Asus Platform error: {}", deets),
RogError::SystemdUnitAction(action) => {
write!(f, "systemd unit action {} failed", action)
@@ -103,6 +106,12 @@ impl From<AnimeError> for RogError {
}
}
impl From<SlashError> for RogError {
fn from(err: SlashError) -> Self {
RogError::Slash(err)
}
}
impl From<PlatformError> for RogError {
fn from(err: PlatformError) -> Self {
RogError::Platform(err)

View File

@@ -3,7 +3,7 @@
pub mod config;
/// Control of anime matrix display
pub mod ctrl_anime;
/// Control of anime slash led bar
/// Control of Slash led bar
pub mod ctrl_slash;
/// Keyboard LED brightness control, RGB, and LED display modes
pub mod ctrl_aura;
@@ -132,7 +132,7 @@ pub fn print_board_info() {
}
pub trait Reloadable {
fn reload(&mut self) -> impl std::future::Future<Output = Result<(), RogError>> + Send;
fn reload(&mut self) -> impl Future<Output = Result<(), RogError>> + Send;
}
pub trait ReloadAndNotify {
@@ -142,18 +142,18 @@ pub trait ReloadAndNotify {
&mut self,
signal_context: &SignalContext<'static>,
data: Self::Data,
) -> impl std::future::Future<Output = Result<(), RogError>> + Send;
) -> impl Future<Output = Result<(), RogError>> + Send;
}
pub trait ZbusRun {
fn add_to_server(self, server: &mut Connection)
-> impl std::future::Future<Output = ()> + Send;
-> impl Future<Output = ()> + Send;
fn add_to_server_helper(
iface: impl zbus::Interface,
path: &str,
server: &mut Connection,
) -> impl std::future::Future<Output = ()> + Send {
) -> impl Future<Output = ()> + Send {
async move {
server
.object_server()
@@ -182,7 +182,7 @@ pub trait CtrlTask {
fn create_tasks(
&self,
signal: SignalContext<'static>,
) -> impl std::future::Future<Output = Result<(), RogError>> + Send;
) -> impl Future<Output = Result<(), RogError>> + Send;
// /// Create a timed repeating task
// async fn repeating_task(&self, millis: u64, mut task: impl FnMut() + Send +
@@ -215,7 +215,7 @@ pub trait CtrlTask {
mut on_prepare_for_shutdown: F2,
mut on_lid_change: F3,
mut on_external_power_change: F4,
) -> impl std::future::Future<Output = ()> + Send
) -> impl Future<Output = ()> + Send
where
F1: FnMut(bool) -> Fut1,
F2: FnMut(bool) -> Fut2,
@@ -309,13 +309,13 @@ pub async fn start_tasks<T>(
where
T: ZbusRun + Reloadable + CtrlTask + Clone,
{
let task = zbus.clone();
let zbus_clone = zbus.clone();
zbus.reload()
.await
.unwrap_or_else(|err| warn!("Controller error: {}", err));
zbus.add_to_server(connection).await;
task.create_tasks(signal_ctx).await.ok();
zbus_clone.create_tasks(signal_ctx).await.ok();
Ok(())
}
}