mirror of
https://github.com/Anshorei/epd-waveshare.git
synced 2026-10-04 06:16:42 +00:00
Started some shared traits between the different epds, saving now
This commit is contained in:
@@ -0,0 +1,142 @@
|
||||
use hal::{
|
||||
blocking::{
|
||||
spi::Write,
|
||||
delay::*
|
||||
},
|
||||
spi::{Mode, Phase, Polarity},
|
||||
digital::*
|
||||
};
|
||||
|
||||
use interface::Command;
|
||||
|
||||
/// EPD4in2 driver
|
||||
///
|
||||
pub struct DataInterface<SPI, CS, BUSY, DC, RST, D> {
|
||||
/// SPI
|
||||
spi: 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,
|
||||
/// The concrete Delay implementation
|
||||
delay: D,
|
||||
}
|
||||
|
||||
|
||||
impl<SPI, CS, BUSY, DC, RST, D, E> DataInterface<SPI, CS, BUSY, DC, RST, D>
|
||||
where
|
||||
SPI: Write<u8, Error = E>,
|
||||
CS: OutputPin,
|
||||
BUSY: InputPin,
|
||||
DC: OutputPin,
|
||||
RST: OutputPin,
|
||||
D: DelayUs<u16> + DelayMs<u16>,
|
||||
{
|
||||
pub fn new(spi: SPI, cs: CS, busy: BUSY, dc: DC, rst: RST, delay: D) -> Self {
|
||||
DataInterface {spi, cs, busy, dc, rst, delay }
|
||||
}
|
||||
|
||||
/// Basic function for sending [Commands](Command).
|
||||
///
|
||||
/// Enables direct interaction with the device with the help of [EPD4in2::send_data()](EPD4in2::send_data())
|
||||
/// Should rarely be needed!
|
||||
/// //TODO: make public?
|
||||
fn send_command<T: Command>(&mut self, command: T) -> Result<(), E> {
|
||||
// low for commands
|
||||
self.dc.set_low();
|
||||
|
||||
// Transfer the command over spi
|
||||
self.with_cs(|epd| {
|
||||
epd.spi.write(&[command.address()])
|
||||
})
|
||||
}
|
||||
|
||||
/// Basic function for sending a single u8 of data over spi
|
||||
///
|
||||
/// Enables direct interaction with the device with the help of [EPD4in2::send_command()](EPD4in2::send_command())
|
||||
///
|
||||
/// Should rarely be needed!
|
||||
/// //TODO: make public?
|
||||
fn send_data(&mut self, val: u8) -> Result<(), E> {
|
||||
// high for data
|
||||
self.dc.set_high();
|
||||
|
||||
// Transfer data (u8) over spi
|
||||
self.with_cs(|epd| {
|
||||
epd.spi.write(&[val])
|
||||
})
|
||||
}
|
||||
|
||||
/// Basic function for sending an array of u8-values of data over spi
|
||||
///
|
||||
/// Enables direct interaction with the device with the help of [EPD4in2::send_command()](EPD4in2::send_command())
|
||||
///
|
||||
/// Should rarely be needed!
|
||||
/// //TODO: make public?
|
||||
fn send_multiple_data(&mut self, data: &[u8]) -> Result<(), E> {
|
||||
// high for data
|
||||
self.dc.set_high();
|
||||
|
||||
// Transfer data (u8-array) over spi
|
||||
self.with_cs(|epd| {
|
||||
epd.spi.write(data)
|
||||
})
|
||||
}
|
||||
|
||||
// spi write helper/abstraction function
|
||||
fn with_cs<F>(&mut self, f: F) -> Result<(), E>
|
||||
where
|
||||
F: FnOnce(&mut Self) -> Result<(), E>,
|
||||
{
|
||||
// activate spi with cs low
|
||||
self.cs.set_low();
|
||||
// transfer spi data
|
||||
let result = f(self);
|
||||
// deativate spi with cs high
|
||||
self.cs.set_high();
|
||||
// return result
|
||||
result
|
||||
}
|
||||
|
||||
|
||||
/// 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
|
||||
pub fn wait_until_idle(&mut self) {
|
||||
//low: busy, high: idle
|
||||
while self.busy.is_low() {
|
||||
//TODO: shorten the time? it was 100 in the beginning
|
||||
self.delay_ms(10);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// Abstraction of setting the delay for simpler calls
|
||||
pub fn delay_ms(&mut self, delay: u16) {
|
||||
self.delay.delay_ms(delay);
|
||||
}
|
||||
|
||||
/// 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 fn reset(&mut self) {
|
||||
self.rst.set_low();
|
||||
|
||||
//TODO: why 200ms? (besides being in the waveshare code)
|
||||
self.delay_ms(200);
|
||||
|
||||
self.rst.set_high();
|
||||
|
||||
//TODO: same as 3 lines above
|
||||
self.delay_ms(200);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
use hal::{
|
||||
blocking::{
|
||||
spi::Write,
|
||||
delay::*
|
||||
},
|
||||
spi::{Mode, Phase, Polarity},
|
||||
digital::*
|
||||
};
|
||||
|
||||
pub mod data_interface;
|
||||
|
||||
//TODO: test spi mode
|
||||
/// SPI mode -
|
||||
/// For more infos see [Requirements: SPI](index.html#spi)
|
||||
pub const SPI_MODE: Mode = Mode {
|
||||
phase: Phase::CaptureOnFirstTransition,
|
||||
polarity: Polarity::IdleLow,
|
||||
};
|
||||
|
||||
use core::marker::Sized;
|
||||
|
||||
pub(crate) trait Command {
|
||||
fn address(&self) -> u8;
|
||||
}
|
||||
|
||||
pub trait WaveshareInterface<SPI, CS, BUSY, DC, RST, D, E>
|
||||
where
|
||||
SPI: Write<u8, Error = E>,
|
||||
CS: OutputPin,
|
||||
BUSY: InputPin,
|
||||
DC: OutputPin,
|
||||
RST: OutputPin,
|
||||
D: DelayUs<u16> + DelayMs<u16>,
|
||||
{
|
||||
/// Get the width of the display
|
||||
fn get_width(&self) -> u32;
|
||||
fn get_height(&self) -> u32;
|
||||
fn new(
|
||||
spi: SPI,
|
||||
cs: CS,
|
||||
busy: BUSY,
|
||||
dc: DC,
|
||||
rst: RST,
|
||||
delay: D
|
||||
) -> Result<Self, E>
|
||||
where Self: Sized;
|
||||
fn init(&mut self) -> Result<(), E>;
|
||||
fn sleep(&mut self) -> Result<(), E>;
|
||||
fn reset(&mut self);
|
||||
fn wait_until_idle(&mut self);
|
||||
fn delay_ms(&mut self, delay: u32);
|
||||
|
||||
/*
|
||||
fn clear_frame(&mut self, reset_color: Option<Color>) -> Result<(), E>
|
||||
|
||||
fn display_frame_quick(&mut self) -> Result<(), E>
|
||||
|
||||
fn display_frame(&mut self) -> Result<(), E>
|
||||
|
||||
pub fn display_and_transfer_frame(
|
||||
&mut self,
|
||||
buffer: &[u8],
|
||||
color: Option<u8>
|
||||
) -> Result<(), E>
|
||||
|
||||
pub fn set_partial_window(
|
||||
&mut self,
|
||||
buffer: &[u8],
|
||||
x: u16,
|
||||
y: u16,
|
||||
w: u16,
|
||||
l: u16,
|
||||
is_dtm1: bool
|
||||
) -> Result<(), E>
|
||||
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
|
||||
pub trait TestInterface
|
||||
{
|
||||
fn get_width(&self) -> u32;
|
||||
fn get_height(&self) -> u32;
|
||||
|
||||
|
||||
}
|
||||
|
||||
struct testStruct {
|
||||
width: u32,
|
||||
height: u32,
|
||||
}
|
||||
|
||||
impl TestInterface for testStruct {
|
||||
fn get_width(&self) -> u32 {
|
||||
self.width
|
||||
}
|
||||
|
||||
fn get_height(&self) -> u32 {
|
||||
self.height
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user