Browse Source

improved traits, now it should be ready to convert 4.2"

embedded-hal-1.0
Christoph Groß 8 years ago
parent
commit
80e5c0ffb1
  1. 14
      src/epd2in9/command.rs
  2. 42
      src/epd2in9/mod.rs
  3. 25
      src/interface/data_interface.rs
  4. 96
      src/interface/mod.rs

14
src/epd2in9/command.rs

@ -1,5 +1,8 @@
//! SPI Commands for the Waveshare 2.9" E-Ink Display //! SPI Commands for the Waveshare 2.9" E-Ink Display
use interface;
/// EPD2IN9 commands /// EPD2IN9 commands
/// ///
/// Should rarely (never?) be needed directly. /// Should rarely (never?) be needed directly.
@ -10,7 +13,7 @@
#[allow(dead_code)] #[allow(dead_code)]
#[allow(non_camel_case_types)] #[allow(non_camel_case_types)]
#[derive(Copy, Clone)] #[derive(Copy, Clone)]
pub(crate) enum Command { pub enum Command {
/// Driver Output control /// Driver Output control
/// 3 Databytes: /// 3 Databytes:
/// A[7:0] /// A[7:0]
@ -39,9 +42,9 @@ pub(crate) enum Command {
impl Command { impl interface::Command for Command {
/// Returns the address of the command /// Returns the address of the command
pub fn addr(self) -> u8 { fn address(self) -> u8 {
self as u8 self as u8
} }
} }
@ -49,11 +52,12 @@ impl Command {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::Command;
use interface::Command as CommandTrait;
#[test] #[test]
fn command_addr() { fn command_addr() {
//assert_eq!(Command::POWER_SAVING.addr(), 0xE3); assert_eq!(Command::DRIVER_OUTPUT_CONTROL.address(), 0x01);
//assert_eq!(Command::PANEL_SETTING.addr(), 0x00); //assert_eq!(Command::PANEL_SETTING.addr(), 0x00);

42
src/epd2in9/mod.rs

@ -53,7 +53,6 @@ use hal::{
spi::Write, spi::Write,
delay::* delay::*
}, },
spi::{Mode, Phase, Polarity},
digital::* digital::*
}; };
@ -69,7 +68,7 @@ use interface::*;
use interface::data_interface::DataInterface; use interface::data_interface::DataInterface;
/// EPD4in2 driver /// EPD2in9 driver
/// ///
pub struct EPD2in9<SPI, CS, BUSY, DC, RST, D> { pub struct EPD2in9<SPI, CS, BUSY, DC, RST, D> {
/// SPI /// SPI
@ -80,7 +79,6 @@ pub struct EPD2in9<SPI, CS, BUSY, DC, RST, D> {
height: u32, height: u32,
} }
impl<SPI, CS, BUSY, DC, RST, D, E> EPD2in9<SPI, CS, BUSY, DC, RST, D> impl<SPI, CS, BUSY, DC, RST, D, E> EPD2in9<SPI, CS, BUSY, DC, RST, D>
where where
SPI: Write<u8, Error = E>, SPI: Write<u8, Error = E>,
@ -103,6 +101,7 @@ where
RST: OutputPin, RST: OutputPin,
D: DelayUs<u16> + DelayMs<u16>, D: DelayUs<u16> + DelayMs<u16>,
{ {
fn get_width(&self) -> u32 { fn get_width(&self) -> u32 {
self.width self.width
} }
@ -136,20 +135,45 @@ where
fn init(&mut self) -> Result<(), E> { fn init(&mut self) -> Result<(), E> {
//TODO: unimplemented!()
Ok(())
} }
fn sleep(&mut self) -> Result<(), E> { fn sleep(&mut self) -> Result<(), E> {
Ok(()) unimplemented!()
} }
fn reset(&mut self) { fn reset(&mut self) {
//TODO: self.interface.reset()
} }
fn wait_until_idle(&mut self) {
fn delay_ms(&mut self, delay: u16) {
self.interface.delay_ms(delay)
}
fn update_frame(&mut self, buffer: &[u8]) -> Result<(), E>{
unimplemented!()
}
fn update_partial_frame(&mut self, buffer: &[u8], x: u16, y: u16, width: u16, height: u16) -> Result<(), E>{
unimplemented!()
}
fn display_frame(&mut self) -> Result<(), E>{
unimplemented!()
}
// TODO: add this abstraction function
// fn update_and_display_frame(&mut self, buffer: &[u8]) -> Result<(), E>;
fn clear_frame(&mut self) -> Result<(), E>{
unimplemented!()
} }
fn delay_ms(&mut self, delay: u32) {
/// Sets the backgroundcolor for various commands like [WaveshareInterface::clear_frame()](clear_frame())
fn set_background_color(&mut self, color: Color){
unimplemented!()
} }
} }

25
src/interface/data_interface.rs

@ -3,7 +3,6 @@ use hal::{
spi::Write, spi::Write,
delay::* delay::*
}, },
spi::{Mode, Phase, Polarity},
digital::* digital::*
}; };
@ -11,7 +10,7 @@ use interface::Command;
/// EPD4in2 driver /// EPD4in2 driver
/// ///
pub struct DataInterface<SPI, CS, BUSY, DC, RST, D> { pub(crate) struct DataInterface<SPI, CS, BUSY, DC, RST, D> {
/// SPI /// SPI
spi: SPI, spi: SPI,
/// CS for SPI /// CS for SPI
@ -36,7 +35,7 @@ where
RST: OutputPin, RST: OutputPin,
D: DelayUs<u16> + DelayMs<u16>, D: DelayUs<u16> + DelayMs<u16>,
{ {
pub fn new(spi: SPI, cs: CS, busy: BUSY, dc: DC, rst: RST, delay: D) -> Self { pub(crate) fn new(spi: SPI, cs: CS, busy: BUSY, dc: DC, rst: RST, delay: D) -> Self {
DataInterface {spi, cs, busy, dc, rst, delay } DataInterface {spi, cs, busy, dc, rst, delay }
} }
@ -45,7 +44,7 @@ where
/// Enables direct interaction with the device with the help of [EPD4in2::send_data()](EPD4in2::send_data()) /// Enables direct interaction with the device with the help of [EPD4in2::send_data()](EPD4in2::send_data())
/// Should rarely be needed! /// Should rarely be needed!
/// //TODO: make public? /// //TODO: make public?
fn send_command<T: Command>(&mut self, command: T) -> Result<(), E> { pub(crate) fn send_command<T: Command>(&mut self, command: T) -> Result<(), E> {
// low for commands // low for commands
self.dc.set_low(); self.dc.set_low();
@ -61,7 +60,7 @@ where
/// ///
/// Should rarely be needed! /// Should rarely be needed!
/// //TODO: make public? /// //TODO: make public?
fn send_data(&mut self, val: u8) -> Result<(), E> { pub(crate) fn send_data(&mut self, val: u8) -> Result<(), E> {
// high for data // high for data
self.dc.set_high(); self.dc.set_high();
@ -77,7 +76,7 @@ where
/// ///
/// Should rarely be needed! /// Should rarely be needed!
/// //TODO: make public? /// //TODO: make public?
fn send_multiple_data(&mut self, data: &[u8]) -> Result<(), E> { pub(crate) fn send_multiple_data(&mut self, data: &[u8]) -> Result<(), E> {
// high for data // high for data
self.dc.set_high(); self.dc.set_high();
@ -88,7 +87,7 @@ where
} }
// spi write helper/abstraction function // spi write helper/abstraction function
fn with_cs<F>(&mut self, f: F) -> Result<(), E> pub(crate) fn with_cs<F>(&mut self, f: F) -> Result<(), E>
where where
F: FnOnce(&mut Self) -> Result<(), E>, F: FnOnce(&mut Self) -> Result<(), E>,
{ {
@ -108,7 +107,7 @@ where
/// This is normally handled by the more complicated commands themselves, /// 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 /// but in the case you send data and commands directly you might need to check
/// if the device is still busy /// if the device is still busy
pub fn wait_until_idle(&mut self) { pub(crate) fn wait_until_idle(&mut self) {
//low: busy, high: idle //low: busy, high: idle
while self.busy.is_low() { while self.busy.is_low() {
//TODO: shorten the time? it was 100 in the beginning //TODO: shorten the time? it was 100 in the beginning
@ -117,17 +116,19 @@ where
} }
/// Abstraction of setting the delay for simpler calls /// Abstraction of setting the delay for simpler calls
pub fn delay_ms(&mut self, delay: u16) { ///
/// maximum delay ~65 seconds (u16:max in ms)
pub(crate) fn delay_ms(&mut self, delay: u16) {
self.delay.delay_ms(delay); self.delay.delay_ms(delay);
} }
/// Resets the device. /// Resets the device.
/// ///
/// Often used to awake the module from deep sleep. See [EPD4in2::sleep()](EPD4in2::sleep()) /// 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? /// TODO: Takes at least 400ms of delay alone, can it be shortened?
pub fn reset(&mut self) { pub(crate) fn reset(&mut self) {
self.rst.set_low(); self.rst.set_low();
//TODO: why 200ms? (besides being in the waveshare code) //TODO: why 200ms? (besides being in the waveshare code)

96
src/interface/mod.rs

@ -7,6 +7,8 @@ use hal::{
digital::* digital::*
}; };
use drawing::color::Color;
pub mod data_interface; pub mod data_interface;
//TODO: test spi mode //TODO: test spi mode
@ -20,7 +22,7 @@ pub const SPI_MODE: Mode = Mode {
use core::marker::Sized; use core::marker::Sized;
pub(crate) trait Command { pub(crate) trait Command {
fn address(&self) -> u8; fn address(self) -> u8;
} }
pub trait WaveshareInterface<SPI, CS, BUSY, DC, RST, D, E> pub trait WaveshareInterface<SPI, CS, BUSY, DC, RST, D, E>
@ -34,7 +36,13 @@ pub trait WaveshareInterface<SPI, CS, BUSY, DC, RST, D, E>
{ {
/// Get the width of the display /// Get the width of the display
fn get_width(&self) -> u32; fn get_width(&self) -> u32;
/// Get the height of the display
fn get_height(&self) -> u32; fn get_height(&self) -> u32;
/// Creates a new driver from a SPI peripheral, CS Pin, Busy InputPin, DC
///
/// This already initialises the device. That means [init()](WaveshareInterface::init()) isn't needed directly afterwards
fn new( fn new(
spi: SPI, spi: SPI,
cs: CS, cs: CS,
@ -44,13 +52,66 @@ pub trait WaveshareInterface<SPI, CS, BUSY, DC, RST, D, E>
delay: D delay: D
) -> Result<Self, E> ) -> Result<Self, E>
where Self: Sized; where Self: Sized;
/// This initialises the EPD and powers it up
///
/// This function is already called from [new()](WaveshareInterface::new())
///
/// This function calls [reset()](WaveshareInterface::reset()),
/// so you don't need to call reset your self when trying to wake your device up
/// after setting it to sleep.
fn init(&mut self) -> Result<(), E>; fn init(&mut self) -> Result<(), E>;
fn update_frame(&mut self, buffer: &[u8]) -> Result<(), E>;
fn update_partial_frame(&mut self, buffer: &[u8], x: u16, y: u16, width: u16, height: u16) -> Result<(), E>;
/// Displays the frame data from SRAM
fn display_frame(&mut self) -> Result<(), E>;
// TODO: add this abstraction function
// fn update_and_display_frame(&mut self, buffer: &[u8]) -> Result<(), E>;
/// Clears the frame from the buffer
///
/// Uses the chosen background color
fn clear_frame(&mut self) -> Result<(), E>;
/// Sets the backgroundcolor for various commands like [clear_frame()](WaveshareInterface::clear_frame())
fn set_background_color(&mut self, color: Color);
/// Let the device enter deep-sleep mode to save power.
///
/// The deep sleep mode returns to standby with a hardware reset.
/// But you can also use [reset()](WaveshareInterface::reset()) to awaken.
/// But as you need to power it up once more anyway you can also just directly use [init()](WaveshareInterface::init()) for resetting
/// and initialising which already contains the reset
fn sleep(&mut self) -> Result<(), E>; fn sleep(&mut self) -> Result<(), E>;
/// Resets the device.
///
/// Often used to awake the module from deep sleep. See [sleep()](WaveshareInterface::sleep())
fn reset(&mut self); fn reset(&mut self);
fn wait_until_idle(&mut self);
fn delay_ms(&mut self, delay: u32); /// Abstraction of setting the delay for simpler calls
///
/// maximum delay ~65 seconds (u16:max in ms)
fn delay_ms(&mut self, delay: u16);
/* /*
-display_frame
-clear_frame
-set_full_frame
-set_partial_frame
//
-set_quick_lut?
-set_normal_mode
fn clear_frame(&mut self, reset_color: Option<Color>) -> Result<(), E> fn clear_frame(&mut self, reset_color: Option<Color>) -> Result<(), E>
fn display_frame_quick(&mut self) -> Result<(), E> fn display_frame_quick(&mut self) -> Result<(), E>
@ -75,31 +136,4 @@ pub trait WaveshareInterface<SPI, CS, BUSY, DC, RST, D, 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
}
}
Loading…
Cancel
Save