use palette::Hsv; use palette::convert::IntoColorUnclamped; mod power; mod lib8; mod render; mod task; mod time; mod geometry; mod platform; #[cfg(feature="embedded-graphics")] mod embedded_graphics_lib; #[cfg(feature="rmt")] #[cfg(feature="embedded-graphics")] use ws2812_esp32_rmt_driver::lib_embedded_graphics::PonderjarTarget; #[cfg(feature="smart-leds")] mod smart_leds_lib; #[cfg(feature="rmt")] #[cfg(feature="smart-leds")] use ws2812_esp32_rmt_driver::lib_smart_leds::Ws2812Esp32Rmt; #[cfg(feature="spi")] #[cfg(feature="smart-leds")] use crate::smart_leds_lib::spi::SPIDisplay; use crate::time::Periodically; use crate::geometry::{Coordinates, VirtualCoordinates}; use crate::render::{Shader, Surfaces, Surface, SimpleSurface}; use crate::task::Task; use crate::platform::{DisplayInit}; struct IdleTask { frame: u8, surface: T, updater: Periodically } struct IdleShader { frame: u8 } impl Shader for IdleShader { fn draw(&self, coords: VirtualCoordinates) -> lib8::RGB8 { Hsv::new_srgb(self.frame.wrapping_add(coords.x()).wrapping_add(coords.y()), 255, 255).into_color_unclamped() } } impl IdleTask { fn new(surface: T) -> Self { IdleTask { frame: 0, surface: surface, updater: Periodically::new_every_n_ms(16) } } } impl Task for IdleTask { fn name(&self) -> &'static str { "Idle" } fn tick(&mut self) { self.updater.run(|| { self.frame = self.frame.wrapping_add(1); self.surface.set_shader(Box::new(IdleShader { frame: self.frame })); }) } fn stop(&mut self) { self.surface.clear_shader(); } } fn main() { // It is necessary to call this function once. Otherwise some patches to the runtime // implemented by esp-idf-sys might not link properly. See https://github.com/esp-rs/esp-idf-template/issues/71 esp_idf_svc::sys::link_patches(); // Bind the log crate to the ESP Logging facilities esp_idf_svc::log::EspLogger::initialize_default(); log::info!("Setting up display"); #[cfg(feature="spi")] let mut display = SPIDisplay::new_display::(); #[cfg(feature="embedded-graphics")] let mut display = PonderjarTarget::new_display::(); #[cfg(feature="rmt")] let mut display = Ws2812Esp32Rmt::new_display::(); log::info!("Creating runner"); let mut runner = task::Scheduler::new(vec![ Box::new(IdleTask::new(display.new_surface().unwrap())), Box::new(display), ]); log::info!("Ready to rock and roll"); loop { runner.tick(); } }