From 39bbe338313f7870d7390d6251caaeb6ba1d278f Mon Sep 17 00:00:00 2001 From: Luke Date: Thu, 4 Feb 2021 11:25:11 +1300 Subject: [PATCH] Further refinement --- asusctl/src/main.rs | 7 +-- daemon/src/ctrl_anime.rs | 95 +++++++++++++++-------------------- rog-dbus/src/zbus_anime.rs | 36 ++++++------- rog-types/src/anime_matrix.rs | 13 ++--- 4 files changed, 69 insertions(+), 82 deletions(-) diff --git a/asusctl/src/main.rs b/asusctl/src/main.rs index ddfa2343..2b2a57ea 100644 --- a/asusctl/src/main.rs +++ b/asusctl/src/main.rs @@ -4,7 +4,7 @@ use rog_dbus::AuraDbusClient; use std::{env::args, process::Command}; use yansi_term::Colour::Green; use yansi_term::Colour::Red; -use rog_types::{cli_options::{AniMeActions, AniMeStatusValue, LedBrightness, SetAuraBuiltin}, profile::{ProfileCommand, ProfileEvent}}; +use rog_types::{anime_matrix::{AniMeDataBuffer, FULL_PANE_LEN}, cli_options::{AniMeActions, AniMeStatusValue, LedBrightness, SetAuraBuiltin}, profile::{ProfileCommand, ProfileEvent}}; #[derive(Default, Options)] struct CLIStart { @@ -197,8 +197,9 @@ fn main() -> Result<(), Box> { if let Some(action) = cmd.command { match action { AniMeActions::Leds(anime_leds) => { - let led_brightness = anime_leds.led_brightness(); - dbus.proxies().anime().set_brightness(led_brightness)?; + let mut data = AniMeDataBuffer::new(); + data.set([anime_leds.led_brightness(); FULL_PANE_LEN]); + dbus.proxies().anime().write_direct(data)?; } } } diff --git a/daemon/src/ctrl_anime.rs b/daemon/src/ctrl_anime.rs index 577d0d9e..1c3f8945 100644 --- a/daemon/src/ctrl_anime.rs +++ b/daemon/src/ctrl_anime.rs @@ -13,8 +13,13 @@ const APPLY: u8 = 0xc4; // The next byte can be 0x03 for "on" and 0x00 for "off" const ON_OFF: u8 = 0x04; -use rog_types::{anime_matrix::{ANIME_PANE1_PREFIX, ANIME_PANE2_PREFIX, AniMeDataBuffer, AniMeImageBuffer, AniMePacketType, PANE_LEN}, error::AuraError}; use log::{error, info, warn}; +use rog_types::{ + anime_matrix::{ + AniMeDataBuffer, AniMeImageBuffer, AniMePacketType, ANIME_PANE1_PREFIX, ANIME_PANE2_PREFIX, + }, + error::AuraError, +}; use rusb::{Device, DeviceHandle}; use std::convert::TryInto; use std::error::Error; @@ -35,30 +40,21 @@ impl GetSupported for CtrlAnimeDisplay { } } -#[allow(dead_code)] -#[derive(Debug)] -pub enum AnimatrixCommand { - Apply, - SetBoot(bool), - Write([u8; 640]), - WriteImage(AniMeImageBuffer), - //ReloadLast, -} - pub struct CtrlAnimeDisplay { handle: DeviceHandle, - initialised: bool, } //AnimatrixWrite pub trait Dbus { - fn write_image(&mut self, input: AniMeImageBuffer); + /// Write an image 34x56 pixels. Each pixel is 0-255 greyscale. + fn write_image(&self, input: AniMeImageBuffer); - fn write_direct(&mut self, input: AniMeDataBuffer); + /// Write a direct stream of data + fn write_direct(&self, input: AniMeDataBuffer); - fn set_on_off(&mut self, status: bool); + fn set_on_off(&self, status: bool); - fn set_boot_on_off(&mut self, status: bool); + fn set_boot_on_off(&self, status: bool); } impl crate::ZbusAdd for CtrlAnimeDisplay { @@ -75,17 +71,19 @@ impl crate::ZbusAdd for CtrlAnimeDisplay { #[dbus_interface(name = "org.asuslinux.Daemon")] impl Dbus for CtrlAnimeDisplay { - fn write_image(&mut self, input: AniMeImageBuffer) { + /// Writes a 34x56 image + fn write_image(&self, input: AniMeImageBuffer) { self.write_image_buffer(input) .map_or_else(|err| warn!("{}", err), |()| info!("Writing image to Anime")); } - fn write_direct(&mut self, input: AniMeDataBuffer) { + /// Writes a data stream of length + fn write_direct(&self, input: AniMeDataBuffer) { self.write_data_buffer(input) - .map_or_else(|err| warn!("{}", err), |()| info!("Writing data to Anime")); + .map_or_else(|err| warn!("{}", err), |()| info!("Writing data to Anime")); } - fn set_on_off(&mut self, status: bool) { + fn set_on_off(&self, status: bool) { let mut buffer = [0u8; PACKET_SIZE]; buffer[0] = DEV_PAGE; buffer[1] = WRITE; @@ -100,21 +98,23 @@ impl Dbus for CtrlAnimeDisplay { status_str = "off"; } - self.do_command(AnimatrixCommand::Write(buffer)).map_or_else( + self.write_bytes(&buffer).map_or_else( |err| warn!("{}", err), |()| info!("Turning {} the AniMe", status_str), ); } - fn set_boot_on_off(&mut self, status: bool) { + fn set_boot_on_off(&self, status: bool) { let status_str = if status { "on" } else { "off" }; - self.do_command(AnimatrixCommand::SetBoot(status)) - .and_then(|()| self.do_command(AnimatrixCommand::Apply)) - .map_or_else( - |err| warn!("{}", err), - |()| info!("Turning {} the AniMe at boot/shutdown", status_str), - ); + self.do_set_boot(status).map_or_else( + |err| warn!("{}", err), + |()| info!("Turning {} the AniMe at boot/shutdown", status_str), + ); + self.do_apply().map_or_else( + |err| warn!("{}", err), + |()| info!("Turning {} the AniMe at boot/shutdown", status_str), + ); } } @@ -138,10 +138,12 @@ impl CtrlAnimeDisplay { })?; info!("Device has an AniMe Matrix display"); - Ok(CtrlAnimeDisplay { + let ctrl = CtrlAnimeDisplay { handle: device, - initialised: false, - }) + }; + ctrl.do_initialization()?; + + Ok(ctrl) } #[inline] @@ -155,22 +157,6 @@ impl CtrlAnimeDisplay { Err(rusb::Error::NoDevice) } - pub fn do_command(&mut self, command: AnimatrixCommand) -> Result<(), AuraError> { - if !self.initialised { - self.do_initialization()? - } - - match command { - AnimatrixCommand::Apply => self.do_apply()?, - //AnimatrixCommand::Set => self.do_set_boot()?, - AnimatrixCommand::SetBoot(status) => self.do_set_boot(status)?, - AnimatrixCommand::Write(bytes) => self.write_bytes(&bytes)?, - AnimatrixCommand::WriteImage(effect) => self.write_image_buffer(effect)?, - //AnimatrixCommand::ReloadLast => self.reload_last_builtin(&config).await?, - } - Ok(()) - } - /// Should only be used if the bytes you are writing are verified correct #[inline] fn write_bytes(&self, message: &[u8]) -> Result<(), AuraError> { @@ -191,7 +177,7 @@ impl CtrlAnimeDisplay { Ok(()) } #[inline] - fn write_data_buffer(&mut self, buffer: AniMeDataBuffer) -> Result<(), AuraError> { + fn write_data_buffer(&self, buffer: AniMeDataBuffer) -> Result<(), AuraError> { let mut image = AniMePacketType::from(buffer); image[0][..7].copy_from_slice(&ANIME_PANE1_PREFIX); image[1][..7].copy_from_slice(&ANIME_PANE2_PREFIX); @@ -205,7 +191,7 @@ impl CtrlAnimeDisplay { /// Write an Animatrix image /// - /// The expected input here is *two* Vectors, 640 bytes in length. The two vectors + /// The expected USB input here is *two* Vectors, 640 bytes in length. The two vectors /// are each one half of the full image write. /// /// After each write a flush is written, it is assumed that this tells the device to @@ -219,7 +205,7 @@ impl CtrlAnimeDisplay { /// /// Where led brightness is 0..255, low to high #[inline] - fn write_image_buffer(&mut self, buffer: AniMeImageBuffer) -> Result<(), AuraError> { + fn write_image_buffer(&self, buffer: AniMeImageBuffer) -> Result<(), AuraError> { let mut image = AniMePacketType::from(buffer); image[0][..7].copy_from_slice(&ANIME_PANE1_PREFIX); image[1][..7].copy_from_slice(&ANIME_PANE2_PREFIX); @@ -232,7 +218,7 @@ impl CtrlAnimeDisplay { } #[inline] - fn do_initialization(&mut self) -> Result<(), AuraError> { + fn do_initialization(&self) -> Result<(), AuraError> { let mut init = [0; PACKET_SIZE]; init[0] = DEV_PAGE; // This is the USB page we're using throughout for (idx, byte) in INIT_STR.as_bytes().iter().enumerate() { @@ -248,12 +234,11 @@ impl CtrlAnimeDisplay { init[1] = INIT; self.write_bytes(&init)?; - self.initialised = true; Ok(()) } #[inline] - fn do_flush(&mut self) -> Result<(), AuraError> { + fn do_flush(&self) -> Result<(), AuraError> { let mut flush = [0; PACKET_SIZE]; flush[0] = DEV_PAGE; flush[1] = WRITE; @@ -264,7 +249,7 @@ impl CtrlAnimeDisplay { } #[inline] - fn do_set_boot(&mut self, status: bool) -> Result<(), AuraError> { + fn do_set_boot(&self, status: bool) -> Result<(), AuraError> { let mut flush = [0; PACKET_SIZE]; flush[0] = DEV_PAGE; flush[1] = SET; @@ -276,7 +261,7 @@ impl CtrlAnimeDisplay { } #[inline] - fn do_apply(&mut self) -> Result<(), AuraError> { + fn do_apply(&self) -> Result<(), AuraError> { let mut flush = [0; PACKET_SIZE]; flush[0] = DEV_PAGE; flush[1] = APPLY; diff --git a/rog-dbus/src/zbus_anime.rs b/rog-dbus/src/zbus_anime.rs index 8318e875..6cb42b72 100644 --- a/rog-dbus/src/zbus_anime.rs +++ b/rog-dbus/src/zbus_anime.rs @@ -19,25 +19,28 @@ //! //! …consequently `zbus-xmlgen` did not generate code for the above interfaces. +use rog_types::anime_matrix::{AniMeDataBuffer, AniMeImageBuffer}; use zbus::{dbus_proxy, Connection, Result}; -use rog_types::anime_matrix::{AniMeImageBuffer, AniMePacketType, ANIME_PANE1_PREFIX, ANIME_PANE2_PREFIX}; - #[dbus_proxy( interface = "org.asuslinux.Daemon", default_path = "/org/asuslinux/Anime" )] trait Daemon { - /// SetAnime method - fn set_anime(&self, input: &[&[u8]]) -> zbus::Result<()>; - /// SetBootOnOff method fn set_boot_on_off(&self, status: bool) -> zbus::Result<()>; /// SetOnOff method fn set_on_off(&self, status: bool) -> zbus::Result<()>; + + /// WriteDirect method + fn write_direct(&self, input: &[u8]) -> zbus::Result<()>; + + /// WriteImage method + fn write_image(&self, input: &[Vec]) -> zbus::Result<()>; } + pub struct AnimeProxy<'a>(DaemonProxy<'a>); impl<'a> AnimeProxy<'a> { @@ -50,19 +53,6 @@ impl<'a> AnimeProxy<'a> { &self.0 } - #[inline] - pub fn set_brightness(&self, led_brightness: u8) -> Result<()> { - let mut anime_matrix = AniMeImageBuffer::new(); - - anime_matrix.fill_with(led_brightness); - - let mut image = AniMePacketType::from(anime_matrix); - image[0][..7].copy_from_slice(&ANIME_PANE1_PREFIX); - image[1][..7].copy_from_slice(&ANIME_PANE2_PREFIX); - - self.0.set_anime(&[&image[0], &image[1]]) - } - #[inline] pub fn toggle_boot_on(&self, on: bool) -> Result<()> { self.0.set_boot_on_off(on) @@ -72,4 +62,14 @@ impl<'a> AnimeProxy<'a> { pub fn toggle_on(&self, on: bool) -> Result<()> { self.0.set_on_off(on) } + + #[inline] + pub fn write_direct(&self, input: AniMeDataBuffer) -> Result<()> { + self.0.write_direct(input.get()) + } + + #[inline] + pub fn write_image(&self, input: AniMeImageBuffer) -> Result<()> { + self.0.write_image(input.get()) + } } diff --git a/rog-types/src/anime_matrix.rs b/rog-types/src/anime_matrix.rs index 4dbe8473..4d9c08dd 100644 --- a/rog-types/src/anime_matrix.rs +++ b/rog-types/src/anime_matrix.rs @@ -3,12 +3,13 @@ use zvariant_derive::Type; pub const WIDTH: usize = 34; // Width is definitely 34 items pub const HEIGHT: usize = 56; -pub type AniMeBufferType = [[u8; WIDTH]; HEIGHT]; pub type AniMePacketType = [[u8; 640]; 2]; const BLOCK_START: usize = 7; -/// Not inclusive +/// *Not* inclusive, the byte before this is the final for each "pane" const BLOCK_END: usize = 634; pub const PANE_LEN: usize = BLOCK_END - BLOCK_START; +/// The length of usable data +pub const FULL_PANE_LEN: usize = PANE_LEN * 2; pub const ANIME_PANE1_PREFIX: [u8; 7] = [0x5e, 0xc0, 0x02, 0x01, 0x00, 0x73, 0x02]; pub const ANIME_PANE2_PREFIX: [u8; 7] = [0x5e, 0xc0, 0x02, 0x74, 0x02, 0x73, 0x02]; @@ -18,14 +19,14 @@ pub struct AniMeDataBuffer(Vec); impl AniMeDataBuffer { pub fn new() -> Self { - AniMeDataBuffer(vec![0u8; PANE_LEN]) + AniMeDataBuffer(vec![0u8; FULL_PANE_LEN]) } pub fn get(&self) -> &[u8] { &self.0 } - pub fn set(&mut self, input: [u8; PANE_LEN]) { + pub fn set(&mut self, input: [u8; FULL_PANE_LEN]) { self.0 = input.to_vec(); } } @@ -33,7 +34,7 @@ impl AniMeDataBuffer { impl From for AniMePacketType { #[inline] fn from(anime: AniMeDataBuffer) -> Self { - assert!(anime.0.len() == PANE_LEN); + assert!(anime.0.len() == FULL_PANE_LEN); let mut buffers = [[0; 640]; 2]; for (idx, chunk) in anime.0.as_slice().chunks(PANE_LEN).enumerate() { buffers[idx][BLOCK_START..BLOCK_END].copy_from_slice(chunk); @@ -197,7 +198,7 @@ mod tests { #[test] fn check_from_data_buffer() { let mut data = AniMeDataBuffer::new(); - data.set([42u8; PANE_LEN]); + data.set([42u8; FULL_PANE_LEN]); let out: AniMePacketType = data.into(); }