improved traits, now it should be ready to convert 4.2"
parent
ceee294cda
commit
80e5c0ffb1
|
|
@ -1,5 +1,8 @@
|
|||
//! SPI Commands for the Waveshare 2.9" E-Ink Display
|
||||
|
||||
use interface;
|
||||
|
||||
|
||||
/// EPD2IN9 commands
|
||||
///
|
||||
/// Should rarely (never?) be needed directly.
|
||||
|
|
@ -10,7 +13,7 @@
|
|||
#[allow(dead_code)]
|
||||
#[allow(non_camel_case_types)]
|
||||
#[derive(Copy, Clone)]
|
||||
pub(crate) enum Command {
|
||||
pub enum Command {
|
||||
/// Driver Output control
|
||||
/// 3 Databytes:
|
||||
/// A[7:0]
|
||||
|
|
@ -39,9 +42,9 @@ pub(crate) enum Command {
|
|||
|
||||
|
||||
|
||||
impl Command {
|
||||
impl interface::Command for Command {
|
||||
/// Returns the address of the command
|
||||
pub fn addr(self) -> u8 {
|
||||
fn address(self) -> u8 {
|
||||
self as u8
|
||||
}
|
||||
}
|
||||
|
|
@ -49,11 +52,12 @@ impl Command {
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use super::Command;
|
||||
use interface::Command as CommandTrait;
|
||||
|
||||
#[test]
|
||||
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);
|
||||
|
||||
|
|
|
|||
|
|
@ -53,7 +53,6 @@ use hal::{
|
|||
spi::Write,
|
||||
delay::*
|
||||
},
|
||||
spi::{Mode, Phase, Polarity},
|
||||
digital::*
|
||||
};
|
||||
|
||||
|
|
@ -69,7 +68,7 @@ use interface::*;
|
|||
|
||||
use interface::data_interface::DataInterface;
|
||||
|
||||
/// EPD4in2 driver
|
||||
/// EPD2in9 driver
|
||||
///
|
||||
pub struct EPD2in9<SPI, CS, BUSY, DC, RST, D> {
|
||||
/// SPI
|
||||
|
|
@ -80,7 +79,6 @@ pub struct EPD2in9<SPI, CS, BUSY, DC, RST, D> {
|
|||
height: u32,
|
||||
}
|
||||
|
||||
|
||||
impl<SPI, CS, BUSY, DC, RST, D, E> EPD2in9<SPI, CS, BUSY, DC, RST, D>
|
||||
where
|
||||
SPI: Write<u8, Error = E>,
|
||||
|
|
@ -103,6 +101,7 @@ where
|
|||
RST: OutputPin,
|
||||
D: DelayUs<u16> + DelayMs<u16>,
|
||||
{
|
||||
|
||||
fn get_width(&self) -> u32 {
|
||||
self.width
|
||||
}
|
||||
|
|
@ -136,20 +135,45 @@ where
|
|||
|
||||
|
||||
fn init(&mut self) -> Result<(), E> {
|
||||
//TODO:
|
||||
Ok(())
|
||||
unimplemented!()
|
||||
}
|
||||
fn sleep(&mut self) -> Result<(), E> {
|
||||
Ok(())
|
||||
unimplemented!()
|
||||
}
|
||||
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 delay_ms(&mut self, delay: u32) {
|
||||
|
||||
|
||||
|
||||
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!()
|
||||
}
|
||||
|
||||
/// Sets the backgroundcolor for various commands like [WaveshareInterface::clear_frame()](clear_frame())
|
||||
fn set_background_color(&mut self, color: Color){
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@ use hal::{
|
|||
spi::Write,
|
||||
delay::*
|
||||
},
|
||||
spi::{Mode, Phase, Polarity},
|
||||
digital::*
|
||||
};
|
||||
|
||||
|
|
@ -11,7 +10,7 @@ use interface::Command;
|
|||
|
||||
/// EPD4in2 driver
|
||||
///
|
||||
pub struct DataInterface<SPI, CS, BUSY, DC, RST, D> {
|
||||
pub(crate) struct DataInterface<SPI, CS, BUSY, DC, RST, D> {
|
||||
/// SPI
|
||||
spi: SPI,
|
||||
/// CS for SPI
|
||||
|
|
@ -36,7 +35,7 @@ where
|
|||
RST: OutputPin,
|
||||
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 }
|
||||
}
|
||||
|
||||
|
|
@ -45,7 +44,7 @@ where
|
|||
/// 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> {
|
||||
pub(crate) fn send_command<T: Command>(&mut self, command: T) -> Result<(), E> {
|
||||
// low for commands
|
||||
self.dc.set_low();
|
||||
|
||||
|
|
@ -61,7 +60,7 @@ where
|
|||
///
|
||||
/// Should rarely be needed!
|
||||
/// //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
|
||||
self.dc.set_high();
|
||||
|
||||
|
|
@ -77,7 +76,7 @@ where
|
|||
///
|
||||
/// Should rarely be needed!
|
||||
/// //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
|
||||
self.dc.set_high();
|
||||
|
||||
|
|
@ -88,7 +87,7 @@ where
|
|||
}
|
||||
|
||||
// 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
|
||||
F: FnOnce(&mut Self) -> Result<(), E>,
|
||||
{
|
||||
|
|
@ -108,7 +107,7 @@ where
|
|||
/// 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) {
|
||||
pub(crate) 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
|
||||
|
|
@ -118,16 +117,18 @@ where
|
|||
|
||||
|
||||
/// 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);
|
||||
}
|
||||
|
||||
/// Resets the device.
|
||||
/// 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) {
|
||||
pub(crate) fn reset(&mut self) {
|
||||
self.rst.set_low();
|
||||
|
||||
//TODO: why 200ms? (besides being in the waveshare code)
|
||||
|
|
|
|||
|
|
@ -7,6 +7,8 @@ use hal::{
|
|||
digital::*
|
||||
};
|
||||
|
||||
use drawing::color::Color;
|
||||
|
||||
pub mod data_interface;
|
||||
|
||||
//TODO: test spi mode
|
||||
|
|
@ -20,7 +22,7 @@ pub const SPI_MODE: Mode = Mode {
|
|||
use core::marker::Sized;
|
||||
|
||||
pub(crate) trait Command {
|
||||
fn address(&self) -> u8;
|
||||
fn address(self) -> u8;
|
||||
}
|
||||
|
||||
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
|
||||
fn get_width(&self) -> u32;
|
||||
|
||||
/// Get the height of the display
|
||||
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(
|
||||
spi: SPI,
|
||||
cs: CS,
|
||||
|
|
@ -44,13 +52,66 @@ pub trait WaveshareInterface<SPI, CS, BUSY, DC, RST, D, E>
|
|||
delay: D
|
||||
) -> Result<Self, E>
|
||||
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 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>;
|
||||
|
||||
/// Resets the device.
|
||||
///
|
||||
/// Often used to awake the module from deep sleep. See [sleep()](WaveshareInterface::sleep())
|
||||
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 display_frame_quick(&mut self) -> Result<(), E>
|
||||
|
|
@ -76,30 +137,3 @@ 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…
Reference in New Issue