Added QuickRefresh trait, and implemented it for 4.2 display
parent
87e63741ef
commit
c30d213bc5
|
|
@ -1,109 +1,115 @@
|
||||||
|
//! This file contains look-up-tables used to set voltages used during
|
||||||
|
//! various categories of pixel refreshes.
|
||||||
|
|
||||||
#[rustfmt::skip]
|
#[rustfmt::skip]
|
||||||
pub(crate) const LUT_VCOM0: [u8; 44] = [
|
pub(crate) const LUT_VCOM0: [u8; 44] = [
|
||||||
0x00, 0x17, 0x00, 0x00, 0x00, 0x02,
|
// The commented-out line below was used in a Ben Krasnow video explaining
|
||||||
0x00, 0x17, 0x17, 0x00, 0x00, 0x02,
|
// partial refreshes.
|
||||||
0x00, 0x0A, 0x01, 0x00, 0x00, 0x01,
|
// 0x40, 0x17, 0x00, 0x00, 0x00, 0x02,
|
||||||
0x00, 0x0E, 0x0E, 0x00, 0x00, 0x02,
|
0x00, 0x17, 0x00, 0x00, 0x00, 0x02,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x17, 0x17, 0x00, 0x00, 0x02,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x0A, 0x01, 0x00, 0x00, 0x01,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x0E, 0x0E, 0x00, 0x00, 0x02,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
];
|
];
|
||||||
|
|
||||||
#[rustfmt::skip]
|
#[rustfmt::skip]
|
||||||
pub(crate) const LUT_VCOM0_QUICK: [u8; 44] = [
|
pub(crate) const LUT_VCOM0_QUICK: [u8; 44] = [
|
||||||
0x00, 0x0E, 0x00, 0x00, 0x00, 0x01,
|
0x00, 0x0E, 0x00, 0x00, 0x00, 0x01,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
];
|
];
|
||||||
|
|
||||||
#[rustfmt::skip]
|
#[rustfmt::skip]
|
||||||
pub(crate) const LUT_WW: [u8; 42] =[
|
pub(crate) const LUT_WW: [u8; 42] =[
|
||||||
0x40, 0x17, 0x00, 0x00, 0x00, 0x02,
|
0x40, 0x17, 0x00, 0x00, 0x00, 0x02,
|
||||||
0x90, 0x17, 0x17, 0x00, 0x00, 0x02,
|
0x90, 0x17, 0x17, 0x00, 0x00, 0x02,
|
||||||
0x40, 0x0A, 0x01, 0x00, 0x00, 0x01,
|
0x40, 0x0A, 0x01, 0x00, 0x00, 0x01,
|
||||||
0xA0, 0x0E, 0x0E, 0x00, 0x00, 0x02,
|
0xA0, 0x0E, 0x0E, 0x00, 0x00, 0x02,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
];
|
];
|
||||||
|
|
||||||
#[rustfmt::skip]
|
#[rustfmt::skip]
|
||||||
pub(crate) const LUT_WW_QUICK: [u8; 42] =[
|
pub(crate) const LUT_WW_QUICK: [u8; 42] =[
|
||||||
0xA0, 0x0E, 0x00, 0x00, 0x00, 0x01,
|
0xA0, 0x0E, 0x00, 0x00, 0x00, 0x01,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
];
|
];
|
||||||
|
|
||||||
#[rustfmt::skip]
|
#[rustfmt::skip]
|
||||||
pub(crate) const LUT_BW: [u8; 42] =[
|
pub(crate) const LUT_BW: [u8; 42] =[
|
||||||
0x40, 0x17, 0x00, 0x00, 0x00, 0x02,
|
0x40, 0x17, 0x00, 0x00, 0x00, 0x02,
|
||||||
0x90, 0x17, 0x17, 0x00, 0x00, 0x02,
|
0x90, 0x17, 0x17, 0x00, 0x00, 0x02,
|
||||||
0x40, 0x0A, 0x01, 0x00, 0x00, 0x01,
|
0x40, 0x0A, 0x01, 0x00, 0x00, 0x01,
|
||||||
0xA0, 0x0E, 0x0E, 0x00, 0x00, 0x02,
|
0xA0, 0x0E, 0x0E, 0x00, 0x00, 0x02,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
];
|
];
|
||||||
|
|
||||||
#[rustfmt::skip]
|
#[rustfmt::skip]
|
||||||
pub(crate) const LUT_BW_QUICK: [u8; 42] =[
|
pub(crate) const LUT_BW_QUICK: [u8; 42] =[
|
||||||
0xA0, 0x0E, 0x00, 0x00, 0x00, 0x01,
|
0xA0, 0x0E, 0x00, 0x00, 0x00, 0x01,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
];
|
];
|
||||||
|
|
||||||
#[rustfmt::skip]
|
#[rustfmt::skip]
|
||||||
pub(crate) const LUT_BB: [u8; 42] =[
|
pub(crate) const LUT_BB: [u8; 42] =[
|
||||||
0x80, 0x17, 0x00, 0x00, 0x00, 0x02,
|
0x80, 0x17, 0x00, 0x00, 0x00, 0x02,
|
||||||
0x90, 0x17, 0x17, 0x00, 0x00, 0x02,
|
0x90, 0x17, 0x17, 0x00, 0x00, 0x02,
|
||||||
0x80, 0x0A, 0x01, 0x00, 0x00, 0x01,
|
0x80, 0x0A, 0x01, 0x00, 0x00, 0x01,
|
||||||
0x50, 0x0E, 0x0E, 0x00, 0x00, 0x02,
|
0x50, 0x0E, 0x0E, 0x00, 0x00, 0x02,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
];
|
];
|
||||||
|
|
||||||
#[rustfmt::skip]
|
#[rustfmt::skip]
|
||||||
pub(crate) const LUT_BB_QUICK: [u8; 42] =[
|
pub(crate) const LUT_BB_QUICK: [u8; 42] =[
|
||||||
0x50, 0x0E, 0x00, 0x00, 0x00, 0x01,
|
0x50, 0x0E, 0x00, 0x00, 0x00, 0x01,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
];
|
];
|
||||||
|
|
||||||
#[rustfmt::skip]
|
#[rustfmt::skip]
|
||||||
pub(crate) const LUT_WB: [u8; 42] =[
|
pub(crate) const LUT_WB: [u8; 42] =[
|
||||||
0x80, 0x17, 0x00, 0x00, 0x00, 0x02,
|
0x80, 0x17, 0x00, 0x00, 0x00, 0x02,
|
||||||
0x90, 0x17, 0x17, 0x00, 0x00, 0x02,
|
0x90, 0x17, 0x17, 0x00, 0x00, 0x02,
|
||||||
0x80, 0x0A, 0x01, 0x00, 0x00, 0x01,
|
0x80, 0x0A, 0x01, 0x00, 0x00, 0x01,
|
||||||
0x50, 0x0E, 0x0E, 0x00, 0x00, 0x02,
|
0x50, 0x0E, 0x0E, 0x00, 0x00, 0x02,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
];
|
];
|
||||||
|
|
||||||
#[rustfmt::skip]
|
#[rustfmt::skip]
|
||||||
pub(crate) const LUT_WB_QUICK: [u8; 42] =[
|
pub(crate) const LUT_WB_QUICK: [u8; 42] =[
|
||||||
0x50, 0x0E, 0x00, 0x00, 0x00, 0x01,
|
0x50, 0x0E, 0x00, 0x00, 0x00, 0x01,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
];
|
];
|
||||||
|
|
|
||||||
|
|
@ -55,7 +55,7 @@ use embedded_hal::{
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::interface::DisplayInterface;
|
use crate::interface::DisplayInterface;
|
||||||
use crate::traits::{InternalWiAdditions, RefreshLUT, WaveshareDisplay};
|
use crate::traits::{InternalWiAdditions, QuickRefresh, RefreshLUT, WaveshareDisplay};
|
||||||
|
|
||||||
//The Lookup Tables for the Display
|
//The Lookup Tables for the Display
|
||||||
mod constants;
|
mod constants;
|
||||||
|
|
@ -407,6 +407,174 @@ where
|
||||||
self.cmd_with_data(spi, Command::LUT_BLACK_TO_BLACK, lut_bb)?;
|
self.cmd_with_data(spi, Command::LUT_BLACK_TO_BLACK, lut_bb)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Helper function. Sets up the display to send pixel data to a custom
|
||||||
|
/// starting point.
|
||||||
|
pub fn shift_display(
|
||||||
|
&mut self,
|
||||||
|
spi: &mut SPI,
|
||||||
|
x: u32,
|
||||||
|
y: u32,
|
||||||
|
width: u32,
|
||||||
|
height: u32,
|
||||||
|
) -> Result<(), SPI::Error> {
|
||||||
|
self.send_data(spi, &[(x >> 8) as u8])?;
|
||||||
|
let tmp = x & 0xf8;
|
||||||
|
self.send_data(spi, &[tmp as u8])?; // x should be the multiple of 8, the last 3 bit will always be ignored
|
||||||
|
let tmp = tmp + width - 1;
|
||||||
|
self.send_data(spi, &[(tmp >> 8) as u8])?;
|
||||||
|
self.send_data(spi, &[(tmp | 0x07) as u8])?;
|
||||||
|
|
||||||
|
self.send_data(spi, &[(y >> 8) as u8])?;
|
||||||
|
self.send_data(spi, &[y as u8])?;
|
||||||
|
|
||||||
|
self.send_data(spi, &[((y + height - 1) >> 8) as u8])?;
|
||||||
|
self.send_data(spi, &[(y + height - 1) as u8])?;
|
||||||
|
|
||||||
|
self.send_data(spi, &[0x01])?; // Gates scan both inside and outside of the partial window. (default)
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<SPI, CS, BUSY, DC, RST> QuickRefresh<SPI, CS, BUSY, DC, RST>
|
||||||
|
for EPD4in2<SPI, CS, BUSY, DC, RST>
|
||||||
|
where
|
||||||
|
SPI: Write<u8>,
|
||||||
|
CS: OutputPin,
|
||||||
|
BUSY: InputPin,
|
||||||
|
DC: OutputPin,
|
||||||
|
RST: OutputPin,
|
||||||
|
{
|
||||||
|
/// To be followed immediately after by `update_old_frame`.
|
||||||
|
fn update_old_frame(&mut self, spi: &mut SPI, buffer: &[u8]) -> Result<(), SPI::Error> {
|
||||||
|
self.wait_until_idle();
|
||||||
|
|
||||||
|
// todo: Eval if you need these 3 res setting items.
|
||||||
|
self.send_resolution(spi)?;
|
||||||
|
self.interface
|
||||||
|
.cmd_with_data(spi, Command::VCM_DC_SETTING, &[0x12])?;
|
||||||
|
//VBDF 17|D7 VBDW 97 VBDB 57 VBDF F7 VBDW 77 VBDB 37 VBDR B7
|
||||||
|
self.interface
|
||||||
|
.cmd_with_data(spi, Command::VCOM_AND_DATA_INTERVAL_SETTING, &[0x97])?;
|
||||||
|
|
||||||
|
self.interface
|
||||||
|
.cmd(spi, Command::DATA_START_TRANSMISSION_1)?;
|
||||||
|
|
||||||
|
self.interface.data(spi, buffer)?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// To be used immediately after `update_old_frame`.
|
||||||
|
fn update_new_frame(&mut self, spi: &mut SPI, buffer: &[u8]) -> Result<(), SPI::Error> {
|
||||||
|
self.wait_until_idle();
|
||||||
|
// self.send_resolution(spi)?;
|
||||||
|
|
||||||
|
self.interface
|
||||||
|
.cmd(spi, Command::DATA_START_TRANSMISSION_2)?;
|
||||||
|
|
||||||
|
self.interface.data(spi, buffer)?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn update_partial_old_frame(
|
||||||
|
&mut self,
|
||||||
|
spi: &mut SPI,
|
||||||
|
buffer: &[u8],
|
||||||
|
x: u32,
|
||||||
|
y: u32,
|
||||||
|
width: u32,
|
||||||
|
height: u32,
|
||||||
|
) -> Result<(), SPI::Error> {
|
||||||
|
self.wait_until_idle();
|
||||||
|
|
||||||
|
// todo: Eval if you need these 3 res setting items.
|
||||||
|
self.send_resolution(spi)?;
|
||||||
|
self.interface
|
||||||
|
.cmd_with_data(spi, Command::VCM_DC_SETTING, &[0x12])?;
|
||||||
|
//VBDF 17|D7 VBDW 97 VBDB 57 VBDF F7 VBDW 77 VBDB 37 VBDR B7
|
||||||
|
self.interface
|
||||||
|
.cmd_with_data(spi, Command::VCOM_AND_DATA_INTERVAL_SETTING, &[0x97])?;
|
||||||
|
|
||||||
|
if buffer.len() as u32 != width / 8 * height {
|
||||||
|
//TODO: panic!! or sth like that
|
||||||
|
//return Err("Wrong buffersize");
|
||||||
|
}
|
||||||
|
|
||||||
|
self.interface.cmd(spi, Command::PARTIAL_IN)?;
|
||||||
|
self.interface.cmd(spi, Command::PARTIAL_WINDOW)?;
|
||||||
|
|
||||||
|
self.shift_display(spi, x, y, width, height)?;
|
||||||
|
|
||||||
|
self.interface
|
||||||
|
.cmd(spi, Command::DATA_START_TRANSMISSION_1)?;
|
||||||
|
|
||||||
|
self.interface.data(spi, buffer)?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Always call `update_partial_old_frame` before this, with buffer-updating code
|
||||||
|
/// between the calls.
|
||||||
|
fn update_partial_new_frame(
|
||||||
|
&mut self,
|
||||||
|
spi: &mut SPI,
|
||||||
|
buffer: &[u8],
|
||||||
|
x: u32,
|
||||||
|
y: u32,
|
||||||
|
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");
|
||||||
|
}
|
||||||
|
|
||||||
|
self.shift_display(spi, x, y, width, height)?;
|
||||||
|
|
||||||
|
self.interface
|
||||||
|
.cmd(spi, Command::DATA_START_TRANSMISSION_2)?;
|
||||||
|
|
||||||
|
self.interface.data(spi, buffer)?;
|
||||||
|
|
||||||
|
self.interface.cmd(spi, Command::PARTIAL_OUT)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn clear_partial_frame(
|
||||||
|
&mut self,
|
||||||
|
spi: &mut SPI,
|
||||||
|
x: u32,
|
||||||
|
y: u32,
|
||||||
|
width: u32,
|
||||||
|
height: u32,
|
||||||
|
) -> Result<(), SPI::Error> {
|
||||||
|
self.wait_until_idle();
|
||||||
|
self.send_resolution(spi)?;
|
||||||
|
|
||||||
|
let color_value = self.color.get_byte_value();
|
||||||
|
|
||||||
|
self.interface.cmd(spi, Command::PARTIAL_IN)?;
|
||||||
|
self.interface.cmd(spi, Command::PARTIAL_WINDOW)?;
|
||||||
|
|
||||||
|
self.shift_display(spi, x, y, width, height)?;
|
||||||
|
|
||||||
|
self.interface
|
||||||
|
.cmd(spi, Command::DATA_START_TRANSMISSION_1)?;
|
||||||
|
self.interface
|
||||||
|
.data_x_times(spi, color_value, width / 8 * height)?;
|
||||||
|
|
||||||
|
self.interface
|
||||||
|
.cmd(spi, Command::DATA_START_TRANSMISSION_2)?;
|
||||||
|
self.interface
|
||||||
|
.data_x_times(spi, color_value, width / 8 * height)?;
|
||||||
|
|
||||||
|
self.interface.cmd(spi, Command::PARTIAL_OUT)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
|
|
||||||
|
|
@ -87,7 +87,9 @@ pub(crate) mod type_a;
|
||||||
/// Includes everything important besides the chosen Display
|
/// Includes everything important besides the chosen Display
|
||||||
pub mod prelude {
|
pub mod prelude {
|
||||||
pub use crate::color::{Color, OctColor, TriColor};
|
pub use crate::color::{Color, OctColor, TriColor};
|
||||||
pub use crate::traits::{RefreshLUT, WaveshareDisplay, WaveshareThreeColorDisplay};
|
pub use crate::traits::{
|
||||||
|
QuickRefresh, RefreshLUT, WaveshareDisplay, WaveshareThreeColorDisplay,
|
||||||
|
};
|
||||||
|
|
||||||
pub use crate::SPI_MODE;
|
pub use crate::SPI_MODE;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -229,3 +229,67 @@ where
|
||||||
/// if the device is still busy
|
/// if the device is still busy
|
||||||
fn is_busy(&self) -> bool;
|
fn is_busy(&self) -> bool;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Allows quick refresh support for displays that support it; lets you send both
|
||||||
|
/// old and new frame data to support this.
|
||||||
|
///
|
||||||
|
/// When using the quick refresh look-up table, the display must receive separate display
|
||||||
|
/// buffer data marked as old, and new. This is used to determine which pixels need to change,
|
||||||
|
/// and how they will change. This isn't required when using full refreshes.
|
||||||
|
///
|
||||||
|
/// Example:
|
||||||
|
/// epd.update_partial_old_frame(spi, disp.buffer(), x, y, frame_width, frame_height)
|
||||||
|
/// .ok();
|
||||||
|
///
|
||||||
|
/// disp.clear_buffer(Color::White);
|
||||||
|
/// // Execute drawing commands here.
|
||||||
|
///
|
||||||
|
/// epd.update_partial_new_frame(spi, disp.buffer(), x, y, frame_width, frame_height)
|
||||||
|
/// .ok();
|
||||||
|
pub trait QuickRefresh<SPI, CS, BUSY, DC, RST>
|
||||||
|
where
|
||||||
|
SPI: Write<u8>,
|
||||||
|
CS: OutputPin,
|
||||||
|
BUSY: InputPin,
|
||||||
|
DC: OutputPin,
|
||||||
|
RST: OutputPin,
|
||||||
|
{
|
||||||
|
/// Updates the old frame.
|
||||||
|
fn update_old_frame(&mut self, spi: &mut SPI, buffer: &[u8]) -> Result<(), SPI::Error>;
|
||||||
|
|
||||||
|
/// Updates the new frame.
|
||||||
|
fn update_new_frame(&mut self, spi: &mut SPI, buffer: &[u8]) -> Result<(), SPI::Error>;
|
||||||
|
|
||||||
|
/// Updates the old frame for a portion of the display.
|
||||||
|
fn update_partial_old_frame(
|
||||||
|
&mut self,
|
||||||
|
spi: &mut SPI,
|
||||||
|
buffer: &[u8],
|
||||||
|
x: u32,
|
||||||
|
y: u32,
|
||||||
|
width: u32,
|
||||||
|
height: u32,
|
||||||
|
) -> Result<(), SPI::Error>;
|
||||||
|
|
||||||
|
/// Updates the new frame for a portion of the display.
|
||||||
|
fn update_partial_new_frame(
|
||||||
|
&mut self,
|
||||||
|
spi: &mut SPI,
|
||||||
|
buffer: &[u8],
|
||||||
|
x: u32,
|
||||||
|
y: u32,
|
||||||
|
width: u32,
|
||||||
|
height: u32,
|
||||||
|
) -> Result<(), SPI::Error>;
|
||||||
|
|
||||||
|
/// Clears the partial frame buffer on the EPD with the declared background color
|
||||||
|
/// The background color can be changed with [`WaveshareDisplay::set_background_color`]
|
||||||
|
fn clear_partial_frame(
|
||||||
|
&mut self,
|
||||||
|
spi: &mut SPI,
|
||||||
|
x: u32,
|
||||||
|
y: u32,
|
||||||
|
width: u32,
|
||||||
|
height: u32,
|
||||||
|
) -> Result<(), SPI::Error>;
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue