Browse Source

Update/Include new update_and_display trait

v0.4
Caemor 3 years ago
parent
commit
ec72357b55
  1. 28
      src/epd1in54/mod.rs
  2. 19
      src/epd1in54b/mod.rs
  3. 29
      src/epd2in9/mod.rs
  4. 22
      src/epd4in2/mod.rs
  5. 16
      src/epd7in5/mod.rs
  6. 36
      src/epd7in5_v2/mod.rs
  7. 2
      src/lib.rs
  8. 15
      src/traits.rs

28
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(())
}
}

19
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(())
}

29
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(())
}
}

22
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(())
}
}

16
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(())
}

36
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<SPI, CS, BUSY, DC, RST> WaveshareDisplayExt<SPI, CS, BUSY, DC, RST>
for EPD7in5<SPI, CS, BUSY, DC, RST>
where
SPI: Write<u8>,
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<SPI, CS, BUSY, DC, RST> EPD7in5<SPI, CS, BUSY, DC, RST>
where
SPI: Write<u8>,

2
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")]

15
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<SPI, CS, BUSY, DC, RST>
where
SPI: Write<u8>,
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>;
}

Loading…
Cancel
Save