From 00bd556d7a03fe0311eaa869c22e99bf07a1cbd2 Mon Sep 17 00:00:00 2001 From: Luke Date: Thu, 4 Feb 2021 10:41:30 +1300 Subject: [PATCH] Initial refactor --- Cargo.lock | 2 ++ asusctl/examples/animatrix.rs | 4 +-- daemon/src/ctrl_anime.rs | 53 +++++++++++++++++++-------- rog-dbus/src/zbus_anime.rs | 4 +-- rog-types/Cargo.toml | 4 ++- rog-types/src/anime_matrix.rs | 68 +++++++++++++++++++++++++++++------ 6 files changed, 104 insertions(+), 31 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2785a1c9..bb6f5f4c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -813,6 +813,8 @@ dependencies = [ "rog_fan_curve", "serde", "serde_derive", + "zvariant", + "zvariant_derive", ] [[package]] diff --git a/asusctl/examples/animatrix.rs b/asusctl/examples/animatrix.rs index 4b93bba7..93566e20 100644 --- a/asusctl/examples/animatrix.rs +++ b/asusctl/examples/animatrix.rs @@ -1,6 +1,6 @@ use rog_dbus::AuraDbusClient; use rog_types::{ - anime_matrix::{AniMeMatrix, AniMePacketType, HEIGHT, WIDTH}, + anime_matrix::{AniMeImageBuffer, AniMePacketType, HEIGHT, WIDTH}, }; use tinybmp::{Bmp, Pixel}; @@ -13,7 +13,7 @@ fn main() { //assert_eq!(pixels.len(), 56 * 56); // Try an outline, top and right - let mut matrix = AniMeMatrix::new(); + let mut matrix = AniMeImageBuffer::new(); // Aligned left for (i, px) in pixels.iter().enumerate() { diff --git a/daemon/src/ctrl_anime.rs b/daemon/src/ctrl_anime.rs index 52efa982..577d0d9e 100644 --- a/daemon/src/ctrl_anime.rs +++ b/daemon/src/ctrl_anime.rs @@ -13,7 +13,7 @@ const APPLY: u8 = 0xc4; // The next byte can be 0x03 for "on" and 0x00 for "off" const ON_OFF: u8 = 0x04; -use rog_types::error::AuraError; +use rog_types::{anime_matrix::{ANIME_PANE1_PREFIX, ANIME_PANE2_PREFIX, AniMeDataBuffer, AniMeImageBuffer, AniMePacketType, PANE_LEN}, error::AuraError}; use log::{error, info, warn}; use rusb::{Device, DeviceHandle}; use std::convert::TryInto; @@ -40,8 +40,8 @@ impl GetSupported for CtrlAnimeDisplay { pub enum AnimatrixCommand { Apply, SetBoot(bool), - Write(Vec), - WriteImage(Vec>), + Write([u8; 640]), + WriteImage(AniMeImageBuffer), //ReloadLast, } @@ -52,7 +52,9 @@ pub struct CtrlAnimeDisplay { //AnimatrixWrite pub trait Dbus { - fn set_anime(&mut self, input: Vec>); + fn write_image(&mut self, input: AniMeImageBuffer); + + fn write_direct(&mut self, input: AniMeDataBuffer); fn set_on_off(&mut self, status: bool); @@ -73,27 +75,32 @@ impl crate::ZbusAdd for CtrlAnimeDisplay { #[dbus_interface(name = "org.asuslinux.Daemon")] impl Dbus for CtrlAnimeDisplay { - fn set_anime(&mut self, input: Vec>) { - self.do_command(AnimatrixCommand::WriteImage(input)) + fn write_image(&mut 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) { + self.write_data_buffer(input) + .map_or_else(|err| warn!("{}", err), |()| info!("Writing data to Anime")); + } + fn set_on_off(&mut self, status: bool) { - let mut flush: Vec = vec![0; PACKET_SIZE]; - flush[0] = DEV_PAGE; - flush[1] = WRITE; - flush[2] = ON_OFF; + let mut buffer = [0u8; PACKET_SIZE]; + buffer[0] = DEV_PAGE; + buffer[1] = WRITE; + buffer[2] = ON_OFF; let status_str; if status { - flush[3] = 0x03; + buffer[3] = 0x03; status_str = "on"; } else { - flush[3] = 0x00; + buffer[3] = 0x00; status_str = "off"; } - self.do_command(AnimatrixCommand::Write(flush)).map_or_else( + self.do_command(AnimatrixCommand::Write(buffer)).map_or_else( |err| warn!("{}", err), |()| info!("Turning {} the AniMe", status_str), ); @@ -158,7 +165,7 @@ impl CtrlAnimeDisplay { //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(effect)?, + AnimatrixCommand::WriteImage(effect) => self.write_image_buffer(effect)?, //AnimatrixCommand::ReloadLast => self.reload_last_builtin(&config).await?, } Ok(()) @@ -183,6 +190,18 @@ impl CtrlAnimeDisplay { } Ok(()) } + #[inline] + fn write_data_buffer(&mut 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); + + for row in image.iter() { + self.write_bytes(row)?; + } + self.do_flush()?; + Ok(()) + } /// Write an Animatrix image /// @@ -200,7 +219,11 @@ impl CtrlAnimeDisplay { /// /// Where led brightness is 0..255, low to high #[inline] - fn write_image(&mut self, image: Vec>) -> Result<(), AuraError> { + fn write_image_buffer(&mut 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); + for row in image.iter() { self.write_bytes(row)?; } diff --git a/rog-dbus/src/zbus_anime.rs b/rog-dbus/src/zbus_anime.rs index e32960c5..8318e875 100644 --- a/rog-dbus/src/zbus_anime.rs +++ b/rog-dbus/src/zbus_anime.rs @@ -21,7 +21,7 @@ use zbus::{dbus_proxy, Connection, Result}; -use rog_types::anime_matrix::{AniMeMatrix, AniMePacketType, ANIME_PANE1_PREFIX, ANIME_PANE2_PREFIX}; +use rog_types::anime_matrix::{AniMeImageBuffer, AniMePacketType, ANIME_PANE1_PREFIX, ANIME_PANE2_PREFIX}; #[dbus_proxy( interface = "org.asuslinux.Daemon", @@ -52,7 +52,7 @@ impl<'a> AnimeProxy<'a> { #[inline] pub fn set_brightness(&self, led_brightness: u8) -> Result<()> { - let mut anime_matrix = AniMeMatrix::new(); + let mut anime_matrix = AniMeImageBuffer::new(); anime_matrix.fill_with(led_brightness); diff --git a/rog-types/Cargo.toml b/rog-types/Cargo.toml index 984d4f4f..890d9e2d 100644 --- a/rog-types/Cargo.toml +++ b/rog-types/Cargo.toml @@ -13,4 +13,6 @@ edition = "2018" gumdrop = "^0.8" serde = "^1.0" serde_derive = "^1.0" -rog_fan_curve = { version = "^0.1", features = ["serde"] } \ No newline at end of file +rog_fan_curve = { version = "^0.1", features = ["serde"] } +zvariant = "^2.5" +zvariant_derive = "^2.5" \ No newline at end of file diff --git a/rog-types/src/anime_matrix.rs b/rog-types/src/anime_matrix.rs index 44cc5614..4dbe8473 100644 --- a/rog-types/src/anime_matrix.rs +++ b/rog-types/src/anime_matrix.rs @@ -1,34 +1,69 @@ +use serde_derive::{Deserialize, Serialize}; +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 const BLOCK_END: usize = 634; +pub const PANE_LEN: usize = BLOCK_END - BLOCK_START; 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]; +#[derive(Debug, Deserialize, Serialize, Type)] +pub struct AniMeDataBuffer(Vec); + +impl AniMeDataBuffer { + pub fn new() -> Self { + AniMeDataBuffer(vec![0u8; PANE_LEN]) + } + + pub fn get(&self) -> &[u8] { + &self.0 + } + + pub fn set(&mut self, input: [u8; PANE_LEN]) { + self.0 = input.to_vec(); + } +} + +impl From for AniMePacketType { + #[inline] + fn from(anime: AniMeDataBuffer) -> Self { + assert!(anime.0.len() == 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); + } + buffers + } +} + /// Helper structure for writing images. /// /// See the examples for ways to write an image to `AniMeMatrix` format. -pub struct AniMeMatrix(AniMeBufferType); +#[derive(Debug, Deserialize, Serialize, Type)] +pub struct AniMeImageBuffer(Vec>); -impl Default for AniMeMatrix { +impl Default for AniMeImageBuffer { fn default() -> Self { Self::new() } } -impl AniMeMatrix { +impl AniMeImageBuffer { pub fn new() -> Self { - AniMeMatrix([[0u8; WIDTH]; HEIGHT]) + AniMeImageBuffer(vec![vec![0u8; WIDTH]; HEIGHT]) } - pub fn get(&self) -> &AniMeBufferType { + pub fn get(&self) -> &Vec> { &self.0 } - pub fn get_mut(&mut self) -> &mut AniMeBufferType { + pub fn get_mut(&mut self) -> &mut Vec> { &mut self.0 } @@ -93,11 +128,11 @@ impl AniMeMatrix { } } -impl From for AniMePacketType { +impl From for AniMePacketType { /// Do conversion from the nested Vec in AniMeMatrix to the two required /// packets suitable for sending over USB #[inline] - fn from(anime: AniMeMatrix) -> Self { + fn from(anime: AniMeImageBuffer) -> Self { let mut buffers = [[0; 640]; 2]; let mut write_index = BLOCK_START; @@ -155,15 +190,26 @@ impl From for AniMePacketType { #[cfg(test)] mod tests { - use crate::anime_matrix::{AniMeMatrix, AniMePacketType}; + use crate::anime_matrix::*; + + use super::AniMeDataBuffer; + + #[test] + fn check_from_data_buffer() { + let mut data = AniMeDataBuffer::new(); + data.set([42u8; PANE_LEN]); + + let out: AniMePacketType = data.into(); + } #[test] fn check_data_alignment() { - let mut matrix = AniMeMatrix::new(); + let mut matrix = AniMeImageBuffer::new(); { let tmp = matrix.get_mut(); for row in tmp.iter_mut() { - row[row.len() - 1] = 0xff; + let idx = row.len() - 1; + row[idx] = 0xff; } }