1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155
use crate::color::Color; use core::marker::Sized; use embedded_hal::{ blocking::{delay::*, spi::Write}, digital::*, }; /// All commands need to have this trait which gives the address of the command /// which needs to be send via SPI with activated CommandsPin (Data/Command Pin in CommandMode) pub(crate) trait Command { fn address(self) -> u8; } /// Seperates the different LUT for the Display Refresh process #[derive(Debug, Clone, PartialEq, Eq)] pub enum RefreshLUT { /// The "normal" full Lookuptable for the Refresh-Sequence FULL, /// The quick LUT where not the full refresh sequence is followed. /// This might lead to some QUICK, } impl Default for RefreshLUT { fn default() -> Self { RefreshLUT::FULL } } pub(crate) trait InternalWiAdditions<SPI, CS, BUSY, DC, RST> where SPI: Write<u8>, CS: OutputPin, BUSY: InputPin, DC: OutputPin, RST: OutputPin, { /// This initialises the EPD and powers it up /// /// This function is already called from /// - [new()](WaveshareInterface::new()) /// - [`wake_up`] /// /// /// 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<DELAY: DelayMs<u8>>( &mut self, spi: &mut SPI, delay: &mut DELAY, ) -> Result<(), SPI::Error>; } /// All the functions to interact with the EPDs /// /// This trait includes all public functions to use the EPDS pub trait WaveshareDisplay<SPI, CS, BUSY, DC, RST> where SPI: Write<u8>, CS: OutputPin, BUSY: InputPin, DC: OutputPin, RST: OutputPin, { /// 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<DELAY: DelayMs<u8>>( spi: &mut SPI, cs: CS, busy: BUSY, dc: DC, rst: RST, delay: &mut DELAY, ) -> Result<Self, SPI::Error> where Self: Sized; /// 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 [wake_up()](WaveshareInterface::wake_up()) to awaken. /// But as you need to power it up once more anyway you can also just directly use [new()](WaveshareInterface::new()) for resetting /// and initialising which already contains the reset fn sleep(&mut self, spi: &mut SPI) -> Result<(), SPI::Error>; /// Wakes the device up from sleep fn wake_up<DELAY: DelayMs<u8>>( &mut self, spi: &mut SPI, delay: &mut DELAY, ) -> Result<(), SPI::Error>; /// Sets the backgroundcolor for various commands like [clear_frame()](WaveshareInterface::clear_frame()) fn set_background_color(&mut self, color: Color); /// Get current background color fn background_color(&self) -> &Color; /// Get the width of the display fn width(&self) -> u32; /// Get the height of the display fn height(&self) -> u32; /// Transmit a full frame to the SRAM of the EPD fn update_frame(&mut self, spi: &mut SPI, buffer: &[u8]) -> Result<(), SPI::Error>; /// Transmits partial data to the SRAM of the EPD /// /// (x,y) is the top left corner /// /// BUFFER needs to be of size: width / 8 * height ! fn update_partial_frame( &mut self, spi: &mut SPI, buffer: &[u8], x: u32, y: u32, width: u32, height: u32, ) -> Result<(), SPI::Error>; /// Displays the frame data from SRAM /// /// This function waits until the device isn`t busy anymore fn display_frame(&mut self, spi: &mut SPI) -> Result<(), SPI::Error>; /// Clears the frame buffer on the EPD with the declared background color /// /// The background color can be changed with [`set_background_color`] fn clear_frame(&mut self, spi: &mut SPI) -> Result<(), SPI::Error>; /// Trait for using various Waveforms from different LUTs /// E.g. for partial refreshes /// /// A full refresh is needed after a certain amount of quick refreshes! /// /// WARNING: Quick Refresh might lead to ghosting-effects/problems with your display. Especially for the 4.2in Display! /// /// If None is used the old value will be loaded on the LUTs once more fn set_lut( &mut self, spi: &mut SPI, refresh_rate: Option<RefreshLUT>, ) -> Result<(), SPI::Error>; /// Checks if the display is busy transmitting data /// /// 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 fn is_busy(&self) -> bool; }