From 42e71fe3bd030cd9a51a53b0e11059ba992e2a50 Mon Sep 17 00:00:00 2001 From: Zac Wilson Date: Thu, 18 Dec 2025 11:48:06 +0000 Subject: [PATCH 1/5] Fix typo --- src/lib.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 1682658..eb43d53 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -69,7 +69,7 @@ pub enum PixelColour { White = 1, } -pub trait ApplyParitalWindow: private::Sealed { +pub trait ApplyPartialWindow: private::Sealed { fn apply< BusyPin: InputPin, ResetPin: OutputPin, @@ -96,7 +96,7 @@ mod private { pub struct NoPartialWindow; -impl ApplyParitalWindow for NoPartialWindow { +impl ApplyPartialWindow for NoPartialWindow { fn apply< BusyPin: InputPin, ResetPin: OutputPin, @@ -121,7 +121,7 @@ pub struct AutomaticPartialWindow { max_y: u16, } -impl ApplyParitalWindow for AutomaticPartialWindow { +impl ApplyPartialWindow for AutomaticPartialWindow { fn apply< BusyPin: InputPin, ResetPin: OutputPin, @@ -272,7 +272,7 @@ impl(&mut self, double_frame: &mut DoubleFrame) { + pub fn draw_full_frame(&mut self, double_frame: &mut DoubleFrame) { double_frame.partial_window.apply(self); self.write_command(0x10); for byte in double_frame.old.0 { From 32edbb8ce4912067a894c345850cdf691da6598b Mon Sep 17 00:00:00 2001 From: Zac Wilson Date: Thu, 18 Dec 2025 11:48:58 +0000 Subject: [PATCH 2/5] Support draw_pixel for both partial window strategies --- src/lib.rs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index eb43d53..075abaa 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -171,10 +171,6 @@ impl DoubleFrame { partial_window: NoPartialWindow, } } - - pub fn draw_pixel(&mut self, x: usize, y: usize, colour: PixelColour) { - todo!() - } } impl DoubleFrame { @@ -192,6 +188,12 @@ impl DoubleFrame { } } +impl DoubleFrame { + pub fn draw_pixel(&mut self, x: u16, y: u16, colour: PixelColour) { + todo!() + } +} + impl EPaperDisplay { From 6e96359b44ac95ee88e92bb75b1bfa9f1f13b492 Mon Sep 17 00:00:00 2001 From: Zac Wilson Date: Thu, 18 Dec 2025 11:50:41 +0000 Subject: [PATCH 3/5] Wrote more doc comments --- src/lib.rs | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/lib.rs b/src/lib.rs index 075abaa..45bacf9 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -64,12 +64,20 @@ pub struct DoubleFrame { partial_window: PartialWindow, } +/// The colour of a given pixel. +/// +/// Since the GDEQ031T10 is pure black-and-white (no greyscale), this is just a two-state enum.S pub enum PixelColour { Black = 0, White = 1, } +/// A trait for partial window strategies for use with [DoubleFrame]. +/// +/// This trait is sealed, so the only strategies available are [NoPartialWindow] +/// and [AutomaticPartialWindow]. pub trait ApplyPartialWindow: private::Sealed { + /// Applies the given window to the display so that its next update will only refresh part of the display. fn apply< BusyPin: InputPin, ResetPin: OutputPin, @@ -81,8 +89,13 @@ pub trait ApplyPartialWindow: private::Sealed { display: &mut EPaperDisplay, ); + /// Add a new bounding box which must be covered by the partial window. + /// + /// Calls to this method accumulate, meaning all bounding boxes will be covered by the + /// partial window until [ApplyPartialWindow::reset_partial_window] is called. fn update_partial_window(&mut self, min_x: u16, max_x: u16, min_y: u16, max_y: u16); + /// Resets the partial window to be empty. fn reset_partial_window(&mut self); } @@ -94,6 +107,8 @@ mod private { impl Sealed for super::AutomaticPartialWindow {} } +/// A partial window strategy which doesn't do any window tracking and simply updates +/// the entire display. pub struct NoPartialWindow; impl ApplyPartialWindow for NoPartialWindow { @@ -114,6 +129,8 @@ impl ApplyPartialWindow for NoPartialWindow { fn reset_partial_window(&mut self) {} } +/// A partial window strategy which tracks the bounding box of all changes made to the display +/// since the last display update and only updates that region. pub struct AutomaticPartialWindow { min_x: u16, max_x: u16, @@ -301,10 +318,12 @@ impl Date: Thu, 18 Dec 2025 11:51:05 +0000 Subject: [PATCH 4/5] Fixed visibility of Sealed trait --- src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib.rs b/src/lib.rs index 45bacf9..35c8d8b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -100,7 +100,7 @@ pub trait ApplyPartialWindow: private::Sealed { } mod private { - pub(super) trait Sealed {} + pub trait Sealed {} impl Sealed for super::NoPartialWindow {} From 78b6442fe30a509a34a5d06f809d2e65be10e382 Mon Sep 17 00:00:00 2001 From: Zac Wilson Date: Thu, 18 Dec 2025 11:51:30 +0000 Subject: [PATCH 5/5] Added support for embedded-graphics --- Cargo.lock | 66 +++++++++++++++++++++++++++++++++++ Cargo.toml | 4 +++ src/embedded_graphics_impl.rs | 38 ++++++++++++++++++++ src/lib.rs | 3 ++ 4 files changed, 111 insertions(+) create mode 100644 src/embedded_graphics_impl.rs diff --git a/Cargo.lock b/Cargo.lock index 5f6495c..6e5e75d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,15 +2,81 @@ # It is not intended for manual editing. version = 4 +[[package]] +name = "autocfg" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" + +[[package]] +name = "az" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b7e4c2464d97fe331d41de9d5db0def0a96f4d823b8b32a2efd503578988973" + +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "embedded-graphics" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0649998afacf6d575d126d83e68b78c0ab0e00ca2ac7e9b3db11b4cbe8274ef0" +dependencies = [ + "az", + "byteorder", + "embedded-graphics-core", + "float-cmp", + "micromath", +] + +[[package]] +name = "embedded-graphics-core" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba9ecd261f991856250d2207f6d8376946cd9f412a2165d3b75bc87a0bc7a044" +dependencies = [ + "az", + "byteorder", +] + [[package]] name = "embedded-hal" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "361a90feb7004eca4019fb28352a9465666b24f840f5c3cddf0ff13920590b89" +[[package]] +name = "float-cmp" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "98de4bbd547a563b716d8dfa9aad1cb19bfab00f4fa09a6a4ed21dbcf44ce9c4" +dependencies = [ + "num-traits", +] + +[[package]] +name = "micromath" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3c8dda44ff03a2f238717214da50f65d5a53b45cd213a7370424ffdb6fae815" + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", +] + [[package]] name = "zel-gdeq031t10" version = "0.1.0" dependencies = [ + "embedded-graphics", "embedded-hal", ] diff --git a/Cargo.toml b/Cargo.toml index f6f4648..ac815a6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,4 +4,8 @@ version = "0.1.0" edition = "2024" [dependencies] +embedded-graphics = { version = "0.8.1", optional = true } embedded-hal = "1.0.0" + +[features] +embedded-graphics = ["dep:embedded-graphics"] diff --git a/src/embedded_graphics_impl.rs b/src/embedded_graphics_impl.rs new file mode 100644 index 0000000..ddd16a8 --- /dev/null +++ b/src/embedded_graphics_impl.rs @@ -0,0 +1,38 @@ +use embedded_graphics::{ + pixelcolor::BinaryColor, + prelude::{DrawTarget, OriginDimensions, Size}, +}; +impl OriginDimensions + for crate::DoubleFrame +{ + fn size(&self) -> Size { + Size { + width: crate::EPD_WIDTH as u32, + height: crate::EPD_HEIGHT as u32, + } + } +} + +impl DrawTarget for crate::DoubleFrame { + type Color = BinaryColor; + + type Error = core::convert::Infallible; + + fn draw_iter(&mut self, pixels: I) -> Result<(), Self::Error> + where + I: IntoIterator>, + { + for pixel in pixels { + self.draw_pixel(pixel.0.x as u16, pixel.0.y as u16, convert_colour(pixel.1)); + } + + Ok(()) + } +} + +fn convert_colour(colour: BinaryColor) -> crate::PixelColour { + match colour { + BinaryColor::Off => crate::PixelColour::Black, + BinaryColor::On => crate::PixelColour::White, + } +} diff --git a/src/lib.rs b/src/lib.rs index 35c8d8b..0ab0e1c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -5,6 +5,9 @@ //! **Note**: 9-bit SPI mode (where the data/command is designated with an extra bit for each byte) //! is not supported by this driver. Only the mode with a dedicated data/command line is supported. +#[cfg(feature = "embedded-graphics")] +mod embedded_graphics_impl; + use embedded_hal::{ delay::DelayNs, digital::{InputPin, OutputPin},