use std::{error::Error, thread::sleep, time::Duration}; use embedded_graphics::{image::Image, pixelcolor::Rgb565, prelude::*}; use esp_idf_hal::{ gpio::{Gpio12, Gpio14, Gpio16, Gpio17, Gpio18, Gpio23, Gpio5, Input, Output}, prelude::{Hertz, Peripherals}, spi::{self, Master, Pins, SPI3}, }; // If using the `binstart` feature of `esp-idf-sys`, always keep this module imported use esp_idf_sys as _; use rand::Rng; use ssd1331::Ssd1331; use tinybmp::Bmp; fn secondary() -> Result<(), Box> { // Temporary. Will disappear once ESP-IDF 4.4 is released, but for now it is necessary to call this function once, // or else some patches to the runtime implemented by esp-idf-sys might not link properly. esp_idf_sys::link_patches(); // Bind the log crate to the ESP Logging facilities esp_idf_svc::log::EspLogger::initialize_default(); let peripherals = Peripherals::take().unwrap(); let spi3 = peripherals.spi3; let pins = peripherals.pins; let cs: Gpio17 = pins.gpio17.into_output()?; let dc: Gpio16 = pins.gpio16.into_output()?; let mosi: Gpio23 = pins.gpio23.into_output()?; let sclk: Gpio18 = pins.gpio18.into_output()?; let reset: Gpio5 = pins.gpio5.into_output()?; let read: Gpio12 = pins.gpio12.into_input()?; let write: Gpio14 = pins.gpio14.into_output()?; let spiman = spi::Master::, Gpio23, Gpio5, Gpio17>::new( spi3, Pins { sclk: sclk, sdo: mosi, sdi: Some(reset), cs: Some(cs), }, spi::config::Config { baudrate: Hertz(24000000), data_mode: embedded_hal::spi::MODE_0, write_only: false, dma: spi::Dma::Disabled, }, )?; let mut display = Ssd1331::new(spiman, dc, ssd1331::DisplayRotation::Rotate180); display.init().unwrap(); display.flush().unwrap(); let (w, h) = display.dimensions(); println!("got resolution {} x {}", w.clone(), h.clone()); let mut rng = rand::thread_rng(); let eye = Bmp::from_slice(include_bytes!("./eye.bmp")).expect("Failed to load BMP image"); let eye_closed = Bmp::from_slice(include_bytes!("./eye_closed.bmp")).expect("Failed to load BMP image"); let emilis = Bmp::from_slice(include_bytes!("./emilis.bmp")).expect("Failed to load BMP image"); print_image(emilis, &mut display, h as u32, w as u32); sleep(Duration::from_secs(3)); display.clear(); puff_idle(&mut display, h as u32, w as u32); loop { print_image(eye, &mut display, h as u32, w as u32); sleep(Duration::from_secs(rng.gen_range(2..8))); print_image(eye_closed, &mut display, h as u32, w as u32); sleep(Duration::from_millis(190)) } } fn print_image( img: Bmp, display: &mut Ssd1331< Master, Gpio23, Gpio5, Gpio17>, Gpio16, >, h: u32, w: u32, ) { let im: Image> = Image::new(&img, Point::zero()); // Position image in the center of the display let moved = im.translate(Point::new( (w - img.size().width) as i32 / 2, (h - img.size().height) as i32 / 2, )); moved.draw(display).unwrap(); display.flush().unwrap(); } fn puff_idle( display: &mut Ssd1331< Master, Gpio23, Gpio5, Gpio17>, Gpio16, >, h: u32, w: u32, ) -> ! { let raw = get_puff_raw(); let mut frames = Vec::>::new(); for raw_image in raw { let frame_bmp = Bmp::from_slice(raw_image).unwrap(); frames.push(frame_bmp); } loop { for frame in &frames { print_image(*frame, display, h, w); sleep(Duration::from_millis(1)); } } } // Manually unrolled because im gay fn get_puff_raw() -> Vec<&'static [u8]> { let mut raw = Vec::<&[u8]>::new(); raw.push(include_bytes!("../puff/puffidle-0.bmp")); raw.push(include_bytes!("../puff/puffidle-1.bmp")); raw.push(include_bytes!("../puff/puffidle-2.bmp")); raw.push(include_bytes!("../puff/puffidle-3.bmp")); raw.push(include_bytes!("../puff/puffidle-4.bmp")); raw.push(include_bytes!("../puff/puffidle-5.bmp")); raw.push(include_bytes!("../puff/puffidle-6.bmp")); raw.push(include_bytes!("../puff/puffidle-7.bmp")); raw.push(include_bytes!("../puff/puffidle-8.bmp")); raw.push(include_bytes!("../puff/puffidle-9.bmp")); raw.push(include_bytes!("../puff/puffidle-10.bmp")); raw.push(include_bytes!("../puff/puffidle-11.bmp")); raw.push(include_bytes!("../puff/puffidle-12.bmp")); raw.push(include_bytes!("../puff/puffidle-13.bmp")); raw.push(include_bytes!("../puff/puffidle-14.bmp")); raw.push(include_bytes!("../puff/puffidle-15.bmp")); raw.push(include_bytes!("../puff/puffidle-16.bmp")); raw.push(include_bytes!("../puff/puffidle-17.bmp")); raw.push(include_bytes!("../puff/puffidle-18.bmp")); raw.push(include_bytes!("../puff/puffidle-19.bmp")); raw.push(include_bytes!("../puff/puffidle-20.bmp")); raw.push(include_bytes!("../puff/puffidle-21.bmp")); raw.push(include_bytes!("../puff/puffidle-22.bmp")); raw.push(include_bytes!("../puff/puffidle-23.bmp")); raw.push(include_bytes!("../puff/puffidle-24.bmp")); raw.push(include_bytes!("../puff/puffidle-25.bmp")); raw.push(include_bytes!("../puff/puffidle-26.bmp")); raw.push(include_bytes!("../puff/puffidle-27.bmp")); raw.push(include_bytes!("../puff/puffidle-28.bmp")); raw.push(include_bytes!("../puff/puffidle-29.bmp")); raw.push(include_bytes!("../puff/puffidle-30.bmp")); raw.push(include_bytes!("../puff/puffidle-31.bmp")); raw.push(include_bytes!("../puff/puffidle-32.bmp")); raw.push(include_bytes!("../puff/puffidle-33.bmp")); raw.push(include_bytes!("../puff/puffidle-34.bmp")); raw.push(include_bytes!("../puff/puffidle-35.bmp")); raw.push(include_bytes!("../puff/puffidle-36.bmp")); raw.push(include_bytes!("../puff/puffidle-37.bmp")); raw.push(include_bytes!("../puff/puffidle-38.bmp")); raw.push(include_bytes!("../puff/puffidle-39.bmp")); raw.push(include_bytes!("../puff/puffidle-40.bmp")); raw.push(include_bytes!("../puff/puffidle-41.bmp")); raw.push(include_bytes!("../puff/puffidle-42.bmp")); raw.push(include_bytes!("../puff/puffidle-43.bmp")); raw.push(include_bytes!("../puff/puffidle-44.bmp")); raw.push(include_bytes!("../puff/puffidle-45.bmp")); raw.push(include_bytes!("../puff/puffidle-46.bmp")); raw.push(include_bytes!("../puff/puffidle-47.bmp")); raw.push(include_bytes!("../puff/puffidle-48.bmp")); raw.push(include_bytes!("../puff/puffidle-49.bmp")); raw.push(include_bytes!("../puff/puffidle-50.bmp")); raw.push(include_bytes!("../puff/puffidle-51.bmp")); raw.push(include_bytes!("../puff/puffidle-52.bmp")); raw.push(include_bytes!("../puff/puffidle-53.bmp")); raw.push(include_bytes!("../puff/puffidle-54.bmp")); raw.push(include_bytes!("../puff/puffidle-55.bmp")); raw.push(include_bytes!("../puff/puffidle-56.bmp")); raw.push(include_bytes!("../puff/puffidle-57.bmp")); raw.push(include_bytes!("../puff/puffidle-58.bmp")); raw.push(include_bytes!("../puff/puffidle-59.bmp")); raw } fn main() -> Result<(), Box> { sleep(Duration::from_secs(1)); Ok(secondary().unwrap()) }