You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

128 lines
4.0 KiB

use hal::{
blocking::{delay::*, spi::Write},
use core::marker::PhantomData;
use traits::Command;
/// The Connection Interface of all (?) Waveshare EPD-Devices
pub(crate) struct DisplayInterface<SPI, CS, BUSY, DC, RST> {
/// SPI
_spi: PhantomData<SPI>,
/// CS for SPI
cs: CS,
/// Low for busy, Wait until display is ready!
busy: BUSY,
/// Data/Command Control Pin (High for data, Low for command)
dc: DC,
/// Pin for Reseting
rst: RST,
impl<SPI, CS, BUSY, DC, RST>
DisplayInterface<SPI, CS, BUSY, DC, RST>
SPI: Write<u8>,
CS: OutputPin,
BUSY: InputPin,
DC: OutputPin,
RST: OutputPin,
pub fn new(cs: CS, busy: BUSY, dc: DC, rst: RST) -> Self {
DisplayInterface {
_spi: PhantomData::default(),
/// Basic function for sending [Commands](Command).
/// Enables direct interaction with the device with the help of [data()](DisplayInterface::data())
/// //TODO: make public?
pub(crate) fn cmd<T: Command>(&mut self, spi: &mut SPI, command: T) -> Result<(), SPI::Error> {
// low for commands
// Transfer the command over spi
self.write(spi, &[command.address()])
/// Basic function for sending an array of u8-values of data over spi
/// Enables direct interaction with the device with the help of [command()](EPD4in2::command())
/// //TODO: make public?
pub(crate) fn data(&mut self, spi: &mut SPI, data: &[u8]) -> Result<(), SPI::Error> {
// high for data
// Transfer data (u8-array) over spi
self.write(spi, data)
/// Basic function for sending [Commands](Command) and the data belonging to it.
/// //TODO: make public?
/// TODO: directly use ::write? cs wouldn't needed to be changed twice than
pub(crate) fn cmd_with_data<T: Command>(&mut self, spi: &mut SPI, command: T, data: &[u8]) -> Result<(), SPI::Error> {
self.cmd(spi, command)?;, data)
// spi write helper/abstraction function
fn write(&mut self, spi: &mut SPI, data: &[u8]) -> Result<(), SPI::Error>
// activate spi with cs low
// transfer spi data
// deativate spi with cs high
/// Waits until device isn't busy anymore (busy == HIGH)
/// This is normally handled by the more complicated commands themselves,
/// but in the case you send data and commands directly you might need to check
/// if the device is still busy
/// is_busy_low
/// - TRUE for epd4in2, epd2in13, epd2in7, epd5in83, epd7in5
/// - FALSE for epd2in9, epd1in54 (for all Display Type A ones?)
/// Most likely there was a mistake with the 2in9 busy connection
/// //TODO: use the #cfg feature to make this compile the right way for the certain types
pub(crate) fn wait_until_idle(&mut self, is_busy_low: bool) {
// TODO: removal of delay. TEST!
//low: busy, high: idle
while (is_busy_low && self.busy.is_low()) || (!is_busy_low && self.busy.is_high()) {
//TODO: REMOVAL of DELAY: it's only waiting for the signal anyway and should continue work asap
//old: shorten the time? it was 100 in the beginning
/// Resets the device.
/// Often used to awake the module from deep sleep. See [EPD4in2::sleep()](EPD4in2::sleep())
/// TODO: Takes at least 400ms of delay alone, can it be shortened?
pub(crate) fn reset<DELAY: DelayMs<u8>>(&mut self, delay: &mut DELAY) {
//TODO: why 200ms? (besides being in the arduino version)
//TODO: same as 3 lines above