#![no_std] #![no_main] extern crate alloc; extern crate lilygo_epd47; use core::{format_args, time::Duration}; use embedded_graphics::prelude::*; use embedded_graphics_core::{ pixelcolor::{Gray4, GrayColor}, primitives::Rectangle, }; use esp_backtrace as _; use esp_hal::{ clock::ClockControl, delay::Delay, gpio::Io, peripherals::Peripherals, prelude::*, rtc_cntl::{ get_reset_reason, get_wakeup_cause, sleep::{RtcSleepConfig, TimerWakeupSource}, Rtc, SocResetReason, }, system::SystemControl, Cpu, }; use lilygo_epd47::{pin_config, Display, DrawMode}; use u8g2_fonts::FontRenderer; static FONT: FontRenderer = FontRenderer::new::(); #[ram(rtc_fast)] static mut CYCLE: u16 = 0; #[ram(rtc_fast)] static mut LAST_RECT: Rectangle = Rectangle { top_left: Point { x: 0, y: 0 }, size: Size { width: 0, height: 0, }, }; #[entry] fn main() -> ! { esp_println::logger::init_logger_from_env(); let peripherals = Peripherals::take(); let system = SystemControl::new(peripherals.SYSTEM); let clocks = ClockControl::boot_defaults(system.clock_control).freeze(); let io = Io::new(peripherals.GPIO, peripherals.IO_MUX); // Create PSRAM allocator esp_alloc::psram_allocator!(peripherals.PSRAM, esp_hal::psram); let mut display = Display::new( pin_config!(io), peripherals.DMA, peripherals.LCD_CAM, peripherals.RMT, &clocks, ); let mut delay = Delay::new(&clocks); let mut rtc = Rtc::new(peripherals.LPWR, None); let reason = get_reset_reason(Cpu::ProCpu).unwrap_or(SocResetReason::ChipPowerOn); let wake_reason = get_wakeup_cause(); // turn screen on display.power_on(); delay.delay_millis(20); // clear let cycle = unsafe { CYCLE }; let last_rect = unsafe { LAST_RECT }; if cycle > 0 && cycle % 5 != 0 { display.fill_solid(&last_rect, Gray4::WHITE).unwrap(); display.flush(DrawMode::WhiteOnBlack).unwrap(); } else { display.clear().unwrap(); } // write out reset and wake reason let rect = FONT .render_aligned( format_args!( "Reset Reason: {:?}\nWake reason: {:?}\nCycle: {}\nRect: ({}, {}, {}, {})", reason, wake_reason, cycle, last_rect.top_left.x, last_rect.top_left.y, last_rect.size.width, last_rect.size.height, ), Point::new( display.bounding_box().center().x, display.bounding_box().center().y, ), u8g2_fonts::types::VerticalPosition::Baseline, u8g2_fonts::types::HorizontalAlignment::Center, u8g2_fonts::types::FontColor::WithBackground { fg: Gray4::BLACK, bg: Gray4::WHITE, }, &mut display, ) .unwrap(); display.flush(DrawMode::BlackOnWhite).unwrap(); // turn screen off display.power_off(); unsafe { if let Some(rect) = rect { LAST_RECT = rect; } CYCLE += 1; } delay.delay_millis(100); let mut rtc_cfg = RtcSleepConfig::deep(); rtc_cfg.set_rtc_fastmem_pd_en(false); rtc_cfg.set_rtc_slowmem_pd_en(false); let timer = TimerWakeupSource::new(Duration::from_secs(30)); rtc.sleep(&rtc_cfg, &[&timer], &mut delay); loop {} }