Started some shared traits between the different epds, saving now

This commit is contained in:
Christoph Groß
2018-07-18 17:03:11 +02:00
parent 4cd9b26a24
commit ceee294cda
7 changed files with 391 additions and 368 deletions
+142
View File
@@ -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);
}
}
+105
View File
@@ -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
}
}