Update embedded-graphics,
remove useless Featuregates (Doesn't change size) Update and integrate a few important examples and remove the othersembedded-hal-1.0
parent
dcaed6fb3e
commit
8da294dd5e
|
|
@ -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
|
||||
|
||||
22
.travis.yml
22
.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
|
||||
|
|
|
|||
28
Cargo.toml
28
Cargo.toml
|
|
@ -13,28 +13,20 @@ version = "0.3.2"
|
|||
edition = "2018"
|
||||
|
||||
[badges]
|
||||
# Travis CI: `repository` in format "<user>/<project>" 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
|
||||
|
||||
# Offers an alternative fast full lut for type_a displays, but the refreshed screen isnt as clean looking
|
||||
type_a_alternative_faster_lut = []
|
||||
|
||||
|
||||
|
||||
[dependencies.embedded-hal]
|
||||
features = ["unproven"]
|
||||
version = "0.2.3"
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
|
||||
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
[package]
|
||||
name = "embedded_linux_eink_example"
|
||||
version = "0.1.0"
|
||||
authors = ["Christoph Groß <christoph-gross@mailbox.org>"]
|
||||
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"] }
|
||||
|
|
@ -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(())
|
||||
}
|
||||
|
|
@ -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");
|
||||
|
||||
|
|
@ -1,12 +0,0 @@
|
|||
[package]
|
||||
name = "embedded_linux_eink_example"
|
||||
version = "0.1.0"
|
||||
authors = ["Christoph Groß <christoph-gross@mailbox.org>"]
|
||||
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"] }
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
[package]
|
||||
name = "embedded_linux_eink_example"
|
||||
version = "0.1.0"
|
||||
authors = ["Christoph Groß <christoph-gross@mailbox.org>"]
|
||||
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"] }
|
||||
|
|
@ -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(())
|
||||
}
|
||||
|
|
@ -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();
|
||||
// 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
|
||||
|
||||
let clocks = rcc
|
||||
.cfgr
|
||||
.use_hse(8.mhz())
|
||||
.sysclk(72.mhz())
|
||||
.pclk1(36.mhz())
|
||||
.freeze(&mut flash.acr);
|
||||
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");
|
||||
|
||||
let mut gpioa = device.GPIOA.split(&mut rcc.apb2);
|
||||
let mut gpiob = device.GPIOB.split(&mut rcc.apb2);
|
||||
// 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 mut delay = delay::Delay::new(core.SYST, clocks);
|
||||
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");
|
||||
|
||||
// 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();
|
||||
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) {
|
||||
|
|
@ -1,15 +0,0 @@
|
|||
[package]
|
||||
name = "embedded_linux_eink_example"
|
||||
version = "0.1.0"
|
||||
authors = ["Christoph Groß <christoph-gross@mailbox.org>"]
|
||||
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"] }
|
||||
|
|
@ -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)
|
||||
}
|
||||
|
|
@ -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"
|
||||
|
|
@ -1,19 +0,0 @@
|
|||
[package]
|
||||
name = "embedded_linux_eink_example"
|
||||
version = "0.1.0"
|
||||
authors = ["Christoph Groß <christoph-gross@mailbox.org>"]
|
||||
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"
|
||||
|
|
@ -1,6 +0,0 @@
|
|||
/* Linker script for the STM32F103C8T6 */
|
||||
MEMORY
|
||||
{
|
||||
FLASH : ORIGIN = 0x08000000, LENGTH = 64K
|
||||
RAM : ORIGIN = 0x20000000, LENGTH = 20K
|
||||
}
|
||||
|
|
@ -1,2 +0,0 @@
|
|||
source [find interface/stlink-v2.cfg]
|
||||
source [find target/stm32f1x.cfg]
|
||||
|
|
@ -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
|
||||
|
|
@ -1,15 +0,0 @@
|
|||
[package]
|
||||
name = "embedded_linux_eink_example"
|
||||
version = "0.1.0"
|
||||
authors = ["Christoph Groß <christoph-gross@mailbox.org>"]
|
||||
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"] }
|
||||
|
|
@ -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(),
|
||||
);
|
||||
draw_text(&mut display, " Hello World! ", 5 + i * 12, 50);
|
||||
|
||||
epd4in2.update_frame(&mut spi, &display.buffer()).unwrap();
|
||||
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);
|
||||
}
|
||||
|
|
@ -1,14 +0,0 @@
|
|||
[package]
|
||||
name = "embedded_linux_eink_example"
|
||||
version = "0.1.0"
|
||||
authors = [
|
||||
"Christoph Groß <christoph-gross@mailbox.org>",
|
||||
"Jack Grigg <thestr4d@gmail.com>",
|
||||
]
|
||||
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"
|
||||
|
|
@ -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)
|
||||
}
|
||||
|
|
@ -1,15 +0,0 @@
|
|||
[package]
|
||||
name = "embedded_linux_eink_example"
|
||||
version = "0.1.0"
|
||||
authors = [
|
||||
"Christoph Groß <christoph-gross@mailbox.org>",
|
||||
"Jack Grigg <thestr4d@gmail.com>",
|
||||
"Christoph Grabo <asaaki@mannaz.cc>",
|
||||
]
|
||||
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"
|
||||
|
|
@ -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)
|
||||
}
|
||||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
19
src/lib.rs
19
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;
|
||||
|
|
|
|||
Loading…
Reference in New Issue