diff --git a/src/platform/smart_leds_lib.rs b/src/platform/smart_leds_lib.rs index ebbb31e..53a4e5d 100644 --- a/src/platform/smart_leds_lib.rs +++ b/src/platform/smart_leds_lib.rs @@ -12,8 +12,29 @@ use smart_leds::brightness; use std::io; use rgb::Rgb; +use std::ops::IndexMut; -pub struct SmartLedDisplay>, S: Surface, const PIXEL_NUM: usize> { +pub trait HardwarePixel: Rgb8Blend + Clone + Copy + AsMilliwatts + Default + From> {} +impl HardwarePixel for T where T: Rgb8Blend + Clone + Copy + AsMilliwatts + Default + From> {} + +pub trait Pixbuf: AsMilliwatts + IndexMut { + fn new() -> Self; + fn blank(&mut self); +} + +impl Pixbuf for [T; PIXEL_NUM] { + fn new() -> Self { + [T::default(); PIXEL_NUM] + } + + fn blank(&mut self) { + self.fill(T::default()) + } +} + +pub struct SmartLedDisplay where +T::Color: HardwarePixel, +[T::Color; PIXEL_NUM]: Pixbuf { surfaces : Option>, pixmap: StrideMapping, target: T, @@ -21,7 +42,9 @@ pub struct SmartLedDisplay>, S: Surface, const max_mw: u32 } -impl>, S: Surface, const PIXEL_NUM: usize> Debug for SmartLedDisplay { +impl Debug for SmartLedDisplay where +T::Color: HardwarePixel, +[T::Color; PIXEL_NUM]: Pixbuf { fn fmt(&self, f: &mut Formatter) -> Result<(), std::fmt::Error> { f.debug_struct("SmartLedDisplay") .field("total_mw", &self.pixbuf.as_milliwatts()) @@ -30,10 +53,12 @@ impl>, S: Surface, const PIXEL_NUM: usize> Deb } } -impl>, S: Surface, const PIXEL_NUM: usize> SmartLedDisplay { +impl SmartLedDisplay where +T::Color: HardwarePixel, +[T::Color; PIXEL_NUM]: Pixbuf { pub fn new(target: T, max_mw: u32) -> Self { SmartLedDisplay { - pixbuf: [Rgb::new(0, 0, 0); PIXEL_NUM], + pixbuf: <[T::Color; PIXEL_NUM]>::new(), surfaces: Some(SurfacePool::new()), target, max_mw, @@ -42,16 +67,21 @@ impl>, S: Surface, const PIXEL_NUM: usize> Sma } } -impl>, S: Surface, const PIXEL_NUM: usize> AsMilliwatts for SmartLedDisplay { +impl AsMilliwatts for SmartLedDisplay where +T: SmartLedsWrite, +S: Surface, +T::Color: HardwarePixel, +[T::Color; PIXEL_NUM]: Pixbuf { fn as_milliwatts(&self) -> u32 { self.pixbuf.as_milliwatts() } } -impl Surfaces for SmartLedDisplay -where -T: SmartLedsWrite>, -S: Surface { +impl Surfaces for SmartLedDisplay where +T: SmartLedsWrite, +S: Surface, +T::Color: HardwarePixel, +[T::Color; PIXEL_NUM]: Pixbuf { fn new_surface(&mut self, area: &Rectangle) -> Result { if let Some(ref mut s) = self.surfaces { s.new_surface(area) @@ -61,15 +91,21 @@ S: Surface { } } -impl>, S: Surface, const PIXEL_NUM: usize> Display for SmartLedDisplay { +impl Display for SmartLedDisplay where +T: SmartLedsWrite, +S: Surface, +T::Color: HardwarePixel, +[T::Color; PIXEL_NUM]: Pixbuf, +Rgb: From { fn start_frame(&mut self) { - self.pixbuf.fill(Rgb::new(0, 0, 0)); + self.pixbuf.blank(); } fn end_frame(&mut self) { let b = brightness_for_mw(self.pixbuf.as_milliwatts(), 255, self.max_mw); - if let Err(_) = self.target.write(brightness(self.pixbuf.iter().cloned(), b).map(|x| { rgb::Bgr::new(x.r, x.g, x.b)})) { + if let Err(_) = self.target.write(brightness(self.pixbuf.iter().cloned().map(|x| { x.into() }), b)) { + //if let Err(_) = self.target.write(self.pixbuf.iter().cloned()) { panic!("Could not write frame"); } } @@ -96,13 +132,20 @@ impl>, S: Surface, const PIXEL_NUM: usize> Dis #[cfg(feature="rmt")] pub mod rmt { use esp_idf_svc::hal::prelude::Peripherals; - use ws2812_esp32_rmt_driver::lib_smart_leds::Ws2812Esp32Rmt; + use ws2812_esp32_rmt_driver::lib_smart_leds::LedPixelEsp32Rmt; + use ws2812_esp32_rmt_driver::driver::color::LedPixelColor; use crate::render::{Display, Surface}; - use crate::platform::smart_leds_lib::SmartLedDisplay; + use crate::platform::smart_leds_lib::{Pixbuf, SmartLedDisplay, HardwarePixel}; use crate::platform::DisplayInit; + use rgb::Rgb; - impl DisplayInit for Ws2812Esp32Rmt<'_> { + impl DisplayInit for LedPixelEsp32Rmt<'_, CSmart, CDev> where + CSmart: HardwarePixel, + [CSmart; 300]: Pixbuf, + CDev: LedPixelColor + From, + Rgb: From + { fn new_display() -> impl Display { let peripherals = Peripherals::take().unwrap(); let led_pin = peripherals.pins.gpio14; @@ -113,7 +156,7 @@ pub mod rmt { const MAX_POWER_MW : u32 = POWER_VOLTS * POWER_MA; let target = Self::new(channel, led_pin).unwrap(); - return SmartLedDisplay::::new(target, MAX_POWER_MW); + return SmartLedDisplay::::new(target, MAX_POWER_MW); } } }