From dcaed6fb3e18a335abc3ab43e76fbe11fa5be135 Mon Sep 17 00:00:00 2001 From: Caemor <11088935+caemor@users.noreply.github.com> Date: Wed, 18 Mar 2020 14:30:40 +0100 Subject: [PATCH 01/15] Update embedded-graphics and update epd4in2-blue-pill-exampleg --- Cargo.toml | 7 +- README.md | 2 +- examples/epd1in54_full/src/main.rs | 12 +- examples/epd2in9_full/src/main.rs | 12 +- examples/epd4in2_full/src/main.rs | 22 ++-- examples/epd4in2_full_blue_pill/Cargo.toml | 4 +- examples/epd4in2_full_blue_pill/src/main.rs | 122 +++++++----------- .../epd4in2_var_display_buffer/src/main.rs | 22 ++-- examples/epd7in5_full/src/main.rs | 22 ++-- examples/epd7in5_v2_full/src/main.rs | 22 ++-- src/color.rs | 9 +- src/epd1in54/graphics.rs | 54 ++++---- src/epd1in54/mod.rs | 2 +- src/epd1in54b/graphics.rs | 17 ++- src/epd2in9/graphics.rs | 17 ++- src/epd2in9/mod.rs | 2 +- src/epd4in2/graphics.rs | 54 ++++---- src/epd7in5/graphics.rs | 53 ++++---- src/epd7in5_v2/graphics.rs | 58 ++++----- src/graphics.rs | 101 ++++++++------- src/lib.rs | 2 +- 21 files changed, 289 insertions(+), 327 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 677ac97..9cac8b4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,6 +17,9 @@ edition = "2018" # `branch` is optional; default is `master` travis-ci = { repository = "caemor/epd-waveshare" } +[dependencies] +embedded-graphics = { version = "0.6.0-beta.2", optional = true} + [features] default = ["epd1in54", "epd1in54b", "epd2in9", "epd4in2", "epd7in5", "epd7in5_v2", "graphics"] @@ -30,9 +33,7 @@ epd7in5_v2 = [] # offers an alternative fast full lut for type_a displays, but the refresh isnt as clean looking type_a_alternative_faster_lut = [] -[dependencies.embedded-graphics] -optional = true -version = "0.5.2" + [dependencies.embedded-hal] features = ["unproven"] diff --git a/README.md b/README.md index 76a3cc1..2771eb9 100644 --- a/README.md +++ b/README.md @@ -25,7 +25,7 @@ display.draw( Font12x16::render_str("Hello Rust!") .stroke(Some(Color::Black)) .fill(Some(Color::White)) - .translate(Coord::new(5, 50)) + .translate(Point::new(5, 50)) .into_iter(), ); diff --git a/examples/epd1in54_full/src/main.rs b/examples/epd1in54_full/src/main.rs index a308905..5742158 100644 --- a/examples/epd1in54_full/src/main.rs +++ b/examples/epd1in54_full/src/main.rs @@ -1,6 +1,6 @@ #![deny(warnings)] -use embedded_graphics::{coord::Coord, fonts::Font6x8, prelude::*, Drawing}; +use embedded_graphics::{fonts::Font6x8, prelude::*, Drawing, Point::Point}; use embedded_hal::prelude::*; use epd_waveshare::{ epd1in54::{Display1in54, EPD1in54}, @@ -82,7 +82,7 @@ fn run() -> Result<(), std::io::Error> { Font6x8::render_str("Rotate 0!") .stroke(Some(Color::Black)) .fill(Some(Color::White)) - .translate(Coord::new(5, 50)) + .translate(Point::new(5, 50)) .into_iter(), ); @@ -91,7 +91,7 @@ fn run() -> Result<(), std::io::Error> { Font6x8::render_str("Rotate 90!") .stroke(Some(Color::Black)) .fill(Some(Color::White)) - .translate(Coord::new(5, 50)) + .translate(Point::new(5, 50)) .into_iter(), ); @@ -100,7 +100,7 @@ fn run() -> Result<(), std::io::Error> { Font6x8::render_str("Rotate 180!") .stroke(Some(Color::Black)) .fill(Some(Color::White)) - .translate(Coord::new(5, 50)) + .translate(Point::new(5, 50)) .into_iter(), ); @@ -109,7 +109,7 @@ fn run() -> Result<(), std::io::Error> { Font6x8::render_str("Rotate 270!") .stroke(Some(Color::Black)) .fill(Some(Color::White)) - .translate(Coord::new(5, 50)) + .translate(Point::new(5, 50)) .into_iter(), ); @@ -134,7 +134,7 @@ fn run() -> Result<(), std::io::Error> { stroke_color: Some(Color::Black), stroke_width: 0u8, // Has no effect on fonts }) - .translate(Coord::new(5 + i * 6, 50)) + .translate(Point::new(5 + i * 6, 50)) .into_iter(), ); diff --git a/examples/epd2in9_full/src/main.rs b/examples/epd2in9_full/src/main.rs index e4e25a0..a5834fe 100644 --- a/examples/epd2in9_full/src/main.rs +++ b/examples/epd2in9_full/src/main.rs @@ -1,6 +1,6 @@ #![deny(warnings)] -use embedded_graphics::{coord::Coord, fonts::Font6x8, prelude::*, Drawing}; +use embedded_graphics::{fonts::Font6x8, prelude::*, Drawing, Point::Point}; use embedded_hal::prelude::*; use epd_waveshare::{ epd2in9::{Display2in9, EPD2in9}, @@ -86,7 +86,7 @@ fn run() -> Result<(), std::io::Error> { Font6x8::render_str("Rotate 0!") .stroke(Some(Color::Black)) .fill(Some(Color::White)) - .translate(Coord::new(5, 50)) + .translate(Point::new(5, 50)) .into_iter(), ); @@ -95,7 +95,7 @@ fn run() -> Result<(), std::io::Error> { Font6x8::render_str("Rotate 90!") .stroke(Some(Color::Black)) .fill(Some(Color::White)) - .translate(Coord::new(5, 50)) + .translate(Point::new(5, 50)) .into_iter(), ); @@ -104,7 +104,7 @@ fn run() -> Result<(), std::io::Error> { Font6x8::render_str("Rotate 180!") .stroke(Some(Color::Black)) .fill(Some(Color::White)) - .translate(Coord::new(5, 50)) + .translate(Point::new(5, 50)) .into_iter(), ); @@ -113,7 +113,7 @@ fn run() -> Result<(), std::io::Error> { Font6x8::render_str("Rotate 270!") .stroke(Some(Color::Black)) .fill(Some(Color::White)) - .translate(Coord::new(5, 50)) + .translate(Point::new(5, 50)) .into_iter(), ); @@ -138,7 +138,7 @@ fn run() -> Result<(), std::io::Error> { stroke_color: Some(Color::Black), stroke_width: 0u8, // Has no effect on fonts }) - .translate(Coord::new(5 + i * 6, 50)) + .translate(Point::new(5 + i * 6, 50)) .into_iter(), ); diff --git a/examples/epd4in2_full/src/main.rs b/examples/epd4in2_full/src/main.rs index b333b23..7cd880c 100644 --- a/examples/epd4in2_full/src/main.rs +++ b/examples/epd4in2_full/src/main.rs @@ -1,11 +1,11 @@ #![deny(warnings)] use embedded_graphics::{ - coord::Coord, fonts::{Font12x16, Font6x8}, prelude::*, primitives::{Circle, Line}, Drawing, + Point::Point, }; use embedded_hal::prelude::*; use epd_waveshare::{ @@ -77,7 +77,7 @@ fn run() -> Result<(), std::io::Error> { Font6x8::render_str("Rotate 0!") .stroke(Some(Color::Black)) .fill(Some(Color::White)) - .translate(Coord::new(5, 50)) + .translate(Point::new(5, 50)) .into_iter(), ); @@ -86,7 +86,7 @@ fn run() -> Result<(), std::io::Error> { Font6x8::render_str("Rotate 90!") .stroke(Some(Color::Black)) .fill(Some(Color::White)) - .translate(Coord::new(5, 50)) + .translate(Point::new(5, 50)) .into_iter(), ); @@ -95,7 +95,7 @@ fn run() -> Result<(), std::io::Error> { Font6x8::render_str("Rotate 180!") .stroke(Some(Color::Black)) .fill(Some(Color::White)) - .translate(Coord::new(5, 50)) + .translate(Point::new(5, 50)) .into_iter(), ); @@ -104,7 +104,7 @@ fn run() -> Result<(), std::io::Error> { Font6x8::render_str("Rotate 270!") .stroke(Some(Color::Black)) .fill(Some(Color::White)) - .translate(Coord::new(5, 50)) + .translate(Point::new(5, 50)) .into_iter(), ); @@ -119,17 +119,17 @@ fn run() -> Result<(), std::io::Error> { // draw a analog clock display.draw( - Circle::new(Coord::new(64, 64), 64) + Circle::new(Point::new(64, 64), 64) .stroke(Some(Color::Black)) .into_iter(), ); display.draw( - Line::new(Coord::new(64, 64), Coord::new(0, 64)) + let _ = Line::new(Point::new(64, 64), Point::new(0, 64)) .stroke(Some(Color::Black)) .into_iter(), ); display.draw( - Line::new(Coord::new(64, 64), Coord::new(80, 80)) + let _ = Line::new(Point::new(64, 64), Point::new(80, 80)) .stroke(Some(Color::Black)) .into_iter(), ); @@ -143,7 +143,7 @@ fn run() -> Result<(), std::io::Error> { stroke_color: Some(Color::White), stroke_width: 0u8, // Has no effect on fonts }) - .translate(Coord::new(175, 250)) + .translate(Point::new(175, 250)) .into_iter(), ); @@ -156,7 +156,7 @@ fn run() -> Result<(), std::io::Error> { stroke_color: Some(Color::Black), stroke_width: 0u8, // Has no effect on fonts }) - .translate(Coord::new(50, 200)) + .translate(Point::new(50, 200)) .into_iter(), ); @@ -172,7 +172,7 @@ fn run() -> Result<(), std::io::Error> { stroke_color: Some(Color::Black), stroke_width: 0u8, // Has no effect on fonts }) - .translate(Coord::new(5 + i * 12, 50)) + .translate(Point::new(5 + i * 12, 50)) .into_iter(), ); diff --git a/examples/epd4in2_full_blue_pill/Cargo.toml b/examples/epd4in2_full_blue_pill/Cargo.toml index b4abfbb..c759fb7 100644 --- a/examples/epd4in2_full_blue_pill/Cargo.toml +++ b/examples/epd4in2_full_blue_pill/Cargo.toml @@ -10,8 +10,8 @@ edition = "2018" #epd_waveshare = { path = "../../"} epd-waveshare = { path = "../../", default-features = false, features = ["epd4in2", "graphics"]} -embedded-graphics = "0.5.2" -embedded-hal = { version = "0.2.2", features = ["unproven"] } +embedded-graphics = "0.6.0-beta.2" +embedded-hal = { version = "0.2.3", features = ["unproven"] } stm32f1xx-hal = { version = "0.2", features = ["rt", "stm32f103" ] } cortex-m = "0.5.0" diff --git a/examples/epd4in2_full_blue_pill/src/main.rs b/examples/epd4in2_full_blue_pill/src/main.rs index a20143b..f5becae 100644 --- a/examples/epd4in2_full_blue_pill/src/main.rs +++ b/examples/epd4in2_full_blue_pill/src/main.rs @@ -10,13 +10,15 @@ use stm32f1xx_hal::prelude::*; use stm32f1xx_hal::{delay, spi}; use embedded_graphics::{ - coord::Coord, - fonts::{Font12x16, Font6x8}, + fonts::{Font12x16, Font6x8, Text}, + pixelcolor::BinaryColor, prelude::*, primitives::{Circle, Line}, - Drawing, + style::{PrimitiveStyle, Styled}, + text_style, DrawTarget, }; use epd_waveshare::{ + color::*, epd4in2::Display4in2, graphics::{Display, DisplayRotation}, prelude::*, @@ -68,41 +70,18 @@ fn main() -> ! { //println!("Test all the rotations"); let mut display = Display4in2::default(); + display.set_rotation(DisplayRotation::Rotate0); - display.draw( - Font6x8::render_str("Rotate 0!") - .stroke(Some(Color::Black)) - .fill(Some(Color::White)) - .translate(Coord::new(5, 50)) - .into_iter(), - ); + draw_text(&mut display, "Rotate 0!", 5, 50); display.set_rotation(DisplayRotation::Rotate90); - display.draw( - Font6x8::render_str("Rotate 90!") - .stroke(Some(Color::Black)) - .fill(Some(Color::White)) - .translate(Coord::new(5, 50)) - .into_iter(), - ); + draw_text(&mut display, "Rotate 90!", 5, 50); display.set_rotation(DisplayRotation::Rotate180); - display.draw( - Font6x8::render_str("Rotate 180!") - .stroke(Some(Color::Black)) - .fill(Some(Color::White)) - .translate(Coord::new(5, 50)) - .into_iter(), - ); + draw_text(&mut display, "Rotate 180!", 5, 50); display.set_rotation(DisplayRotation::Rotate270); - display.draw( - Font6x8::render_str("Rotate 270!") - .stroke(Some(Color::Black)) - .fill(Some(Color::White)) - .translate(Coord::new(5, 50)) - .into_iter(), - ); + draw_text(&mut display, "Rotate 270!", 5, 50); epd4in2.update_frame(&mut spi, &display.buffer()).unwrap(); epd4in2 @@ -114,47 +93,33 @@ fn main() -> ! { display.clear_buffer(Color::White); // draw a analog clock - display.draw( - Circle::new(Coord::new(64, 64), 64) - .stroke(Some(Color::Black)) - .into_iter(), - ); - display.draw( - Line::new(Coord::new(64, 64), Coord::new(0, 64)) - .stroke(Some(Color::Black)) - .into_iter(), - ); - display.draw( - Line::new(Coord::new(64, 64), Coord::new(80, 80)) - .stroke(Some(Color::Black)) - .into_iter(), - ); + Circle::new(Point::new(64, 64), 64) + .into_styled(PrimitiveStyle::with_stroke(Black, 1)) + .draw(&mut display); + Line::new(Point::new(64, 64), Point::new(0, 64)) + .into_styled(PrimitiveStyle::with_stroke(Black, 1)) + .draw(&mut display); + Line::new(Point::new(64, 64), Point::new(80, 80)) + .into_styled(PrimitiveStyle::with_stroke(Black, 1)) + .draw(&mut display); // draw white on black background - display.draw( - Font6x8::render_str("It's working-WoB!") - // Using Style here - .style(Style { - fill_color: Some(Color::Black), - stroke_color: Some(Color::White), - stroke_width: 0u8, // Has no effect on fonts - }) - .translate(Coord::new(175, 250)) - .into_iter(), - ); + let _ = Text::new("It's working-WoB!", Point::new(175, 250)) + .into_styled(text_style!( + font = Font6x8, + text_color = White, + background_color = Black + )) + .draw(&mut display); // use bigger/different font - display.draw( - Font12x16::render_str("It's working-BoW!") - // Using Style here - .style(Style { - fill_color: Some(Color::White), - stroke_color: Some(Color::Black), - stroke_width: 0u8, // Has no effect on fonts - }) - .translate(Coord::new(50, 200)) - .into_iter(), - ); + let _ = Text::new("It's working-WoB!", Point::new(50, 200)) + .into_styled(text_style!( + font = Font12x16, + text_color = White, + background_color = Black + )) + .draw(&mut display); // a moving `Hello World!` let limit = 10; @@ -163,16 +128,7 @@ fn main() -> ! { for i in 0..limit { //println!("Moving Hello World. Loop {} from {}", (i + 1), limit); - display.draw( - Font6x8::render_str(" Hello World! ") - .style(Style { - fill_color: Some(Color::White), - stroke_color: Some(Color::Black), - stroke_width: 0u8, // Has no effect on fonts - }) - .translate(Coord::new(5 + i * 12, 50)) - .into_iter(), - ); + draw_text(&mut display, " Hello World! ", 5 + i * 12, 50); epd4in2.update_frame(&mut spi, &display.buffer()).unwrap(); epd4in2 @@ -190,3 +146,13 @@ fn main() -> ! { cortex_m::asm::wfi(); } } + +fn draw_text(display: &mut Display4in2, text: &str, x: i32, y: i32) { + let _ = Text::new(text, Point::new(x, y)) + .into_styled(text_style!( + font = Font6x8, + text_color = Black, + background_color = White + )) + .draw(display); +} diff --git a/examples/epd4in2_var_display_buffer/src/main.rs b/examples/epd4in2_var_display_buffer/src/main.rs index f15ab4b..ae365be 100644 --- a/examples/epd4in2_var_display_buffer/src/main.rs +++ b/examples/epd4in2_var_display_buffer/src/main.rs @@ -1,11 +1,11 @@ #![deny(warnings)] use embedded_graphics::{ - coord::Coord, fonts::{Font12x16, Font6x8}, prelude::*, primitives::{Circle, Line}, Drawing, + Point::Point, }; use embedded_hal::prelude::*; use epd_waveshare::{ @@ -81,7 +81,7 @@ fn run() -> Result<(), std::io::Error> { Font6x8::render_str("Rotate 0!") .stroke(Some(Color::Black)) .fill(Some(Color::White)) - .translate(Coord::new(5, 50)) + .translate(Point::new(5, 50)) .into_iter(), ); @@ -90,7 +90,7 @@ fn run() -> Result<(), std::io::Error> { Font6x8::render_str("Rotate 90!") .stroke(Some(Color::Black)) .fill(Some(Color::White)) - .translate(Coord::new(5, 50)) + .translate(Point::new(5, 50)) .into_iter(), ); @@ -99,7 +99,7 @@ fn run() -> Result<(), std::io::Error> { Font6x8::render_str("Rotate 180!") .stroke(Some(Color::Black)) .fill(Some(Color::White)) - .translate(Coord::new(5, 50)) + .translate(Point::new(5, 50)) .into_iter(), ); @@ -108,7 +108,7 @@ fn run() -> Result<(), std::io::Error> { Font6x8::render_str("Rotate 270!") .stroke(Some(Color::Black)) .fill(Some(Color::White)) - .translate(Coord::new(5, 50)) + .translate(Point::new(5, 50)) .into_iter(), ); @@ -125,17 +125,17 @@ fn run() -> Result<(), std::io::Error> { // draw a analog clock display.draw( - Circle::new(Coord::new(64, 64), 64) + Circle::new(Point::new(64, 64), 64) .stroke(Some(Color::Black)) .into_iter(), ); display.draw( - Line::new(Coord::new(64, 64), Coord::new(0, 64)) + let _ = Line::new(Point::new(64, 64), Point::new(0, 64)) .stroke(Some(Color::Black)) .into_iter(), ); display.draw( - Line::new(Coord::new(64, 64), Coord::new(80, 80)) + let _ = Line::new(Point::new(64, 64), Point::new(80, 80)) .stroke(Some(Color::Black)) .into_iter(), ); @@ -149,7 +149,7 @@ fn run() -> Result<(), std::io::Error> { stroke_color: Some(Color::White), stroke_width: 0u8, // Has no effect on fonts }) - .translate(Coord::new(175, 250)) + .translate(Point::new(175, 250)) .into_iter(), ); @@ -162,7 +162,7 @@ fn run() -> Result<(), std::io::Error> { stroke_color: Some(Color::Black), stroke_width: 0u8, // Has no effect on fonts }) - .translate(Coord::new(50, 200)) + .translate(Point::new(50, 200)) .into_iter(), ); @@ -178,7 +178,7 @@ fn run() -> Result<(), std::io::Error> { stroke_color: Some(Color::Black), stroke_width: 0u8, // Has no effect on fonts }) - .translate(Coord::new(5 + i * 12, 50)) + .translate(Point::new(5 + i * 12, 50)) .into_iter(), ); diff --git a/examples/epd7in5_full/src/main.rs b/examples/epd7in5_full/src/main.rs index 1a3ed2f..3e324da 100644 --- a/examples/epd7in5_full/src/main.rs +++ b/examples/epd7in5_full/src/main.rs @@ -1,11 +1,11 @@ #![deny(warnings)] use embedded_graphics::{ - coord::Coord, fonts::{Font12x16, Font6x8}, prelude::*, primitives::{Circle, Line}, Drawing, + Point::Point, }; use embedded_hal::prelude::*; use epd_waveshare::{ @@ -76,7 +76,7 @@ fn run() -> Result<(), std::io::Error> { Font6x8::render_str("Rotate 0!") .stroke(Some(Color::Black)) .fill(Some(Color::White)) - .translate(Coord::new(5, 50)) + .translate(Point::new(5, 50)) .into_iter(), ); @@ -85,7 +85,7 @@ fn run() -> Result<(), std::io::Error> { Font6x8::render_str("Rotate 90!") .stroke(Some(Color::Black)) .fill(Some(Color::White)) - .translate(Coord::new(5, 50)) + .translate(Point::new(5, 50)) .into_iter(), ); @@ -94,7 +94,7 @@ fn run() -> Result<(), std::io::Error> { Font6x8::render_str("Rotate 180!") .stroke(Some(Color::Black)) .fill(Some(Color::White)) - .translate(Coord::new(5, 50)) + .translate(Point::new(5, 50)) .into_iter(), ); @@ -103,7 +103,7 @@ fn run() -> Result<(), std::io::Error> { Font6x8::render_str("Rotate 270!") .stroke(Some(Color::Black)) .fill(Some(Color::White)) - .translate(Coord::new(5, 50)) + .translate(Point::new(5, 50)) .into_iter(), ); @@ -118,17 +118,17 @@ fn run() -> Result<(), std::io::Error> { // draw a analog clock display.draw( - Circle::new(Coord::new(64, 64), 64) + Circle::new(Point::new(64, 64), 64) .stroke(Some(Color::Black)) .into_iter(), ); display.draw( - Line::new(Coord::new(64, 64), Coord::new(0, 64)) + let _ = Line::new(Point::new(64, 64), Point::new(0, 64)) .stroke(Some(Color::Black)) .into_iter(), ); display.draw( - Line::new(Coord::new(64, 64), Coord::new(80, 80)) + let _ = Line::new(Point::new(64, 64), Point::new(80, 80)) .stroke(Some(Color::Black)) .into_iter(), ); @@ -142,7 +142,7 @@ fn run() -> Result<(), std::io::Error> { stroke_color: Some(Color::White), stroke_width: 0u8, // Has no effect on fonts }) - .translate(Coord::new(175, 250)) + .translate(Point::new(175, 250)) .into_iter(), ); @@ -155,7 +155,7 @@ fn run() -> Result<(), std::io::Error> { stroke_color: Some(Color::Black), stroke_width: 0u8, // Has no effect on fonts }) - .translate(Coord::new(50, 200)) + .translate(Point::new(50, 200)) .into_iter(), ); @@ -171,7 +171,7 @@ fn run() -> Result<(), std::io::Error> { stroke_color: Some(Color::Black), stroke_width: 0u8, // Has no effect on fonts }) - .translate(Coord::new(5 + i * 12, 50)) + .translate(Point::new(5 + i * 12, 50)) .into_iter(), ); diff --git a/examples/epd7in5_v2_full/src/main.rs b/examples/epd7in5_v2_full/src/main.rs index e7381f1..1f0dc00 100644 --- a/examples/epd7in5_v2_full/src/main.rs +++ b/examples/epd7in5_v2_full/src/main.rs @@ -1,11 +1,11 @@ #![deny(warnings)] use embedded_graphics::{ - coord::Coord, fonts::{Font12x16, Font6x8}, prelude::*, primitives::{Circle, Line}, Drawing, + Point::Point, }; use embedded_hal::prelude::*; use epd_waveshare::{ @@ -76,7 +76,7 @@ fn run() -> Result<(), std::io::Error> { Font6x8::render_str("Rotate 0!") .stroke(Some(Color::Black)) .fill(Some(Color::White)) - .translate(Coord::new(5, 50)) + .translate(Point::new(5, 50)) .into_iter(), ); @@ -85,7 +85,7 @@ fn run() -> Result<(), std::io::Error> { Font6x8::render_str("Rotate 90!") .stroke(Some(Color::Black)) .fill(Some(Color::White)) - .translate(Coord::new(5, 50)) + .translate(Point::new(5, 50)) .into_iter(), ); @@ -94,7 +94,7 @@ fn run() -> Result<(), std::io::Error> { Font6x8::render_str("Rotate 180!") .stroke(Some(Color::Black)) .fill(Some(Color::White)) - .translate(Coord::new(5, 50)) + .translate(Point::new(5, 50)) .into_iter(), ); @@ -103,7 +103,7 @@ fn run() -> Result<(), std::io::Error> { Font6x8::render_str("Rotate 270!") .stroke(Some(Color::Black)) .fill(Some(Color::White)) - .translate(Coord::new(5, 50)) + .translate(Point::new(5, 50)) .into_iter(), ); @@ -118,17 +118,17 @@ fn run() -> Result<(), std::io::Error> { // draw a analog clock display.draw( - Circle::new(Coord::new(64, 64), 64) + Circle::new(Point::new(64, 64), 64) .stroke(Some(Color::Black)) .into_iter(), ); display.draw( - Line::new(Coord::new(64, 64), Coord::new(0, 64)) + Line::new(Point::new(64, 64), Point::new(0, 64)) .stroke(Some(Color::Black)) .into_iter(), ); display.draw( - Line::new(Coord::new(64, 64), Coord::new(80, 80)) + Line::new(Point::new(64, 64), Point::new(80, 80)) .stroke(Some(Color::Black)) .into_iter(), ); @@ -142,7 +142,7 @@ fn run() -> Result<(), std::io::Error> { stroke_color: Some(Color::White), stroke_width: 0u8, // Has no effect on fonts }) - .translate(Coord::new(175, 250)) + .translate(Point::new(175, 250)) .into_iter(), ); @@ -155,7 +155,7 @@ fn run() -> Result<(), std::io::Error> { stroke_color: Some(Color::Black), stroke_width: 0u8, // Has no effect on fonts }) - .translate(Coord::new(50, 200)) + .translate(Point::new(50, 200)) .into_iter(), ); @@ -171,7 +171,7 @@ fn run() -> Result<(), std::io::Error> { stroke_color: Some(Color::Black), stroke_width: 0u8, // Has no effect on fonts }) - .translate(Coord::new(5 + i * 12, 50)) + .translate(Point::new(5 + i * 12, 50)) .into_iter(), ); diff --git a/src/color.rs b/src/color.rs index e9223de..b6ca8fc 100644 --- a/src/color.rs +++ b/src/color.rs @@ -1,5 +1,9 @@ //! B/W Color for EPDs +use embedded_graphics::pixelcolor::BinaryColor; + +pub use BinaryColor::Off as White; +pub use BinaryColor::On as Black; /// Only for the Black/White-Displays #[derive(Clone, Copy, PartialEq, Debug)] pub enum Color { @@ -51,11 +55,6 @@ impl Color { } } -#[cfg(feature = "graphics")] -use embedded_graphics::prelude::*; -#[cfg(feature = "graphics")] -impl PixelColor for Color {} - impl From for Color { fn from(value: u8) -> Self { Color::from_u8(value) diff --git a/src/epd1in54/graphics.rs b/src/epd1in54/graphics.rs index b63c460..2cdc1d2 100644 --- a/src/epd1in54/graphics.rs +++ b/src/epd1in54/graphics.rs @@ -1,6 +1,6 @@ use crate::epd1in54::{DEFAULT_BACKGROUND_COLOR, HEIGHT, WIDTH}; use crate::graphics::{Display, DisplayRotation}; -use crate::prelude::*; +use embedded_graphics::pixelcolor::BinaryColor; use embedded_graphics::prelude::*; /// Full size buffer for use with the 1in54 EPD @@ -22,12 +22,15 @@ impl Default for Display1in54 { } } -impl Drawing for Display1in54 { - fn draw(&mut self, item_pixels: T) - where - T: IntoIterator>, - { - self.draw_helper(WIDTH, HEIGHT, item_pixels); +impl DrawTarget for Display1in54 { + type Error = core::convert::Infallible; + + fn draw_pixel(&mut self, pixel: Pixel) -> Result<(), Self::Error> { + self.draw_helper(WIDTH, HEIGHT, pixel) + } + + fn size(&self) -> Size { + Size::new(WIDTH, HEIGHT) } } @@ -52,10 +55,9 @@ impl Display for Display1in54 { #[cfg(test)] mod tests { use super::*; - use crate::color::Color; + use crate::color::{Black, Color}; use crate::graphics::{Display, DisplayRotation}; - use embedded_graphics::coord::Coord; - use embedded_graphics::primitives::Line; + use embedded_graphics::{primitives::Line, style::PrimitiveStyle}; // test buffer length #[test] @@ -76,11 +78,9 @@ mod tests { #[test] fn graphics_rotation_0() { let mut display = Display1in54::default(); - display.draw( - Line::new(Coord::new(0, 0), Coord::new(7, 0)) - .stroke(Some(Color::Black)) - .into_iter(), - ); + let _ = Line::new(Point::new(0, 0), Point::new(7, 0)) + .into_styled(PrimitiveStyle::with_stroke(Black, 1)) + .draw(&mut display); let buffer = display.buffer(); @@ -95,11 +95,9 @@ mod tests { fn graphics_rotation_90() { let mut display = Display1in54::default(); display.set_rotation(DisplayRotation::Rotate90); - display.draw( - Line::new(Coord::new(0, 192), Coord::new(0, 199)) - .stroke(Some(Color::Black)) - .into_iter(), - ); + let _ = Line::new(Point::new(0, 192), Point::new(0, 199)) + .into_styled(PrimitiveStyle::with_stroke(Black, 1)) + .draw(&mut display); let buffer = display.buffer(); @@ -114,11 +112,9 @@ mod tests { fn graphics_rotation_180() { let mut display = Display1in54::default(); display.set_rotation(DisplayRotation::Rotate180); - display.draw( - Line::new(Coord::new(192, 199), Coord::new(199, 199)) - .stroke(Some(Color::Black)) - .into_iter(), - ); + let _ = Line::new(Point::new(192, 199), Point::new(199, 199)) + .into_styled(PrimitiveStyle::with_stroke(Black, 1)) + .draw(&mut display); let buffer = display.buffer(); @@ -136,11 +132,9 @@ mod tests { fn graphics_rotation_270() { let mut display = Display1in54::default(); display.set_rotation(DisplayRotation::Rotate270); - display.draw( - Line::new(Coord::new(199, 0), Coord::new(199, 7)) - .stroke(Some(Color::Black)) - .into_iter(), - ); + let _ = Line::new(Point::new(199, 0), Point::new(199, 7)) + .into_styled(PrimitiveStyle::with_stroke(Black, 1)) + .draw(&mut display); let buffer = display.buffer(); diff --git a/src/epd1in54/mod.rs b/src/epd1in54/mod.rs index e66f032..8078676 100644 --- a/src/epd1in54/mod.rs +++ b/src/epd1in54/mod.rs @@ -21,7 +21,7 @@ //! Font6x8::render_str("Hello World!") //! .stroke(Some(Color::Black)) //! .fill(Some(Color::White)) -//! .translate(Coord::new(5, 50)) +//! .translate(Point::new(5, 50)) //! .into_iter(), //! ); //! diff --git a/src/epd1in54b/graphics.rs b/src/epd1in54b/graphics.rs index 536ba6a..a1e83e1 100644 --- a/src/epd1in54b/graphics.rs +++ b/src/epd1in54b/graphics.rs @@ -1,6 +1,6 @@ use crate::epd1in54b::{DEFAULT_BACKGROUND_COLOR, HEIGHT, WIDTH}; use crate::graphics::{Display, DisplayRotation}; -use crate::prelude::*; +use embedded_graphics::pixelcolor::BinaryColor; use embedded_graphics::prelude::*; pub struct Display1in54b { @@ -18,12 +18,15 @@ impl Default for Display1in54b { } } -impl Drawing for Display1in54b { - fn draw(&mut self, item_pixels: T) - where - T: IntoIterator>, - { - self.draw_helper(WIDTH, HEIGHT, item_pixels); +impl DrawTarget for Display1in54b { + type Error = core::convert::Infallible; + + fn draw_pixel(&mut self, pixel: Pixel) -> Result<(), Self::Error> { + self.draw_helper(WIDTH, HEIGHT, pixel) + } + + fn size(&self) -> Size { + Size::new(WIDTH, HEIGHT) } } diff --git a/src/epd2in9/graphics.rs b/src/epd2in9/graphics.rs index d9b723c..fb1154e 100644 --- a/src/epd2in9/graphics.rs +++ b/src/epd2in9/graphics.rs @@ -1,6 +1,6 @@ use crate::epd2in9::{DEFAULT_BACKGROUND_COLOR, HEIGHT, WIDTH}; use crate::graphics::{Display, DisplayRotation}; -use crate::prelude::*; +use embedded_graphics::pixelcolor::BinaryColor; use embedded_graphics::prelude::*; /// Display with Fullsize buffer for use with the 2in9 EPD @@ -22,12 +22,15 @@ impl Default for Display2in9 { } } -impl Drawing for Display2in9 { - fn draw(&mut self, item_pixels: T) - where - T: IntoIterator>, - { - self.draw_helper(WIDTH, HEIGHT, item_pixels); +impl DrawTarget for Display2in9 { + type Error = core::convert::Infallible; + + fn draw_pixel(&mut self, pixel: Pixel) -> Result<(), Self::Error> { + self.draw_helper(WIDTH, HEIGHT, pixel) + } + + fn size(&self) -> Size { + Size::new(WIDTH, HEIGHT) } } diff --git a/src/epd2in9/mod.rs b/src/epd2in9/mod.rs index 2e2665f..3bd61db 100644 --- a/src/epd2in9/mod.rs +++ b/src/epd2in9/mod.rs @@ -23,7 +23,7 @@ //! Font6x8::render_str("Hello World!") //! .stroke(Some(Color::Black)) //! .fill(Some(Color::White)) -//! .translate(Coord::new(5, 50)) +//! .translate(Point::new(5, 50)) //! .into_iter(), //! ); //! diff --git a/src/epd4in2/graphics.rs b/src/epd4in2/graphics.rs index 41332ab..101501e 100644 --- a/src/epd4in2/graphics.rs +++ b/src/epd4in2/graphics.rs @@ -1,6 +1,6 @@ use crate::epd4in2::{DEFAULT_BACKGROUND_COLOR, HEIGHT, WIDTH}; use crate::graphics::{Display, DisplayRotation}; -use crate::prelude::*; +use embedded_graphics::pixelcolor::BinaryColor; use embedded_graphics::prelude::*; /// Full size buffer for use with the 4in2 EPD @@ -22,12 +22,15 @@ impl Default for Display4in2 { } } -impl Drawing for Display4in2 { - fn draw(&mut self, item_pixels: T) - where - T: IntoIterator>, - { - self.draw_helper(WIDTH, HEIGHT, item_pixels); +impl DrawTarget for Display4in2 { + type Error = core::convert::Infallible; + + fn draw_pixel(&mut self, pixel: Pixel) -> Result<(), Self::Error> { + self.draw_helper(WIDTH, HEIGHT, pixel) + } + + fn size(&self) -> Size { + Size::new(WIDTH, HEIGHT) } } @@ -52,11 +55,11 @@ impl Display for Display4in2 { #[cfg(test)] mod tests { use super::*; + use crate::color::Black; use crate::color::Color; use crate::epd4in2; use crate::graphics::{Display, DisplayRotation}; - use embedded_graphics::coord::Coord; - use embedded_graphics::primitives::Line; + use embedded_graphics::{primitives::Line, style::PrimitiveStyle}; // test buffer length #[test] @@ -77,11 +80,9 @@ mod tests { #[test] fn graphics_rotation_0() { let mut display = Display4in2::default(); - display.draw( - Line::new(Coord::new(0, 0), Coord::new(7, 0)) - .stroke(Some(Color::Black)) - .into_iter(), - ); + let _ = Line::new(Point::new(0, 0), Point::new(7, 0)) + .into_styled(PrimitiveStyle::with_stroke(Black, 1)) + .draw(&mut display); let buffer = display.buffer(); @@ -96,11 +97,9 @@ mod tests { fn graphics_rotation_90() { let mut display = Display4in2::default(); display.set_rotation(DisplayRotation::Rotate90); - display.draw( - Line::new(Coord::new(0, 392), Coord::new(0, 399)) - .stroke(Some(Color::Black)) - .into_iter(), - ); + let _ = Line::new(Point::new(0, 392), Point::new(0, 399)) + .into_styled(PrimitiveStyle::with_stroke(Black, 1)) + .draw(&mut display); let buffer = display.buffer(); @@ -115,11 +114,10 @@ mod tests { fn graphics_rotation_180() { let mut display = Display4in2::default(); display.set_rotation(DisplayRotation::Rotate180); - display.draw( - Line::new(Coord::new(392, 299), Coord::new(399, 299)) - .stroke(Some(Color::Black)) - .into_iter(), - ); + + let _ = Line::new(Point::new(392, 299), Point::new(399, 299)) + .into_styled(PrimitiveStyle::with_stroke(Black, 1)) + .draw(&mut display); let buffer = display.buffer(); @@ -137,11 +135,9 @@ mod tests { fn graphics_rotation_270() { let mut display = Display4in2::default(); display.set_rotation(DisplayRotation::Rotate270); - display.draw( - Line::new(Coord::new(299, 0), Coord::new(299, 7)) - .stroke(Some(Color::Black)) - .into_iter(), - ); + let _ = Line::new(Point::new(299, 0), Point::new(299, 7)) + .into_styled(PrimitiveStyle::with_stroke(Black, 1)) + .draw(&mut display); let buffer = display.buffer(); diff --git a/src/epd7in5/graphics.rs b/src/epd7in5/graphics.rs index c7c20dd..62d1563 100644 --- a/src/epd7in5/graphics.rs +++ b/src/epd7in5/graphics.rs @@ -1,6 +1,6 @@ use crate::epd7in5::{DEFAULT_BACKGROUND_COLOR, HEIGHT, WIDTH}; use crate::graphics::{Display, DisplayRotation}; -use crate::prelude::*; +use embedded_graphics::pixelcolor::BinaryColor; use embedded_graphics::prelude::*; /// Full size buffer for use with the 7in5 EPD @@ -22,12 +22,15 @@ impl Default for Display7in5 { } } -impl Drawing for Display7in5 { - fn draw(&mut self, item_pixels: T) - where - T: IntoIterator>, - { - self.draw_helper(WIDTH, HEIGHT, item_pixels); +impl DrawTarget for Display7in5 { + type Error = core::convert::Infallible; + + fn draw_pixel(&mut self, pixel: Pixel) -> Result<(), Self::Error> { + self.draw_helper(WIDTH, HEIGHT, pixel) + } + + fn size(&self) -> Size { + Size::new(WIDTH, HEIGHT) } } @@ -52,11 +55,11 @@ impl Display for Display7in5 { #[cfg(test)] mod tests { use super::*; + use crate::color::Black; use crate::color::Color; use crate::epd7in5; use crate::graphics::{Display, DisplayRotation}; - use embedded_graphics::coord::Coord; - use embedded_graphics::primitives::Line; + use embedded_graphics::{primitives::Line, style::PrimitiveStyle}; // test buffer length #[test] @@ -77,11 +80,9 @@ mod tests { #[test] fn graphics_rotation_0() { let mut display = Display7in5::default(); - display.draw( - Line::new(Coord::new(0, 0), Coord::new(7, 0)) - .stroke(Some(Color::Black)) - .into_iter(), - ); + let _ = Line::new(Point::new(0, 0), Point::new(7, 0)) + .into_styled(PrimitiveStyle::with_stroke(Black, 1)) + .draw(&mut display); let buffer = display.buffer(); @@ -96,11 +97,9 @@ mod tests { fn graphics_rotation_90() { let mut display = Display7in5::default(); display.set_rotation(DisplayRotation::Rotate90); - display.draw( - Line::new(Coord::new(0, 632), Coord::new(0, 639)) - .stroke(Some(Color::Black)) - .into_iter(), - ); + let _ = Line::new(Point::new(0, 632), Point::new(0, 639)) + .into_styled(PrimitiveStyle::with_stroke(Black, 1)) + .draw(&mut display); let buffer = display.buffer(); @@ -115,11 +114,9 @@ mod tests { fn graphics_rotation_180() { let mut display = Display7in5::default(); display.set_rotation(DisplayRotation::Rotate180); - display.draw( - Line::new(Coord::new(632, 383), Coord::new(639, 383)) - .stroke(Some(Color::Black)) - .into_iter(), - ); + let _ = Line::new(Point::new(632, 383), Point::new(639, 383)) + .into_styled(PrimitiveStyle::with_stroke(Black, 1)) + .draw(&mut display); let buffer = display.buffer(); @@ -134,11 +131,9 @@ mod tests { fn graphics_rotation_270() { let mut display = Display7in5::default(); display.set_rotation(DisplayRotation::Rotate270); - display.draw( - Line::new(Coord::new(383, 0), Coord::new(383, 7)) - .stroke(Some(Color::Black)) - .into_iter(), - ); + let _ = Line::new(Point::new(383, 0), Point::new(383, 7)) + .into_styled(PrimitiveStyle::with_stroke(Black, 1)) + .draw(&mut display); let buffer = display.buffer(); diff --git a/src/epd7in5_v2/graphics.rs b/src/epd7in5_v2/graphics.rs index aa6f464..8c3211f 100644 --- a/src/epd7in5_v2/graphics.rs +++ b/src/epd7in5_v2/graphics.rs @@ -1,6 +1,6 @@ use crate::epd7in5_v2::{DEFAULT_BACKGROUND_COLOR, HEIGHT, WIDTH}; use crate::graphics::{Display, DisplayRotation}; -use crate::prelude::*; +use embedded_graphics::pixelcolor::BinaryColor; use embedded_graphics::prelude::*; /// Full size buffer for use with the 7in5 EPD @@ -22,12 +22,15 @@ impl Default for Display7in5 { } } -impl Drawing for Display7in5 { - fn draw(&mut self, item_pixels: T) - where - T: IntoIterator>, - { - self.draw_helper(WIDTH, HEIGHT, item_pixels); +impl DrawTarget for Display7in5 { + type Error = core::convert::Infallible; + + fn draw_pixel(&mut self, pixel: Pixel) -> Result<(), Self::Error> { + self.draw_helper(WIDTH, HEIGHT, pixel) + } + + fn size(&self) -> Size { + Size::new(WIDTH, HEIGHT) } } @@ -52,11 +55,10 @@ impl Display for Display7in5 { #[cfg(test)] mod tests { use super::*; - use crate::color::Color; + use crate::color::{Black, Color}; use crate::epd7in5_v2; use crate::graphics::{Display, DisplayRotation}; - use embedded_graphics::coord::Coord; - use embedded_graphics::primitives::Line; + use embedded_graphics::{primitives::Line, style::PrimitiveStyle}; // test buffer length #[test] @@ -77,11 +79,10 @@ mod tests { #[test] fn graphics_rotation_0() { let mut display = Display7in5::default(); - display.draw( - Line::new(Coord::new(0, 0), Coord::new(7, 0)) - .stroke(Some(Color::Black)) - .into_iter(), - ); + + let _ = Line::new(Point::new(0, 0), Point::new(7, 0)) + .into_styled(PrimitiveStyle::with_stroke(Black, 1)) + .draw(&mut display); let buffer = display.buffer(); @@ -96,11 +97,10 @@ mod tests { fn graphics_rotation_90() { let mut display = Display7in5::default(); display.set_rotation(DisplayRotation::Rotate90); - display.draw( - Line::new(Coord::new(0, 792), Coord::new(0, 799)) - .stroke(Some(Color::Black)) - .into_iter(), - ); + + let _ = Line::new(Point::new(0, 792), Point::new(0, 799)) + .into_styled(PrimitiveStyle::with_stroke(Black, 1)) + .draw(&mut display); let buffer = display.buffer(); @@ -115,11 +115,10 @@ mod tests { fn graphics_rotation_180() { let mut display = Display7in5::default(); display.set_rotation(DisplayRotation::Rotate180); - display.draw( - Line::new(Coord::new(792, 479), Coord::new(799, 479)) - .stroke(Some(Color::Black)) - .into_iter(), - ); + + let _ = Line::new(Point::new(792, 479), Point::new(799, 479)) + .into_styled(PrimitiveStyle::with_stroke(Black, 1)) + .draw(&mut display); let buffer = display.buffer(); @@ -134,11 +133,10 @@ mod tests { fn graphics_rotation_270() { let mut display = Display7in5::default(); display.set_rotation(DisplayRotation::Rotate270); - display.draw( - Line::new(Coord::new(479, 0), Coord::new(479, 7)) - .stroke(Some(Color::Black)) - .into_iter(), - ); + + let _ = Line::new(Point::new(479, 0), Point::new(479, 7)) + .into_styled(PrimitiveStyle::with_stroke(Black, 1)) + .draw(&mut display); let buffer = display.buffer(); diff --git a/src/graphics.rs b/src/graphics.rs index d01ecb7..49758d3 100644 --- a/src/graphics.rs +++ b/src/graphics.rs @@ -1,7 +1,7 @@ //! Graphics Support for EPDs use crate::color::Color; -use embedded_graphics::prelude::*; +use embedded_graphics::{pixelcolor::BinaryColor, prelude::*}; /// Displayrotation #[derive(Clone, Copy)] @@ -22,7 +22,7 @@ impl Default for DisplayRotation { } } -pub trait Display: Drawing { +pub trait Display: DrawTarget { /// Clears the buffer of the display with the chosen background color fn clear_buffer(&mut self, background_color: Color) { for elem in self.get_mut_buffer().iter_mut() { @@ -45,31 +45,36 @@ pub trait Display: Drawing { /// Helperfunction for the Embedded Graphics draw trait /// /// Becomes uneccesary when const_generics become stablised - fn draw_helper(&mut self, width: u32, height: u32, item_pixels: T) - where - T: IntoIterator>, - { + fn draw_helper( + &mut self, + width: u32, + height: u32, + pixel: Pixel, + ) -> Result<(), Self::Error> { let rotation = self.rotation(); let buffer = self.get_mut_buffer(); - for Pixel(UnsignedCoord(x, y), color) in item_pixels { - if outside_display(x, y, width, height, rotation) { - continue; - } - // Give us index inside the buffer and the bit-position in that u8 which needs to be changed - let (index, bit) = find_position(x, y, width, height, rotation); - let index = index as usize; + let Pixel(point, color) = pixel; + if outside_display(point, width, height, rotation) { + return Ok(()); + } - // "Draw" the Pixel on that bit - match color { - Color::Black => { - buffer[index] &= !bit; - } - Color::White => { - buffer[index] |= bit; - } + // Give us index inside the buffer and the bit-position in that u8 which needs to be changed + let (index, bit) = find_position(point.x as u32, point.y as u32, width, height, rotation); + let index = index as usize; + + // "Draw" the Pixel on that bit + match color { + // Black + BinaryColor::On => { + buffer[index] &= !bit; + } + // White + BinaryColor::Off => { + buffer[index] |= bit; } } + Ok(()) } } @@ -83,8 +88,10 @@ pub trait Display: Drawing { /// # use epd_waveshare::epd2in9::DEFAULT_BACKGROUND_COLOR; /// # use epd_waveshare::prelude::*; /// # use epd_waveshare::graphics::VarDisplay; +/// # use epd_waveshare::color::Black; /// # use embedded_graphics::prelude::*; /// # use embedded_graphics::primitives::{Circle, Line}; +/// # use embedded_graphics::style::PrimitiveStyle; /// let width = 128; /// let height = 296; /// @@ -93,11 +100,9 @@ pub trait Display: Drawing { /// /// display.set_rotation(DisplayRotation::Rotate90); /// -/// display.draw( -/// Line::new(Coord::new(0, 120), Coord::new(0, 295)) -/// .stroke(Some(Color::Black)) -/// .into_iter(), -/// ); +/// let _ = Line::new(Point::new(0, 120), Point::new(0, 295)) +/// .into_styled(PrimitiveStyle::with_stroke(Black, 1)) +/// .draw(&mut display); /// ``` pub struct VarDisplay<'a> { width: u32, @@ -119,12 +124,15 @@ impl<'a> VarDisplay<'a> { } } -impl<'a> Drawing for VarDisplay<'a> { - fn draw(&mut self, item_pixels: T) - where - T: IntoIterator>, - { - self.draw_helper(self.width, self.height, item_pixels); +impl<'a> DrawTarget for VarDisplay<'a> { + type Error = core::convert::Infallible; + + fn draw_pixel(&mut self, pixel: Pixel) -> Result<(), Self::Error> { + self.draw_helper(self.width, self.height, pixel) + } + + fn size(&self) -> Size { + Size::new(self.width, self.height) } } @@ -147,7 +155,11 @@ impl<'a> Display for VarDisplay<'a> { } // Checks if a pos is outside the defined display -fn outside_display(x: u32, y: u32, width: u32, height: u32, rotation: DisplayRotation) -> bool { +fn outside_display(p: Point, width: u32, height: u32, rotation: DisplayRotation) -> bool { + if p.x < 0 || p.y < 0 { + return true; + } + let (x, y) = (p.x as u32, p.y as u32); match rotation { DisplayRotation::Rotate0 | DisplayRotation::Rotate180 => { if x >= width || y >= height { @@ -189,10 +201,9 @@ fn find_position(x: u32, y: u32, width: u32, height: u32, rotation: DisplayRotat #[cfg(test)] mod tests { use super::{find_position, outside_display, Display, DisplayRotation, VarDisplay}; + use crate::color::Black; use crate::color::Color; - use embedded_graphics::coord::Coord; - use embedded_graphics::prelude::*; - use embedded_graphics::primitives::Line; + use embedded_graphics::{prelude::*, primitives::Line, style::PrimitiveStyle}; #[test] fn buffer_clear() { @@ -228,7 +239,7 @@ mod tests { for x in 0..(width + height) { //limit x because it runs too long for y in 0..(u32::max_value()) { - if outside_display(x, y, width, height, rotation2) { + if outside_display(Point::new(x as i32, y as i32), width, height, rotation2) { break; } else { let (idx, _) = find_position(x, y, width, height, rotation2); @@ -247,11 +258,9 @@ mod tests { let mut buffer = [DEFAULT_BACKGROUND_COLOR.get_byte_value(); 128 / 8 * 296]; let mut display = VarDisplay::new(width, height, &mut buffer); - display.draw( - Line::new(Coord::new(0, 0), Coord::new(7, 0)) - .stroke(Some(Color::Black)) - .into_iter(), - ); + let _ = Line::new(Point::new(0, 0), Point::new(7, 0)) + .into_styled(PrimitiveStyle::with_stroke(Black, 1)) + .draw(&mut display); let buffer = display.buffer(); @@ -273,11 +282,9 @@ mod tests { display.set_rotation(DisplayRotation::Rotate90); - display.draw( - Line::new(Coord::new(0, 120), Coord::new(0, 295)) - .stroke(Some(Color::Black)) - .into_iter(), - ); + let _ = Line::new(Point::new(0, 120), Point::new(0, 295)) + .into_styled(PrimitiveStyle::with_stroke(Black, 1)) + .draw(&mut display); let buffer = display.buffer(); diff --git a/src/lib.rs b/src/lib.rs index 00e8183..7f31513 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -39,7 +39,7 @@ //! Font6x8::render_str("Hello World!") //! .stroke(Some(Color::Black)) //! .fill(Some(Color::White)) -//! .translate(Coord::new(5, 50)) +//! .translate(Point::new(5, 50)) //! .into_iter(), //! ); //! From 8da294dd5e24adc3f2e43597e6a3ba0053e169e8 Mon Sep 17 00:00:00 2001 From: Caemor <11088935+caemor@users.noreply.github.com> Date: Sat, 21 Mar 2020 23:37:27 +0100 Subject: [PATCH 02/15] Update embedded-graphics, remove useless Featuregates (Doesn't change size) Update and integrate a few important examples and remove the others --- .github/workflows/rust.yml | 35 ++++ .travis.yml | 22 +- Cargo.toml | 28 +-- examples/Readme.md | 47 ----- examples/epd1in54_full/Cargo.toml | 13 -- examples/epd1in54_full/src/main.rs | 150 -------------- .../src/main.rs => epd1in54_no_graphics.rs} | 10 +- examples/epd1in54_no_graphics/Cargo.toml | 12 -- examples/epd2in9_full/Cargo.toml | 13 -- examples/epd2in9_full/src/main.rs | 154 -------------- .../src/main.rs => epd4in2.rs} | 128 ++++++------ examples/epd4in2_full/Cargo.toml | 15 -- examples/epd4in2_full/src/main.rs | 189 ------------------ examples/epd4in2_full_blue_pill/.cargo/config | 12 -- examples/epd4in2_full_blue_pill/Cargo.toml | 19 -- examples/epd4in2_full_blue_pill/memory.x | 6 - examples/epd4in2_full_blue_pill/openocd.cfg | 2 - examples/epd4in2_full_blue_pill/openocd.gdb | 10 - .../epd4in2_var_display_buffer/Cargo.toml | 15 -- .../src/main.rs => epd4in2_variable_size.rs} | 139 +++++-------- examples/epd7in5_full/Cargo.toml | 14 -- examples/epd7in5_full/src/main.rs | 188 ----------------- examples/epd7in5_v2_full/Cargo.toml | 15 -- examples/epd7in5_v2_full/src/main.rs | 188 ----------------- src/color.rs | 4 + src/epd1in54/mod.rs | 12 +- src/lib.rs | 19 +- 27 files changed, 172 insertions(+), 1287 deletions(-) create mode 100644 .github/workflows/rust.yml delete mode 100644 examples/Readme.md delete mode 100644 examples/epd1in54_full/Cargo.toml delete mode 100644 examples/epd1in54_full/src/main.rs rename examples/{epd1in54_no_graphics/src/main.rs => epd1in54_no_graphics.rs} (94%) delete mode 100644 examples/epd1in54_no_graphics/Cargo.toml delete mode 100644 examples/epd2in9_full/Cargo.toml delete mode 100644 examples/epd2in9_full/src/main.rs rename examples/{epd4in2_full_blue_pill/src/main.rs => epd4in2.rs} (54%) delete mode 100644 examples/epd4in2_full/Cargo.toml delete mode 100644 examples/epd4in2_full/src/main.rs delete mode 100644 examples/epd4in2_full_blue_pill/.cargo/config delete mode 100644 examples/epd4in2_full_blue_pill/Cargo.toml delete mode 100644 examples/epd4in2_full_blue_pill/memory.x delete mode 100644 examples/epd4in2_full_blue_pill/openocd.cfg delete mode 100644 examples/epd4in2_full_blue_pill/openocd.gdb delete mode 100644 examples/epd4in2_var_display_buffer/Cargo.toml rename examples/{epd4in2_var_display_buffer/src/main.rs => epd4in2_variable_size.rs} (54%) delete mode 100644 examples/epd7in5_full/Cargo.toml delete mode 100644 examples/epd7in5_full/src/main.rs delete mode 100644 examples/epd7in5_v2_full/Cargo.toml delete mode 100644 examples/epd7in5_v2_full/src/main.rs diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml new file mode 100644 index 0000000..923e565 --- /dev/null +++ b/.github/workflows/rust.yml @@ -0,0 +1,35 @@ + +name: Rust + +on: + push: + branches: + - master + pull_request: + branches: + - master + +jobs: + build: + + runs-on: ubuntu-latest + strategy: + matrix: + rust: + - stable + - beta + steps: + - uses: actions/checkout@v1 + - name: Install ARM toolchain + run: rustup target add thumbv7em-none-eabihf + - name: Check Fmt + run: cargo fmt --all -- --check + - name: Build lib + run: cargo check --verbose + - name: Clippy + run: cargo clippy --all-targets --all-features -- -D warnings -A clippy::new_ret_no_self + - name: Build examples + run: cargo build --examples --verbose + #- name: Run tests + # run: cargo test --verbose + diff --git a/.travis.yml b/.travis.yml index 31e2682..f8d2824 100644 --- a/.travis.yml +++ b/.travis.yml @@ -53,12 +53,9 @@ matrix: script: - cargo fmt --all -- --check - cargo doc --all-features --release - - cd examples/epd4in2_full && cargo fmt --all -- --check && cd ../../ - - cd examples/epd2in9_full && cargo fmt --all -- --check && cd ../../ - - cd examples/epd1in54_full && cargo fmt --all -- --check && cd ../../ - - cd examples/epd1in54_no_graphics && cargo fmt --all -- --check && cd ../../ - - cd examples/epd4in2_var_display_buffer && cargo fmt --all -- --check && cd ../../ - - cd examples/epd4in2_full_blue_pill && cargo fmt --all -- --check && cd ../../ + - name: "check" + script: + - cargo check --examples --all-features - name: "clippy" rust: stable env: RUN=FMT @@ -66,19 +63,6 @@ matrix: - rustup component add clippy script: - cargo clippy --all-targets --all-features -- -D warnings -A clippy::new_ret_no_self - - - name: "check examples" - rust: stable - before_script: - - rustup target add thumbv7m-none-eabi - script: - - cd examples/epd4in2_full_blue_pill && cargo check && cd ../../ - - cd examples/epd4in2_full && cargo check && cd ../../ - - cd examples/epd2in9_full && cargo check && cd ../../ - - cd examples/epd1in54_full && cargo check && cd ../../ - - cd examples/epd1in54_no_graphics && cargo check && cd ../../ - - cd examples/epd4in2_var_display_buffer && cargo check && cd ../../ - - name before_install: - set -e diff --git a/Cargo.toml b/Cargo.toml index 9cac8b4..abd2aef 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,28 +13,20 @@ version = "0.3.2" edition = "2018" [badges] -# Travis CI: `repository` in format "/" is required. -# `branch` is optional; default is `master` -travis-ci = { repository = "caemor/epd-waveshare" } +# travis-ci = { repository = "caemor/epd-waveshare" } [dependencies] -embedded-graphics = { version = "0.6.0-beta.2", optional = true} +embedded-graphics = { version = "0.6.0", optional = true} +embedded-hal = {version = "0.2.3", features = ["unproven"]} + +[dev-dependencies] +linux-embedded-hal = "0.3" +embedded-hal-mock = "0.7" [features] -default = ["epd1in54", "epd1in54b", "epd2in9", "epd4in2", "epd7in5", "epd7in5_v2", "graphics"] +default = ["graphics"] graphics = ["embedded-graphics"] -epd1in54 = [] -epd1in54b = [] -epd2in9 = [] -epd4in2 = [] -epd7in5 = [] -epd7in5_v2 = [] -# offers an alternative fast full lut for type_a displays, but the refresh isnt as clean looking -type_a_alternative_faster_lut = [] - - -[dependencies.embedded-hal] -features = ["unproven"] -version = "0.2.3" +# Offers an alternative fast full lut for type_a displays, but the refreshed screen isnt as clean looking +type_a_alternative_faster_lut = [] diff --git a/examples/Readme.md b/examples/Readme.md deleted file mode 100644 index a1c8bc9..0000000 --- a/examples/Readme.md +++ /dev/null @@ -1,47 +0,0 @@ -# Examples: - -All of these examples are projects of their own. - -A few notes: - - If not stated otherwise the example is for a Raspberry Pi running Linux. - - epdXinYY_full showcase most of what can be done with this crate. This means that they are using graphics feature and use the DisplayXinYY with its buffer. - -Special Examples: - -### epd4in2_var_display_buffer - -This examples used the graphics feature with VarDisplay and therefore a variable buffer(size). - -### epd1in54_no_graphics (Fastest Example) - -This example doesn't use the graphics feature and handles all the "drawing" by itself. It also has a speeddemonstration included. - -### epd4in2_full_blue_pill - -Connect epd4in2 display to blue pill board: -- BUSY -> A10 -- RST -> A9 -- DC -> A8 -- CS -> B12 -- CLK -> B13 -- DIN -> B15 -- GND -> G -- VCC -> 3.3 - -For compiling and flashing, please refer to [TeXitois blue pill quickstart](https://github.com/TeXitoi/blue-pill-quickstart/blob/master/README.md). - -Basically: - -```shell -curl https://sh.rustup.rs -sSf | sh -rustup target add thumbv7m-none-eabi -sudo apt-get install gdb-arm-none-eabi openocd -cd epd4in2_full_blue_pill -# connect ST-Link v2 to the blue pill and the computer -# openocd in another terminal -cargo run --release -``` - -Ff you can't connect to openocd you might need to adapt your udev rules or use sudo ([openOCD Problems](https://rust-embedded.github.io/discovery/03-setup/linux.html#udev-rules)) - - diff --git a/examples/epd1in54_full/Cargo.toml b/examples/epd1in54_full/Cargo.toml deleted file mode 100644 index d900b46..0000000 --- a/examples/epd1in54_full/Cargo.toml +++ /dev/null @@ -1,13 +0,0 @@ -[package] -name = "embedded_linux_eink_example" -version = "0.1.0" -authors = ["Christoph Groß "] -edition = "2018" - -[dependencies] - -epd-waveshare = { path = "../../", default-features = false, features = ["epd1in54", "graphics"]} - -linux-embedded-hal = "0.2.2" -embedded-graphics = "0.5.2" -embedded-hal = { version = "0.2.2", features = ["unproven"] } diff --git a/examples/epd1in54_full/src/main.rs b/examples/epd1in54_full/src/main.rs deleted file mode 100644 index 5742158..0000000 --- a/examples/epd1in54_full/src/main.rs +++ /dev/null @@ -1,150 +0,0 @@ -#![deny(warnings)] - -use embedded_graphics::{fonts::Font6x8, prelude::*, Drawing, Point::Point}; -use embedded_hal::prelude::*; -use epd_waveshare::{ - epd1in54::{Display1in54, EPD1in54}, - graphics::{Display, DisplayRotation}, - prelude::*, -}; -use linux_embedded_hal::{ - spidev::{self, SpidevOptions}, - sysfs_gpio::Direction, - Delay, Pin, Spidev, -}; - -// activate spi, gpio in raspi-config -// needs to be run with sudo because of some sysfs_gpio permission problems and follow-up timing problems -// see https://github.com/rust-embedded/rust-sysfs-gpio/issues/5 and follow-up issues - -fn main() { - if let Err(e) = run() { - eprintln!("Program exited early with error: {}", e); - } -} - -fn run() -> Result<(), std::io::Error> { - // Configure SPI - // SPI settings are from eink-waveshare-rs documenation - let mut spi = Spidev::open("/dev/spidev0.0").expect("spidev directory"); - let options = SpidevOptions::new() - .bits_per_word(8) - .max_speed_hz(4_000_000) - .mode(spidev::SPI_MODE_0) - .build(); - spi.configure(&options).expect("spi configuration"); - - // Configure Digital I/O Pin to be used as Chip Select for SPI - let cs_pin = Pin::new(26); //BCM7 CE0 - cs_pin.export().expect("cs_pin export"); - while !cs_pin.is_exported() {} - cs_pin - .set_direction(Direction::Out) - .expect("cs_pin Direction"); - cs_pin.set_value(1).expect("cs_pin Value set to 1"); - - // Configure Busy Input Pin - let busy = Pin::new(5); //pin 29 - busy.export().expect("busy export"); - while !busy.is_exported() {} - busy.set_direction(Direction::In).expect("busy Direction"); - //busy.set_value(1).expect("busy Value set to 1"); - - // Configure Data/Command OutputPin - let dc = Pin::new(6); //pin 31 //bcm6 - dc.export().expect("dc export"); - while !dc.is_exported() {} - dc.set_direction(Direction::Out).expect("dc Direction"); - dc.set_value(1).expect("dc Value set to 1"); - - // Configure Reset OutputPin - let rst = Pin::new(16); //pin 36 //bcm16 - rst.export().expect("rst export"); - while !rst.is_exported() {} - rst.set_direction(Direction::Out).expect("rst Direction"); - rst.set_value(1).expect("rst Value set to 1"); - - // Configure Delay - let mut delay = Delay {}; - - // Setup of the needed pins is finished here - // Now the "real" usage of the eink-waveshare-rs crate begins - let mut epd = EPD1in54::new(&mut spi, cs_pin, busy, dc, rst, &mut delay)?; - - // Clear the full screen - epd.clear_frame(&mut spi).expect("clear frame 1"); - epd.display_frame(&mut spi).expect("disp 1"); - - println!("Test all the rotations"); - let mut display = Display1in54::default(); - display.set_rotation(DisplayRotation::Rotate0); - display.draw( - Font6x8::render_str("Rotate 0!") - .stroke(Some(Color::Black)) - .fill(Some(Color::White)) - .translate(Point::new(5, 50)) - .into_iter(), - ); - - display.set_rotation(DisplayRotation::Rotate90); - display.draw( - Font6x8::render_str("Rotate 90!") - .stroke(Some(Color::Black)) - .fill(Some(Color::White)) - .translate(Point::new(5, 50)) - .into_iter(), - ); - - display.set_rotation(DisplayRotation::Rotate180); - display.draw( - Font6x8::render_str("Rotate 180!") - .stroke(Some(Color::Black)) - .fill(Some(Color::White)) - .translate(Point::new(5, 50)) - .into_iter(), - ); - - display.set_rotation(DisplayRotation::Rotate270); - display.draw( - Font6x8::render_str("Rotate 270!") - .stroke(Some(Color::Black)) - .fill(Some(Color::White)) - .translate(Point::new(5, 50)) - .into_iter(), - ); - - // Display updated frame - epd.update_frame(&mut spi, &display.buffer()).unwrap(); - epd.display_frame(&mut spi) - .expect("display frame new graphics"); - delay.delay_ms(5000u16); - - // a quickly moving `Hello World!` - display.set_rotation(DisplayRotation::Rotate0); - epd.set_lut(&mut spi, Some(RefreshLUT::QUICK)) - .expect("SET LUT QUICK error"); - let limit = 20; - for i in 0..limit { - println!("Moving Hello World. Loop {} from {}", (i + 1), limit); - - display.draw( - Font6x8::render_str(" Hello World! ") - .style(Style { - fill_color: Some(Color::White), - stroke_color: Some(Color::Black), - stroke_width: 0u8, // Has no effect on fonts - }) - .translate(Point::new(5 + i * 6, 50)) - .into_iter(), - ); - - epd.update_frame(&mut spi, &display.buffer()).unwrap(); - epd.display_frame(&mut spi) - .expect("display frame new graphics"); - } - - // Set the EPD to sleep - epd.sleep(&mut spi).expect("sleep"); - - Ok(()) -} diff --git a/examples/epd1in54_no_graphics/src/main.rs b/examples/epd1in54_no_graphics.rs similarity index 94% rename from examples/epd1in54_no_graphics/src/main.rs rename to examples/epd1in54_no_graphics.rs index bdff7a9..7fd30ae 100644 --- a/examples/epd1in54_no_graphics/src/main.rs +++ b/examples/epd1in54_no_graphics.rs @@ -12,20 +12,14 @@ use linux_embedded_hal::{ // needs to be run with sudo because of some sysfs_gpio permission problems and follow-up timing problems // see https://github.com/rust-embedded/rust-sysfs-gpio/issues/5 and follow-up issues -fn main() { - if let Err(e) = run() { - eprintln!("Program exited early with error: {}", e); - } -} - -fn run() -> Result<(), std::io::Error> { +fn main() -> Result<(), std::io::Error> { // Configure SPI // SPI settings are from eink-waveshare-rs documenation let mut spi = Spidev::open("/dev/spidev0.0")?; let options = SpidevOptions::new() .bits_per_word(8) .max_speed_hz(4_000_000) - .mode(spidev::SPI_MODE_0) + .mode(spidev::SpiModeFlags::SPI_MODE_0) .build(); spi.configure(&options).expect("spi configuration"); diff --git a/examples/epd1in54_no_graphics/Cargo.toml b/examples/epd1in54_no_graphics/Cargo.toml deleted file mode 100644 index 3868a67..0000000 --- a/examples/epd1in54_no_graphics/Cargo.toml +++ /dev/null @@ -1,12 +0,0 @@ -[package] -name = "embedded_linux_eink_example" -version = "0.1.0" -authors = ["Christoph Groß "] -edition = "2018" - -[dependencies] - -epd-waveshare = { path = "../../", default-features = false, features = ["epd1in54"]} - -linux-embedded-hal = "0.2.2" -embedded-hal = { version = "0.2.2", features = ["unproven"] } diff --git a/examples/epd2in9_full/Cargo.toml b/examples/epd2in9_full/Cargo.toml deleted file mode 100644 index da71ecb..0000000 --- a/examples/epd2in9_full/Cargo.toml +++ /dev/null @@ -1,13 +0,0 @@ -[package] -name = "embedded_linux_eink_example" -version = "0.1.0" -authors = ["Christoph Groß "] -edition = "2018" - -[dependencies] - -epd-waveshare = { path = "../../", default-features = false, features = ["epd2in9", "graphics"]} - -linux-embedded-hal = "0.2.2" -embedded-graphics = "0.5.2" -embedded-hal = { version = "0.2.2", features = ["unproven"] } diff --git a/examples/epd2in9_full/src/main.rs b/examples/epd2in9_full/src/main.rs deleted file mode 100644 index a5834fe..0000000 --- a/examples/epd2in9_full/src/main.rs +++ /dev/null @@ -1,154 +0,0 @@ -#![deny(warnings)] - -use embedded_graphics::{fonts::Font6x8, prelude::*, Drawing, Point::Point}; -use embedded_hal::prelude::*; -use epd_waveshare::{ - epd2in9::{Display2in9, EPD2in9}, - graphics::{Display, DisplayRotation}, - prelude::*, -}; -use linux_embedded_hal::{ - spidev::{self, SpidevOptions}, - sysfs_gpio::Direction, - Delay, Pin, Spidev, -}; - -// activate spi, gpio in raspi-config -// needs to be run with sudo because of some sysfs_gpio permission problems and follow-up timing problems -// see https://github.com/rust-embedded/rust-sysfs-gpio/issues/5 and follow-up issues - -//TODO: Test this implemenation with a new display -fn main() { - if let Err(e) = run() { - eprintln!("Program exited early with error: {}", e); - } -} - -fn run() -> Result<(), std::io::Error> { - // Configure SPI - // SPI settings are from eink-waveshare-rs documenation - let mut spi = Spidev::open("/dev/spidev0.0").expect("spidev directory"); - let options = SpidevOptions::new() - .bits_per_word(8) - .max_speed_hz(4_000_000) - .mode(spidev::SPI_MODE_0) - .build(); - spi.configure(&options).expect("spi configuration"); - - // Configure Digital I/O Pin to be used as Chip Select for SPI - let cs_pin = Pin::new(26); //BCM7 CE0 - cs_pin.export().expect("cs_pin export"); - while !cs_pin.is_exported() {} - cs_pin - .set_direction(Direction::Out) - .expect("cs_pin Direction"); - cs_pin.set_value(1).expect("cs_pin Value set to 1"); - - // Configure Busy Input Pin - let busy = Pin::new(5); //pin 29 - busy.export().expect("busy export"); - while !busy.is_exported() {} - busy.set_direction(Direction::In).expect("busy Direction"); - //busy.set_value(1).expect("busy Value set to 1"); - - // Configure Data/Command OutputPin - let dc = Pin::new(6); //pin 31 //bcm6 - dc.export().expect("dc export"); - while !dc.is_exported() {} - dc.set_direction(Direction::Out).expect("dc Direction"); - dc.set_value(1).expect("dc Value set to 1"); - - // Configure Reset OutputPin - let rst = Pin::new(16); //pin 36 //bcm16 - rst.export().expect("rst export"); - while !rst.is_exported() {} - rst.set_direction(Direction::Out).expect("rst Direction"); - rst.set_value(1).expect("rst Value set to 1"); - - // Configure Delay - let mut delay = Delay {}; - - // Setup of the needed pins is finished here - // Now the "real" usage of the eink-waveshare-rs crate begins - let mut epd = EPD2in9::new(&mut spi, cs_pin, busy, dc, rst, &mut delay)?; - - // Clear the full screen - epd.clear_frame(&mut spi).expect("clear frame 1"); - epd.display_frame(&mut spi).expect("disp 1"); - - println!("Test all the rotations"); - let mut display = Display2in9::default(); - epd.update_frame(&mut spi, display.buffer()).unwrap(); - epd.display_frame(&mut spi).expect("display frame x03"); - - display.set_rotation(DisplayRotation::Rotate0); - display.draw( - Font6x8::render_str("Rotate 0!") - .stroke(Some(Color::Black)) - .fill(Some(Color::White)) - .translate(Point::new(5, 50)) - .into_iter(), - ); - - display.set_rotation(DisplayRotation::Rotate90); - display.draw( - Font6x8::render_str("Rotate 90!") - .stroke(Some(Color::Black)) - .fill(Some(Color::White)) - .translate(Point::new(5, 50)) - .into_iter(), - ); - - display.set_rotation(DisplayRotation::Rotate180); - display.draw( - Font6x8::render_str("Rotate 180!") - .stroke(Some(Color::Black)) - .fill(Some(Color::White)) - .translate(Point::new(5, 50)) - .into_iter(), - ); - - display.set_rotation(DisplayRotation::Rotate270); - display.draw( - Font6x8::render_str("Rotate 270!") - .stroke(Some(Color::Black)) - .fill(Some(Color::White)) - .translate(Point::new(5, 50)) - .into_iter(), - ); - - // Display updated frame - epd.update_frame(&mut spi, &display.buffer()).unwrap(); - epd.display_frame(&mut spi) - .expect("display frame new graphics"); - delay.delay_ms(5000u16); - - // a quickly moving `Hello World!` - display.set_rotation(DisplayRotation::Rotate0); - epd.set_lut(&mut spi, Some(RefreshLUT::QUICK)) - .expect("SET LUT QUICK error"); - let limit = 20; - for i in 0..limit { - println!("Moving Hello World. Loop {} from {}", (i + 1), limit); - - display.draw( - Font6x8::render_str(" Hello World! ") - .style(Style { - fill_color: Some(Color::White), - stroke_color: Some(Color::Black), - stroke_width: 0u8, // Has no effect on fonts - }) - .translate(Point::new(5 + i * 6, 50)) - .into_iter(), - ); - - epd.update_frame(&mut spi, &display.buffer()).unwrap(); - epd.display_frame(&mut spi) - .expect("display frame new graphics"); - } - - // Set the EPD to sleep - epd.sleep(&mut spi).expect("sleep"); - - Ok(()) -} diff --git a/examples/epd4in2_full_blue_pill/src/main.rs b/examples/epd4in2.rs similarity index 54% rename from examples/epd4in2_full_blue_pill/src/main.rs rename to examples/epd4in2.rs index f5becae..04730ed 100644 --- a/examples/epd4in2_full_blue_pill/src/main.rs +++ b/examples/epd4in2.rs @@ -1,72 +1,69 @@ -#![no_main] -#![no_std] - -// set the panic handler -#[allow(unused_imports)] -use panic_semihosting; - -use cortex_m_rt::entry; -use stm32f1xx_hal::prelude::*; -use stm32f1xx_hal::{delay, spi}; +#![deny(warnings)] use embedded_graphics::{ fonts::{Font12x16, Font6x8, Text}, - pixelcolor::BinaryColor, prelude::*, primitives::{Circle, Line}, - style::{PrimitiveStyle, Styled}, - text_style, DrawTarget, + style::PrimitiveStyle, + text_style, }; +use embedded_hal::prelude::*; use epd_waveshare::{ color::*, - epd4in2::Display4in2, + epd4in2::{Display4in2, EPD4in2}, graphics::{Display, DisplayRotation}, prelude::*, }; +use linux_embedded_hal::{ + spidev::{self, SpidevOptions}, + sysfs_gpio::Direction, + Delay, Pin, Spidev, +}; -#[entry] -fn main() -> ! { - let core = cortex_m::Peripherals::take().unwrap(); - let device = stm32f1xx_hal::stm32::Peripherals::take().unwrap(); - let mut rcc = device.RCC.constrain(); - let mut flash = device.FLASH.constrain(); - - let clocks = rcc - .cfgr - .use_hse(8.mhz()) - .sysclk(72.mhz()) - .pclk1(36.mhz()) - .freeze(&mut flash.acr); - - let mut gpioa = device.GPIOA.split(&mut rcc.apb2); - let mut gpiob = device.GPIOB.split(&mut rcc.apb2); - - let mut delay = delay::Delay::new(core.SYST, clocks); - - // spi setup - let sck = gpiob.pb13.into_alternate_push_pull(&mut gpiob.crh); - let miso = gpiob.pb14; - let mosi = gpiob.pb15.into_alternate_push_pull(&mut gpiob.crh); - let mut spi = spi::Spi::spi2( - device.SPI2, - (sck, miso, mosi), - epd_waveshare::SPI_MODE, - 4.mhz(), - clocks, - &mut rcc.apb1, - ); - // epd setup - let mut epd4in2 = epd_waveshare::epd4in2::EPD4in2::new( - &mut spi, - gpiob.pb12.into_push_pull_output(&mut gpiob.crh), - gpioa.pa10.into_floating_input(&mut gpioa.crh), - gpioa.pa8.into_push_pull_output(&mut gpioa.crh), - gpioa.pa9.into_push_pull_output(&mut gpioa.crh), - &mut delay, - ) - .unwrap(); - epd4in2.set_lut(&mut spi, Some(RefreshLUT::QUICK)).unwrap(); - epd4in2.clear_frame(&mut spi).unwrap(); +// activate spi, gpio in raspi-config +// needs to be run with sudo because of some sysfs_gpio permission problems and follow-up timing problems +// see https://github.com/rust-embedded/rust-sysfs-gpio/issues/5 and follow-up issues + +fn main() -> Result<(), std::io::Error> { + // Configure SPI + // Settings are taken from + let mut spi = Spidev::open("/dev/spidev0.0").expect("spidev directory"); + let options = SpidevOptions::new() + .bits_per_word(8) + .max_speed_hz(4_000_000) + .mode(spidev::SpiModeFlags::SPI_MODE_0) + .build(); + spi.configure(&options).expect("spi configuration"); + + // Configure Digital I/O Pin to be used as Chip Select for SPI + let cs = Pin::new(26); //BCM7 CE0 + cs.export().expect("cs export"); + while !cs.is_exported() {} + cs.set_direction(Direction::Out).expect("CS Direction"); + cs.set_value(1).expect("CS Value set to 1"); + + let busy = Pin::new(5); //pin 29 + busy.export().expect("busy export"); + while !busy.is_exported() {} + busy.set_direction(Direction::In).expect("busy Direction"); + //busy.set_value(1).expect("busy Value set to 1"); + + let dc = Pin::new(6); //pin 31 //bcm6 + dc.export().expect("dc export"); + while !dc.is_exported() {} + dc.set_direction(Direction::Out).expect("dc Direction"); + dc.set_value(1).expect("dc Value set to 1"); + + let rst = Pin::new(16); //pin 36 //bcm16 + rst.export().expect("rst export"); + while !rst.is_exported() {} + rst.set_direction(Direction::Out).expect("rst Direction"); + rst.set_value(1).expect("rst Value set to 1"); + + let mut delay = Delay {}; + + let mut epd4in2 = + EPD4in2::new(&mut spi, cs, busy, dc, rst, &mut delay).expect("eink initalize error"); //println!("Test all the rotations"); let mut display = Display4in2::default(); @@ -83,7 +80,7 @@ fn main() -> ! { display.set_rotation(DisplayRotation::Rotate270); draw_text(&mut display, "Rotate 270!", 5, 50); - epd4in2.update_frame(&mut spi, &display.buffer()).unwrap(); + epd4in2.update_frame(&mut spi, &display.buffer())?; epd4in2 .display_frame(&mut spi) .expect("display frame new graphics"); @@ -93,13 +90,13 @@ fn main() -> ! { display.clear_buffer(Color::White); // draw a analog clock - Circle::new(Point::new(64, 64), 64) + let _ = Circle::new(Point::new(64, 64), 64) .into_styled(PrimitiveStyle::with_stroke(Black, 1)) .draw(&mut display); - Line::new(Point::new(64, 64), Point::new(0, 64)) + let _ = Line::new(Point::new(64, 64), Point::new(0, 64)) .into_styled(PrimitiveStyle::with_stroke(Black, 1)) .draw(&mut display); - Line::new(Point::new(64, 64), Point::new(80, 80)) + let _ = Line::new(Point::new(64, 64), Point::new(80, 80)) .into_styled(PrimitiveStyle::with_stroke(Black, 1)) .draw(&mut display); @@ -138,13 +135,8 @@ fn main() -> ! { delay.delay_ms(1_000u16); } - //println!("Finished tests - going to sleep"); - epd4in2.sleep(&mut spi).expect("epd goes to sleep"); - - loop { - // sleep - cortex_m::asm::wfi(); - } + println!("Finished tests - going to sleep"); + epd4in2.sleep(&mut spi) } fn draw_text(display: &mut Display4in2, text: &str, x: i32, y: i32) { diff --git a/examples/epd4in2_full/Cargo.toml b/examples/epd4in2_full/Cargo.toml deleted file mode 100644 index c8b1068..0000000 --- a/examples/epd4in2_full/Cargo.toml +++ /dev/null @@ -1,15 +0,0 @@ -[package] -name = "embedded_linux_eink_example" -version = "0.1.0" -authors = ["Christoph Groß "] -edition = "2018" - -[dependencies] - -## The Only difference between this one and the one without default features sizewise seems to be a different .d-file Size (dependencies-file) -#epd_waveshare = { path = "../../"} -epd-waveshare = { path = "../../", default-features = false, features = ["epd4in2", "graphics"]} - -linux-embedded-hal = "0.2.2" -embedded-graphics = "0.5.2" -embedded-hal = { version = "0.2.2", features = ["unproven"] } diff --git a/examples/epd4in2_full/src/main.rs b/examples/epd4in2_full/src/main.rs deleted file mode 100644 index 7cd880c..0000000 --- a/examples/epd4in2_full/src/main.rs +++ /dev/null @@ -1,189 +0,0 @@ -#![deny(warnings)] - -use embedded_graphics::{ - fonts::{Font12x16, Font6x8}, - prelude::*, - primitives::{Circle, Line}, - Drawing, - Point::Point, -}; -use embedded_hal::prelude::*; -use epd_waveshare::{ - epd4in2::{Display4in2, EPD4in2}, - graphics::{Display, DisplayRotation}, - prelude::*, -}; -use linux_embedded_hal::{ - spidev::{self, SpidevOptions}, - sysfs_gpio::Direction, - Delay, Pin, Spidev, -}; - -// activate spi, gpio in raspi-config -// needs to be run with sudo because of some sysfs_gpio permission problems and follow-up timing problems -// see https://github.com/rust-embedded/rust-sysfs-gpio/issues/5 and follow-up issues - -fn main() { - if let Err(e) = run() { - eprintln!("Program exited early with error: {}", e); - } -} - -fn run() -> Result<(), std::io::Error> { - // Configure SPI - // Settings are taken from - let mut spi = Spidev::open("/dev/spidev0.0").expect("spidev directory"); - let options = SpidevOptions::new() - .bits_per_word(8) - .max_speed_hz(4_000_000) - .mode(spidev::SPI_MODE_0) - .build(); - spi.configure(&options).expect("spi configuration"); - - // Configure Digital I/O Pin to be used as Chip Select for SPI - let cs = Pin::new(26); //BCM7 CE0 - cs.export().expect("cs export"); - while !cs.is_exported() {} - cs.set_direction(Direction::Out).expect("CS Direction"); - cs.set_value(1).expect("CS Value set to 1"); - - let busy = Pin::new(5); //pin 29 - busy.export().expect("busy export"); - while !busy.is_exported() {} - busy.set_direction(Direction::In).expect("busy Direction"); - //busy.set_value(1).expect("busy Value set to 1"); - - let dc = Pin::new(6); //pin 31 //bcm6 - dc.export().expect("dc export"); - while !dc.is_exported() {} - dc.set_direction(Direction::Out).expect("dc Direction"); - dc.set_value(1).expect("dc Value set to 1"); - - let rst = Pin::new(16); //pin 36 //bcm16 - rst.export().expect("rst export"); - while !rst.is_exported() {} - rst.set_direction(Direction::Out).expect("rst Direction"); - rst.set_value(1).expect("rst Value set to 1"); - - let mut delay = Delay {}; - - let mut epd4in2 = - EPD4in2::new(&mut spi, cs, busy, dc, rst, &mut delay).expect("eink initalize error"); - - println!("Test all the rotations"); - let mut display = Display4in2::default(); - display.set_rotation(DisplayRotation::Rotate0); - display.draw( - Font6x8::render_str("Rotate 0!") - .stroke(Some(Color::Black)) - .fill(Some(Color::White)) - .translate(Point::new(5, 50)) - .into_iter(), - ); - - display.set_rotation(DisplayRotation::Rotate90); - display.draw( - Font6x8::render_str("Rotate 90!") - .stroke(Some(Color::Black)) - .fill(Some(Color::White)) - .translate(Point::new(5, 50)) - .into_iter(), - ); - - display.set_rotation(DisplayRotation::Rotate180); - display.draw( - Font6x8::render_str("Rotate 180!") - .stroke(Some(Color::Black)) - .fill(Some(Color::White)) - .translate(Point::new(5, 50)) - .into_iter(), - ); - - display.set_rotation(DisplayRotation::Rotate270); - display.draw( - Font6x8::render_str("Rotate 270!") - .stroke(Some(Color::Black)) - .fill(Some(Color::White)) - .translate(Point::new(5, 50)) - .into_iter(), - ); - - epd4in2.update_frame(&mut spi, &display.buffer()).unwrap(); - epd4in2 - .display_frame(&mut spi) - .expect("display frame new graphics"); - delay.delay_ms(5000u16); - - println!("Now test new graphics with default rotation and some special stuff:"); - display.clear_buffer(Color::White); - - // draw a analog clock - display.draw( - Circle::new(Point::new(64, 64), 64) - .stroke(Some(Color::Black)) - .into_iter(), - ); - display.draw( - let _ = Line::new(Point::new(64, 64), Point::new(0, 64)) - .stroke(Some(Color::Black)) - .into_iter(), - ); - display.draw( - let _ = Line::new(Point::new(64, 64), Point::new(80, 80)) - .stroke(Some(Color::Black)) - .into_iter(), - ); - - // draw white on black background - display.draw( - Font6x8::render_str("It's working-WoB!") - // Using Style here - .style(Style { - fill_color: Some(Color::Black), - stroke_color: Some(Color::White), - stroke_width: 0u8, // Has no effect on fonts - }) - .translate(Point::new(175, 250)) - .into_iter(), - ); - - // use bigger/different font - display.draw( - Font12x16::render_str("It's working-BoW!") - // Using Style here - .style(Style { - fill_color: Some(Color::White), - stroke_color: Some(Color::Black), - stroke_width: 0u8, // Has no effect on fonts - }) - .translate(Point::new(50, 200)) - .into_iter(), - ); - - // a moving `Hello World!` - let limit = 10; - for i in 0..limit { - println!("Moving Hello World. Loop {} from {}", (i + 1), limit); - - display.draw( - Font6x8::render_str(" Hello World! ") - .style(Style { - fill_color: Some(Color::White), - stroke_color: Some(Color::Black), - stroke_width: 0u8, // Has no effect on fonts - }) - .translate(Point::new(5 + i * 12, 50)) - .into_iter(), - ); - - epd4in2.update_frame(&mut spi, &display.buffer()).unwrap(); - epd4in2 - .display_frame(&mut spi) - .expect("display frame new graphics"); - - delay.delay_ms(1_000u16); - } - - println!("Finished tests - going to sleep"); - epd4in2.sleep(&mut spi) -} diff --git a/examples/epd4in2_full_blue_pill/.cargo/config b/examples/epd4in2_full_blue_pill/.cargo/config deleted file mode 100644 index 313e8f0..0000000 --- a/examples/epd4in2_full_blue_pill/.cargo/config +++ /dev/null @@ -1,12 +0,0 @@ -[target.thumbv7m-none-eabi] - -# uncomment ONE of these three option to make `cargo run` start a GDB session -# which option to pick depends on your system -runner = "arm-none-eabi-gdb -q -x openocd.gdb" -# runner = "gdb-multiarch -q -x openocd.gdb" -# runner = "gdb -q -x openocd.gdb" - -rustflags = ["-C", "link-arg=-Tlink.x"] - -[build] -target = "thumbv7m-none-eabi" \ No newline at end of file diff --git a/examples/epd4in2_full_blue_pill/Cargo.toml b/examples/epd4in2_full_blue_pill/Cargo.toml deleted file mode 100644 index c759fb7..0000000 --- a/examples/epd4in2_full_blue_pill/Cargo.toml +++ /dev/null @@ -1,19 +0,0 @@ -[package] -name = "embedded_linux_eink_example" -version = "0.1.0" -authors = ["Christoph Groß "] -edition = "2018" - -[dependencies] - -## The Only difference between this one and the one without default features sizewise seems to be a different .d-file Size (dependencies-file) -#epd_waveshare = { path = "../../"} -epd-waveshare = { path = "../../", default-features = false, features = ["epd4in2", "graphics"]} - -embedded-graphics = "0.6.0-beta.2" -embedded-hal = { version = "0.2.3", features = ["unproven"] } - -stm32f1xx-hal = { version = "0.2", features = ["rt", "stm32f103" ] } -cortex-m = "0.5.0" -cortex-m-rt = { version = "0.6.6", features = ["device"] } -panic-semihosting = "0.5" diff --git a/examples/epd4in2_full_blue_pill/memory.x b/examples/epd4in2_full_blue_pill/memory.x deleted file mode 100644 index fc092da..0000000 --- a/examples/epd4in2_full_blue_pill/memory.x +++ /dev/null @@ -1,6 +0,0 @@ -/* Linker script for the STM32F103C8T6 */ -MEMORY -{ - FLASH : ORIGIN = 0x08000000, LENGTH = 64K - RAM : ORIGIN = 0x20000000, LENGTH = 20K -} \ No newline at end of file diff --git a/examples/epd4in2_full_blue_pill/openocd.cfg b/examples/epd4in2_full_blue_pill/openocd.cfg deleted file mode 100644 index 5ac6a60..0000000 --- a/examples/epd4in2_full_blue_pill/openocd.cfg +++ /dev/null @@ -1,2 +0,0 @@ -source [find interface/stlink-v2.cfg] -source [find target/stm32f1x.cfg] \ No newline at end of file diff --git a/examples/epd4in2_full_blue_pill/openocd.gdb b/examples/epd4in2_full_blue_pill/openocd.gdb deleted file mode 100644 index 5f5b068..0000000 --- a/examples/epd4in2_full_blue_pill/openocd.gdb +++ /dev/null @@ -1,10 +0,0 @@ -target remote :3333 -set print asm-demangle on -monitor arm semihosting enable - -# detect unhandled exceptions, hard faults and panics -break DefaultHandler -break HardFault -break rust_begin_unwind - -load \ No newline at end of file diff --git a/examples/epd4in2_var_display_buffer/Cargo.toml b/examples/epd4in2_var_display_buffer/Cargo.toml deleted file mode 100644 index c8b1068..0000000 --- a/examples/epd4in2_var_display_buffer/Cargo.toml +++ /dev/null @@ -1,15 +0,0 @@ -[package] -name = "embedded_linux_eink_example" -version = "0.1.0" -authors = ["Christoph Groß "] -edition = "2018" - -[dependencies] - -## The Only difference between this one and the one without default features sizewise seems to be a different .d-file Size (dependencies-file) -#epd_waveshare = { path = "../../"} -epd-waveshare = { path = "../../", default-features = false, features = ["epd4in2", "graphics"]} - -linux-embedded-hal = "0.2.2" -embedded-graphics = "0.5.2" -embedded-hal = { version = "0.2.2", features = ["unproven"] } diff --git a/examples/epd4in2_var_display_buffer/src/main.rs b/examples/epd4in2_variable_size.rs similarity index 54% rename from examples/epd4in2_var_display_buffer/src/main.rs rename to examples/epd4in2_variable_size.rs index ae365be..6c03851 100644 --- a/examples/epd4in2_var_display_buffer/src/main.rs +++ b/examples/epd4in2_variable_size.rs @@ -1,14 +1,16 @@ #![deny(warnings)] +#![deny(warnings)] use embedded_graphics::{ - fonts::{Font12x16, Font6x8}, + fonts::{Font12x16, Font6x8, Text}, prelude::*, primitives::{Circle, Line}, - Drawing, - Point::Point, + style::PrimitiveStyle, + text_style, }; use embedded_hal::prelude::*; use epd_waveshare::{ + color::*, epd4in2::{self, EPD4in2}, graphics::{Display, DisplayRotation, VarDisplay}, prelude::*, @@ -23,20 +25,14 @@ use linux_embedded_hal::{ // needs to be run with sudo because of some sysfs_gpio permission problems and follow-up timing problems // see https://github.com/rust-embedded/rust-sysfs-gpio/issues/5 and follow-up issues -fn main() { - if let Err(e) = run() { - eprintln!("Program exited early with error: {}", e); - } -} - -fn run() -> Result<(), std::io::Error> { +fn main() -> Result<(), std::io::Error> { // Configure SPI // Settings are taken from let mut spi = Spidev::open("/dev/spidev0.0").expect("spidev directory"); let options = SpidevOptions::new() .bits_per_word(8) .max_speed_hz(4_000_000) - .mode(spidev::SPI_MODE_0) + .mode(spidev::SpiModeFlags::SPI_MODE_0) .build(); spi.configure(&options).expect("spi configuration"); @@ -77,40 +73,16 @@ fn run() -> Result<(), std::io::Error> { let mut buffer = [epd4in2::DEFAULT_BACKGROUND_COLOR.get_byte_value(); 62500]; //250*250 let mut display = VarDisplay::new(width, height, &mut buffer); display.set_rotation(DisplayRotation::Rotate0); - display.draw( - Font6x8::render_str("Rotate 0!") - .stroke(Some(Color::Black)) - .fill(Some(Color::White)) - .translate(Point::new(5, 50)) - .into_iter(), - ); + draw_text(&mut display, "Rotate 0!", 5, 50); display.set_rotation(DisplayRotation::Rotate90); - display.draw( - Font6x8::render_str("Rotate 90!") - .stroke(Some(Color::Black)) - .fill(Some(Color::White)) - .translate(Point::new(5, 50)) - .into_iter(), - ); + draw_text(&mut display, "Rotate 90!", 5, 50); display.set_rotation(DisplayRotation::Rotate180); - display.draw( - Font6x8::render_str("Rotate 180!") - .stroke(Some(Color::Black)) - .fill(Some(Color::White)) - .translate(Point::new(5, 50)) - .into_iter(), - ); + draw_text(&mut display, "Rotate 180!", 5, 50); display.set_rotation(DisplayRotation::Rotate270); - display.draw( - Font6x8::render_str("Rotate 270!") - .stroke(Some(Color::Black)) - .fill(Some(Color::White)) - .translate(Point::new(5, 50)) - .into_iter(), - ); + draw_text(&mut display, "Rotate 270!", 5, 50); epd4in2 .update_partial_frame(&mut spi, &display.buffer(), x, y, width, height) @@ -121,68 +93,49 @@ fn run() -> Result<(), std::io::Error> { delay.delay_ms(5000u16); println!("Now test new graphics with default rotation and some special stuff:"); + display.set_rotation(DisplayRotation::Rotate0); display.clear_buffer(Color::White); // draw a analog clock - display.draw( - Circle::new(Point::new(64, 64), 64) - .stroke(Some(Color::Black)) - .into_iter(), - ); - display.draw( - let _ = Line::new(Point::new(64, 64), Point::new(0, 64)) - .stroke(Some(Color::Black)) - .into_iter(), - ); - display.draw( - let _ = Line::new(Point::new(64, 64), Point::new(80, 80)) - .stroke(Some(Color::Black)) - .into_iter(), - ); + // draw a analog clock + let _ = Circle::new(Point::new(64, 64), 64) + .into_styled(PrimitiveStyle::with_stroke(Black, 1)) + .draw(&mut display); + let _ = Line::new(Point::new(64, 64), Point::new(0, 64)) + .into_styled(PrimitiveStyle::with_stroke(Black, 1)) + .draw(&mut display); + let _ = Line::new(Point::new(64, 64), Point::new(80, 80)) + .into_styled(PrimitiveStyle::with_stroke(Black, 1)) + .draw(&mut display); // draw white on black background - display.draw( - Font6x8::render_str("It's working-WoB!") - // Using Style here - .style(Style { - fill_color: Some(Color::Black), - stroke_color: Some(Color::White), - stroke_width: 0u8, // Has no effect on fonts - }) - .translate(Point::new(175, 250)) - .into_iter(), - ); + let _ = Text::new("It's working-WoB!", Point::new(175, 250)) + .into_styled(text_style!( + font = Font6x8, + text_color = White, + background_color = Black + )) + .draw(&mut display); // use bigger/different font - display.draw( - Font12x16::render_str("It's working-BoW!") - // Using Style here - .style(Style { - fill_color: Some(Color::White), - stroke_color: Some(Color::Black), - stroke_width: 0u8, // Has no effect on fonts - }) - .translate(Point::new(50, 200)) - .into_iter(), - ); + let _ = Text::new("It's working-WoB!", Point::new(50, 200)) + .into_styled(text_style!( + font = Font12x16, + text_color = White, + background_color = Black + )) + .draw(&mut display); // a moving `Hello World!` let limit = 10; for i in 0..limit { println!("Moving Hello World. Loop {} from {}", (i + 1), limit); - display.draw( - Font6x8::render_str(" Hello World! ") - .style(Style { - fill_color: Some(Color::White), - stroke_color: Some(Color::Black), - stroke_width: 0u8, // Has no effect on fonts - }) - .translate(Point::new(5 + i * 12, 50)) - .into_iter(), - ); - - epd4in2.update_frame(&mut spi, &display.buffer()).unwrap(); + draw_text(&mut display, " Hello World! ", 5 + i * 12, 50); + + epd4in2 + .update_partial_frame(&mut spi, &display.buffer(), x, y, width, height) + .unwrap(); epd4in2 .display_frame(&mut spi) .expect("display frame new graphics"); @@ -193,3 +146,13 @@ fn run() -> Result<(), std::io::Error> { println!("Finished tests - going to sleep"); epd4in2.sleep(&mut spi) } + +fn draw_text(display: &mut VarDisplay, text: &str, x: i32, y: i32) { + let _ = Text::new(text, Point::new(x, y)) + .into_styled(text_style!( + font = Font6x8, + text_color = Black, + background_color = White + )) + .draw(display); +} diff --git a/examples/epd7in5_full/Cargo.toml b/examples/epd7in5_full/Cargo.toml deleted file mode 100644 index e9e1b8e..0000000 --- a/examples/epd7in5_full/Cargo.toml +++ /dev/null @@ -1,14 +0,0 @@ -[package] -name = "embedded_linux_eink_example" -version = "0.1.0" -authors = [ - "Christoph Groß ", - "Jack Grigg ", -] -edition = "2018" - -[dependencies] -embedded-graphics = "0.5.2" -embedded-hal = { version = "0.2.2", features = ["unproven"] } -epd-waveshare = { path = "../../", default-features = false, features = ["epd7in5", "graphics"]} -linux-embedded-hal = "0.2.2" diff --git a/examples/epd7in5_full/src/main.rs b/examples/epd7in5_full/src/main.rs deleted file mode 100644 index 3e324da..0000000 --- a/examples/epd7in5_full/src/main.rs +++ /dev/null @@ -1,188 +0,0 @@ -#![deny(warnings)] - -use embedded_graphics::{ - fonts::{Font12x16, Font6x8}, - prelude::*, - primitives::{Circle, Line}, - Drawing, - Point::Point, -}; -use embedded_hal::prelude::*; -use epd_waveshare::{ - epd7in5::{Display7in5, EPD7in5}, - graphics::{Display, DisplayRotation}, - prelude::*, -}; -use linux_embedded_hal::{ - spidev::{self, SpidevOptions}, - sysfs_gpio::Direction, - Delay, Pin, Spidev, -}; - -// activate spi, gpio in raspi-config -// needs to be run with sudo because of some sysfs_gpio permission problems and follow-up timing problems -// see https://github.com/rust-embedded/rust-sysfs-gpio/issues/5 and follow-up issues - -fn main() { - if let Err(e) = run() { - eprintln!("Program exited early with error: {}", e); - } -} - -fn run() -> Result<(), std::io::Error> { - // Configure SPI - // Settings are taken from - let mut spi = Spidev::open("/dev/spidev0.0").expect("spidev directory"); - let options = SpidevOptions::new() - .bits_per_word(8) - .max_speed_hz(4_000_000) - .mode(spidev::SPI_MODE_0) - .build(); - spi.configure(&options).expect("spi configuration"); - - // Configure Digital I/O Pin to be used as Chip Select for SPI - let cs = Pin::new(8); - cs.export().expect("cs export"); - while !cs.is_exported() {} - cs.set_direction(Direction::Out).expect("CS Direction"); - cs.set_value(1).expect("CS Value set to 1"); - - let busy = Pin::new(24); - busy.export().expect("busy export"); - while !busy.is_exported() {} - busy.set_direction(Direction::In).expect("busy Direction"); - - let dc = Pin::new(25); - dc.export().expect("dc export"); - while !dc.is_exported() {} - dc.set_direction(Direction::Out).expect("dc Direction"); - dc.set_value(1).expect("dc Value set to 1"); - - let rst = Pin::new(17); - rst.export().expect("rst export"); - while !rst.is_exported() {} - rst.set_direction(Direction::Out).expect("rst Direction"); - rst.set_value(1).expect("rst Value set to 1"); - - let mut delay = Delay {}; - - let mut epd7in5 = - EPD7in5::new(&mut spi, cs, busy, dc, rst, &mut delay).expect("eink initalize error"); - - println!("Test all the rotations"); - let mut display = Display7in5::default(); - display.set_rotation(DisplayRotation::Rotate0); - display.draw( - Font6x8::render_str("Rotate 0!") - .stroke(Some(Color::Black)) - .fill(Some(Color::White)) - .translate(Point::new(5, 50)) - .into_iter(), - ); - - display.set_rotation(DisplayRotation::Rotate90); - display.draw( - Font6x8::render_str("Rotate 90!") - .stroke(Some(Color::Black)) - .fill(Some(Color::White)) - .translate(Point::new(5, 50)) - .into_iter(), - ); - - display.set_rotation(DisplayRotation::Rotate180); - display.draw( - Font6x8::render_str("Rotate 180!") - .stroke(Some(Color::Black)) - .fill(Some(Color::White)) - .translate(Point::new(5, 50)) - .into_iter(), - ); - - display.set_rotation(DisplayRotation::Rotate270); - display.draw( - Font6x8::render_str("Rotate 270!") - .stroke(Some(Color::Black)) - .fill(Some(Color::White)) - .translate(Point::new(5, 50)) - .into_iter(), - ); - - epd7in5.update_frame(&mut spi, &display.buffer()).unwrap(); - epd7in5 - .display_frame(&mut spi) - .expect("display frame new graphics"); - delay.delay_ms(5000u16); - - println!("Now test new graphics with default rotation and some special stuff:"); - display.clear_buffer(Color::White); - - // draw a analog clock - display.draw( - Circle::new(Point::new(64, 64), 64) - .stroke(Some(Color::Black)) - .into_iter(), - ); - display.draw( - let _ = Line::new(Point::new(64, 64), Point::new(0, 64)) - .stroke(Some(Color::Black)) - .into_iter(), - ); - display.draw( - let _ = Line::new(Point::new(64, 64), Point::new(80, 80)) - .stroke(Some(Color::Black)) - .into_iter(), - ); - - // draw white on black background - display.draw( - Font6x8::render_str("It's working-WoB!") - // Using Style here - .style(Style { - fill_color: Some(Color::Black), - stroke_color: Some(Color::White), - stroke_width: 0u8, // Has no effect on fonts - }) - .translate(Point::new(175, 250)) - .into_iter(), - ); - - // use bigger/different font - display.draw( - Font12x16::render_str("It's working-BoW!") - // Using Style here - .style(Style { - fill_color: Some(Color::White), - stroke_color: Some(Color::Black), - stroke_width: 0u8, // Has no effect on fonts - }) - .translate(Point::new(50, 200)) - .into_iter(), - ); - - // a moving `Hello World!` - let limit = 10; - for i in 0..limit { - println!("Moving Hello World. Loop {} from {}", (i + 1), limit); - - display.draw( - Font6x8::render_str(" Hello World! ") - .style(Style { - fill_color: Some(Color::White), - stroke_color: Some(Color::Black), - stroke_width: 0u8, // Has no effect on fonts - }) - .translate(Point::new(5 + i * 12, 50)) - .into_iter(), - ); - - epd7in5.update_frame(&mut spi, &display.buffer()).unwrap(); - epd7in5 - .display_frame(&mut spi) - .expect("display frame new graphics"); - - delay.delay_ms(1_000u16); - } - - println!("Finished tests - going to sleep"); - epd7in5.sleep(&mut spi) -} diff --git a/examples/epd7in5_v2_full/Cargo.toml b/examples/epd7in5_v2_full/Cargo.toml deleted file mode 100644 index d12cdd1..0000000 --- a/examples/epd7in5_v2_full/Cargo.toml +++ /dev/null @@ -1,15 +0,0 @@ -[package] -name = "embedded_linux_eink_example" -version = "0.1.0" -authors = [ - "Christoph Groß ", - "Jack Grigg ", - "Christoph Grabo ", -] -edition = "2018" - -[dependencies] -embedded-graphics = "0.5.2" -embedded-hal = { version = "0.2.3", features = ["unproven"] } -epd-waveshare = { path = "../../", default-features = false, features = ["epd7in5_v2", "graphics"]} -linux-embedded-hal = "0.3.0" diff --git a/examples/epd7in5_v2_full/src/main.rs b/examples/epd7in5_v2_full/src/main.rs deleted file mode 100644 index 1f0dc00..0000000 --- a/examples/epd7in5_v2_full/src/main.rs +++ /dev/null @@ -1,188 +0,0 @@ -#![deny(warnings)] - -use embedded_graphics::{ - fonts::{Font12x16, Font6x8}, - prelude::*, - primitives::{Circle, Line}, - Drawing, - Point::Point, -}; -use embedded_hal::prelude::*; -use epd_waveshare::{ - epd7in5_v2::{Display7in5, EPD7in5}, - graphics::{Display, DisplayRotation}, - prelude::*, -}; -use linux_embedded_hal::{ - spidev::{self, SpidevOptions}, - sysfs_gpio::Direction, - Delay, Pin, Spidev, -}; - -// activate spi, gpio in raspi-config -// needs to be run with sudo because of some sysfs_gpio permission problems and follow-up timing problems -// see https://github.com/rust-embedded/rust-sysfs-gpio/issues/5 and follow-up issues - -fn main() { - if let Err(e) = run() { - eprintln!("Program exited early with error: {}", e); - } -} - -fn run() -> Result<(), std::io::Error> { - // Configure SPI - // Settings are taken from - let mut spi = Spidev::open("/dev/spidev0.0").expect("spidev directory"); - let options = SpidevOptions::new() - .bits_per_word(8) - .max_speed_hz(4_000_000) - .mode(spidev::SpiModeFlags::SPI_MODE_0) - .build(); - spi.configure(&options).expect("spi configuration"); - - // Configure Digital I/O Pin to be used as Chip Select for SPI - let cs = Pin::new(8); - cs.export().expect("cs export"); - while !cs.is_exported() {} - cs.set_direction(Direction::Out).expect("CS Direction"); - cs.set_value(1).expect("CS Value set to 1"); - - let busy = Pin::new(24); - busy.export().expect("busy export"); - while !busy.is_exported() {} - busy.set_direction(Direction::In).expect("busy Direction"); - - let dc = Pin::new(25); - dc.export().expect("dc export"); - while !dc.is_exported() {} - dc.set_direction(Direction::Out).expect("dc Direction"); - dc.set_value(1).expect("dc Value set to 1"); - - let rst = Pin::new(17); - rst.export().expect("rst export"); - while !rst.is_exported() {} - rst.set_direction(Direction::Out).expect("rst Direction"); - rst.set_value(1).expect("rst Value set to 1"); - - let mut delay = Delay {}; - - let mut epd7in5 = - EPD7in5::new(&mut spi, cs, busy, dc, rst, &mut delay).expect("eink initalize error"); - - println!("Test all the rotations"); - let mut display = Display7in5::default(); - display.set_rotation(DisplayRotation::Rotate0); - display.draw( - Font6x8::render_str("Rotate 0!") - .stroke(Some(Color::Black)) - .fill(Some(Color::White)) - .translate(Point::new(5, 50)) - .into_iter(), - ); - - display.set_rotation(DisplayRotation::Rotate90); - display.draw( - Font6x8::render_str("Rotate 90!") - .stroke(Some(Color::Black)) - .fill(Some(Color::White)) - .translate(Point::new(5, 50)) - .into_iter(), - ); - - display.set_rotation(DisplayRotation::Rotate180); - display.draw( - Font6x8::render_str("Rotate 180!") - .stroke(Some(Color::Black)) - .fill(Some(Color::White)) - .translate(Point::new(5, 50)) - .into_iter(), - ); - - display.set_rotation(DisplayRotation::Rotate270); - display.draw( - Font6x8::render_str("Rotate 270!") - .stroke(Some(Color::Black)) - .fill(Some(Color::White)) - .translate(Point::new(5, 50)) - .into_iter(), - ); - - epd7in5.update_frame(&mut spi, &display.buffer()).unwrap(); - epd7in5 - .display_frame(&mut spi) - .expect("display frame new graphics"); - delay.delay_ms(5000u16); - - println!("Now test new graphics with default rotation and some special stuff:"); - display.clear_buffer(Color::White); - - // draw a analog clock - display.draw( - Circle::new(Point::new(64, 64), 64) - .stroke(Some(Color::Black)) - .into_iter(), - ); - display.draw( - Line::new(Point::new(64, 64), Point::new(0, 64)) - .stroke(Some(Color::Black)) - .into_iter(), - ); - display.draw( - Line::new(Point::new(64, 64), Point::new(80, 80)) - .stroke(Some(Color::Black)) - .into_iter(), - ); - - // draw white on black background - display.draw( - Font6x8::render_str("It's working-WoB!") - // Using Style here - .style(Style { - fill_color: Some(Color::Black), - stroke_color: Some(Color::White), - stroke_width: 0u8, // Has no effect on fonts - }) - .translate(Point::new(175, 250)) - .into_iter(), - ); - - // use bigger/different font - display.draw( - Font12x16::render_str("It's working-BoW!") - // Using Style here - .style(Style { - fill_color: Some(Color::White), - stroke_color: Some(Color::Black), - stroke_width: 0u8, // Has no effect on fonts - }) - .translate(Point::new(50, 200)) - .into_iter(), - ); - - // a moving `Hello World!` - let limit = 10; - for i in 0..limit { - println!("Moving Hello World. Loop {} from {}", (i + 1), limit); - - display.draw( - Font6x8::render_str(" Hello World! ") - .style(Style { - fill_color: Some(Color::White), - stroke_color: Some(Color::Black), - stroke_width: 0u8, // Has no effect on fonts - }) - .translate(Point::new(5 + i * 12, 50)) - .into_iter(), - ); - - epd7in5.update_frame(&mut spi, &display.buffer()).unwrap(); - epd7in5 - .display_frame(&mut spi) - .expect("display frame new graphics"); - - delay.delay_ms(1_000u16); - } - - println!("Finished tests - going to sleep"); - epd7in5.sleep(&mut spi) -} diff --git a/src/color.rs b/src/color.rs index b6ca8fc..92b9f41 100644 --- a/src/color.rs +++ b/src/color.rs @@ -1,9 +1,13 @@ //! B/W Color for EPDs +#[cfg(feature = "graphics")] use embedded_graphics::pixelcolor::BinaryColor; +#[cfg(feature = "graphics")] pub use BinaryColor::Off as White; +#[cfg(feature = "graphics")] pub use BinaryColor::On as Black; + /// Only for the Black/White-Displays #[derive(Clone, Copy, PartialEq, Debug)] pub enum Color { diff --git a/src/epd1in54/mod.rs b/src/epd1in54/mod.rs index 8078676..95ed53b 100644 --- a/src/epd1in54/mod.rs +++ b/src/epd1in54/mod.rs @@ -2,7 +2,7 @@ //! //! # Example for the 1.54 in E-Ink Display //! -//! ```rust,ignore +//! ```rust,no_run //! use epd_waveshare::{ //! epd1in54::{EPD1in54, Display1in54}, //! graphics::{Display, DisplayRotation}, @@ -17,13 +17,9 @@ //! let mut display = Display1in54::default(); //! //! // Write some hello world in the screenbuffer -//! display.draw( -//! Font6x8::render_str("Hello World!") -//! .stroke(Some(Color::Black)) -//! .fill(Some(Color::White)) -//! .translate(Point::new(5, 50)) -//! .into_iter(), -//! ); +//! let _ = Line::new(Point::new(0, 120), Point::new(0, 295)) +//! .into_styled(PrimitiveStyle::with_stroke(BinaryColor::On, 1)) +//! .draw(&mut display); //! //! // Display updated frame //! epd.update_frame(&mut spi, &display.buffer()).unwrap(); diff --git a/src/lib.rs b/src/lib.rs index 7f31513..88e54b0 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -64,31 +64,18 @@ pub mod color; /// Interface for the physical connection between display and the controlling device mod interface; -#[cfg(feature = "epd7in5")] -pub mod epd7in5; -#[cfg(feature = "epd7in5_v2")] -pub mod epd7in5_v2; - -#[cfg(feature = "epd4in2")] -pub mod epd4in2; - -#[cfg(feature = "epd1in54")] pub mod epd1in54; - -#[cfg(feature = "epd1in54b")] pub mod epd1in54b; - -#[cfg(feature = "epd2in9")] pub mod epd2in9; - -#[cfg(any(feature = "epd1in54", feature = "epd2in9"))] +pub mod epd4in2; +pub mod epd7in5; +pub mod epd7in5_v2; pub(crate) mod type_a; pub mod prelude { pub use crate::color::Color; pub use crate::traits::{RefreshLUT, WaveshareDisplay, WaveshareThreeColorDisplay}; - #[cfg(feature = "epd7in5_v2")] pub use crate::traits::WaveshareDisplayExt; pub use crate::SPI_MODE; From ec72357b55ae2f85552099c7d54e25ef588543f0 Mon Sep 17 00:00:00 2001 From: Caemor <11088935+caemor@users.noreply.github.com> Date: Sun, 22 Mar 2020 00:42:20 +0100 Subject: [PATCH 03/15] Update/Include new update_and_display trait --- src/epd1in54/mod.rs | 28 +++++++++++++--------------- src/epd1in54b/mod.rs | 19 +++++++++++-------- src/epd2in9/mod.rs | 29 +++++++++++++++-------------- src/epd4in2/mod.rs | 22 +++++++++++----------- src/epd7in5/mod.rs | 16 +++++++++------- src/epd7in5_v2/mod.rs | 36 +++++++++++------------------------- src/lib.rs | 2 -- src/traits.rs | 15 +++------------ 8 files changed, 73 insertions(+), 94 deletions(-) diff --git a/src/epd1in54/mod.rs b/src/epd1in54/mod.rs index 95ed53b..2927730 100644 --- a/src/epd1in54/mod.rs +++ b/src/epd1in54/mod.rs @@ -175,21 +175,19 @@ where } fn sleep(&mut self, spi: &mut SPI) -> Result<(), SPI::Error> { + self.wait_until_idle(); // 0x00 for Normal mode (Power on Reset), 0x01 for Deep Sleep Mode //TODO: is 0x00 needed here or would 0x01 be even more efficient? self.interface .cmd_with_data(spi, Command::DEEP_SLEEP_MODE, &[0x00])?; - - self.wait_until_idle(); Ok(()) } fn update_frame(&mut self, spi: &mut SPI, buffer: &[u8]) -> Result<(), SPI::Error> { + self.wait_until_idle(); self.use_full_frame(spi)?; self.interface .cmd_with_data(spi, Command::WRITE_RAM, buffer)?; - - self.wait_until_idle(); Ok(()) } @@ -203,17 +201,17 @@ where width: u32, height: u32, ) -> Result<(), SPI::Error> { + self.wait_until_idle(); self.set_ram_area(spi, x, y, x + width, y + height)?; self.set_ram_counter(spi, x, y)?; self.interface .cmd_with_data(spi, Command::WRITE_RAM, buffer)?; - - self.wait_until_idle(); Ok(()) } fn display_frame(&mut self, spi: &mut SPI) -> Result<(), SPI::Error> { + self.wait_until_idle(); // enable clock signal, enable cp, display pattern -> 0xC4 (tested with the arduino version) //TODO: test control_1 or control_2 with default value 0xFF (from the datasheet) self.interface @@ -223,12 +221,17 @@ where // MASTER Activation should not be interupted to avoid currption of panel images // therefore a terminate command is send self.interface.cmd(spi, Command::NOP)?; + Ok(()) + } - self.wait_until_idle(); + fn update_and_display_frame(&mut self, spi: &mut SPI, buffer: &[u8]) -> Result<(), SPI::Error> { + self.update_frame(spi, buffer)?; + self.display_frame(spi)?; Ok(()) } fn clear_frame(&mut self, spi: &mut SPI) -> Result<(), SPI::Error> { + self.wait_until_idle(); self.use_full_frame(spi)?; // clear the ram with the background color @@ -237,8 +240,6 @@ where self.interface.cmd(spi, Command::WRITE_RAM)?; self.interface .data_x_times(spi, color, WIDTH / 8 * HEIGHT)?; - - self.wait_until_idle(); Ok(()) } @@ -297,6 +298,7 @@ where end_x: u32, end_y: u32, ) -> Result<(), SPI::Error> { + self.wait_until_idle(); assert!(start_x < end_x); assert!(start_y < end_y); @@ -319,8 +321,6 @@ where (end_y >> 8) as u8, ], )?; - - self.wait_until_idle(); Ok(()) } @@ -330,6 +330,7 @@ where x: u32, y: u32, ) -> Result<(), SPI::Error> { + self.wait_until_idle(); // x is positioned in bytes, so the last 3 bits which show the position inside a byte in the ram // aren't relevant self.interface @@ -341,18 +342,15 @@ where Command::SET_RAM_Y_ADDRESS_COUNTER, &[y as u8, (y >> 8) as u8], )?; - - self.wait_until_idle(); Ok(()) } fn set_lut_helper(&mut self, spi: &mut SPI, buffer: &[u8]) -> Result<(), SPI::Error> { + self.wait_until_idle(); assert!(buffer.len() == 30); self.interface .cmd_with_data(spi, Command::WRITE_LUT_REGISTER, buffer)?; - - self.wait_until_idle(); Ok(()) } } diff --git a/src/epd1in54b/mod.rs b/src/epd1in54b/mod.rs index 75bd987..52d402f 100644 --- a/src/epd1in54b/mod.rs +++ b/src/epd1in54b/mod.rs @@ -100,6 +100,7 @@ where black: &[u8], red: &[u8], ) -> Result<(), SPI::Error> { + self.wait_until_idle(); self.send_resolution(spi)?; self.interface @@ -113,8 +114,6 @@ where self.interface .cmd(spi, Command::DATA_START_TRANSMISSION_2)?; self.interface.data(spi, red)?; - - self.wait_until_idle(); Ok(()) } } @@ -147,6 +146,7 @@ where } fn sleep(&mut self, spi: &mut SPI) -> Result<(), SPI::Error> { + self.wait_until_idle(); self.interface .cmd_with_data(spi, Command::VCOM_AND_DATA_INTERVAL_SETTING, &[0x17])?; //border floating @@ -190,6 +190,7 @@ where } fn update_frame(&mut self, spi: &mut SPI, buffer: &[u8]) -> Result<(), SPI::Error> { + self.wait_until_idle(); self.send_resolution(spi)?; self.interface @@ -212,8 +213,6 @@ where self.interface.data_x_times(spi, color, nbits)?; //NOTE: Example code has a delay here - - self.wait_until_idle(); Ok(()) } @@ -227,17 +226,23 @@ where width: u32, height: u32, ) -> Result<(), SPI::Error> { - Ok(()) + unimplemented!() } fn display_frame(&mut self, spi: &mut SPI) -> Result<(), SPI::Error> { + self.wait_until_idle(); self.command(spi, Command::DISPLAY_REFRESH)?; + Ok(()) + } - self.wait_until_idle(); + fn update_and_display_frame(&mut self, spi: &mut SPI, buffer: &[u8]) -> Result<(), SPI::Error> { + self.update_frame(spi, buffer)?; + self.display_frame(spi)?; Ok(()) } fn clear_frame(&mut self, spi: &mut SPI) -> Result<(), SPI::Error> { + self.wait_until_idle(); self.send_resolution(spi)?; let color = DEFAULT_BACKGROUND_COLOR.get_byte_value(); @@ -255,8 +260,6 @@ where .cmd(spi, Command::DATA_START_TRANSMISSION_2)?; self.interface .data_x_times(spi, color, WIDTH * HEIGHT / 8)?; - - self.wait_until_idle(); Ok(()) } diff --git a/src/epd2in9/mod.rs b/src/epd2in9/mod.rs index 3bd61db..28c283b 100644 --- a/src/epd2in9/mod.rs +++ b/src/epd2in9/mod.rs @@ -87,6 +87,8 @@ where ) -> Result<(), SPI::Error> { self.interface.reset(delay); + self.wait_until_idle(); + // 3 Databytes: // A[7:0] // 0.. A[8] @@ -166,12 +168,11 @@ where } fn sleep(&mut self, spi: &mut SPI) -> Result<(), SPI::Error> { + self.wait_until_idle(); // 0x00 for Normal mode (Power on Reset), 0x01 for Deep Sleep Mode //TODO: is 0x00 needed here? (see also epd1in54) self.interface .cmd_with_data(spi, Command::DEEP_SLEEP_MODE, &[0x00])?; - - self.wait_until_idle(); Ok(()) } @@ -180,19 +181,17 @@ where spi: &mut SPI, delay: &mut DELAY, ) -> Result<(), SPI::Error> { - self.init(spi, delay)?; - self.wait_until_idle(); + self.init(spi, delay)?; Ok(()) } fn update_frame(&mut self, spi: &mut SPI, buffer: &[u8]) -> Result<(), SPI::Error> { + self.wait_until_idle(); self.use_full_frame(spi)?; self.interface .cmd_with_data(spi, Command::WRITE_RAM, buffer)?; - - self.wait_until_idle(); Ok(()) } @@ -206,17 +205,17 @@ where width: u32, height: u32, ) -> Result<(), SPI::Error> { + self.wait_until_idle(); self.set_ram_area(spi, x, y, x + width, y + height)?; self.set_ram_counter(spi, x, y)?; self.interface .cmd_with_data(spi, Command::WRITE_RAM, buffer)?; - - self.wait_until_idle(); Ok(()) } fn display_frame(&mut self, spi: &mut SPI) -> Result<(), SPI::Error> { + self.wait_until_idle(); // enable clock signal, enable cp, display pattern -> 0xC4 (tested with the arduino version) //TODO: test control_1 or control_2 with default value 0xFF (from the datasheet) self.interface @@ -226,12 +225,17 @@ where // MASTER Activation should not be interupted to avoid currption of panel images // therefore a terminate command is send self.interface.cmd(spi, Command::NOP)?; + Ok(()) + } - self.wait_until_idle(); + fn update_and_display_frame(&mut self, spi: &mut SPI, buffer: &[u8]) -> Result<(), SPI::Error> { + self.update_frame(spi, buffer)?; + self.display_frame(spi)?; Ok(()) } fn clear_frame(&mut self, spi: &mut SPI) -> Result<(), SPI::Error> { + self.wait_until_idle(); self.use_full_frame(spi)?; // clear the ram with the background color @@ -240,8 +244,6 @@ where self.interface.cmd(spi, Command::WRITE_RAM)?; self.interface .data_x_times(spi, color, WIDTH / 8 * HEIGHT)?; - - self.wait_until_idle(); Ok(()) } @@ -325,6 +327,7 @@ where } fn set_ram_counter(&mut self, spi: &mut SPI, x: u32, y: u32) -> Result<(), SPI::Error> { + self.wait_until_idle(); // x is positioned in bytes, so the last 3 bits which show the position inside a byte in the ram // aren't relevant self.interface @@ -336,17 +339,15 @@ where Command::SET_RAM_Y_ADDRESS_COUNTER, &[y as u8, (y >> 8) as u8], )?; - - self.wait_until_idle(); Ok(()) } /// Set your own LUT, this function is also used internally for set_lut fn set_lut_helper(&mut self, spi: &mut SPI, buffer: &[u8]) -> Result<(), SPI::Error> { + self.wait_until_idle(); assert!(buffer.len() == 30); self.interface .cmd_with_data(spi, Command::WRITE_LUT_REGISTER, buffer)?; - self.wait_until_idle(); Ok(()) } } diff --git a/src/epd4in2/mod.rs b/src/epd4in2/mod.rs index f983083..7772ad4 100644 --- a/src/epd4in2/mod.rs +++ b/src/epd4in2/mod.rs @@ -188,6 +188,7 @@ where } fn sleep(&mut self, spi: &mut SPI) -> Result<(), SPI::Error> { + self.wait_until_idle(); self.interface .cmd_with_data(spi, Command::VCOM_AND_DATA_INTERVAL_SETTING, &[0x17])?; //border floating self.command(spi, Command::VCM_DC_SETTING)?; // VCOM to 0V @@ -202,12 +203,11 @@ where self.wait_until_idle(); self.interface .cmd_with_data(spi, Command::DEEP_SLEEP, &[0xA5])?; - - self.wait_until_idle(); Ok(()) } fn update_frame(&mut self, spi: &mut SPI, buffer: &[u8]) -> Result<(), SPI::Error> { + self.wait_until_idle(); let color_value = self.color.get_byte_value(); self.send_resolution(spi)?; @@ -226,8 +226,6 @@ where self.interface .cmd_with_data(spi, Command::DATA_START_TRANSMISSION_2, buffer)?; - - self.wait_until_idle(); Ok(()) } @@ -240,6 +238,7 @@ where width: u32, height: u32, ) -> Result<(), SPI::Error> { + self.wait_until_idle(); if buffer.len() as u32 != width / 8 * height { //TODO: panic!! or sth like that //return Err("Wrong buffersize"); @@ -273,19 +272,23 @@ where self.send_data(spi, buffer)?; self.command(spi, Command::PARTIAL_OUT)?; - - self.wait_until_idle(); Ok(()) } fn display_frame(&mut self, spi: &mut SPI) -> Result<(), SPI::Error> { + self.wait_until_idle(); self.command(spi, Command::DISPLAY_REFRESH)?; + Ok(()) + } - self.wait_until_idle(); + fn update_and_display_frame(&mut self, spi: &mut SPI, buffer: &[u8]) -> Result<(), SPI::Error> { + self.update_frame(spi, buffer)?; + self.command(spi, Command::DISPLAY_REFRESH)?; Ok(()) } fn clear_frame(&mut self, spi: &mut SPI) -> Result<(), SPI::Error> { + self.wait_until_idle(); self.send_resolution(spi)?; let color_value = self.color.get_byte_value(); @@ -299,8 +302,6 @@ where .cmd(spi, Command::DATA_START_TRANSMISSION_2)?; self.interface .data_x_times(spi, color_value, WIDTH / 8 * HEIGHT)?; - - self.wait_until_idle(); Ok(()) } @@ -397,6 +398,7 @@ where lut_wb: &[u8], lut_bb: &[u8], ) -> Result<(), SPI::Error> { + self.wait_until_idle(); // LUT VCOM self.cmd_with_data(spi, Command::LUT_FOR_VCOM, lut_vcom)?; @@ -411,8 +413,6 @@ where // LUT BLACK to BLACK self.cmd_with_data(spi, Command::LUT_BLACK_TO_BLACK, lut_bb)?; - - self.wait_until_idle(); Ok(()) } } diff --git a/src/epd7in5/mod.rs b/src/epd7in5/mod.rs index 42711d8..f30c396 100644 --- a/src/epd7in5/mod.rs +++ b/src/epd7in5/mod.rs @@ -150,15 +150,15 @@ where } fn sleep(&mut self, spi: &mut SPI) -> Result<(), SPI::Error> { + self.wait_until_idle(); self.command(spi, Command::POWER_OFF)?; self.wait_until_idle(); self.cmd_with_data(spi, Command::DEEP_SLEEP, &[0xA5])?; - - self.wait_until_idle(); Ok(()) } fn update_frame(&mut self, spi: &mut SPI, buffer: &[u8]) -> Result<(), SPI::Error> { + self.wait_until_idle(); self.command(spi, Command::DATA_START_TRANSMISSION_1)?; for byte in buffer { let mut temp = *byte; @@ -171,8 +171,6 @@ where self.send_data(spi, &[data])?; } } - - self.wait_until_idle(); Ok(()) } @@ -189,21 +187,25 @@ where } fn display_frame(&mut self, spi: &mut SPI) -> Result<(), SPI::Error> { + self.wait_until_idle(); self.command(spi, Command::DISPLAY_REFRESH)?; + Ok(()) + } - self.wait_until_idle(); + fn update_and_display_frame(&mut self, spi: &mut SPI, buffer: &[u8]) -> Result<(), SPI::Error> { + self.update_frame(spi, buffer)?; + self.command(spi, Command::DISPLAY_REFRESH)?; Ok(()) } fn clear_frame(&mut self, spi: &mut SPI) -> Result<(), SPI::Error> { + self.wait_until_idle(); self.send_resolution(spi)?; // The Waveshare controllers all implement clear using 0x33 self.command(spi, Command::DATA_START_TRANSMISSION_1)?; self.interface .data_x_times(spi, 0x33, WIDTH / 8 * HEIGHT * 4)?; - - self.wait_until_idle(); Ok(()) } diff --git a/src/epd7in5_v2/mod.rs b/src/epd7in5_v2/mod.rs index e1d95ca..68c9a46 100644 --- a/src/epd7in5_v2/mod.rs +++ b/src/epd7in5_v2/mod.rs @@ -17,7 +17,7 @@ use embedded_hal::{ use crate::color::Color; use crate::interface::DisplayInterface; -use crate::traits::{InternalWiAdditions, RefreshLUT, WaveshareDisplay, WaveshareDisplayExt}; +use crate::traits::{InternalWiAdditions, RefreshLUT, WaveshareDisplay}; pub(crate) mod command; use self::command::Command; @@ -132,6 +132,7 @@ where } fn sleep(&mut self, spi: &mut SPI) -> Result<(), SPI::Error> { + self.wait_until_idle(); self.command(spi, Command::POWER_OFF)?; self.wait_until_idle(); self.cmd_with_data(spi, Command::DEEP_SLEEP, &[0xA5])?; @@ -139,9 +140,8 @@ where } fn update_frame(&mut self, spi: &mut SPI, buffer: &[u8]) -> Result<(), SPI::Error> { - self.command(spi, Command::DATA_START_TRANSMISSION_2)?; - self.send_data(spi, buffer)?; self.wait_until_idle(); + self.cmd_with_data(spi, Command::DATA_START_TRANSMISSION_2, buffer)?; Ok(()) } @@ -158,12 +158,19 @@ where } fn display_frame(&mut self, spi: &mut SPI) -> Result<(), SPI::Error> { - self.command(spi, Command::DISPLAY_REFRESH)?; self.wait_until_idle(); + self.command(spi, Command::DISPLAY_REFRESH)?; + Ok(()) + } + + fn update_and_display_frame(&mut self, spi: &mut SPI, buffer: &[u8]) -> Result<(), SPI::Error> { + self.update_frame(spi, buffer)?; + self.command(spi, Command::DISPLAY_REFRESH)?; Ok(()) } fn clear_frame(&mut self, spi: &mut SPI) -> Result<(), SPI::Error> { + self.wait_until_idle(); self.send_resolution(spi)?; self.command(spi, Command::DATA_START_TRANSMISSION_1)?; @@ -173,7 +180,6 @@ where self.interface.data_x_times(spi, 0x00, WIDTH * HEIGHT / 8)?; self.command(spi, Command::DISPLAY_REFRESH)?; - self.wait_until_idle(); Ok(()) } @@ -206,26 +212,6 @@ where } } -impl WaveshareDisplayExt - for EPD7in5 -where - SPI: Write, - CS: OutputPin, - BUSY: InputPin, - DC: OutputPin, - RST: OutputPin, -{ - fn update_and_display_frame(&mut self, spi: &mut SPI, buffer: &[u8]) -> Result<(), SPI::Error> { - self.command(spi, Command::DATA_START_TRANSMISSION_2)?; - for b in buffer { - self.send_data(spi, &[255 - b])?; - } - self.command(spi, Command::DISPLAY_REFRESH)?; - self.wait_until_idle(); - Ok(()) - } -} - impl EPD7in5 where SPI: Write, diff --git a/src/lib.rs b/src/lib.rs index 88e54b0..5d8c9d8 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -76,8 +76,6 @@ pub mod prelude { pub use crate::color::Color; pub use crate::traits::{RefreshLUT, WaveshareDisplay, WaveshareThreeColorDisplay}; - pub use crate::traits::WaveshareDisplayExt; - pub use crate::SPI_MODE; #[cfg(feature = "graphics")] diff --git a/src/traits.rs b/src/traits.rs index 9f83da5..91352ee 100644 --- a/src/traits.rs +++ b/src/traits.rs @@ -148,6 +148,9 @@ where /// This function waits until the device isn`t busy anymore fn display_frame(&mut self, spi: &mut SPI) -> Result<(), SPI::Error>; + /// Provide a combined update&display and save some time (skipping a busy check in between) + fn update_and_display_frame(&mut self, spi: &mut SPI, buffer: &[u8]) -> Result<(), SPI::Error>; + /// Clears the frame buffer on the EPD with the declared background color /// /// The background color can be changed with [`set_background_color`] @@ -174,15 +177,3 @@ where /// if the device is still busy fn is_busy(&self) -> bool; } -/// Tiny optional extension trait -pub trait WaveshareDisplayExt -where - SPI: Write, - CS: OutputPin, - BUSY: InputPin, - DC: OutputPin, - RST: OutputPin, -{ - // provide a combined update&display and save some time (skipping a busy check in between) - fn update_and_display_frame(&mut self, spi: &mut SPI, buffer: &[u8]) -> Result<(), SPI::Error>; -} From dcc264c2b0a5dea87fda2a3d619750fbf58058a4 Mon Sep 17 00:00:00 2001 From: Caemor <11088935+caemor@users.noreply.github.com> Date: Thu, 26 Mar 2020 17:19:55 +0100 Subject: [PATCH 04/15] Replace tabs with spaces --- src/type_a/command.rs | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/src/type_a/command.rs b/src/type_a/command.rs index 30a2df6..e966aa9 100644 --- a/src/type_a/command.rs +++ b/src/type_a/command.rs @@ -12,28 +12,28 @@ use crate::traits; #[derive(Copy, Clone)] pub(crate) enum Command { /// Driver Output control - /// 3 Databytes: - /// A[7:0] - /// 0.. A[8] - /// 0.. B[2:0] - /// Default: Set A[8:0] = 0x127 and B[2:0] = 0x0 + /// 3 Databytes: + /// A[7:0] + /// 0.. A[8] + /// 0.. B[2:0] + /// Default: Set A[8:0] = 0x127 and B[2:0] = 0x0 DRIVER_OUTPUT_CONTROL = 0x01, /// Booster Soft start control - /// 3 Databytes: - /// 1.. A[6:0] - /// 1.. B[6:0] - /// 1.. C[6:0] - /// Default: A[7:0] = 0xCF, B[7:0] = 0xCE, C[7:0] = 0x8D + /// 3 Databytes: + /// 1.. A[6:0] + /// 1.. B[6:0] + /// 1.. C[6:0] + /// Default: A[7:0] = 0xCF, B[7:0] = 0xCE, C[7:0] = 0x8D BOOSTER_SOFT_START_CONTROL = 0x0C, GATE_SCAN_START_POSITION = 0x0F, //TODO: useful? // GATE_SCAN_START_POSITION = 0x0F, /// Deep Sleep Mode Control - /// 1 Databyte: - /// 0.. A[0] - /// Values: - /// A[0] = 0: Normal Mode (POR) - /// A[0] = 1: Enter Deep Sleep Mode + /// 1 Databyte: + /// 0.. A[0] + /// Values: + /// A[0] = 0: Normal Mode (POR) + /// A[0] = 1: Enter Deep Sleep Mode DEEP_SLEEP_MODE = 0x10, // /// Data Entry mode setting DATA_ENTRY_MODE_SETTING = 0x11, From 1dfea538b7ab5c52fcab6e8006945daf358904c3 Mon Sep 17 00:00:00 2001 From: Caemor <11088935+caemor@users.noreply.github.com> Date: Thu, 26 Mar 2020 17:33:54 +0100 Subject: [PATCH 05/15] Update changelog and ci --- .github/workflows/rust.yml | 10 ++++++---- CHANGELOG.md | 5 +++++ 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 923e565..71d1ca5 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -25,11 +25,13 @@ jobs: - name: Check Fmt run: cargo fmt --all -- --check - name: Build lib - run: cargo check --verbose + run: cargo check --all-targets --verbose - name: Clippy run: cargo clippy --all-targets --all-features -- -D warnings -A clippy::new_ret_no_self - name: Build examples - run: cargo build --examples --verbose - #- name: Run tests - # run: cargo test --verbose + run: cargo build --examples --all-targets --verbose + - name: Run tests + run: cargo test --verbose + - name: Build docs + run: cargo doc --all-features diff --git a/CHANGELOG.md b/CHANGELOG.md index 459d601..b06b281 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,11 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/). ## [Unreleased] + - Update embedded-graphics, + - Remove useless Featuregates (Doesn't change size) + - Update and integrate a few important examples and remove the others + - Add update_and_display_frame to the main trait, fixes #38 + - Also improve position of busy_wait (#30) once more From 409676423de7465b95db6d4ce67793bc7eb6e582 Mon Sep 17 00:00:00 2001 From: Caemor <11088935+caemor@users.noreply.github.com> Date: Thu, 26 Mar 2020 19:55:17 +0100 Subject: [PATCH 06/15] Mainly improved Documenation --- CHANGELOG.md | 2 + README.md | 6 +-- src/epd1in54/mod.rs | 58 +++++++++++++++--------- src/epd1in54b/graphics.rs | 3 ++ src/epd1in54b/mod.rs | 3 ++ src/epd2in9/mod.rs | 61 ++++++++++++++----------- src/epd4in2/mod.rs | 79 +++++++++++++++----------------- src/epd7in5/mod.rs | 21 ++------- src/epd7in5_v2/mod.rs | 21 ++------- src/graphics.rs | 9 ++++ src/lib.rs | 95 +++++++++++++++++++++------------------ src/traits.rs | 57 +++++++++++++++++++---- 12 files changed, 230 insertions(+), 185 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b06b281..873d235 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - Update and integrate a few important examples and remove the others - Add update_and_display_frame to the main trait, fixes #38 - Also improve position of busy_wait (#30) once more + - Fixed all doc tests + - Some more documentation improvements diff --git a/README.md b/README.md index 2771eb9..5ac5ce0 100644 --- a/README.md +++ b/README.md @@ -45,7 +45,7 @@ epd.display_frame(&mut spi)?; | [4.2 Inch B/W (A)](https://www.waveshare.com/product/4.2inch-e-paper-module.htm) | Black, White | ✕ | Not officially [[2](#2-42-inch-e-ink-blackwhite---partial-refresh)] | ✔ | ✔ | | [1.54 Inch B/W (A)](https://www.waveshare.com/1.54inch-e-Paper-Module.htm) | Black, White | ✕ | ✔ | ✔ | ✔ | | [2.13 Inch B/W (A)](https://www.waveshare.com/product/2.13inch-e-paper-hat.htm) | Black, White | ✕ | ✔ | | | -| [2.9 Inch B/W (A)](https://www.waveshare.com/product/2.9inch-e-paper-module.htm) | Black, White | ✕ | ✔ | ✔ | ✔ [[3](#3-29-inch-e-ink-blackwhite---tests)] | +| [2.9 Inch B/W (A)](https://www.waveshare.com/product/2.9inch-e-paper-module.htm) | Black, White | ✕ | ✔ | ✔ | ✔ | | [1.54 Inch B/W/R (B)](https://www.waveshare.com/product/modules/oleds-lcds/e-paper/1.54inch-e-paper-module-b.htm) | Black, White, Red | ✕ | ✕ | ✔ | ✔ | ### [1]: 7.5 Inch B/W V2 (A) @@ -62,10 +62,6 @@ Out of the Box the original driver from Waveshare only supports full updates. That means: Be careful with the quick refresh updates:
It's possible with this driver but might lead to ghosting / burn-in effects therefore it's hidden behind a feature. -### [3]: 2.9 Inch E-Ink Black/White - Tests - -Since my 2.9 Inch Display has some blurring issues I am not absolutly sure if everything was working correctly as it should :-) - ### Interface | Interface | Description | diff --git a/src/epd1in54/mod.rs b/src/epd1in54/mod.rs index 2927730..bc5cd5b 100644 --- a/src/epd1in54/mod.rs +++ b/src/epd1in54/mod.rs @@ -2,37 +2,51 @@ //! //! # Example for the 1.54 in E-Ink Display //! -//! ```rust,no_run -//! use epd_waveshare::{ -//! epd1in54::{EPD1in54, Display1in54}, -//! graphics::{Display, DisplayRotation}, -//! prelude::*, -//! }; -//! use embedded_graphics::Drawing; +//!```rust, no_run +//!# use embedded_hal_mock::*; +//!# fn main() -> Result<(), MockError> { +//!use embedded_graphics::{ +//! pixelcolor::BinaryColor::On as Black, prelude::*, primitives::Line, style::PrimitiveStyle, +//!}; +//!use epd_waveshare::{epd1in54::*, prelude::*}; +//!# +//!# let expectations = []; +//!# let mut spi = spi::Mock::new(&expectations); +//!# let expectations = []; +//!# let cs_pin = pin::Mock::new(&expectations); +//!# let busy_in = pin::Mock::new(&expectations); +//!# let dc = pin::Mock::new(&expectations); +//!# let rst = pin::Mock::new(&expectations); +//!# let mut delay = delay::MockNoop::new(); //! -//! // Setup EPD -//! let mut epd = EPD1in54::new(&mut spi, cs_pin, busy_in, dc, rst, &mut delay).unwrap(); +//!// Setup EPD +//!let mut epd = EPD1in54::new(&mut spi, cs_pin, busy_in, dc, rst, &mut delay)?; //! -//! // Use display graphics -//! let mut display = Display1in54::default(); +//!// Use display graphics from embedded-graphics +//!let mut display = Display1in54::default(); //! -//! // Write some hello world in the screenbuffer -//! let _ = Line::new(Point::new(0, 120), Point::new(0, 295)) -//! .into_styled(PrimitiveStyle::with_stroke(BinaryColor::On, 1)) -//! .draw(&mut display); +//!// Use embedded graphics for drawing a line +//!let _ = Line::new(Point::new(0, 120), Point::new(0, 295)) +//! .into_styled(PrimitiveStyle::with_stroke(Black, 1)) +//! .draw(&mut display); //! -//! // Display updated frame -//! epd.update_frame(&mut spi, &display.buffer()).unwrap(); -//! epd.display_frame(&mut spi).expect("display frame new graphics"); +//! // Display updated frame +//!epd.update_frame(&mut spi, &display.buffer())?; +//!epd.display_frame(&mut spi)?; //! -//! // Set the EPD to sleep -//! epd.sleep(&mut spi).expect("sleep"); -//! ``` +//!// Set the EPD to sleep +//!epd.sleep(&mut spi)?; +//!# Ok(()) +//!# } +//!``` +/// Width of the display pub const WIDTH: u32 = 200; +/// Height of the display pub const HEIGHT: u32 = 200; -//const DPI: u16 = 184; +/// Default Background Color pub const DEFAULT_BACKGROUND_COLOR: Color = Color::White; +//const DPI: u16 = 184; const IS_BUSY_LOW: bool = false; use embedded_hal::{ diff --git a/src/epd1in54b/graphics.rs b/src/epd1in54b/graphics.rs index a1e83e1..617d697 100644 --- a/src/epd1in54b/graphics.rs +++ b/src/epd1in54b/graphics.rs @@ -3,6 +3,9 @@ use crate::graphics::{Display, DisplayRotation}; use embedded_graphics::pixelcolor::BinaryColor; use embedded_graphics::prelude::*; +/// Full size buffer for use with the 1in54 EPD +/// +/// Can also be manually constructed and be used together with VarDisplay pub struct Display1in54b { buffer: [u8; WIDTH as usize * HEIGHT as usize / 8], rotation: DisplayRotation, diff --git a/src/epd1in54b/mod.rs b/src/epd1in54b/mod.rs index 52d402f..9244093 100644 --- a/src/epd1in54b/mod.rs +++ b/src/epd1in54b/mod.rs @@ -14,8 +14,11 @@ use crate::traits::{ mod constants; use crate::epd1in54b::constants::*; +/// Width of epd1in54 in pixels pub const WIDTH: u32 = 200; +/// Height of epd1in54 in pixels pub const HEIGHT: u32 = 200; +/// Default Background Color (white) pub const DEFAULT_BACKGROUND_COLOR: Color = Color::White; const IS_BUSY_LOW: bool = true; diff --git a/src/epd2in9/mod.rs b/src/epd2in9/mod.rs index 28c283b..6ccd551 100644 --- a/src/epd2in9/mod.rs +++ b/src/epd2in9/mod.rs @@ -1,42 +1,51 @@ //! A simple Driver for the Waveshare 2.9" E-Ink Display via SPI //! -//! Untested! //! //! # Example for the 2.9 in E-Ink Display //! -//! ```rust,ignore -//! use epd_waveshare::{ -//! epd2in9::{EPD2in9, Display2in9}, -//! graphics::{Display, DisplayRotation}, -//! prelude::*, -//! }; -//! use embedded_graphics::Drawing; +//!```rust, no_run +//!# use embedded_hal_mock::*; +//!# fn main() -> Result<(), MockError> { +//!use embedded_graphics::{ +//! pixelcolor::BinaryColor::On as Black, prelude::*, primitives::Line, style::PrimitiveStyle, +//!}; +//!use epd_waveshare::{epd2in9::*, prelude::*}; +//!# +//!# let expectations = []; +//!# let mut spi = spi::Mock::new(&expectations); +//!# let expectations = []; +//!# let cs_pin = pin::Mock::new(&expectations); +//!# let busy_in = pin::Mock::new(&expectations); +//!# let dc = pin::Mock::new(&expectations); +//!# let rst = pin::Mock::new(&expectations); +//!# let mut delay = delay::MockNoop::new(); //! -//! // Setup EPD -//! let mut epd = EPD2in9::new(&mut spi, cs_pin, busy_in, dc, rst, &mut delay).unwrap(); +//!// Setup EPD +//!let mut epd = EPD2in9::new(&mut spi, cs_pin, busy_in, dc, rst, &mut delay)?; //! -//! // Use display graphics -//! let mut display = Display2in9::default(); +//!// Use display graphics from embedded-graphics +//!let mut display = Display2in9::default(); //! -//! // Write some hello world in the screenbuffer -//! display.draw( -//! Font6x8::render_str("Hello World!") -//! .stroke(Some(Color::Black)) -//! .fill(Some(Color::White)) -//! .translate(Point::new(5, 50)) -//! .into_iter(), -//! ); +//!// Use embedded graphics for drawing a line +//!let _ = Line::new(Point::new(0, 120), Point::new(0, 295)) +//! .into_styled(PrimitiveStyle::with_stroke(Black, 1)) +//! .draw(&mut display); //! -//! // Display updated frame -//! epd.update_frame(&mut spi, &display.buffer()).unwrap(); -//! epd.display_frame(&mut spi).expect("display frame new graphics"); +//! // Display updated frame +//!epd.update_frame(&mut spi, &display.buffer())?; +//!epd.display_frame(&mut spi)?; //! -//! // Set the EPD to sleep -//! epd.sleep(&mut spi).expect("sleep"); -//! ``` +//!// Set the EPD to sleep +//!epd.sleep(&mut spi)?; +//!# Ok(()) +//!# } +//!``` +/// Width of epd2in9 in pixels pub const WIDTH: u32 = 128; +/// Height of epd2in9 in pixels pub const HEIGHT: u32 = 296; +/// Default Background Color (white) pub const DEFAULT_BACKGROUND_COLOR: Color = Color::White; const IS_BUSY_LOW: bool = false; diff --git a/src/epd4in2/mod.rs b/src/epd4in2/mod.rs index 7772ad4..582b409 100644 --- a/src/epd4in2/mod.rs +++ b/src/epd4in2/mod.rs @@ -1,46 +1,49 @@ //! A simple Driver for the Waveshare 4.2" E-Ink Display via SPI //! -//! The other Waveshare E-Ink Displays should be added later on //! //! Build with the help of documentation/code from [Waveshare](https://www.waveshare.com/wiki/4.2inch_e-Paper_Module), //! [Ben Krasnows partial Refresh tips](https://benkrasnow.blogspot.de/2017/10/fast-partial-refresh-on-42-e-paper.html) and //! the driver documents in the `pdfs`-folder as orientation. //! -//! This driver was built using [`embedded-hal`] traits. -//! -//! [`embedded-hal`]: https://docs.rs/embedded-hal/~0.1 -//! -//! # Requirements -//! -//! ### SPI -//! -//! - MISO is not connected/available -//! - SPI_MODE_0 is used (CPHL = 0, CPOL = 0) -//! - 8 bits per word, MSB first -//! - Max. Speed tested was 8Mhz but more should be possible -//! -//! ### Other.... -//! -//! - Buffersize: Wherever a buffer is used it always needs to be of the size: `width / 8 * length`, -//! where width and length being either the full e-ink size or the partial update window size -//! //! # Examples //! -//! ```ignore -//! let mut epd4in2 = EPD4in2::new(spi, cs, busy, dc, rst, delay).unwrap(); -//! -//! let mut buffer = [0u8, epd4in2.get_width() / 8 * epd4in2.get_height()]; +//!```rust, no_run +//!# use embedded_hal_mock::*; +//!# fn main() -> Result<(), MockError> { +//!use embedded_graphics::{ +//! pixelcolor::BinaryColor::On as Black, prelude::*, primitives::Line, style::PrimitiveStyle, +//!}; +//!use epd_waveshare::{epd4in2::*, prelude::*}; +//!# +//!# let expectations = []; +//!# let mut spi = spi::Mock::new(&expectations); +//!# let expectations = []; +//!# let cs_pin = pin::Mock::new(&expectations); +//!# let busy_in = pin::Mock::new(&expectations); +//!# let dc = pin::Mock::new(&expectations); +//!# let rst = pin::Mock::new(&expectations); +//!# let mut delay = delay::MockNoop::new(); //! -//! // draw something into the buffer +//!// Setup EPD +//!let mut epd = EPD4in2::new(&mut spi, cs_pin, busy_in, dc, rst, &mut delay)?; //! -//! epd4in2.display_and_transfer_buffer(buffer, None); +//!// Use display graphics from embedded-graphics +//!let mut display = Display4in2::default(); //! -//! // wait and look at the image +//!// Use embedded graphics for drawing a line +//!let _ = Line::new(Point::new(0, 120), Point::new(0, 295)) +//! .into_styled(PrimitiveStyle::with_stroke(Black, 1)) +//! .draw(&mut display); //! -//! epd4in2.clear_frame(None); +//! // Display updated frame +//!epd.update_frame(&mut spi, &display.buffer())?; +//!epd.display_frame(&mut spi)?; //! -//! epd4in2.sleep(); -//! ``` +//!// Set the EPD to sleep +//!epd.sleep(&mut spi)?; +//!# Ok(()) +//!# } +//!``` //! //! //! @@ -58,8 +61,11 @@ use crate::traits::{InternalWiAdditions, RefreshLUT, WaveshareDisplay}; mod constants; use crate::epd4in2::constants::*; +/// Width of the display pub const WIDTH: u32 = 400; +/// Height of the display pub const HEIGHT: u32 = 300; +/// Default Background Color pub const DEFAULT_BACKGROUND_COLOR: Color = Color::White; const IS_BUSY_LOW: bool = true; @@ -142,21 +148,6 @@ where DC: OutputPin, RST: OutputPin, { - /// Creates a new driver from a SPI peripheral, CS Pin, Busy InputPin, DC - /// - /// This already initialises the device. That means [init()](init()) isn't needed directly afterwards - /// - /// # Example - /// - /// ```ignore - /// //buffer = some image data; - /// - /// let mut epd4in2 = EPD4in2::new(spi, cs, busy, dc, rst, delay); - /// - /// epd4in2.display_and_transfer_frame(buffer, None); - /// - /// epd4in2.sleep(); - /// ``` fn new>( spi: &mut SPI, cs: CS, diff --git a/src/epd7in5/mod.rs b/src/epd7in5/mod.rs index f30c396..2c6e76b 100644 --- a/src/epd7in5/mod.rs +++ b/src/epd7in5/mod.rs @@ -23,8 +23,11 @@ mod graphics; #[cfg(feature = "graphics")] pub use self::graphics::Display7in5; +/// Width of the display pub const WIDTH: u32 = 640; +/// Height of the display pub const HEIGHT: u32 = 384; +/// Default Background Color pub const DEFAULT_BACKGROUND_COLOR: Color = Color::White; const IS_BUSY_LOW: bool = true; @@ -105,24 +108,6 @@ where DC: OutputPin, RST: OutputPin, { - /// Creates a new driver from a SPI peripheral, CS Pin, Busy InputPin, DC - /// - /// This already initialises the device. That means [init()] isn't needed - /// directly afterwards. - /// - /// [init()]: InternalWiAdditions::init - /// - /// # Example - /// - /// ```ignore - /// //buffer = some image data; - /// - /// let mut epd7in5 = EPD7in5::new(spi, cs, busy, dc, rst, delay); - /// - /// epd7in5.display_and_transfer_frame(buffer, None); - /// - /// epd7in5.sleep(); - /// ``` fn new>( spi: &mut SPI, cs: CS, diff --git a/src/epd7in5_v2/mod.rs b/src/epd7in5_v2/mod.rs index 68c9a46..89d5614 100644 --- a/src/epd7in5_v2/mod.rs +++ b/src/epd7in5_v2/mod.rs @@ -27,8 +27,11 @@ mod graphics; #[cfg(feature = "graphics")] pub use self::graphics::Display7in5; +/// Width of the display pub const WIDTH: u32 = 800; +/// Height of the display pub const HEIGHT: u32 = 480; +/// Default Background Color pub const DEFAULT_BACKGROUND_COLOR: Color = Color::White; const IS_BUSY_LOW: bool = true; @@ -87,24 +90,6 @@ where DC: OutputPin, RST: OutputPin, { - /// Creates a new driver from a SPI peripheral, CS Pin, Busy InputPin, DC - /// - /// This already initialises the device. That means [init()] isn't needed - /// directly afterwards. - /// - /// [init()]: InternalWiAdditions::init - /// - /// # Example - /// - /// ```rust,ignore - /// //buffer = some image data; - /// - /// let mut epd7in5 = EPD7in5::new(spi, cs, busy, dc, rst, delay); - /// - /// epd7in5.update_and_display_frame(&mut spi, &buffer); - /// - /// epd7in5.sleep(); - /// ``` fn new>( spi: &mut SPI, cs: CS, diff --git a/src/graphics.rs b/src/graphics.rs index 49758d3..e8ff524 100644 --- a/src/graphics.rs +++ b/src/graphics.rs @@ -22,6 +22,12 @@ impl Default for DisplayRotation { } } +/// Necessary traits for all displays to implement for drawing +/// +/// Adds support for: +/// - Drawing (With the help of DrawTarget/Embedded Graphics) +/// - Rotations +/// - Clearing pub trait Display: DrawTarget { /// Clears the buffer of the display with the chosen background color fn clear_buffer(&mut self, background_color: Color) { @@ -112,6 +118,9 @@ pub struct VarDisplay<'a> { } impl<'a> VarDisplay<'a> { + /// Create a new variable sized display. + /// + /// Buffersize must be at least width / 8 * height bytes. pub fn new(width: u32, height: u32, buffer: &'a mut [u8]) -> VarDisplay<'a> { let len = buffer.len() as u32; assert!(width / 8 * height >= len); diff --git a/src/lib.rs b/src/lib.rs index 5d8c9d8..754c790 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,58 +1,66 @@ -//! A simple Driver for the Waveshare E-Ink Displays via SPI +//! A simple Driver for the [Waveshare](https://github.com/waveshare/e-Paper) E-Ink Displays via SPI //! -//! This driver was built using [`embedded-hal`] traits. +//! - Built using [`embedded-hal`] traits. +//! - Graphics support is added through [`embedded-graphics`] //! -//! [`embedded-hal`]: https://docs.rs/embedded-hal/~0.1 +//! [`embedded-graphics`]: https://docs.rs/embedded-graphics/ +//! [`embedded-hal`]: https://docs.rs/embedded-hal //! -//! # Requirements -//! -//! ### SPI -//! -//! - MISO is not connected/available -//! - SPI_MODE_0 is used (CPHL = 0, CPOL = 0) -//! - 8 bits per word, MSB first -//! - Max. Speed tested by myself was 8Mhz but more should be possible (Ben Krasnow used 18Mhz with his implemenation) + //! -//! ### Other.... +//! # Example +//! +//!```rust, no_run +//!# use embedded_hal_mock::*; +//!# fn main() -> Result<(), MockError> { +//!use embedded_graphics::{ +//! pixelcolor::BinaryColor::On as Black, prelude::*, primitives::Line, style::PrimitiveStyle, +//!}; +//!use epd_waveshare::{epd1in54::*, prelude::*}; +//!# +//!# let expectations = []; +//!# let mut spi = spi::Mock::new(&expectations); +//!# let expectations = []; +//!# let cs_pin = pin::Mock::new(&expectations); +//!# let busy_in = pin::Mock::new(&expectations); +//!# let dc = pin::Mock::new(&expectations); +//!# let rst = pin::Mock::new(&expectations); +//!# let mut delay = delay::MockNoop::new(); +//! +//!// Setup EPD +//!let mut epd = EPD1in54::new(&mut spi, cs_pin, busy_in, dc, rst, &mut delay)?; +//! +//!// Use display graphics from embedded-graphics +//!let mut display = Display1in54::default(); +//! +//!// Use embedded graphics for drawing a line +//!let _ = Line::new(Point::new(0, 120), Point::new(0, 295)) +//! .into_styled(PrimitiveStyle::with_stroke(Black, 1)) +//! .draw(&mut display); +//! +//! // Display updated frame +//!epd.update_frame(&mut spi, &display.buffer())?; +//!epd.display_frame(&mut spi)?; +//! +//!// Set the EPD to sleep +//!epd.sleep(&mut spi)?; +//!# Ok(()) +//!# } +//!``` +//! +//! # Other information and requirements //! //! - Buffersize: Wherever a buffer is used it always needs to be of the size: `width / 8 * length`, //! where width and length being either the full e-ink size or the partial update window size //! -//! # Examples -//! -//! ```rust,ignore -//! use epd_waveshare::{ -//! epd2in9::{EPD2in9, Display2in9}, -//! graphics::{Display, DisplayRotation}, -//! prelude::*, -//! }; -//! use embedded_graphics::Drawing; -//! -//! // Setup EPD -//! let mut epd = EPD2in9::new(&mut spi, cs_pin, busy_in, dc, rst, &mut delay).unwrap(); -//! -//! // Use display graphics -//! let mut display = Display2in9::default(); -//! -//! // Write some hello world in the screenbuffer -//! display.draw( -//! Font6x8::render_str("Hello World!") -//! .stroke(Some(Color::Black)) -//! .fill(Some(Color::White)) -//! .translate(Point::new(5, 50)) -//! .into_iter(), -//! ); -//! -//! // Display updated frame -//! epd.update_frame(&mut spi, &display.buffer()).unwrap(); -//! epd.display_frame(&mut spi).expect("display frame new graphics"); +//! ### SPI //! -//! // Set the EPD to sleep -//! epd.sleep(&mut spi).expect("sleep"); -//! ``` +//! MISO is not connected/available. SPI_MODE_0 is used (CPHL = 0, CPOL = 0) with 8 bits per word, MSB first. //! +//! Maximum speed tested by myself was 8Mhz but more should be possible (Ben Krasnow used 18Mhz with his implemenation) //! #![no_std] +#![deny(missing_docs)] #[cfg(feature = "graphics")] pub mod graphics; @@ -72,6 +80,7 @@ pub mod epd7in5; pub mod epd7in5_v2; pub(crate) mod type_a; +/// Includes everything important besides the chosen Display pub mod prelude { pub use crate::color::Color; pub use crate::traits::{RefreshLUT, WaveshareDisplay, WaveshareThreeColorDisplay}; diff --git a/src/traits.rs b/src/traits.rs index 91352ee..eed2672 100644 --- a/src/traits.rs +++ b/src/traits.rs @@ -38,11 +38,11 @@ where /// This initialises the EPD and powers it up /// /// This function is already called from - /// - [new()](WaveshareInterface::new()) + /// - [new()](WaveshareDisplay::new()) /// - [`wake_up`] /// /// - /// This function calls [reset()](WaveshareInterface::reset()), + /// This function calls [reset](WaveshareDisplay::reset), /// so you don't need to call reset your self when trying to wake your device up /// after setting it to sleep. fn init>( @@ -75,7 +75,47 @@ where /// All the functions to interact with the EPDs /// -/// This trait includes all public functions to use the EPDS +/// This trait includes all public functions to use the EPDs +/// +/// # Example +/// +///```rust, no_run +///# use embedded_hal_mock::*; +///# fn main() -> Result<(), MockError> { +///use embedded_graphics::{ +/// pixelcolor::BinaryColor::On as Black, prelude::*, primitives::Line, style::PrimitiveStyle, +///}; +///use epd_waveshare::{epd4in2::*, prelude::*}; +///# +///# let expectations = []; +///# let mut spi = spi::Mock::new(&expectations); +///# let expectations = []; +///# let cs_pin = pin::Mock::new(&expectations); +///# let busy_in = pin::Mock::new(&expectations); +///# let dc = pin::Mock::new(&expectations); +///# let rst = pin::Mock::new(&expectations); +///# let mut delay = delay::MockNoop::new(); +/// +///// Setup EPD +///let mut epd = EPD4in2::new(&mut spi, cs_pin, busy_in, dc, rst, &mut delay)?; +/// +///// Use display graphics from embedded-graphics +///let mut display = Display4in2::default(); +/// +///// Use embedded graphics for drawing a line +///let _ = Line::new(Point::new(0, 120), Point::new(0, 295)) +/// .into_styled(PrimitiveStyle::with_stroke(Black, 1)) +/// .draw(&mut display); +/// +/// // Display updated frame +///epd.update_frame(&mut spi, &display.buffer())?; +///epd.display_frame(&mut spi)?; +/// +///// Set the EPD to sleep +///epd.sleep(&mut spi)?; +///# Ok(()) +///# } +///``` pub trait WaveshareDisplay where SPI: Write, @@ -86,7 +126,7 @@ where { /// Creates a new driver from a SPI peripheral, CS Pin, Busy InputPin, DC /// - /// This already initialises the device. That means [init()](WaveshareInterface::init()) isn't needed directly afterwards + /// This already initialises the device. fn new>( spi: &mut SPI, cs: CS, @@ -101,19 +141,18 @@ where /// Let the device enter deep-sleep mode to save power. /// /// The deep sleep mode returns to standby with a hardware reset. - /// But you can also use [wake_up()](WaveshareInterface::wake_up()) to awaken. - /// But as you need to power it up once more anyway you can also just directly use [new()](WaveshareInterface::new()) for resetting - /// and initialising which already contains the reset fn sleep(&mut self, spi: &mut SPI) -> Result<(), SPI::Error>; /// Wakes the device up from sleep + /// + /// Also reintialises the device if necessary. fn wake_up>( &mut self, spi: &mut SPI, delay: &mut DELAY, ) -> Result<(), SPI::Error>; - /// Sets the backgroundcolor for various commands like [clear_frame()](WaveshareInterface::clear_frame()) + /// Sets the backgroundcolor for various commands like [clear_frame](WaveshareDisplay::clear_frame) fn set_background_color(&mut self, color: Color); /// Get current background color @@ -153,7 +192,7 @@ where /// Clears the frame buffer on the EPD with the declared background color /// - /// The background color can be changed with [`set_background_color`] + /// The background color can be changed with [`WaveshareDisplay::set_background_color`] fn clear_frame(&mut self, spi: &mut SPI) -> Result<(), SPI::Error>; /// Trait for using various Waveforms from different LUTs From 0ab1e7db35ddf951d09004c21ca29dba7258d2c7 Mon Sep 17 00:00:00 2001 From: Caemor <11088935+caemor@users.noreply.github.com> Date: Thu, 26 Mar 2020 19:55:53 +0100 Subject: [PATCH 07/15] Fix changelog --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 873d235..8cc5085 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/). ## [Unreleased] - - Update embedded-graphics, + - Update embedded-graphics to 0.6, - Remove useless Featuregates (Doesn't change size) - Update and integrate a few important examples and remove the others - Add update_and_display_frame to the main trait, fixes #38 From 5c5c04d1fb618e9ef94815c94a5cb22ee462326a Mon Sep 17 00:00:00 2001 From: Caemor <11088935+caemor@users.noreply.github.com> Date: Thu, 26 Mar 2020 20:01:05 +0100 Subject: [PATCH 08/15] Speed Up Travis, since most of the stuff switched to github ci --- .travis.yml | 61 ++++++----------------------------------------------- 1 file changed, 7 insertions(+), 54 deletions(-) diff --git a/.travis.yml b/.travis.yml index f8d2824..7948ba5 100644 --- a/.travis.yml +++ b/.travis.yml @@ -15,68 +15,21 @@ matrix: - rust: nightly - name: clippy fast_finish: true - # TODO These are all the build jobs. Adjust as necessary. Comment out what you - # don't need - include: - # Linux - #- env: TARGET=aarch64-unknown-linux-gnu - # Raspberry Pi - - env: TARGET=arm-unknown-linux-gnueabi - # Raspberry Pi 3... - - env: TARGET=armv7-unknown-linux-gnueabihf - # is already included as global env - #- env: TARGET=x86_64-unknown-linux-gnu - - env: TARGET=x86_64-unknown-linux-musl - # Bare metal - # These targets don't support std and as such are likely not suitable for - # most crates. - - env: TARGET=thumbv6m-none-eabi - before_script: rustup target add $TARGET - script: cargo check --verbose --target $TARGET - - env: TARGET=thumbv7em-none-eabi - before_script: rustup target add $TARGET - script: cargo check --verbose --target $TARGET - - env: TARGET=thumbv7em-none-eabihf - before_script: rustup target add $TARGET - script: cargo check --verbose --target $TARGET - - env: TARGET=thumbv7m-none-eabi - before_script: rustup target add $TARGET - script: cargo check --verbose --target $TARGET - - - name: "fmt" - rust: stable - env: RUN=FMT - before_script: - - rustup component add rustfmt - script: - - cargo fmt --all -- --check - - cargo doc --all-features --release - - name: "check" - script: - - cargo check --examples --all-features - - name: "clippy" - rust: stable - env: RUN=FMT - before_script: - - rustup component add clippy - script: - - cargo clippy --all-targets --all-features -- -D warnings -A clippy::new_ret_no_self - before_install: - set -e - rustup self update -install: - - cargo install cargo-update || echo "cargo-update already installed" - - cargo install-update -a # update outdated cached binaries - - cargo install cross || echo "cross already installed" +# install: +# - cargo install cargo-update || echo "cargo-update already installed" +# - cargo install-update -a # update outdated cached binaries +# - cargo install cross || echo "cross already installed" #TODO: remove -A clippy::new_ret_no_self when new version of clippy gets released! script: - - cross check --verbose --target $TARGET - - cross test --all-features --release --verbose --target $TARGET + - cross check --verbose + - cross test --all-features --release --verbose cache: cargo before_cache: @@ -93,7 +46,7 @@ after_success: | # cargo tarpaulin --ciserver travis-ci --coveralls $TRAVIS_JOB_ID # Uncomment the following two lines create and upload a report for codecov.io - cargo tarpaulin --out Xml + cargo tarpaulin --all-features --out Xml bash <(curl -s https://codecov.io/bash) -t "$CODECOV_TOKEN" fi From 08c46952f76a71258b67fec3bf373194e3ad288e Mon Sep 17 00:00:00 2001 From: Caemor <11088935+caemor@users.noreply.github.com> Date: Thu, 26 Mar 2020 20:07:55 +0100 Subject: [PATCH 09/15] Further shorten work of travis --- .travis.yml | 17 ++--------------- 1 file changed, 2 insertions(+), 15 deletions(-) diff --git a/.travis.yml b/.travis.yml index 7948ba5..dfb9607 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,22 +1,9 @@ -# Based on the "trust" template v0.1.2 -# https://github.com/japaric/trust/tree/v0.1.2 language: rust rust: - stable - - beta - - nightly sudo: required env: TARGET=x86_64-unknown-linux-gnu -# TODO Rust builds on stable by default, this can be -# overridden on a case by case basis down below. -matrix: - allow_failures: - - rust: nightly - - name: clippy - fast_finish: true - - before_install: - set -e - rustup self update @@ -28,8 +15,8 @@ before_install: #TODO: remove -A clippy::new_ret_no_self when new version of clippy gets released! script: - - cross check --verbose - - cross test --all-features --release --verbose + - cargo check --all-features + - cargo test --all-features cache: cargo before_cache: From 2fcf788673a561aba72daabb0cfb0185785e4887 Mon Sep 17 00:00:00 2001 From: Caemor <11088935+caemor@users.noreply.github.com> Date: Thu, 26 Mar 2020 20:33:51 +0100 Subject: [PATCH 10/15] don't reinstall tarpaulin every time --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index dfb9607..3ddb454 100644 --- a/.travis.yml +++ b/.travis.yml @@ -24,7 +24,7 @@ before_cache: - chmod -R a+r $HOME/.cargo - | if [[ "$TRAVIS_RUST_VERSION" == stable ]]; then - cargo install cargo-tarpaulin -f + cargo install cargo-tarpaulin fi after_success: | From 85ad681229795b27c8f48a31df0f5c21123aa15f Mon Sep 17 00:00:00 2001 From: Caemor <11088935+caemor@users.noreply.github.com> Date: Thu, 26 Mar 2020 20:43:04 +0100 Subject: [PATCH 11/15] Refine Changelog --- CHANGELOG.md | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8cc5085..51cc2a7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,13 +6,22 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/). ## [Unreleased] - - Update embedded-graphics to 0.6, + +### Added + - New supported epds: epd7in5 (thanks to @str4d), epd7in5 v2 (thanks to @asaaki), epd1in54b (thanks to @jkristell) + - Added update_and_display_frame to WaveshareDisplay trait (fixes #38) + - also improve position of busy_wait (#30) once more + - More Documenation + +### Changed + - Update embedded-graphics to 0.6 (changes Display Trait) (and to 0.5 before thanks to @dbr) - Remove useless Featuregates (Doesn't change size) - Update and integrate a few important examples and remove the others - - Add update_and_display_frame to the main trait, fixes #38 - - Also improve position of busy_wait (#30) once more - - Fixed all doc tests - - Some more documentation improvements + - Use Embedded_hal:digital::v2 + + +### Fixed + - Doc Tests From 5ba408d5a789f95f0021473d97512ddfeb35b818 Mon Sep 17 00:00:00 2001 From: Caemor <11088935+caemor@users.noreply.github.com> Date: Thu, 26 Mar 2020 20:49:15 +0100 Subject: [PATCH 12/15] Fixed Readme Example --- README.md | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 5ac5ce0..899086a 100644 --- a/README.md +++ b/README.md @@ -22,11 +22,13 @@ let mut display = Display::new(epd.width(), epd.height(), &mut buffer.buffer); // Draw some text display.draw( - Font12x16::render_str("Hello Rust!") - .stroke(Some(Color::Black)) - .fill(Some(Color::White)) - .translate(Point::new(5, 50)) - .into_iter(), + let _ = Text::new("Hello Rust!", Point::new(x, y)) + .into_styled(text_style!( + font = Font12x16, + text_color = Black, + background_color = White + )) + .draw(display); ); // Transfer the frame data to the epd From 1a670ef8c66b5ec1e53caf3066016d968347a6bf Mon Sep 17 00:00:00 2001 From: Chris <11088935+caemor@users.noreply.github.com> Date: Fri, 27 Mar 2020 10:11:06 +0100 Subject: [PATCH 13/15] Update README.md --- README.md | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 899086a..8771ade 100644 --- a/README.md +++ b/README.md @@ -31,11 +31,8 @@ display.draw( .draw(display); ); -// Transfer the frame data to the epd -epd.update_frame(&mut spi, &display.buffer())?; - -// Display the frame on the epd -epd.display_frame(&mut spi)?; +// Transfer the frame data to the epd and display it +epd.update_and_display_frame(&mut spi, &display.buffer())?; ``` ## (Supported) Devices From 87762115369e87cc3865cb1b9a8ee38a98e35162 Mon Sep 17 00:00:00 2001 From: Chris <11088935+caemor@users.noreply.github.com> Date: Fri, 27 Mar 2020 10:12:12 +0100 Subject: [PATCH 14/15] Update Readme example --- README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/README.md b/README.md index 8771ade..6514acd 100644 --- a/README.md +++ b/README.md @@ -17,8 +17,7 @@ There are multiple examples in the examples folder. For more infos about the exa let mut epd = EPD4in2::new(&mut spi, cs, busy, dc, rst, &mut delay)?; // Setup the graphics -let mut buffer = Buffer4in2::default(); -let mut display = Display::new(epd.width(), epd.height(), &mut buffer.buffer); +let mut display = Display4in2::default(); // Draw some text display.draw( From c62ee89960b7da05b2d3e2720c0519d385186ca0 Mon Sep 17 00:00:00 2001 From: Chris <11088935+caemor@users.noreply.github.com> Date: Fri, 27 Mar 2020 10:13:22 +0100 Subject: [PATCH 15/15] Update Readme for examples --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 6514acd..d7a0489 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ Other similiar libraries with support for much more displays are [u8g2](https:// ## Examples -There are multiple examples in the examples folder. For more infos about the examples see the seperate Readme [there](/examples/Readme.md). These examples are all rust projects of their own, so you need to go inside the project to execute it (cargo run --example doesn't work). +There are multiple examples in the examples folder. Use `cargo run --example example_name` to try them. ```Rust // Setup the epd