diff --git a/src/eink_display/frame.rs b/src/eink_display/frame.rs index 895e3ce..6db1089 100644 --- a/src/eink_display/frame.rs +++ b/src/eink_display/frame.rs @@ -60,10 +60,16 @@ impl OriginDimensions for Frame { } } +#[derive(defmt::Format, Debug)] +pub(crate) enum Axis { + X, + Y, +} + #[derive(defmt::Format, Debug)] pub(crate) enum DrawError { - /// If more details about the error are needed at runtime, then add them - OutOfBounds, + PointTooLarge { axis: Axis, value: i32 }, + OutOfBounds { axis: Axis, value: u16, max: u16 }, } impl DrawTarget for Frame { @@ -75,15 +81,33 @@ impl DrawTarget for Frame { where I: IntoIterator>, { - const X_RANGE: Range = 0..Frame::WIDTH; - const Y_RANGE: Range = 0..Frame::HEIGHT; + const X_RANGE: RangeInclusive = 0..=Frame::HEIGHT; + const Y_RANGE: RangeInclusive = 0..=Frame::WIDTH; for Pixel(point, color) in pixels { - let x = u16::try_from(point.x).map_err(|_| DrawError::OutOfBounds)?; - let y = u16::try_from(point.y).map_err(|_| DrawError::OutOfBounds)?; + let x = u16::try_from(point.x).map_err(|_| DrawError::PointTooLarge { + axis: Axis::X, + value: point.x, + })?; + let y = u16::try_from(point.y).map_err(|_| DrawError::PointTooLarge { + axis: Axis::Y, + value: point.y, + })?; + + if !X_RANGE.contains(&x) { + return Err(DrawError::OutOfBounds { + axis: Axis::X, + value: x, + max: *X_RANGE.end(), + }); + } - if !X_RANGE.contains(&x) || !Y_RANGE.contains(&y) { - return Err(DrawError::OutOfBounds); + if !Y_RANGE.contains(&y) { + return Err(DrawError::OutOfBounds { + axis: Axis::Y, + value: y, + max: *Y_RANGE.end(), + }); } // Map to pixel on hardware diff --git a/src/main.rs b/src/main.rs index 079e578..c824516 100644 --- a/src/main.rs +++ b/src/main.rs @@ -20,8 +20,8 @@ use defmt::{error, info}; use embassy_executor::Spawner; use embassy_time::{Instant, Timer}; use embedded_graphics::Drawable; -use embedded_graphics::mono_font::MonoTextStyle; use embedded_graphics::mono_font::ascii::FONT_10X20; +use embedded_graphics::mono_font::{MonoTextStyle, MonoTextStyleBuilder}; use embedded_graphics::pixelcolor::BinaryColor; use embedded_graphics::prelude::*; use embedded_graphics::text::Text; @@ -179,9 +179,6 @@ async fn run(spawner: Spawner) -> Result<(), ApplicationError> { info!("Initializing SD card"); let storage = Storage::new(sd_card_spi); - if let Err(error) = storage.debug_files().await { - error!("Failed to debug files: {:?}", error); - } info!("Initializing display"); @@ -193,7 +190,12 @@ async fn run(spawner: Spawner) -> Result<(), ApplicationError> { // Draw the image with the top left corner at (10, 20) by wrapping it in // an embedded-graphics `Image`. - let style = MonoTextStyle::new(&FONT_10X20, BinaryColor::On); + let style = MonoTextStyleBuilder::new() + .font(&FONT_10X20) + .text_color(BinaryColor::On) + .background_color(BinaryColor::Off) + .build(); + // let style = MonoTextStyle::new(&FONT_10X20, BinaryColor::On); // let text = Text::new("Hello, World!", Point::new(0, 20), style); // if let Err(error) = text.draw(&mut frame) { // error!("Failed to draw text: {:?}", error); @@ -204,11 +206,11 @@ async fn run(spawner: Spawner) -> Result<(), ApplicationError> { // .await // .map_err(ApplicationError::Display)?; - spawner.spawn(handle_power_button( - peripherals.GPIO3, - peripherals.LPWR, - display, - ))?; + // spawner.spawn(handle_power_button( + // peripherals.GPIO3, + // peripherals.LPWR, + // display, + // ))?; let start = Instant::now(); let mut y = 20; @@ -232,11 +234,22 @@ async fn run(spawner: Spawner) -> Result<(), ApplicationError> { .draw(&mut frame) .map_err(ApplicationError::Draw)?; y += 20; - if y > 480 { + + let refresh_mode = if y >= 800 { y = 20; + eink_display::RefreshMode::Full + } else { + eink_display::RefreshMode::Fast + }; + + if let Err(error) = display.display(refresh_mode, &frame).await { + error!( + "Failed to display frame: {:?}", + defmt::Display2Format(&error) + ); } - Timer::after_secs(5).await; + Timer::after_secs(2).await; } } diff --git a/src/storage.rs b/src/storage.rs index 6a916eb..fb09883 100644 --- a/src/storage.rs +++ b/src/storage.rs @@ -1,6 +1,5 @@ use alloc::string::ToString; -use defmt::info; -use embedded_sdmmc::{Continue, LfnBuffer, TimeSource, Timestamp, VolumeIdx, VolumeManager}; +use embedded_sdmmc::{TimeSource, Timestamp, VolumeIdx, VolumeManager}; use crate::spi; @@ -36,31 +35,6 @@ impl<'a> Storage<'a> { Self { volume_manager } } - pub(crate) async fn debug_files(&self) -> Result<(), SdCardError> { - let volume = self.volume_manager.open_volume(VolumeIdx(0)).await?; - let root_directory = volume.open_root_dir()?; - - let mut count = 0; - let mut buffer = [0u8; 256]; - let mut buffer = LfnBuffer::new(&mut buffer); - root_directory - .iterate_dir_lfn(&mut buffer, |entry, i_dont_know| { - count += 1; - - let file_name = core::str::from_utf8(entry.name.base_name()); - info!( - "Entry: {:?} {}", - defmt::Debug2Format(&file_name), - i_dont_know - ); - Continue::Yes - }) - .await?; - - info!("Total entries: {}", count); - Ok(()) - } - pub(crate) async fn write_log(&self, time: u64, battery_level: u16) -> Result<(), SdCardError> { let volume = self.volume_manager.open_volume(VolumeIdx(0)).await?; let root_directory = volume.open_root_dir()?; @@ -77,6 +51,12 @@ impl<'a> Storage<'a> { file.write(level).await?; file.write(b"\n").await?; + file.close().await?; + + root_directory.close()?; + + volume.close().await?; + Ok(()) } }