Skip to content

Commit

Permalink
experiment with other display modes
Browse files Browse the repository at this point in the history
  • Loading branch information
pbert519 committed Jun 19, 2024
1 parent f190511 commit f3e2614
Show file tree
Hide file tree
Showing 6 changed files with 187 additions and 15 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ This driver can be used with the embedded graphics trait, currently only suppori
- Support display engine fill area
- Support display engine 1 bit per pixel mode
- Support static buffer allocations
- Use 1bbp or 2 bpp if possible


## Changelog

Expand Down
106 changes: 106 additions & 0 deletions examples/esp32/src/demo.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
// based on https://github.com/waveshareteam/IT8951-ePaper/blob/master/Raspberry
use embedded_graphics::{
draw_target::DrawTarget,
pixelcolor::{Gray4, GrayColor},
};
use it8951::{
interface::*,
memory_converter_settings::{MemoryConverterBitPerPixel, MemoryConverterSetting},
*,
};
use std::time::Instant;

pub fn display_color_palette_example(
epd: &mut it8951::IT8951<impl IT8951Interface, Run>,
bpp: MemoryConverterBitPerPixel,
) {
// create stripes for each color and display it
let width = epd.get_dev_info().panel_width as usize;
let height = 85;
let pixels = width * height / bpp.pixel_per_byte() / 2;
let mut buf = vec![0u16; pixels];

let pattern = [
0x0000, 0x1111, 0x2222, 0x3333, 0x4444, 0x5555, 0x6666, 0x7777, 0x8888, 0x9999, 0xAAAA,
0xBBBB, 0xCCCC, 0xDDDD, 0xEEEE, 0xFFFF,
];

let before = Instant::now();

for i in 0..pattern.len() {
buf.fill(pattern[i]);
// write buff & display

epd.load_image_area(
epd.get_dev_info().memory_address,
MemoryConverterSetting {
bit_per_pixel: bpp,
..MemoryConverterSetting::default()
},
&AreaImgInfo {
area_x: 0,
area_y: (i * height) as u16,
area_w: width as u16,
area_h: height as u16,
},
&buf,
)
.unwrap();
println!(
"all Elapsed time: {:.2?}, written chunk {}",
before.elapsed(),
i
);
}

epd.display(it8951::WaveformMode::GrayscaleClearing16)
.unwrap();

println!("Elapsed time: {:.2?}", before.elapsed());
}

pub fn display_area_1bpp(epd: &mut it8951::IT8951<impl IT8951Interface, Run>) {
let pattern = [
0x0000, 0x1111, 0x2222, 0x3333, 0x4444, 0x5555, 0x6666, 0x7777, 0x8888, 0x9999, 0xAAAA,
0xBBBB, 0xCCCC, 0xDDDD, 0xEEEE, 0xFFFF,
];
let height = 85;

let before = Instant::now();

for i in 0..pattern.len() {
let area = AreaImgInfo {
area_x: 0,
area_y: (i * height) as u16,
area_w: 1872 as u16,
area_h: height as u16,
};

epd.display_area_with_color(&area, WaveformMode::GrayscaleClearing16, pattern[i])
.unwrap();
println!("Elapsed time: {:.2?}", before.elapsed());
}
println!("Elapsed time: {:.2?}", before.elapsed());

}

pub fn clear_refresh(epd: &mut it8951::IT8951<impl IT8951Interface, Run>) {
epd.clear(Gray4::WHITE).unwrap();
}

pub fn run(epd: &mut it8951::IT8951<impl IT8951Interface, Run>) {
clear_refresh(epd);

// 16 color grayscale
display_color_palette_example(epd, MemoryConverterBitPerPixel::BitsPerPixel4);
std::thread::sleep(std::time::Duration::from_secs(10));
clear_refresh(epd);
// 4 color grayscale
display_color_palette_example(epd, MemoryConverterBitPerPixel::BitsPerPixel2);
std::thread::sleep(std::time::Duration::from_secs(10));
clear_refresh(epd);
// 2 color grayscale
display_area_1bpp(epd);
std::thread::sleep(std::time::Duration::from_secs(10));
clear_refresh(epd);
}
15 changes: 13 additions & 2 deletions examples/esp32/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,16 @@
use embedded_graphics::{
pixelcolor::Gray4,
prelude::*,
primitives::{PrimitiveStyle, Rectangle},
};
use esp_idf_hal::{delay::Ets, gpio::PinDriver, prelude::*, spi::*};
use esp_idf_sys as _; // If using the `binstart` feature of `esp-idf-sys`, always keep this module imported
use it8951::{interface::*, *};
use embedded_graphics::{prelude::*, primitives::{Rectangle, PrimitiveStyle}, pixelcolor::Gray4};
use it8951::Config;

mod demo;

fn main() -> ! {
// Bind the log crate to the ESP Logging facilities
esp_idf_svc::log::EspLogger::initialize_default();
Expand Down Expand Up @@ -65,10 +72,14 @@ fn main() -> ! {

epd.display(it8951::WaveformMode::GL16).unwrap();

demo::run(&mut epd);

let epd = epd.standby().unwrap();
let _epd = epd.standby().unwrap();

loop {}
loop {
println!("Reached main loop, sleep!");
std::thread::sleep(std::time::Duration::from_secs(1));
}
}

fn setup_watchdog() -> Result<(), esp_idf_sys::EspError> {
Expand Down
62 changes: 51 additions & 11 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,18 @@ pub struct AreaImgInfo {
pub area_h: u16,
}

impl AreaImgInfo {
/// Creates a area image info with the given size and the origin (0, 0)
pub fn with_size(width: u16, height: u16) -> Self {
Self {
area_x: 0,
area_y: 0,
area_w: width,
area_h: height,
}
}
}

/// See https://www.waveshare.com/w/upload/c/c4/E-paper-mode-declaration.pdf for full description
pub enum WaveformMode {
/// used for full erase to white, flashy, should be used if framebuffer is not up to date
Expand Down Expand Up @@ -388,6 +400,35 @@ impl<IT8951Interface: interface::IT8951Interface> IT8951<IT8951Interface, Run> {
Ok(())
}

/// Display the defined area, but interpret the framebuffer as 1 bit per pixel.
/// the grayscale value for foreground and background are given by the parameters as fg_color and bg_color.
pub fn display_area_with_color(
&mut self,
area_info: &AreaImgInfo,
mode: WaveformMode,
color: u16,
) -> Result<(), Error> {
self.wait_for_display_ready()?;

// enable 1bpp mode
let reg_value = self.read_register(register::UP1SR + 2)?;
self.write_register(register::UP1SR + 2, reg_value | (1u16 << 2))?;

// write color values
//let color_value = (fg_color as u16) << 8 | (bg_color as u16);
self.write_register(register::BGVR, color)?;

// update display
self.display_area(area_info, mode)?;
self.wait_for_display_ready()?;

// disable 1bpp mode
let reg_value = self.read_register(register::UP1SR + 2)?;
self.write_register(register::UP1SR + 2, reg_value & !(1u16 << 2))?;

Ok(())
}

// misc ------------------------------------------------------------------------------------------------

fn wait_for_display_ready(&mut self) -> Result<(), Error> {
Expand Down Expand Up @@ -513,18 +554,17 @@ impl<IT8951Interface: interface::IT8951Interface> DrawTarget for IT8951<IT8951In
type Error = Error;

fn clear(&mut self, color: Self::Color) -> Result<(), Self::Error> {
let info = self.get_dev_info();

self.fill_solid(
&Rectangle::new(
Point::zero(),
Size {
width: info.panel_width as u32,
height: info.panel_height as u32,
},
let raw_color = color.luma() as u16;
self.display_area_with_color(
&AreaImgInfo::with_size(
self.get_dev_info().panel_width,
self.get_dev_info().panel_width,
),
color,
)
WaveformMode::GrayscaleClearing16,
raw_color,
)?;
//self.clear_frame_buffer(raw_color)
Ok(())
}

fn fill_solid(&mut self, area: &Rectangle, color: Self::Color) -> Result<(), Self::Error> {
Expand Down
13 changes: 13 additions & 0 deletions src/memory_converter_settings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ pub enum MemoryConverterEndianness {

/// Bits per pixel
/// the pixel data send to the controller can encode the pixels with a different number of bits
#[derive(Clone, Copy, Debug)]
#[repr(u16)]
pub enum MemoryConverterBitPerPixel {
/// each pixel value is given by 2 bits
Expand All @@ -23,6 +24,18 @@ pub enum MemoryConverterBitPerPixel {
BitsPerPixel8 = 0b11,
}

impl MemoryConverterBitPerPixel {
/// Returns the number of pixels per byte
pub fn pixel_per_byte(&self) -> usize {
match self {
MemoryConverterBitPerPixel::BitsPerPixel2 => 4,
MemoryConverterBitPerPixel::BitsPerPixel3 => unimplemented!(),
MemoryConverterBitPerPixel::BitsPerPixel4 => 2,
MemoryConverterBitPerPixel::BitsPerPixel8 => 1,
}
}
}

/// The memory converter supports rotating the written pixel data
#[repr(u16)]
pub enum MemoryConverterRotation {
Expand Down
4 changes: 2 additions & 2 deletions src/register.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,12 @@ const _LUT01AF: u16 = DISPLAY_REG_BASE + 0x114; //LUT0 and LUT1 Active Flag Reg

//Update Parameter Setting Register
const _UP0SR: u16 = DISPLAY_REG_BASE + 0x134; //Update Parameter0 Setting Reg
const _UP1SR: u16 = DISPLAY_REG_BASE + 0x138; //Update Parameter1 Setting Reg
pub const UP1SR: u16 = DISPLAY_REG_BASE + 0x138; //Update Parameter1 Setting Reg
const _LUT0ABFRV: u16 = DISPLAY_REG_BASE + 0x13C; //LUT0 Alpha blend and Fill rectangle Value
const _UPBBADDR: u16 = DISPLAY_REG_BASE + 0x17C; //Update Buffer Base Address
const _LUT0IMXY: u16 = DISPLAY_REG_BASE + 0x180; //LUT0 Image buffer X/Y offset Reg
pub const LUTAFSR: u16 = DISPLAY_REG_BASE + 0x224; //LUT Status Reg (status of All LUT Engines)
const _BGVR: u16 = DISPLAY_REG_BASE + 0x250; //Bitmap (1bpp) image color table
pub const BGVR: u16 = DISPLAY_REG_BASE + 0x250; //Bitmap (1bpp) image color table

//System Registers
const SYS_REG_BASE: u16 = 0x0000;
Expand Down

0 comments on commit f3e2614

Please sign in to comment.