use embedded_hal::{
blocking::{delay::*, serial::Write},
digital::v2::*,
serial::Read,
};
use crate::color::EpdColor;
use crate::interface::DisplayInterface;
use crate::traits::{Error, InternalWiAdditions, WaveshareDisplay};
pub const WIDTH: u32 = 800;
pub const HEIGHT: u32 = 600;
pub const DEFAULT_BACKGROUND_COLOR: EpdColor = EpdColor::White;
pub const DEFAULT_FOREGROUND_COLOR: EpdColor = EpdColor::Black;
pub mod command;
#[cfg(feature = "graphics")]
mod graphics;
#[cfg(feature = "graphics")]
pub use self::graphics::Display4in3;
pub struct EPD4in3<SERIAL, WAKE, RST> {
interface: DisplayInterface<SERIAL, WAKE, RST>,
bg_color: EpdColor,
fg_color: EpdColor,
}
impl<E, F, G, SERIAL, WAKE, RST> InternalWiAdditions<E, F, G, SERIAL, WAKE, RST>
for EPD4in3<SERIAL, WAKE, RST>
where
SERIAL: Write<u8, Error = F> + Read<u8, Error = E>,
WAKE: OutputPin<Error = G>,
RST: OutputPin<Error = G>,
{
fn init<DELAY: DelayMs<u16>>(
&mut self,
_serial: &mut SERIAL,
delay: &mut DELAY,
) -> Result<(), Error<E, F, G>> {
self.interface.reset(delay)
}
fn wake<DELAY: DelayMs<u16>>(
&mut self,
_serial: &mut SERIAL,
delay: &mut DELAY,
) -> Result<(), Error<E, F, G>> {
self.interface.wake(delay)
}
}
impl<E, F, G, SERIAL, WAKE, RST> WaveshareDisplay<E, F, G, SERIAL, WAKE, RST>
for EPD4in3<SERIAL, WAKE, RST>
where
SERIAL: Write<u8, Error = F> + Read<u8, Error = E>,
WAKE: OutputPin<Error = G>,
RST: OutputPin<Error = G>,
{
fn new<DELAY: DelayMs<u16>>(
serial: &mut SERIAL,
wake: WAKE,
rst: RST,
delay: &mut DELAY,
) -> Result<Self, Error<E, F, G>> {
let interface = DisplayInterface::new(wake, rst);
let bg_color = DEFAULT_BACKGROUND_COLOR;
let fg_color = DEFAULT_FOREGROUND_COLOR;
let mut epd = EPD4in3 {
interface,
bg_color,
fg_color,
};
epd.init(serial, delay)?;
Ok(epd)
}
fn wake_up<DELAY: DelayMs<u16>>(
&mut self,
serial: &mut SERIAL,
delay: &mut DELAY,
) -> Result<(), Error<E, F, G>> {
self.wake(serial, delay)
}
fn sleep(&mut self, serial: &mut SERIAL) -> Result<(), Error<E, F, G>> {
let cmd_sleep = command::sleep().unwrap();
self.interface.data(serial, cmd_sleep.get_bytes())?;
Ok(())
}
fn update_frame<DELAY: DelayMs<u16>>(
&mut self,
serial: &mut SERIAL,
buffer: &[EpdColor],
_delay: &mut DELAY,
) -> Result<(), Error<E, F, G>> {
for (index, &color) in buffer.iter().enumerate() {
let mut retries = 0;
let mut response_ok = false;
while (retries < 10) && !response_ok {
let mut read_bytes = 0;
if self.bg_color == color {
break;
}
if self.fg_color != color {
self.set_foreground_color(color);
let cmd_color = command::set_color(color, self.bg_color).unwrap();
self.interface.data(serial, cmd_color.get_bytes())?;
read_bytes += 2;
}
let (x, y) = (index as u32 % self.width(), index as u32 / self.width());
let cmd_point = command::point(x as u16, y as u16).unwrap();
self.interface.data(serial, cmd_point.get_bytes())?;
read_bytes += 2;
let mut data = [0u8; 4];
if read_bytes > 0 {
response_ok = true;
self.interface
.read_serial(serial, &mut data[0..read_bytes])?;
for &byte in data[0..read_bytes].iter() {
if byte == 0x00 {
response_ok = false;
retries+=1;
}
}
} else {
retries = 10;
}
} }
Ok(())
}
fn display_frame(&mut self, serial: &mut SERIAL) -> Result<(), Error<E, F, G>> {
let cmd = command::refresh().unwrap();
let bytes = cmd.get_bytes();
self.interface.data(serial, bytes)
}
fn clear_frame(&mut self, serial: &mut SERIAL) -> Result<(), Error<E, F, G>> {
let cmd = command::clear().unwrap();
let bytes = cmd.get_bytes();
self.interface.data(serial, bytes)
}
fn set_background_color(&mut self, color: EpdColor) {
self.bg_color = color;
}
fn set_foreground_color(&mut self, color: EpdColor) {
self.fg_color = color;
}
fn width(&self) -> u32 {
WIDTH
}
fn height(&self) -> u32 {
HEIGHT
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn epd_size() {
assert_eq!(WIDTH, 800);
assert_eq!(HEIGHT, 600);
assert_eq!(DEFAULT_BACKGROUND_COLOR, EpdColor::White);
}
}