diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml
index 0c06d2f5..fcfe6a40 100644
--- a/.github/workflows/rust.yml
+++ b/.github/workflows/rust.yml
@@ -27,6 +27,8 @@ jobs:
run: cargo build --examples --all-targets --verbose
- name: Run tests
run: cargo test --verbose
+ - name: Run tests (async)
+ run: cargo test --verbose --lib --tests --benches --features async
- name: Build docs
run: cargo doc
- name: Clippy
diff --git a/Cargo.toml b/Cargo.toml
index 73c33370..172c7cb3 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -16,7 +16,9 @@ rust-version = "1.62"
[dependencies]
embedded-graphics-core = { version = "0.4", optional = true }
embedded-hal = "1.0.0"
+embedded-hal-async = { version = "1.0.0", optional = true }
bit_field = "0.10.1"
+maybe-async = { git = "https://github.com/XLPhere/maybe-async-rs.git", branch = "default_sync", features = ["default_sync"] }
[dev-dependencies]
embedded-graphics = "0.8"
@@ -47,11 +49,16 @@ required-features = ["linux-dev"]
name = "epd4in2"
required-features = ["linux-dev"]
+[[example]]
+name = "epd7in5_v2"
+required-features = ["linux-dev"]
+
[features]
# Remove the linux-dev feature to build the tests on non unix systems
default = ["graphics", "linux-dev", "epd2in13_v3"]
graphics = ["embedded-graphics-core"]
+async = ["embedded-hal-async", "maybe-async/is_async"]
epd2in13_v2 = []
epd2in13_v3 = []
linux-dev = []
diff --git a/src/epd12in48b_v2/mod.rs b/src/epd12in48b_v2/mod.rs
index c802286e..8df93202 100644
--- a/src/epd12in48b_v2/mod.rs
+++ b/src/epd12in48b_v2/mod.rs
@@ -11,12 +11,9 @@
mod command;
mod config;
-use embedded_hal::{
- delay::DelayNs,
- digital::{InputPin, OutputPin, PinState},
- spi::SpiBus,
-};
+use embedded_hal::digital::{InputPin, OutputPin, PinState};
+use crate::interface::{DelayNs, SpiBus};
pub use crate::rect::Rect;
use command::Command;
pub use config::*;
@@ -133,6 +130,7 @@ where
control_state: CS,
}
+#[maybe_async::maybe_async]
impl EpdDriver
where
INPUT: InputPin,
@@ -161,7 +159,7 @@ where
/// Reset the display, potentially waking it up from deep sleep.
/// Normally should be followed by a call to [`init()`](EpdDriver::init).
- pub fn reset(&mut self) -> Result<(), OUTPUT::Error> {
+ pub async fn reset(&mut self) -> Result<(), OUTPUT::Error> {
drop(self.peris.m1_cs.set_high());
drop(self.peris.s1_cs.set_high());
drop(self.peris.m2_cs.set_high());
@@ -172,25 +170,26 @@ where
self.peris.m1s1_rst.set_high()?;
self.peris.m2s2_rst.set_high()?;
- self.delay.delay_ms(1);
+ self.delay.delay_ms(1).await;
self.peris.m1s1_rst.set_low()?;
- self.delay.delay_us(100); // min RST low = 50us
+ self.delay.delay_us(100).await; // min RST low = 50us
self.peris.m1s1_rst.set_high()?;
- self.delay.delay_ms(100); // min wait after RST = 10ms
+ self.delay.delay_ms(100).await; // min wait after RST = 10ms
self.peris.m2s2_rst.set_low()?;
- self.delay.delay_us(100);
+ self.delay.delay_us(100).await;
self.peris.m2s2_rst.set_high()?;
- self.delay.delay_ms(100);
+ self.delay.delay_ms(100).await;
Ok(())
}
/// Initialize display registers.
- pub fn init(&mut self, config: &Config) -> Result<(), SPI::Error> {
+ pub async fn init(&mut self, config: &Config) -> Result<(), SPI::Error> {
// booster soft start
- self.cmd_with_data(CS_ALL, Command::BoosterSoftStart, &[0x17, 0x17, 0x39, 0x17])?;
+ self.cmd_with_data(CS_ALL, Command::BoosterSoftStart, &[0x17, 0x17, 0x39, 0x17])
+ .await?;
// resolution setting
fn resolution_data(rect: Rect) -> [u8; 4] {
@@ -201,24 +200,33 @@ where
(rect.h % 256) as u8,
]
}
- self.cmd_with_data(CS_M1, Command::TconResolution, &resolution_data(M1_RECT))?;
- self.cmd_with_data(CS_S1, Command::TconResolution, &resolution_data(S1_RECT))?;
- self.cmd_with_data(CS_M2, Command::TconResolution, &resolution_data(M2_RECT))?;
- self.cmd_with_data(CS_S2, Command::TconResolution, &resolution_data(S2_RECT))?;
-
- self.cmd_with_data(CS_ALL, Command::DualSPI, &[0x20])?;
- self.cmd_with_data(CS_ALL, Command::TconSetting, &[0x22])?;
- self.cmd_with_data(CS_ALL, Command::PowerSaving, &[0x00])?;
- self.cmd_with_data(CS_ALL, Command::CascadeSetting, &[0x03])?;
- self.cmd_with_data(CS_ALL, Command::ForceTemperature, &[25])?;
-
- self.set_mode(config)?;
-
- self.flush()
+ self.cmd_with_data(CS_M1, Command::TconResolution, &resolution_data(M1_RECT))
+ .await?;
+ self.cmd_with_data(CS_S1, Command::TconResolution, &resolution_data(S1_RECT))
+ .await?;
+ self.cmd_with_data(CS_M2, Command::TconResolution, &resolution_data(M2_RECT))
+ .await?;
+ self.cmd_with_data(CS_S2, Command::TconResolution, &resolution_data(S2_RECT))
+ .await?;
+
+ self.cmd_with_data(CS_ALL, Command::DualSPI, &[0x20])
+ .await?;
+ self.cmd_with_data(CS_ALL, Command::TconSetting, &[0x22])
+ .await?;
+ self.cmd_with_data(CS_ALL, Command::PowerSaving, &[0x00])
+ .await?;
+ self.cmd_with_data(CS_ALL, Command::CascadeSetting, &[0x03])
+ .await?;
+ self.cmd_with_data(CS_ALL, Command::ForceTemperature, &[25])
+ .await?;
+
+ self.set_mode(config).await?;
+
+ self.flush().await
}
/// Set data "polarity", waveform lookup table mode, etc, without re-initializing anything else.
- pub fn set_mode(&mut self, config: &Config) -> Result<(), SPI::Error> {
+ pub async fn set_mode(&mut self, config: &Config) -> Result<(), SPI::Error> {
let ddx = match (config.inverted_r, config.inverted_kw) {
(false, true) => 0b00,
(false, false) => 0b01,
@@ -238,19 +246,24 @@ where
};
let reg = (config.external_lut as u8) << 5;
- self.cmd_with_data(CS_M1, Command::PanelSetting, &[reg | 0x0F])?;
- self.cmd_with_data(CS_S1, Command::PanelSetting, &[reg | 0x0F])?;
- self.cmd_with_data(CS_M2, Command::PanelSetting, &[reg | 0x03])?;
- self.cmd_with_data(CS_S2, Command::PanelSetting, &[reg | 0x03])?;
+ self.cmd_with_data(CS_M1, Command::PanelSetting, &[reg | 0x0F])
+ .await?;
+ self.cmd_with_data(CS_S1, Command::PanelSetting, &[reg | 0x0F])
+ .await?;
+ self.cmd_with_data(CS_M2, Command::PanelSetting, &[reg | 0x03])
+ .await?;
+ self.cmd_with_data(CS_S2, Command::PanelSetting, &[reg | 0x03])
+ .await?;
let bdv = bdv << 4;
self.cmd_with_data(
CS_ALL,
Command::VcomAndDataIntervalSetting,
&[bdv | ddx, 0x07],
- )?;
+ )
+ .await?;
- self.flush()
+ self.flush().await
}
/// Fill data1 buffer with pixels:
@@ -259,30 +272,42 @@ where
///
/// `pixels` may contain a lesser number of rows than the window being written,
/// in which case it will be treated as circular.
- pub fn write_data1(&mut self, pixels: &[u8]) -> Result<(), SPI::Error> {
- self.write_window_data(Command::DataStartTransmission1, FULL_RECT, pixels)?;
- self.flush()
+ pub async fn write_data1(&mut self, pixels: &[u8]) -> Result<(), SPI::Error> {
+ self.write_window_data(Command::DataStartTransmission1, FULL_RECT, pixels)
+ .await?;
+ self.flush().await
}
/// Fill data2 buffer with pixels.
/// See also [`write_data1`](EpdDriver::write_data1).
- pub fn write_data2(&mut self, pixels: &[u8]) -> Result<(), SPI::Error> {
- self.write_window_data(Command::DataStartTransmission2, FULL_RECT, pixels)?;
- self.flush()
+ pub async fn write_data2(&mut self, pixels: &[u8]) -> Result<(), SPI::Error> {
+ self.write_window_data(Command::DataStartTransmission2, FULL_RECT, pixels)
+ .await?;
+ self.flush().await
}
/// Fill a window in the data1 buffer with pixels.
/// See also [`write_data1`](EpdDriver::write_data1).
- pub fn write_data1_partial(&mut self, window: Rect, pixels: &[u8]) -> Result<(), SPI::Error> {
- self.write_partial(Command::DataStartTransmission1, window, pixels)?;
- self.flush()
+ pub async fn write_data1_partial(
+ &mut self,
+ window: Rect,
+ pixels: &[u8],
+ ) -> Result<(), SPI::Error> {
+ self.write_partial(Command::DataStartTransmission1, window, pixels)
+ .await?;
+ self.flush().await
}
/// Fill a window in the data2 buffer with pixels.
/// See also [`write_data1`](EpdDriver::write_data1).
- pub fn write_data2_partial(&mut self, window: Rect, pixels: &[u8]) -> Result<(), SPI::Error> {
- self.write_partial(Command::DataStartTransmission2, window, pixels)?;
- self.flush()
+ pub async fn write_data2_partial(
+ &mut self,
+ window: Rect,
+ pixels: &[u8],
+ ) -> Result<(), SPI::Error> {
+ self.write_partial(Command::DataStartTransmission2, window, pixels)
+ .await?;
+ self.flush().await
}
/// Store VCOM Look-Up Table.
@@ -290,116 +315,123 @@ where
/// If LUT data is shorter than expected, the rest is filled with zeroes.
/// Note that stored lookup tables need to be activated by setting
/// [`Config::external_lut`](config::Config::external_lut)`=true`.
- pub fn set_lutc(&mut self, data: &[u8]) -> Result<(), SPI::Error> {
- self.set_lut(Command::LutC, data, 60)
+ pub async fn set_lutc(&mut self, data: &[u8]) -> Result<(), SPI::Error> {
+ self.set_lut(Command::LutC, data, 60).await
}
/// Store White-to-White Look-Up Table.
/// See also [`write_data1`](EpdDriver::set_lutc).
- pub fn set_lutww(&mut self, data: &[u8]) -> Result<(), SPI::Error> {
- self.set_lut(Command::LutWW, data, 42)
+ pub async fn set_lutww(&mut self, data: &[u8]) -> Result<(), SPI::Error> {
+ self.set_lut(Command::LutWW, data, 42).await
}
/// Store Black-to-White (KW mode) / Red (KWR mode) Look-Up Table.
/// See also [`write_data1`](EpdDriver::set_lutc).
- pub fn set_lutkw_lutr(&mut self, data: &[u8]) -> Result<(), SPI::Error> {
- self.set_lut(Command::LutKW_LutR, data, 60)
+ pub async fn set_lutkw_lutr(&mut self, data: &[u8]) -> Result<(), SPI::Error> {
+ self.set_lut(Command::LutKW_LutR, data, 60).await
}
/// Store White-to-Black (KW mode) / White (KWR mode) Look-Up Table.
/// See also [`write_data1`](EpdDriver::set_lutc).
- pub fn set_lutwk_lutw(&mut self, data: &[u8]) -> Result<(), SPI::Error> {
- self.set_lut(Command::LutWK_LutW, data, 60)
+ pub async fn set_lutwk_lutw(&mut self, data: &[u8]) -> Result<(), SPI::Error> {
+ self.set_lut(Command::LutWK_LutW, data, 60).await
}
/// Store Black-to-Black (KW mode) / Black (KWR mode) Look-Up Table.
/// See also [`write_data1`](EpdDriver::set_lutc).
- pub fn set_lutkk_lutk(&mut self, data: &[u8]) -> Result<(), SPI::Error> {
- self.set_lut(Command::LutKK_LutK, data, 60)
+ pub async fn set_lutkk_lutk(&mut self, data: &[u8]) -> Result<(), SPI::Error> {
+ self.set_lut(Command::LutKK_LutK, data, 60).await
}
/// Store Border Look-Up Table.
/// See also [`write_data1`](EpdDriver::set_lutc).
- pub fn set_lutbd(&mut self, data: &[u8]) -> Result<(), SPI::Error> {
- self.set_lut(Command::LutBD, data, 42)
+ pub async fn set_lutbd(&mut self, data: &[u8]) -> Result<(), SPI::Error> {
+ self.set_lut(Command::LutBD, data, 42).await
}
- fn set_lut(&mut self, cmd: Command, data: &[u8], reqd_len: usize) -> Result<(), SPI::Error> {
- self.cmd_with_data(CS_ALL, cmd, data)?;
+ async fn set_lut(
+ &mut self,
+ cmd: Command,
+ data: &[u8],
+ reqd_len: usize,
+ ) -> Result<(), SPI::Error> {
+ self.cmd_with_data(CS_ALL, cmd, data).await?;
if data.len() < reqd_len {
let zeroes = [0; 60];
- self.spi_write(CS_ALL | CS_DATA, &zeroes[..reqd_len - data.len()])?;
+ self.spi_write(CS_ALL | CS_DATA, &zeroes[..reqd_len - data.len()])
+ .await?;
}
- self.flush()
+ self.flush().await
}
/// Refresh the entire display.
- pub fn refresh_display(&mut self) -> Result<(), SPI::Error> {
- self.begin_refresh_display()?;
- drop(self.wait_ready(CS_ALL));
+ pub async fn refresh_display(&mut self) -> Result<(), SPI::Error> {
+ self.begin_refresh_display().await?;
+ drop(self.wait_ready(CS_ALL).await);
Ok(())
}
/// Asynchronous version of [`refresh_display`](EpdDriver::refresh_display).
/// Use [`is_busy`](EpdDriver::is_busy) to poll for completion.
- pub fn begin_refresh_display(&mut self) -> Result<(), SPI::Error> {
- self.cmd(CS_ALL, Command::PowerOn)?;
- drop(self.wait_ready(CS_ALL));
+ pub async fn begin_refresh_display(&mut self) -> Result<(), SPI::Error> {
+ self.cmd(CS_ALL, Command::PowerOn).await?;
+ drop(self.wait_ready(CS_ALL).await);
// Appears to be required to reliably trigger display refresh after a power-on.
- self.delay.delay_ms(100);
+ self.delay.delay_ms(100).await;
- self.cmd(CS_ALL, Command::DisplayRefresh)?;
+ self.cmd(CS_ALL, Command::DisplayRefresh).await?;
- self.flush()
+ self.flush().await
}
/// Refresh the specified sub-window of the display.
///
/// Technically, this works, however, after 2+ partial updates, the rest of the displayed image becomes visibly degraded.
- pub fn refresh_display_partial(&mut self, window: Rect) -> Result<(), SPI::Error> {
- self.begin_refresh_display_partial(window)?;
+ pub async fn refresh_display_partial(&mut self, window: Rect) -> Result<(), SPI::Error> {
+ self.begin_refresh_display_partial(window).await?;
- drop(self.wait_ready(CS_ALL));
+ drop(self.wait_ready(CS_ALL).await);
Ok(())
}
/// Asynchronous version of [`refresh_display_partial`](EpdDriver::refresh_display_partial).
/// Use [`is_busy`](EpdDriver::is_busy) to poll for completion.
- pub fn begin_refresh_display_partial(&mut self, window: Rect) -> Result<(), SPI::Error> {
- self.setup_partial_windows(window)?;
+ pub async fn begin_refresh_display_partial(&mut self, window: Rect) -> Result<(), SPI::Error> {
+ self.setup_partial_windows(window).await?;
- self.cmd(CS_ALL, Command::PowerOn)?;
- drop(self.wait_ready(CS_ALL));
- self.delay.delay_ms(100);
+ self.cmd(CS_ALL, Command::PowerOn).await?;
+ drop(self.wait_ready(CS_ALL).await);
+ self.delay.delay_ms(100).await;
- self.cmd(CS_ALL, Command::PartialIn)?;
- self.cmd(CS_ALL, Command::DisplayRefresh)?;
- self.cmd(CS_ALL, Command::PartialOut)?;
+ self.cmd(CS_ALL, Command::PartialIn).await?;
+ self.cmd(CS_ALL, Command::DisplayRefresh).await?;
+ self.cmd(CS_ALL, Command::PartialOut).await?;
- self.flush()
+ self.flush().await
}
/// Turn off booster, controller, source driver, gate driver, VCOM, and temperature sensor.
/// However, the contents of the data memory buffers will be retained.
- pub fn power_off(&mut self) -> Result<(), SPI::Error> {
- self.cmd(CS_ALL, Command::PowerOff)?;
- drop(self.wait_ready(CS_ALL));
+ pub async fn power_off(&mut self) -> Result<(), SPI::Error> {
+ self.cmd(CS_ALL, Command::PowerOff).await?;
+ drop(self.wait_ready(CS_ALL).await);
- self.flush()
+ self.flush().await
}
/// Put display into deep sleep. Only [`reset()`](EpdDriver::reset) can bring it out of this state.
/// The contents of the data memory buffers will be lost.
- pub fn hibernate(&mut self) -> Result<(), SPI::Error> {
- self.cmd(CS_ALL, Command::PowerOff)?;
- drop(self.wait_ready(CS_ALL));
+ pub async fn hibernate(&mut self) -> Result<(), SPI::Error> {
+ self.cmd(CS_ALL, Command::PowerOff).await?;
+ drop(self.wait_ready(CS_ALL).await);
- self.cmd_with_data(CS_ALL, Command::DeepSleep, &[0xA5])?;
+ self.cmd_with_data(CS_ALL, Command::DeepSleep, &[0xA5])
+ .await?;
- self.flush()
+ self.flush().await
}
- fn setup_partial_windows(&mut self, window: Rect) -> Result<(), SPI::Error> {
+ async fn setup_partial_windows(&mut self, window: Rect) -> Result<(), SPI::Error> {
let s2_part = window.intersect(S2_RECT).sub_offset(S2_RECT.x, S2_RECT.y);
let m2_part = window.intersect(M2_RECT).sub_offset(M2_RECT.x, M2_RECT.y);
let m1_part = window.intersect(M1_RECT).sub_offset(M1_RECT.x, M1_RECT.y);
@@ -434,27 +466,31 @@ where
CS_S2,
Command::PartialWindow,
&partial_window_data(s2_part, Some(S2_RECT.w)),
- )?;
+ )
+ .await?;
self.cmd_with_data(
CS_M2,
Command::PartialWindow,
&partial_window_data(m2_part, Some(M2_RECT.w)),
- )?;
+ )
+ .await?;
self.cmd_with_data(
CS_M1,
Command::PartialWindow,
&partial_window_data(m1_part, None),
- )?;
+ )
+ .await?;
self.cmd_with_data(
CS_S1,
Command::PartialWindow,
&partial_window_data(s1_part, None),
- )?;
+ )
+ .await?;
Ok(())
}
- fn write_partial(
+ async fn write_partial(
&mut self,
transmission_cmd: Command,
window: Rect,
@@ -464,16 +500,17 @@ where
panic!("Window is not 8-aligned horizontally");
}
- self.cmd(CS_ALL, Command::PartialIn)?;
+ self.cmd(CS_ALL, Command::PartialIn).await?;
- self.setup_partial_windows(window)?;
- self.write_window_data(transmission_cmd, window, pixels)?;
+ self.setup_partial_windows(window).await?;
+ self.write_window_data(transmission_cmd, window, pixels)
+ .await?;
- self.cmd(CS_ALL, Command::PartialOut)
+ self.cmd(CS_ALL, Command::PartialOut).await
}
// Send data to each sub-display for the window area that overlaps with it.
- fn write_window_data(
+ async fn write_window_data(
&mut self,
transmission_cmd: Command,
window: Rect,
@@ -501,40 +538,40 @@ where
if top_rows > 0 {
if left_bytes > 0 {
- self.cmd(CS_S2, transmission_cmd)?;
+ self.cmd(CS_S2, transmission_cmd).await?;
for y in 0..top_rows {
let begin = row_offset(y);
let end = begin + left_bytes;
- self.spi_write(CS_S2 | CS_DATA, &pixels[begin..end])?;
+ self.spi_write(CS_S2 | CS_DATA, &pixels[begin..end]).await?;
}
}
if right_bytes > 0 {
- self.cmd(CS_M2, transmission_cmd)?;
+ self.cmd(CS_M2, transmission_cmd).await?;
for y in 0..top_rows {
let begin = row_offset(y) + left_bytes;
let end = begin + right_bytes;
- self.spi_write(CS_M2 | CS_DATA, &pixels[begin..end])?;
+ self.spi_write(CS_M2 | CS_DATA, &pixels[begin..end]).await?;
}
}
}
if bottom_rows > 0 {
if left_bytes > 0 {
- self.cmd(CS_M1, transmission_cmd)?;
+ self.cmd(CS_M1, transmission_cmd).await?;
for y in 0..bottom_rows {
let begin = row_offset(top_rows + y);
let end = begin + left_bytes;
- self.spi_write(CS_M1 | CS_DATA, &pixels[begin..end])?;
+ self.spi_write(CS_M1 | CS_DATA, &pixels[begin..end]).await?;
}
}
if right_bytes > 0 {
- self.cmd(CS_S1, transmission_cmd)?;
+ self.cmd(CS_S1, transmission_cmd).await?;
for y in 0..bottom_rows {
let begin = row_offset(top_rows + y) + left_bytes;
let end = begin + right_bytes;
- self.spi_write(CS_S1 | CS_DATA, &pixels[begin..end])?;
+ self.spi_write(CS_S1 | CS_DATA, &pixels[begin..end]).await?;
}
}
}
@@ -542,22 +579,22 @@ where
Ok(())
}
- fn cmd(&mut self, chips: CS, command: Command) -> Result<(), SPI::Error> {
- self.spi_write(chips, &[command as u8])
+ async fn cmd(&mut self, chips: CS, command: Command) -> Result<(), SPI::Error> {
+ self.spi_write(chips, &[command as u8]).await
}
- fn cmd_with_data(
+ async fn cmd_with_data(
&mut self,
chips: CS,
command: Command,
data: &[u8],
) -> Result<(), SPI::Error> {
- self.spi_write(chips, &[command as u8])?;
- self.spi_write(chips | CS_DATA, data)
+ self.spi_write(chips, &[command as u8]).await?;
+ self.spi_write(chips | CS_DATA, data).await
}
// Set control pins to the specified state, then send data via SPI.
- fn spi_write(&mut self, control: CS, data: &[u8]) -> Result<(), SPI::Error> {
+ async fn spi_write(&mut self, control: CS, data: &[u8]) -> Result<(), SPI::Error> {
if self.control_state != control {
fn pin_state(high: bool) -> PinState {
if high {
@@ -567,8 +604,8 @@ where
}
}
- self.peris.spi.flush()?;
- self.delay.delay_ns(100); // Tscc = 20ns, Tchw = 40ns
+ self.peris.spi.flush().await?;
+ self.delay.delay_ns(100).await; // Tscc = 20ns, Tchw = 40ns
// CS is active low
drop(self.peris.m1_cs.set_state(pin_state(control & CS_M1 == 0)));
@@ -581,16 +618,16 @@ where
drop(self.peris.m1s1_dc.set_state(dc));
drop(self.peris.m2s2_dc.set_state(dc));
- self.delay.delay_ns(100); // Tcss = 60ns, Tsds = 30ns
+ self.delay.delay_ns(100).await; // Tcss = 60ns, Tsds = 30ns
self.control_state = control;
}
- self.peris.spi.write(data)
+ self.peris.spi.write(data).await
}
// Flush SPI, reset control pins to the default state.
- fn flush(&mut self) -> Result<(), SPI::Error> {
- self.peris.spi.flush()?;
+ async fn flush(&mut self) -> Result<(), SPI::Error> {
+ self.peris.spi.flush().await?;
drop(self.peris.m1_cs.set_high());
drop(self.peris.s1_cs.set_high());
drop(self.peris.m2_cs.set_high());
@@ -601,9 +638,9 @@ where
Ok(())
}
- fn wait_ready(&mut self, chips: CS) -> Result<(), INPUT::Error> {
+ async fn wait_ready(&mut self, chips: CS) -> Result<(), INPUT::Error> {
while self.busy_chips(chips)? != 0 {
- self.delay.delay_ms(200);
+ self.delay.delay_ms(200).await;
}
Ok(())
}
@@ -637,7 +674,7 @@ where
/// Query and return the status byte of each sub-display.
/// Order: \[M1, S1, M2, S2\].
- pub fn get_status(&mut self) -> Result<[u8; 4], SPI::Error> {
+ pub async fn get_status(&mut self) -> Result<[u8; 4], SPI::Error> {
self.control_state = 0xFF;
let mut status = [0u8; 4];
for i in 0..4 {
@@ -650,20 +687,20 @@ where
// Request status
drop(cs.set_low());
drop(dc.set_low());
- self.delay.delay_ns(100); // Tcss = 60ns
- self.peris.spi.write(&[Command::GetStatus as u8])?;
- self.peris.spi.flush()?;
- self.delay.delay_ns(100); // Tsds = 30ns
+ self.delay.delay_ns(100).await; // Tcss = 60ns
+ self.peris.spi.write(&[Command::GetStatus as u8]).await?;
+ self.peris.spi.flush().await?;
+ self.delay.delay_ns(100).await; // Tsds = 30ns
// Read status
drop(dc.set_high());
- self.delay.delay_ns(100); // Tsdh = 30ns
- self.peris.spi.read(&mut status[i..i + 1])?;
- self.delay.delay_ns(100); // Tscc = 20ns
+ self.delay.delay_ns(100).await; // Tsdh = 30ns
+ self.peris.spi.read(&mut status[i..i + 1]).await?;
+ self.delay.delay_ns(100).await; // Tscc = 20ns
drop(dc.set_low());
drop(cs.set_high());
- self.delay.delay_ns(100); // Tchw = 40ns
+ self.delay.delay_ns(100).await; // Tchw = 40ns
}
self.control_state = 0;
Ok(status)
diff --git a/src/epd1in02/mod.rs b/src/epd1in02/mod.rs
index 6eafea13..b4585790 100644
--- a/src/epd1in02/mod.rs
+++ b/src/epd1in02/mod.rs
@@ -4,14 +4,10 @@
//!
//! The display controller IC is UC8175
-use embedded_hal::{
- delay::DelayNs,
- digital::{InputPin, OutputPin},
- spi::SpiDevice,
-};
+use embedded_hal::digital::{InputPin, OutputPin};
use crate::color::Color;
-use crate::interface::DisplayInterface;
+use crate::interface::{DelayNs, DisplayInterface, SpiDevice};
use crate::prelude::WaveshareDisplay;
use crate::traits::{InternalWiAdditions, QuickRefresh, RefreshLut};
@@ -58,6 +54,7 @@ pub struct Epd1in02 {
refresh_mode: RefreshLut,
}
+#[maybe_async::maybe_async(AFIT)]
impl WaveshareDisplay
for Epd1in02
where
@@ -69,7 +66,7 @@ where
{
type DisplayColor = Color;
- fn new(
+ async fn new(
spi: &mut SPI,
busy: BUSY,
dc: DC,
@@ -87,15 +84,15 @@ where
refresh_mode: RefreshLut::Full,
};
- epd.init(spi, delay)?;
+ epd.init(spi, delay).await?;
Ok(epd)
}
- fn sleep(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
- self.wait_until_idle(spi, delay)?;
- self.turn_off(spi, delay)?;
- self.cmd_with_data(spi, Command::DeepSleep, &[0xA5])?;
+ async fn sleep(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
+ self.wait_until_idle(spi, delay).await?;
+ self.turn_off(spi, delay).await?;
+ self.cmd_with_data(spi, Command::DeepSleep, &[0xA5]).await?;
// display registers are set to default value
self.refresh_mode = RefreshLut::Full;
@@ -103,8 +100,8 @@ where
Ok(())
}
- fn wake_up(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
- self.init(spi, delay)
+ async fn wake_up(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
+ self.init(spi, delay).await
}
fn set_background_color(&mut self, color: Color) {
@@ -123,29 +120,31 @@ where
HEIGHT
}
- fn update_frame(
+ async fn update_frame(
&mut self,
spi: &mut SPI,
buffer: &[u8],
delay: &mut DELAY,
) -> Result<(), SPI::Error> {
- self.wait_until_idle(spi, delay)?;
+ self.wait_until_idle(spi, delay).await?;
- self.set_full_mode(spi, delay)?;
+ self.set_full_mode(spi, delay).await?;
let color_value = self.background_color().get_byte_value();
- self.command(spi, Command::DataStartTransmission1)?;
+ self.command(spi, Command::DataStartTransmission1).await?;
self.interface
- .data_x_times(spi, color_value, NUMBER_OF_BYTES)?;
+ .data_x_times(spi, color_value, NUMBER_OF_BYTES)
+ .await?;
- self.cmd_with_data(spi, Command::DataStartTransmission2, buffer)?;
+ self.cmd_with_data(spi, Command::DataStartTransmission2, buffer)
+ .await?;
Ok(())
}
// Implemented as quick partial update
// as it requires old frame update
- fn update_partial_frame(
+ async fn update_partial_frame(
&mut self,
_spi: &mut SPI,
_delay: &mut DELAY,
@@ -158,44 +157,46 @@ where
unimplemented!()
}
- fn display_frame(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
- self.wait_until_idle(spi, delay)?;
- self.turn_on_if_turned_off(spi, delay)?;
+ async fn display_frame(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
+ self.wait_until_idle(spi, delay).await?;
+ self.turn_on_if_turned_off(spi, delay).await?;
- self.command(spi, Command::DisplayRefresh)?;
- self.wait_until_idle(spi, delay)?;
+ self.command(spi, Command::DisplayRefresh).await?;
+ self.wait_until_idle(spi, delay).await?;
Ok(())
}
- fn update_and_display_frame(
+ async fn update_and_display_frame(
&mut self,
spi: &mut SPI,
buffer: &[u8],
delay: &mut DELAY,
) -> Result<(), SPI::Error> {
- self.update_frame(spi, buffer, delay)?;
- self.display_frame(spi, delay)?;
+ self.update_frame(spi, buffer, delay).await?;
+ self.display_frame(spi, delay).await?;
Ok(())
}
- fn clear_frame(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
- self.wait_until_idle(spi, delay)?;
- self.set_full_mode(spi, delay)?;
+ async fn clear_frame(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
+ self.wait_until_idle(spi, delay).await?;
+ self.set_full_mode(spi, delay).await?;
let color_value = self.background_color().get_byte_value();
- self.command(spi, Command::DataStartTransmission1)?;
+ self.command(spi, Command::DataStartTransmission1).await?;
self.interface
- .data_x_times(spi, !color_value, NUMBER_OF_BYTES)?;
+ .data_x_times(spi, !color_value, NUMBER_OF_BYTES)
+ .await?;
- self.command(spi, Command::DataStartTransmission2)?;
+ self.command(spi, Command::DataStartTransmission2).await?;
self.interface
- .data_x_times(spi, color_value, NUMBER_OF_BYTES)?;
+ .data_x_times(spi, color_value, NUMBER_OF_BYTES)
+ .await?;
Ok(())
}
- fn set_lut(
+ async fn set_lut(
&mut self,
spi: &mut SPI,
_delay: &mut DELAY,
@@ -207,17 +208,24 @@ where
None => return Ok(()),
};
- self.cmd_with_data(spi, Command::SetWhiteLut, white_lut)?;
- self.cmd_with_data(spi, Command::SetBlackLut, black_lut)?;
+ self.cmd_with_data(spi, Command::SetWhiteLut, white_lut)
+ .await?;
+ self.cmd_with_data(spi, Command::SetBlackLut, black_lut)
+ .await?;
Ok(())
}
- fn wait_until_idle(&mut self, _spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
- self.interface.wait_until_idle(delay, IS_BUSY_LOW);
+ async fn wait_until_idle(
+ &mut self,
+ _spi: &mut SPI,
+ delay: &mut DELAY,
+ ) -> Result<(), SPI::Error> {
+ self.interface.wait_until_idle(delay, IS_BUSY_LOW).await;
Ok(())
}
}
+#[maybe_async::maybe_async(AFIT)]
impl QuickRefresh
for Epd1in02
where
@@ -228,35 +236,42 @@ where
DELAY: DelayNs,
{
/// To be followed immediately by update_new_frame
- fn update_old_frame(
+ async fn update_old_frame(
&mut self,
spi: &mut SPI,
buffer: &[u8],
delay: &mut DELAY,
) -> Result<(), SPI::Error> {
- self.set_partial_mode(spi, delay)?;
- self.set_partial_window(spi, delay, 0, 0, WIDTH, HEIGHT)?;
+ self.set_partial_mode(spi, delay).await?;
+ self.set_partial_window(spi, delay, 0, 0, WIDTH, HEIGHT)
+ .await?;
- self.cmd_with_data(spi, Command::DataStartTransmission1, buffer)?;
+ self.cmd_with_data(spi, Command::DataStartTransmission1, buffer)
+ .await?;
Ok(())
}
/// To be used immediately after update_old_frame
- fn update_new_frame(
+ async fn update_new_frame(
&mut self,
spi: &mut SPI,
buffer: &[u8],
_delay: &mut DELAY,
) -> Result<(), SPI::Error> {
- self.cmd_with_data(spi, Command::DataStartTransmission2, buffer)?;
+ self.cmd_with_data(spi, Command::DataStartTransmission2, buffer)
+ .await?;
Ok(())
}
- fn display_new_frame(&mut self, _spi: &mut SPI, _delay: &mut DELAY) -> Result<(), SPI::Error> {
+ async fn display_new_frame(
+ &mut self,
+ _spi: &mut SPI,
+ _delay: &mut DELAY,
+ ) -> Result<(), SPI::Error> {
unimplemented!()
}
- fn update_and_display_new_frame(
+ async fn update_and_display_new_frame(
&mut self,
_spi: &mut SPI,
_buffer: &[u8],
@@ -267,7 +282,7 @@ where
/// To be followed immediately by update_partial_new_frame
/// isn't faster then full update
- fn update_partial_old_frame(
+ async fn update_partial_old_frame(
&mut self,
spi: &mut SPI,
delay: &mut DELAY,
@@ -281,15 +296,17 @@ where
panic!("Image buffer size is not correct")
}
- self.set_partial_mode(spi, delay)?;
- self.set_partial_window(spi, delay, x, y, width, height)?;
+ self.set_partial_mode(spi, delay).await?;
+ self.set_partial_window(spi, delay, x, y, width, height)
+ .await?;
- self.cmd_with_data(spi, Command::DataStartTransmission1, buffer)?;
+ self.cmd_with_data(spi, Command::DataStartTransmission1, buffer)
+ .await?;
Ok(())
}
/// To be used immediately after update_partial_old_frame
- fn update_partial_new_frame(
+ async fn update_partial_new_frame(
&mut self,
spi: &mut SPI,
_delay: &mut DELAY,
@@ -303,12 +320,13 @@ where
panic!("Image buffer size is not correct")
}
- self.cmd_with_data(spi, Command::DataStartTransmission2, buffer)?;
+ self.cmd_with_data(spi, Command::DataStartTransmission2, buffer)
+ .await?;
Ok(())
}
/// Isn't faster then full clear
- fn clear_partial_frame(
+ async fn clear_partial_frame(
&mut self,
spi: &mut SPI,
delay: &mut DELAY,
@@ -317,29 +335,33 @@ where
width: u32,
height: u32,
) -> Result<(), SPI::Error> {
- self.wait_until_idle(spi, delay)?;
+ self.wait_until_idle(spi, delay).await?;
// set full LUT as quick LUT requires old image
- self.set_full_mode(spi, delay)?;
- self.command(spi, Command::PartialIn)?;
- self.set_partial_window(spi, delay, x, y, width, height)?;
+ self.set_full_mode(spi, delay).await?;
+ self.command(spi, Command::PartialIn).await?;
+ self.set_partial_window(spi, delay, x, y, width, height)
+ .await?;
let color_value = self.background_color().get_byte_value();
let number_of_bytes = buffer_len(width as usize, height as usize) as u32;
- self.command(spi, Command::DataStartTransmission1)?;
+ self.command(spi, Command::DataStartTransmission1).await?;
self.interface
- .data_x_times(spi, !color_value, number_of_bytes)?;
+ .data_x_times(spi, !color_value, number_of_bytes)
+ .await?;
- self.command(spi, Command::DataStartTransmission2)?;
+ self.command(spi, Command::DataStartTransmission2).await?;
self.interface
- .data_x_times(spi, color_value, number_of_bytes)?;
+ .data_x_times(spi, color_value, number_of_bytes)
+ .await?;
- self.command(spi, Command::PartialOut)?;
+ self.command(spi, Command::PartialOut).await?;
Ok(())
}
}
+#[maybe_async::maybe_async(AFIT)]
impl InternalWiAdditions
for Epd1in02
where
@@ -349,24 +371,29 @@ where
RST: OutputPin,
DELAY: DelayNs,
{
- fn init(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
+ async fn init(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
// Reset the device
- self.interface.reset(delay, 20_000, 2000);
+ self.interface.reset(delay, 20_000, 2000).await;
// Set the panel settings: LUT from register
- self.cmd_with_data(spi, Command::PanelSetting, &[0x6F])?;
+ self.cmd_with_data(spi, Command::PanelSetting, &[0x6F])
+ .await?;
// Set the power settings: VGH=16V, VGL=-16V, VDH=11V, VDL=-11V
- self.cmd_with_data(spi, Command::PowerSetting, &[0x03, 0x00, 0x2b, 0x2b])?;
+ self.cmd_with_data(spi, Command::PowerSetting, &[0x03, 0x00, 0x2b, 0x2b])
+ .await?;
// Set the charge pump settings: 50ms, Strength 4, 8kHz
- self.cmd_with_data(spi, Command::ChargePumpSetting, &[0x3F])?;
+ self.cmd_with_data(spi, Command::ChargePumpSetting, &[0x3F])
+ .await?;
// Set LUT option: no All-Gate-ON
- self.cmd_with_data(spi, Command::LutOption, &[0x00, 0x00])?;
+ self.cmd_with_data(spi, Command::LutOption, &[0x00, 0x00])
+ .await?;
// Set the clock frequency: 50 Hz
- self.cmd_with_data(spi, Command::PllControl, &[0x17])?;
+ self.cmd_with_data(spi, Command::PllControl, &[0x17])
+ .await?;
// Set Vcom and data interval: default
// set the border color the same as background color
@@ -374,27 +401,32 @@ where
Color::Black => 0x57,
Color::White => 0x97,
};
- self.cmd_with_data(spi, Command::VcomAndDataIntervalSetting, &[value])?;
+ self.cmd_with_data(spi, Command::VcomAndDataIntervalSetting, &[value])
+ .await?;
// Set the non-overlapping period of Gate and Source: 24us
- self.cmd_with_data(spi, Command::TconSetting, &[0x22])?;
+ self.cmd_with_data(spi, Command::TconSetting, &[0x22])
+ .await?;
// Set the real resolution
- self.send_resolution(spi)?;
+ self.send_resolution(spi).await?;
// Set Vcom DC value: -1 V
- self.cmd_with_data(spi, Command::VcomDcSetting, &[0x12])?;
+ self.cmd_with_data(spi, Command::VcomDcSetting, &[0x12])
+ .await?;
// Set pover saving settings
- self.cmd_with_data(spi, Command::PowerSaving, &[0x33])?;
+ self.cmd_with_data(spi, Command::PowerSaving, &[0x33])
+ .await?;
- self.set_lut(spi, delay, Some(self.refresh_mode))?;
+ self.set_lut(spi, delay, Some(self.refresh_mode)).await?;
- self.wait_until_idle(spi, delay)?;
+ self.wait_until_idle(spi, delay).await?;
Ok(())
}
}
+#[maybe_async::maybe_async]
impl Epd1in02
where
SPI: SpiDevice,
@@ -403,72 +435,76 @@ where
RST: OutputPin,
DELAY: DelayNs,
{
- fn command(&mut self, spi: &mut SPI, command: Command) -> Result<(), SPI::Error> {
- self.interface.cmd(spi, command)
+ async fn command(&mut self, spi: &mut SPI, command: Command) -> Result<(), SPI::Error> {
+ self.interface.cmd(spi, command).await
}
- fn send_data(&mut self, spi: &mut SPI, data: &[u8]) -> Result<(), SPI::Error> {
- self.interface.data(spi, data)
+ async fn send_data(&mut self, spi: &mut SPI, data: &[u8]) -> Result<(), SPI::Error> {
+ self.interface.data(spi, data).await
}
- fn cmd_with_data(
+ async fn cmd_with_data(
&mut self,
spi: &mut SPI,
command: Command,
data: &[u8],
) -> Result<(), SPI::Error> {
- self.interface.cmd_with_data(spi, command, data)
+ self.interface.cmd_with_data(spi, command, data).await
}
- fn send_resolution(&mut self, spi: &mut SPI) -> Result<(), SPI::Error> {
+ async fn send_resolution(&mut self, spi: &mut SPI) -> Result<(), SPI::Error> {
let w = self.width();
let h = self.height();
- self.command(spi, Command::TconResolution)?;
- self.send_data(spi, &[h as u8])?;
- self.send_data(spi, &[w as u8])
+ self.command(spi, Command::TconResolution).await?;
+ self.send_data(spi, &[h as u8]).await?;
+ self.send_data(spi, &[w as u8]).await
}
/// PowerOn command
- fn turn_on_if_turned_off(
+ async fn turn_on_if_turned_off(
&mut self,
spi: &mut SPI,
delay: &mut DELAY,
) -> Result<(), SPI::Error> {
if !self.is_turned_on {
- self.command(spi, Command::PowerOn)?;
- self.wait_until_idle(spi, delay)?;
+ self.command(spi, Command::PowerOn).await?;
+ self.wait_until_idle(spi, delay).await?;
self.is_turned_on = true;
}
Ok(())
}
- fn turn_off(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
- self.command(spi, Command::PowerOff)?;
- self.wait_until_idle(spi, delay)?;
+ async fn turn_off(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
+ self.command(spi, Command::PowerOff).await?;
+ self.wait_until_idle(spi, delay).await?;
self.is_turned_on = false;
Ok(())
}
- fn set_full_mode(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
+ async fn set_full_mode(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
if self.refresh_mode != RefreshLut::Full {
- self.command(spi, Command::PartialOut)?;
- self.set_lut(spi, delay, Some(RefreshLut::Full))?;
+ self.command(spi, Command::PartialOut).await?;
+ self.set_lut(spi, delay, Some(RefreshLut::Full)).await?;
self.refresh_mode = RefreshLut::Full;
}
Ok(())
}
- fn set_partial_mode(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
+ async fn set_partial_mode(
+ &mut self,
+ spi: &mut SPI,
+ delay: &mut DELAY,
+ ) -> Result<(), SPI::Error> {
if self.refresh_mode != RefreshLut::Quick {
- self.command(spi, Command::PartialIn)?;
- self.set_lut(spi, delay, Some(RefreshLut::Quick))?;
+ self.command(spi, Command::PartialIn).await?;
+ self.set_lut(spi, delay, Some(RefreshLut::Quick)).await?;
self.refresh_mode = RefreshLut::Quick;
}
Ok(())
}
- fn set_partial_window(
+ async fn set_partial_window(
&mut self,
spi: &mut SPI,
_delay: &mut DELAY,
@@ -491,7 +527,8 @@ where
(y + height - 1) as u8,
0x00,
],
- )?;
+ )
+ .await?;
Ok(())
}
diff --git a/src/epd1in54/mod.rs b/src/epd1in54/mod.rs
index b598693e..8dd7e324 100644
--- a/src/epd1in54/mod.rs
+++ b/src/epd1in54/mod.rs
@@ -54,7 +54,7 @@ pub const DEFAULT_BACKGROUND_COLOR: Color = Color::White;
const IS_BUSY_LOW: bool = false;
const SINGLE_BYTE_WRITE: bool = true;
-use embedded_hal::{delay::*, digital::*, spi::SpiDevice};
+use embedded_hal::digital::*;
use crate::type_a::{
command::Command,
@@ -66,7 +66,7 @@ use crate::color::Color;
use crate::traits::{RefreshLut, WaveshareDisplay};
use crate::buffer_len;
-use crate::interface::DisplayInterface;
+use crate::interface::{DelayNs, DisplayInterface, SpiDevice};
/// Full size buffer for use with the 1in54b EPD
#[cfg(feature = "graphics")]
@@ -88,6 +88,7 @@ pub struct Epd1in54 {
refresh: RefreshLut,
}
+#[maybe_async::maybe_async]
impl Epd1in54
where
SPI: SpiDevice,
@@ -96,19 +97,21 @@ where
RST: OutputPin,
DELAY: DelayNs,
{
- fn init(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
- self.interface.reset(delay, 10_000, 10_000);
+ async fn init(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
+ self.interface.reset(delay, 10_000, 10_000).await;
// 3 Databytes:
// A[7:0]
// 0.. A[8]
// 0.. B[2:0]
// Default Values: A = Height of Screen (0x127), B = 0x00 (GD, SM and TB=0?)
- self.interface.cmd_with_data(
- spi,
- Command::DriverOutputControl,
- &[HEIGHT as u8, (HEIGHT >> 8) as u8, 0x00],
- )?;
+ self.interface
+ .cmd_with_data(
+ spi,
+ Command::DriverOutputControl,
+ &[HEIGHT as u8, (HEIGHT >> 8) as u8, 0x00],
+ )
+ .await?;
// 3 Databytes: (and default values from datasheet and arduino)
// 1 .. A[6:0] = 0xCF | 0xD7
@@ -116,32 +119,38 @@ where
// 1 .. C[6:0] = 0x8D | 0x9D
//TODO: test
self.interface
- .cmd_with_data(spi, Command::BoosterSoftStartControl, &[0xD7, 0xD6, 0x9D])?;
+ .cmd_with_data(spi, Command::BoosterSoftStartControl, &[0xD7, 0xD6, 0x9D])
+ .await?;
// One Databyte with value 0xA8 for 7V VCOM
self.interface
- .cmd_with_data(spi, Command::WriteVcomRegister, &[0xA8])?;
+ .cmd_with_data(spi, Command::WriteVcomRegister, &[0xA8])
+ .await?;
// One Databyte with default value 0x1A for 4 dummy lines per gate
self.interface
- .cmd_with_data(spi, Command::SetDummyLinePeriod, &[0x1A])?;
+ .cmd_with_data(spi, Command::SetDummyLinePeriod, &[0x1A])
+ .await?;
// One Databyte with default value 0x08 for 2us per line
self.interface
- .cmd_with_data(spi, Command::SetGateLineWidth, &[0x08])?;
+ .cmd_with_data(spi, Command::SetGateLineWidth, &[0x08])
+ .await?;
// One Databyte with default value 0x03
// -> address: x increment, y increment, address counter is updated in x direction
self.interface
- .cmd_with_data(spi, Command::DataEntryModeSetting, &[0x03])?;
+ .cmd_with_data(spi, Command::DataEntryModeSetting, &[0x03])
+ .await?;
- self.set_lut(spi, delay, None)?;
+ self.set_lut(spi, delay, None).await?;
- self.wait_until_idle(spi, delay)?;
+ self.wait_until_idle(spi, delay).await?;
Ok(())
}
}
+#[maybe_async::maybe_async(AFIT)]
impl WaveshareDisplay
for Epd1in54
where
@@ -160,7 +169,7 @@ where
HEIGHT
}
- fn new(
+ async fn new(
spi: &mut SPI,
busy: BUSY,
dc: DC,
@@ -176,39 +185,41 @@ where
refresh: RefreshLut::Full,
};
- epd.init(spi, delay)?;
+ epd.init(spi, delay).await?;
Ok(epd)
}
- fn wake_up(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
- self.init(spi, delay)
+ async fn wake_up(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
+ self.init(spi, delay).await
}
- fn sleep(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
- self.wait_until_idle(spi, delay)?;
+ async fn sleep(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
+ self.wait_until_idle(spi, delay).await?;
// 0x00 for Normal mode (Power on Reset), 0x01 for Deep Sleep Mode
//TODO: is 0x00 needed here or would 0x01 be even more efficient?
self.interface
- .cmd_with_data(spi, Command::DeepSleepMode, &[0x00])?;
+ .cmd_with_data(spi, Command::DeepSleepMode, &[0x00])
+ .await?;
Ok(())
}
- fn update_frame(
+ async fn update_frame(
&mut self,
spi: &mut SPI,
buffer: &[u8],
delay: &mut DELAY,
) -> Result<(), SPI::Error> {
- self.wait_until_idle(spi, delay)?;
- self.use_full_frame(spi, delay)?;
+ self.wait_until_idle(spi, delay).await?;
+ self.use_full_frame(spi, delay).await?;
self.interface
- .cmd_with_data(spi, Command::WriteRam, buffer)?;
+ .cmd_with_data(spi, Command::WriteRam, buffer)
+ .await?;
Ok(())
}
//TODO: update description: last 3 bits will be ignored for width and x_pos
- fn update_partial_frame(
+ async fn update_partial_frame(
&mut self,
spi: &mut SPI,
delay: &mut DELAY,
@@ -218,50 +229,54 @@ where
width: u32,
height: u32,
) -> Result<(), SPI::Error> {
- self.wait_until_idle(spi, delay)?;
- self.set_ram_area(spi, delay, x, y, x + width, y + height)?;
- self.set_ram_counter(spi, delay, x, y)?;
+ self.wait_until_idle(spi, delay).await?;
+ self.set_ram_area(spi, delay, x, y, x + width, y + height)
+ .await?;
+ self.set_ram_counter(spi, delay, x, y).await?;
self.interface
- .cmd_with_data(spi, Command::WriteRam, buffer)?;
+ .cmd_with_data(spi, Command::WriteRam, buffer)
+ .await?;
Ok(())
}
- fn display_frame(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
- self.wait_until_idle(spi, delay)?;
+ async fn display_frame(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
+ self.wait_until_idle(spi, delay).await?;
// enable clock signal, enable cp, display pattern -> 0xC4 (tested with the arduino version)
//TODO: test control_1 or control_2 with default value 0xFF (from the datasheet)
self.interface
- .cmd_with_data(spi, Command::DisplayUpdateControl2, &[0xC4])?;
+ .cmd_with_data(spi, Command::DisplayUpdateControl2, &[0xC4])
+ .await?;
- self.interface.cmd(spi, Command::MasterActivation)?;
+ self.interface.cmd(spi, Command::MasterActivation).await?;
// MASTER Activation should not be interupted to avoid currption of panel images
// therefore a terminate command is send
- self.interface.cmd(spi, Command::Nop)?;
+ self.interface.cmd(spi, Command::Nop).await?;
Ok(())
}
- fn update_and_display_frame(
+ async fn update_and_display_frame(
&mut self,
spi: &mut SPI,
buffer: &[u8],
delay: &mut DELAY,
) -> Result<(), SPI::Error> {
- self.update_frame(spi, buffer, delay)?;
- self.display_frame(spi, delay)?;
+ self.update_frame(spi, buffer, delay).await?;
+ self.display_frame(spi, delay).await?;
Ok(())
}
- fn clear_frame(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
- self.wait_until_idle(spi, delay)?;
- self.use_full_frame(spi, delay)?;
+ async fn clear_frame(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
+ self.wait_until_idle(spi, delay).await?;
+ self.use_full_frame(spi, delay).await?;
// clear the ram with the background color
let color = self.background_color.get_byte_value();
- self.interface.cmd(spi, Command::WriteRam)?;
+ self.interface.cmd(spi, Command::WriteRam).await?;
self.interface
- .data_x_times(spi, color, WIDTH / 8 * HEIGHT)?;
+ .data_x_times(spi, color, WIDTH / 8 * HEIGHT)
+ .await?;
Ok(())
}
@@ -273,7 +288,7 @@ where
&self.background_color
}
- fn set_lut(
+ async fn set_lut(
&mut self,
spi: &mut SPI,
delay: &mut DELAY,
@@ -283,17 +298,22 @@ where
self.refresh = refresh_lut;
}
match self.refresh {
- RefreshLut::Full => self.set_lut_helper(spi, delay, &LUT_FULL_UPDATE),
- RefreshLut::Quick => self.set_lut_helper(spi, delay, &LUT_PARTIAL_UPDATE),
+ RefreshLut::Full => self.set_lut_helper(spi, delay, &LUT_FULL_UPDATE).await,
+ RefreshLut::Quick => self.set_lut_helper(spi, delay, &LUT_PARTIAL_UPDATE).await,
}
}
- fn wait_until_idle(&mut self, _spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
- self.interface.wait_until_idle(delay, IS_BUSY_LOW);
+ async fn wait_until_idle(
+ &mut self,
+ _spi: &mut SPI,
+ delay: &mut DELAY,
+ ) -> Result<(), SPI::Error> {
+ self.interface.wait_until_idle(delay, IS_BUSY_LOW).await;
Ok(())
}
}
+#[maybe_async::maybe_async]
impl Epd1in54
where
SPI: SpiDevice,
@@ -302,19 +322,20 @@ where
RST: OutputPin,
DELAY: DelayNs,
{
- pub(crate) fn use_full_frame(
+ pub(crate) async fn use_full_frame(
&mut self,
spi: &mut SPI,
delay: &mut DELAY,
) -> Result<(), SPI::Error> {
// choose full frame/ram
- self.set_ram_area(spi, delay, 0, 0, WIDTH - 1, HEIGHT - 1)?;
+ self.set_ram_area(spi, delay, 0, 0, WIDTH - 1, HEIGHT - 1)
+ .await?;
// start from the beginning
- self.set_ram_counter(spi, delay, 0, 0)
+ self.set_ram_counter(spi, delay, 0, 0).await
}
- pub(crate) fn set_ram_area(
+ pub(crate) async fn set_ram_area(
&mut self,
spi: &mut SPI,
delay: &mut DELAY,
@@ -323,65 +344,73 @@ where
end_x: u32,
end_y: u32,
) -> Result<(), SPI::Error> {
- self.wait_until_idle(spi, delay)?;
+ self.wait_until_idle(spi, delay).await?;
assert!(start_x < end_x);
assert!(start_y < end_y);
// x is positioned in bytes, so the last 3 bits which show the position inside a byte in the ram
// aren't relevant
- self.interface.cmd_with_data(
- spi,
- Command::SetRamXAddressStartEndPosition,
- &[(start_x >> 3) as u8, (end_x >> 3) as u8],
- )?;
+ self.interface
+ .cmd_with_data(
+ spi,
+ Command::SetRamXAddressStartEndPosition,
+ &[(start_x >> 3) as u8, (end_x >> 3) as u8],
+ )
+ .await?;
// 2 Databytes: A[7:0] & 0..A[8] for each - start and end
- self.interface.cmd_with_data(
- spi,
- Command::SetRamYAddressStartEndPosition,
- &[
- start_y as u8,
- (start_y >> 8) as u8,
- end_y as u8,
- (end_y >> 8) as u8,
- ],
- )?;
+ self.interface
+ .cmd_with_data(
+ spi,
+ Command::SetRamYAddressStartEndPosition,
+ &[
+ start_y as u8,
+ (start_y >> 8) as u8,
+ end_y as u8,
+ (end_y >> 8) as u8,
+ ],
+ )
+ .await?;
Ok(())
}
- pub(crate) fn set_ram_counter(
+ pub(crate) async fn set_ram_counter(
&mut self,
spi: &mut SPI,
delay: &mut DELAY,
x: u32,
y: u32,
) -> Result<(), SPI::Error> {
- self.wait_until_idle(spi, delay)?;
+ self.wait_until_idle(spi, delay).await?;
// x is positioned in bytes, so the last 3 bits which show the position inside a byte in the ram
// aren't relevant
self.interface
- .cmd_with_data(spi, Command::SetRamXAddressCounter, &[(x >> 3) as u8])?;
+ .cmd_with_data(spi, Command::SetRamXAddressCounter, &[(x >> 3) as u8])
+ .await?;
// 2 Databytes: A[7:0] & 0..A[8]
- self.interface.cmd_with_data(
- spi,
- Command::SetRamYAddressCounter,
- &[y as u8, (y >> 8) as u8],
- )?;
+ self.interface
+ .cmd_with_data(
+ spi,
+ Command::SetRamYAddressCounter,
+ &[y as u8, (y >> 8) as u8],
+ )
+ .await?;
Ok(())
}
- fn set_lut_helper(
+ async fn set_lut_helper(
&mut self,
spi: &mut SPI,
delay: &mut DELAY,
buffer: &[u8],
) -> Result<(), SPI::Error> {
- self.wait_until_idle(spi, delay)?;
+ self.wait_until_idle(spi, delay).await?;
assert!(buffer.len() == 30);
self.interface
- .cmd_with_data(spi, Command::WriteLutRegister, buffer)?;
+ .cmd_with_data(spi, Command::WriteLutRegister, buffer)
+ .await?;
Ok(())
}
}
diff --git a/src/epd1in54_v2/mod.rs b/src/epd1in54_v2/mod.rs
index 80bf5849..0fcc3f09 100644
--- a/src/epd1in54_v2/mod.rs
+++ b/src/epd1in54_v2/mod.rs
@@ -11,7 +11,7 @@ pub const DEFAULT_BACKGROUND_COLOR: Color = Color::White;
const IS_BUSY_LOW: bool = false;
const SINGLE_BYTE_WRITE: bool = true;
-use embedded_hal::{delay::*, digital::*, spi::SpiDevice};
+use embedded_hal::digital::*;
use crate::type_a::command::Command;
@@ -22,7 +22,7 @@ use crate::color::Color;
use crate::traits::{RefreshLut, WaveshareDisplay};
-use crate::interface::DisplayInterface;
+use crate::interface::{DelayNs, DisplayInterface, SpiDevice};
#[cfg(feature = "graphics")]
pub use crate::epd1in54::Display1in54;
@@ -38,6 +38,7 @@ pub struct Epd1in54 {
refresh: RefreshLut,
}
+#[maybe_async::maybe_async]
impl Epd1in54
where
SPI: SpiDevice,
@@ -46,47 +47,55 @@ where
RST: OutputPin,
DELAY: DelayNs,
{
- fn init(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
- self.interface.reset(delay, 10_000, 10_000);
- self.wait_until_idle(spi, delay)?;
- self.interface.cmd(spi, Command::SwReset)?;
- self.wait_until_idle(spi, delay)?;
+ async fn init(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
+ self.interface.reset(delay, 10_000, 10_000).await;
+ self.wait_until_idle(spi, delay).await?;
+ self.interface.cmd(spi, Command::SwReset).await?;
+ self.wait_until_idle(spi, delay).await?;
// 3 Databytes:
// A[7:0]
// 0.. A[8]
// 0.. B[2:0]
// Default Values: A = Height of Screen (0x127), B = 0x00 (GD, SM and TB=0?)
- self.interface.cmd_with_data(
- spi,
- Command::DriverOutputControl,
- &[(HEIGHT - 1) as u8, 0x0, 0x00],
- )?;
+ self.interface
+ .cmd_with_data(
+ spi,
+ Command::DriverOutputControl,
+ &[(HEIGHT - 1) as u8, 0x0, 0x00],
+ )
+ .await?;
self.interface
- .cmd_with_data(spi, Command::DataEntryModeSetting, &[0x3])?;
+ .cmd_with_data(spi, Command::DataEntryModeSetting, &[0x3])
+ .await?;
- self.set_ram_area(spi, delay, 0, 0, WIDTH - 1, HEIGHT - 1)?;
+ self.set_ram_area(spi, delay, 0, 0, WIDTH - 1, HEIGHT - 1)
+ .await?;
- self.interface.cmd_with_data(
- spi,
- Command::TemperatureSensorSelection,
- &[0x80], // 0x80: internal temperature sensor
- )?;
+ self.interface
+ .cmd_with_data(
+ spi,
+ Command::TemperatureSensorSelection,
+ &[0x80], // 0x80: internal temperature sensor
+ )
+ .await?;
self.interface
- .cmd_with_data(spi, Command::TemperatureSensorControl, &[0xB1, 0x20])?;
+ .cmd_with_data(spi, Command::TemperatureSensorControl, &[0xB1, 0x20])
+ .await?;
- self.set_ram_counter(spi, delay, 0, 0)?;
+ self.set_ram_counter(spi, delay, 0, 0).await?;
//Initialize the lookup table with a refresh waveform
- self.set_lut(spi, delay, None)?;
+ self.set_lut(spi, delay, None).await?;
- self.wait_until_idle(spi, delay)?;
+ self.wait_until_idle(spi, delay).await?;
Ok(())
}
}
+#[maybe_async::maybe_async(AFIT)]
impl WaveshareDisplay
for Epd1in54
where
@@ -105,7 +114,7 @@ where
HEIGHT
}
- fn new(
+ async fn new(
spi: &mut SPI,
busy: BUSY,
dc: DC,
@@ -121,37 +130,39 @@ where
refresh: RefreshLut::Full,
};
- epd.init(spi, delay)?;
+ epd.init(spi, delay).await?;
Ok(epd)
}
- fn wake_up(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
- self.init(spi, delay)
+ async fn wake_up(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
+ self.init(spi, delay).await
}
- fn sleep(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
- self.wait_until_idle(spi, delay)?;
+ async fn sleep(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
+ self.wait_until_idle(spi, delay).await?;
self.interface
- .cmd_with_data(spi, Command::DeepSleepMode, &[0x01])?;
+ .cmd_with_data(spi, Command::DeepSleepMode, &[0x01])
+ .await?;
Ok(())
}
- fn update_frame(
+ async fn update_frame(
&mut self,
spi: &mut SPI,
buffer: &[u8],
delay: &mut DELAY,
) -> Result<(), SPI::Error> {
- self.wait_until_idle(spi, delay)?;
- self.use_full_frame(spi, delay)?;
+ self.wait_until_idle(spi, delay).await?;
+ self.use_full_frame(spi, delay).await?;
self.interface
- .cmd_with_data(spi, Command::WriteRam, buffer)?;
+ .cmd_with_data(spi, Command::WriteRam, buffer)
+ .await?;
Ok(())
}
//TODO: update description: last 3 bits will be ignored for width and x_pos
- fn update_partial_frame(
+ async fn update_partial_frame(
&mut self,
spi: &mut SPI,
delay: &mut DELAY,
@@ -161,56 +172,62 @@ where
width: u32,
height: u32,
) -> Result<(), SPI::Error> {
- self.wait_until_idle(spi, delay)?;
- self.set_ram_area(spi, delay, x, y, x + width, y + height)?;
- self.set_ram_counter(spi, delay, x, y)?;
+ self.wait_until_idle(spi, delay).await?;
+ self.set_ram_area(spi, delay, x, y, x + width, y + height)
+ .await?;
+ self.set_ram_counter(spi, delay, x, y).await?;
self.interface
- .cmd_with_data(spi, Command::WriteRam, buffer)?;
+ .cmd_with_data(spi, Command::WriteRam, buffer)
+ .await?;
Ok(())
}
- fn display_frame(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
- self.wait_until_idle(spi, delay)?;
+ async fn display_frame(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
+ self.wait_until_idle(spi, delay).await?;
if self.refresh == RefreshLut::Full {
self.interface
- .cmd_with_data(spi, Command::DisplayUpdateControl2, &[0xC7])?;
+ .cmd_with_data(spi, Command::DisplayUpdateControl2, &[0xC7])
+ .await?;
} else if self.refresh == RefreshLut::Quick {
self.interface
- .cmd_with_data(spi, Command::DisplayUpdateControl2, &[0xCF])?;
+ .cmd_with_data(spi, Command::DisplayUpdateControl2, &[0xCF])
+ .await?;
}
- self.interface.cmd(spi, Command::MasterActivation)?;
+ self.interface.cmd(spi, Command::MasterActivation).await?;
// MASTER Activation should not be interupted to avoid currption of panel images
// therefore a terminate command is send
- self.interface.cmd(spi, Command::Nop)?;
+ self.interface.cmd(spi, Command::Nop).await?;
Ok(())
}
- fn update_and_display_frame(
+ async fn update_and_display_frame(
&mut self,
spi: &mut SPI,
buffer: &[u8],
delay: &mut DELAY,
) -> Result<(), SPI::Error> {
- self.update_frame(spi, buffer, delay)?;
- self.display_frame(spi, delay)?;
+ self.update_frame(spi, buffer, delay).await?;
+ self.display_frame(spi, delay).await?;
Ok(())
}
- fn clear_frame(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
- self.wait_until_idle(spi, delay)?;
- self.use_full_frame(spi, delay)?;
+ async fn clear_frame(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
+ self.wait_until_idle(spi, delay).await?;
+ self.use_full_frame(spi, delay).await?;
// clear the ram with the background color
let color = self.background_color.get_byte_value();
- self.interface.cmd(spi, Command::WriteRam)?;
+ self.interface.cmd(spi, Command::WriteRam).await?;
self.interface
- .data_x_times(spi, color, WIDTH / 8 * HEIGHT)?;
- self.interface.cmd(spi, Command::WriteRam2)?;
+ .data_x_times(spi, color, WIDTH / 8 * HEIGHT)
+ .await?;
+ self.interface.cmd(spi, Command::WriteRam2).await?;
self.interface
- .data_x_times(spi, color, WIDTH / 8 * HEIGHT)?;
+ .data_x_times(spi, color, WIDTH / 8 * HEIGHT)
+ .await?;
Ok(())
}
@@ -222,7 +239,7 @@ where
&self.background_color
}
- fn set_lut(
+ async fn set_lut(
&mut self,
spi: &mut SPI,
delay: &mut DELAY,
@@ -234,33 +251,43 @@ where
match self.refresh {
RefreshLut::Full => self.set_lut_helper(spi, delay, &LUT_FULL_UPDATE),
RefreshLut::Quick => self.set_lut_helper(spi, delay, &LUT_PARTIAL_UPDATE),
- }?;
+ }
+ .await?;
// Additional configuration required only for partial updates
if self.refresh == RefreshLut::Quick {
- self.interface.cmd_with_data(
- spi,
- Command::WriteOtpSelection,
- &[0x0, 0x0, 0x0, 0x0, 0x0, 0x40, 0x0, 0x0, 0x0, 0x0],
- )?;
self.interface
- .cmd_with_data(spi, Command::BorderWaveformControl, &[0x80])?;
+ .cmd_with_data(
+ spi,
+ Command::WriteOtpSelection,
+ &[0x0, 0x0, 0x0, 0x0, 0x0, 0x40, 0x0, 0x0, 0x0, 0x0],
+ )
+ .await?;
+ self.interface
+ .cmd_with_data(spi, Command::BorderWaveformControl, &[0x80])
+ .await?;
self.interface
- .cmd_with_data(spi, Command::DisplayUpdateControl2, &[0xc0])?;
- self.interface.cmd(spi, Command::MasterActivation)?;
+ .cmd_with_data(spi, Command::DisplayUpdateControl2, &[0xc0])
+ .await?;
+ self.interface.cmd(spi, Command::MasterActivation).await?;
// MASTER Activation should not be interupted to avoid currption of panel images
// therefore a terminate command is send
- self.interface.cmd(spi, Command::Nop)?;
+ self.interface.cmd(spi, Command::Nop).await?;
}
Ok(())
}
- fn wait_until_idle(&mut self, _spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
- self.interface.wait_until_idle(delay, IS_BUSY_LOW);
+ async fn wait_until_idle(
+ &mut self,
+ _spi: &mut SPI,
+ delay: &mut DELAY,
+ ) -> Result<(), SPI::Error> {
+ self.interface.wait_until_idle(delay, IS_BUSY_LOW).await;
Ok(())
}
}
+#[maybe_async::maybe_async]
impl Epd1in54
where
SPI: SpiDevice,
@@ -269,19 +296,20 @@ where
RST: OutputPin,
DELAY: DelayNs,
{
- pub(crate) fn use_full_frame(
+ pub(crate) async fn use_full_frame(
&mut self,
spi: &mut SPI,
delay: &mut DELAY,
) -> Result<(), SPI::Error> {
// choose full frame/ram
- self.set_ram_area(spi, delay, 0, 0, WIDTH - 1, HEIGHT - 1)?;
+ self.set_ram_area(spi, delay, 0, 0, WIDTH - 1, HEIGHT - 1)
+ .await?;
// start from the beginning
- self.set_ram_counter(spi, delay, 0, 0)
+ self.set_ram_counter(spi, delay, 0, 0).await
}
- pub(crate) fn set_ram_area(
+ pub(crate) async fn set_ram_area(
&mut self,
spi: &mut SPI,
delay: &mut DELAY,
@@ -290,81 +318,94 @@ where
end_x: u32,
end_y: u32,
) -> Result<(), SPI::Error> {
- self.wait_until_idle(spi, delay)?;
+ self.wait_until_idle(spi, delay).await?;
assert!(start_x < end_x);
assert!(start_y < end_y);
// x is positioned in bytes, so the last 3 bits which show the position inside a byte in the ram
// aren't relevant
- self.interface.cmd_with_data(
- spi,
- Command::SetRamXAddressStartEndPosition,
- &[(start_x >> 3) as u8, (end_x >> 3) as u8],
- )?;
+ self.interface
+ .cmd_with_data(
+ spi,
+ Command::SetRamXAddressStartEndPosition,
+ &[(start_x >> 3) as u8, (end_x >> 3) as u8],
+ )
+ .await?;
// 2 Databytes: A[7:0] & 0..A[8] for each - start and end
- self.interface.cmd_with_data(
- spi,
- Command::SetRamYAddressStartEndPosition,
- &[
- start_y as u8,
- (start_y >> 8) as u8,
- end_y as u8,
- (end_y >> 8) as u8,
- ],
- )?;
+ self.interface
+ .cmd_with_data(
+ spi,
+ Command::SetRamYAddressStartEndPosition,
+ &[
+ start_y as u8,
+ (start_y >> 8) as u8,
+ end_y as u8,
+ (end_y >> 8) as u8,
+ ],
+ )
+ .await?;
Ok(())
}
- pub(crate) fn set_ram_counter(
+ pub(crate) async fn set_ram_counter(
&mut self,
spi: &mut SPI,
delay: &mut DELAY,
x: u32,
y: u32,
) -> Result<(), SPI::Error> {
- self.wait_until_idle(spi, delay)?;
+ self.wait_until_idle(spi, delay).await?;
// x is positioned in bytes, so the last 3 bits which show the position inside a byte in the ram
// aren't relevant
self.interface
- .cmd_with_data(spi, Command::SetRamXAddressCounter, &[(x >> 3) as u8])?;
+ .cmd_with_data(spi, Command::SetRamXAddressCounter, &[(x >> 3) as u8])
+ .await?;
// 2 Databytes: A[7:0] & 0..A[8]
- self.interface.cmd_with_data(
- spi,
- Command::SetRamYAddressCounter,
- &[y as u8, (y >> 8) as u8],
- )?;
+ self.interface
+ .cmd_with_data(
+ spi,
+ Command::SetRamYAddressCounter,
+ &[y as u8, (y >> 8) as u8],
+ )
+ .await?;
Ok(())
}
- fn set_lut_helper(
+ async fn set_lut_helper(
&mut self,
spi: &mut SPI,
delay: &mut DELAY,
buffer: &[u8],
) -> Result<(), SPI::Error> {
- self.wait_until_idle(spi, delay)?;
+ self.wait_until_idle(spi, delay).await?;
assert!(buffer.len() == 159);
self.interface
- .cmd_with_data(spi, Command::WriteLutRegister, &buffer[0..153])?;
+ .cmd_with_data(spi, Command::WriteLutRegister, &buffer[0..153])
+ .await?;
self.interface
- .cmd_with_data(spi, Command::WriteLutRegisterEnd, &[buffer[153]])?;
+ .cmd_with_data(spi, Command::WriteLutRegisterEnd, &[buffer[153]])
+ .await?;
- self.wait_until_idle(spi, delay)?;
+ self.wait_until_idle(spi, delay).await?;
self.interface
- .cmd_with_data(spi, Command::GateDrivingVoltage, &[buffer[154]])?;
+ .cmd_with_data(spi, Command::GateDrivingVoltage, &[buffer[154]])
+ .await?;
- self.interface.cmd_with_data(
- spi,
- Command::SourceDrivingVoltage,
- &[buffer[155], buffer[156], buffer[157]],
- )?;
self.interface
- .cmd_with_data(spi, Command::WriteVcomRegister, &[buffer[158]])?;
+ .cmd_with_data(
+ spi,
+ Command::SourceDrivingVoltage,
+ &[buffer[155], buffer[156], buffer[157]],
+ )
+ .await?;
+ self.interface
+ .cmd_with_data(spi, Command::WriteVcomRegister, &[buffer[158]])
+ .await?;
Ok(())
}
diff --git a/src/epd1in54b/mod.rs b/src/epd1in54b/mod.rs
index 08aae37c..f476060e 100644
--- a/src/epd1in54b/mod.rs
+++ b/src/epd1in54b/mod.rs
@@ -1,8 +1,8 @@
//! A simple Driver for the Waveshare 1.54" (B) E-Ink Display via SPI
-use embedded_hal::{delay::*, digital::*, spi::SpiDevice};
+use embedded_hal::digital::*;
-use crate::interface::DisplayInterface;
+use crate::interface::{DelayNs, DisplayInterface, SpiDevice};
use crate::traits::{
InternalWiAdditions, RefreshLut, WaveshareDisplay, WaveshareThreeColorDisplay,
};
@@ -43,6 +43,7 @@ pub struct Epd1in54b {
color: Color,
}
+#[maybe_async::maybe_async(AFIT)]
impl InternalWiAdditions
for Epd1in54b
where
@@ -52,43 +53,50 @@ where
RST: OutputPin,
DELAY: DelayNs,
{
- fn init(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
- self.interface.reset(delay, 10_000, 10_000);
+ async fn init(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
+ self.interface.reset(delay, 10_000, 10_000).await;
// set the power settings
self.interface
- .cmd_with_data(spi, Command::PowerSetting, &[0x07, 0x00, 0x08, 0x00])?;
+ .cmd_with_data(spi, Command::PowerSetting, &[0x07, 0x00, 0x08, 0x00])
+ .await?;
// start the booster
self.interface
- .cmd_with_data(spi, Command::BoosterSoftStart, &[0x07, 0x07, 0x07])?;
+ .cmd_with_data(spi, Command::BoosterSoftStart, &[0x07, 0x07, 0x07])
+ .await?;
// power on
- self.command(spi, Command::PowerOn)?;
- delay.delay_us(5000);
- self.wait_until_idle(spi, delay)?;
+ self.command(spi, Command::PowerOn).await?;
+ delay.delay_us(5000).await;
+ self.wait_until_idle(spi, delay).await?;
// set the panel settings
- self.cmd_with_data(spi, Command::PanelSetting, &[0xCF])?;
+ self.cmd_with_data(spi, Command::PanelSetting, &[0xCF])
+ .await?;
- self.cmd_with_data(spi, Command::VcomAndDataIntervalSetting, &[0x37])?;
+ self.cmd_with_data(spi, Command::VcomAndDataIntervalSetting, &[0x37])
+ .await?;
// PLL
- self.cmd_with_data(spi, Command::PllControl, &[0x39])?;
+ self.cmd_with_data(spi, Command::PllControl, &[0x39])
+ .await?;
// set resolution
- self.send_resolution(spi)?;
+ self.send_resolution(spi).await?;
- self.cmd_with_data(spi, Command::VcmDcSetting, &[0x0E])?;
+ self.cmd_with_data(spi, Command::VcmDcSetting, &[0x0E])
+ .await?;
- self.set_lut(spi, delay, None)?;
+ self.set_lut(spi, delay, None).await?;
- self.wait_until_idle(spi, delay)?;
+ self.wait_until_idle(spi, delay).await?;
Ok(())
}
}
+#[maybe_async::maybe_async(AFIT)]
impl WaveshareThreeColorDisplay
for Epd1in54b
where
@@ -98,47 +106,52 @@ where
RST: OutputPin,
DELAY: DelayNs,
{
- fn update_color_frame(
+ async fn update_color_frame(
&mut self,
spi: &mut SPI,
delay: &mut DELAY,
black: &[u8],
chromatic: &[u8],
) -> Result<(), SPI::Error> {
- self.update_achromatic_frame(spi, delay, black)?;
- self.update_chromatic_frame(spi, delay, chromatic)
+ self.update_achromatic_frame(spi, delay, black).await?;
+ self.update_chromatic_frame(spi, delay, chromatic).await
}
- fn update_achromatic_frame(
+ async fn update_achromatic_frame(
&mut self,
spi: &mut SPI,
delay: &mut DELAY,
black: &[u8],
) -> Result<(), SPI::Error> {
- self.wait_until_idle(spi, delay)?;
- self.send_resolution(spi)?;
+ self.wait_until_idle(spi, delay).await?;
+ self.send_resolution(spi).await?;
- self.interface.cmd(spi, Command::DataStartTransmission1)?;
+ self.interface
+ .cmd(spi, Command::DataStartTransmission1)
+ .await?;
for b in black {
let expanded = expand_bits(*b);
- self.interface.data(spi, &expanded)?;
+ self.interface.data(spi, &expanded).await?;
}
Ok(())
}
- fn update_chromatic_frame(
+ async fn update_chromatic_frame(
&mut self,
spi: &mut SPI,
_delay: &mut DELAY,
chromatic: &[u8],
) -> Result<(), SPI::Error> {
- self.interface.cmd(spi, Command::DataStartTransmission2)?;
- self.interface.data(spi, chromatic)?;
+ self.interface
+ .cmd(spi, Command::DataStartTransmission2)
+ .await?;
+ self.interface.data(spi, chromatic).await?;
Ok(())
}
}
+#[maybe_async::maybe_async(AFIT)]
impl WaveshareDisplay
for Epd1in54b
where
@@ -149,7 +162,7 @@ where
DELAY: DelayNs,
{
type DisplayColor = Color;
- fn new(
+ async fn new(
spi: &mut SPI,
busy: BUSY,
dc: DC,
@@ -162,33 +175,36 @@ where
let mut epd = Epd1in54b { interface, color };
- epd.init(spi, delay)?;
+ epd.init(spi, delay).await?;
Ok(epd)
}
- fn sleep(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
- self.wait_until_idle(spi, delay)?;
+ async fn sleep(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
+ self.wait_until_idle(spi, delay).await?;
self.interface
- .cmd_with_data(spi, Command::VcomAndDataIntervalSetting, &[0x17])?; //border floating
+ .cmd_with_data(spi, Command::VcomAndDataIntervalSetting, &[0x17])
+ .await?; //border floating
self.interface
- .cmd_with_data(spi, Command::VcmDcSetting, &[0x00])?; // Vcom to 0V
+ .cmd_with_data(spi, Command::VcmDcSetting, &[0x00])
+ .await?; // Vcom to 0V
self.interface
- .cmd_with_data(spi, Command::PowerSetting, &[0x02, 0x00, 0x00, 0x00])?; //VG&VS to 0V fast
+ .cmd_with_data(spi, Command::PowerSetting, &[0x02, 0x00, 0x00, 0x00])
+ .await?; //VG&VS to 0V fast
- self.wait_until_idle(spi, delay)?;
+ self.wait_until_idle(spi, delay).await?;
//NOTE: The example code has a 1s delay here
- self.command(spi, Command::PowerOff)?;
+ self.command(spi, Command::PowerOff).await?;
Ok(())
}
- fn wake_up(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
- self.init(spi, delay)
+ async fn wake_up(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
+ self.init(spi, delay).await
}
fn set_background_color(&mut self, color: Color) {
@@ -207,21 +223,23 @@ where
HEIGHT
}
- fn update_frame(
+ async fn update_frame(
&mut self,
spi: &mut SPI,
buffer: &[u8],
delay: &mut DELAY,
) -> Result<(), SPI::Error> {
- self.wait_until_idle(spi, delay)?;
- self.send_resolution(spi)?;
+ self.wait_until_idle(spi, delay).await?;
+ self.send_resolution(spi).await?;
- self.interface.cmd(spi, Command::DataStartTransmission1)?;
+ self.interface
+ .cmd(spi, Command::DataStartTransmission1)
+ .await?;
for b in buffer {
// Two bits per pixel
let expanded = expand_bits(*b);
- self.interface.data(spi, &expanded)?;
+ self.interface.data(spi, &expanded).await?;
}
//NOTE: Example code has a delay here
@@ -230,15 +248,17 @@ where
let color = self.color.get_byte_value();
let nbits = WIDTH * (HEIGHT / 8);
- self.interface.cmd(spi, Command::DataStartTransmission2)?;
- self.interface.data_x_times(spi, color, nbits)?;
+ self.interface
+ .cmd(spi, Command::DataStartTransmission2)
+ .await?;
+ self.interface.data_x_times(spi, color, nbits).await?;
//NOTE: Example code has a delay here
Ok(())
}
#[allow(unused)]
- fn update_partial_frame(
+ async fn update_partial_frame(
&mut self,
spi: &mut SPI,
delay: &mut DELAY,
@@ -251,73 +271,94 @@ where
unimplemented!()
}
- fn display_frame(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
- self.wait_until_idle(spi, delay)?;
- self.command(spi, Command::DisplayRefresh)?;
+ async fn display_frame(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
+ self.wait_until_idle(spi, delay).await?;
+ self.command(spi, Command::DisplayRefresh).await?;
Ok(())
}
- fn update_and_display_frame(
+ async fn update_and_display_frame(
&mut self,
spi: &mut SPI,
buffer: &[u8],
delay: &mut DELAY,
) -> Result<(), SPI::Error> {
- self.update_frame(spi, buffer, delay)?;
- self.display_frame(spi, delay)?;
+ self.update_frame(spi, buffer, delay).await?;
+ self.display_frame(spi, delay).await?;
Ok(())
}
- fn clear_frame(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
- self.wait_until_idle(spi, delay)?;
- self.send_resolution(spi)?;
+ async fn clear_frame(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
+ self.wait_until_idle(spi, delay).await?;
+ self.send_resolution(spi).await?;
let color = DEFAULT_BACKGROUND_COLOR.get_byte_value();
// Clear the black
- self.interface.cmd(spi, Command::DataStartTransmission1)?;
+ self.interface
+ .cmd(spi, Command::DataStartTransmission1)
+ .await?;
// Uses 2 bits per pixel
self.interface
- .data_x_times(spi, color, 2 * (WIDTH / 8 * HEIGHT))?;
+ .data_x_times(spi, color, 2 * (WIDTH / 8 * HEIGHT))
+ .await?;
// Clear the red
- self.interface.cmd(spi, Command::DataStartTransmission2)?;
self.interface
- .data_x_times(spi, color, WIDTH / 8 * HEIGHT)?;
+ .cmd(spi, Command::DataStartTransmission2)
+ .await?;
+ self.interface
+ .data_x_times(spi, color, WIDTH / 8 * HEIGHT)
+ .await?;
Ok(())
}
- fn set_lut(
+ async fn set_lut(
&mut self,
spi: &mut SPI,
_delay: &mut DELAY,
_refresh_rate: Option,
) -> Result<(), SPI::Error> {
self.interface
- .cmd_with_data(spi, Command::LutForVcom, LUT_VCOM0)?;
+ .cmd_with_data(spi, Command::LutForVcom, LUT_VCOM0)
+ .await?;
self.interface
- .cmd_with_data(spi, Command::LutWhiteToWhite, LUT_WHITE_TO_WHITE)?;
+ .cmd_with_data(spi, Command::LutWhiteToWhite, LUT_WHITE_TO_WHITE)
+ .await?;
self.interface
- .cmd_with_data(spi, Command::LutBlackToWhite, LUT_BLACK_TO_WHITE)?;
- self.interface.cmd_with_data(spi, Command::LutG0, LUT_G1)?;
- self.interface.cmd_with_data(spi, Command::LutG1, LUT_G2)?;
+ .cmd_with_data(spi, Command::LutBlackToWhite, LUT_BLACK_TO_WHITE)
+ .await?;
self.interface
- .cmd_with_data(spi, Command::LutRedVcom, LUT_RED_VCOM)?;
+ .cmd_with_data(spi, Command::LutG0, LUT_G1)
+ .await?;
self.interface
- .cmd_with_data(spi, Command::LutRed0, LUT_RED0)?;
+ .cmd_with_data(spi, Command::LutG1, LUT_G2)
+ .await?;
self.interface
- .cmd_with_data(spi, Command::LutRed1, LUT_RED1)?;
+ .cmd_with_data(spi, Command::LutRedVcom, LUT_RED_VCOM)
+ .await?;
+ self.interface
+ .cmd_with_data(spi, Command::LutRed0, LUT_RED0)
+ .await?;
+ self.interface
+ .cmd_with_data(spi, Command::LutRed1, LUT_RED1)
+ .await?;
Ok(())
}
- fn wait_until_idle(&mut self, _spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
- self.interface.wait_until_idle(delay, IS_BUSY_LOW);
+ async fn wait_until_idle(
+ &mut self,
+ _spi: &mut SPI,
+ delay: &mut DELAY,
+ ) -> Result<(), SPI::Error> {
+ self.interface.wait_until_idle(delay, IS_BUSY_LOW).await;
Ok(())
}
}
+#[maybe_async::maybe_async]
impl Epd1in54b
where
SPI: SpiDevice,
@@ -326,32 +367,32 @@ where
RST: OutputPin,
DELAY: DelayNs,
{
- fn command(&mut self, spi: &mut SPI, command: Command) -> Result<(), SPI::Error> {
- self.interface.cmd(spi, command)
+ async fn command(&mut self, spi: &mut SPI, command: Command) -> Result<(), SPI::Error> {
+ self.interface.cmd(spi, command).await
}
- fn send_data(&mut self, spi: &mut SPI, data: &[u8]) -> Result<(), SPI::Error> {
- self.interface.data(spi, data)
+ async fn send_data(&mut self, spi: &mut SPI, data: &[u8]) -> Result<(), SPI::Error> {
+ self.interface.data(spi, data).await
}
- fn cmd_with_data(
+ async fn cmd_with_data(
&mut self,
spi: &mut SPI,
command: Command,
data: &[u8],
) -> Result<(), SPI::Error> {
- self.interface.cmd_with_data(spi, command, data)
+ self.interface.cmd_with_data(spi, command, data).await
}
- fn send_resolution(&mut self, spi: &mut SPI) -> Result<(), SPI::Error> {
+ async fn send_resolution(&mut self, spi: &mut SPI) -> Result<(), SPI::Error> {
let w = self.width();
let h = self.height();
- self.command(spi, Command::ResolutionSetting)?;
+ self.command(spi, Command::ResolutionSetting).await?;
- self.send_data(spi, &[w as u8])?;
- self.send_data(spi, &[(h >> 8) as u8])?;
- self.send_data(spi, &[h as u8])
+ self.send_data(spi, &[w as u8]).await?;
+ self.send_data(spi, &[(h >> 8) as u8]).await?;
+ self.send_data(spi, &[h as u8]).await
}
}
diff --git a/src/epd1in54c/mod.rs b/src/epd1in54c/mod.rs
index bbe27302..899123ee 100644
--- a/src/epd1in54c/mod.rs
+++ b/src/epd1in54c/mod.rs
@@ -1,8 +1,8 @@
//! A simple Driver for the Waveshare 1.54" (C) E-Ink Display via SPI
-use embedded_hal::{delay::*, digital::*, spi::SpiDevice};
+use embedded_hal::digital::*;
-use crate::interface::DisplayInterface;
+use crate::interface::{DelayNs, DisplayInterface, SpiDevice};
use crate::traits::{
InternalWiAdditions, RefreshLut, WaveshareDisplay, WaveshareThreeColorDisplay,
};
@@ -40,6 +40,7 @@ pub struct Epd1in54c {
color: Color,
}
+#[maybe_async::maybe_async(AFIT)]
impl InternalWiAdditions
for Epd1in54c
where
@@ -49,33 +50,37 @@ where
RST: OutputPin,
DELAY: DelayNs,
{
- fn init(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
+ async fn init(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
// Based on Reference Program Code from:
// https://www.waveshare.com/w/upload/a/ac/1.54inch_e-Paper_Module_C_Specification.pdf
// and:
// https://github.com/waveshare/e-Paper/blob/master/STM32/STM32-F103ZET6/User/e-Paper/EPD_1in54c.c
- self.interface.reset(delay, 10_000, 2_000);
+ self.interface.reset(delay, 10_000, 2_000).await;
// start the booster
- self.cmd_with_data(spi, Command::BoosterSoftStart, &[0x17, 0x17, 0x17])?;
+ self.cmd_with_data(spi, Command::BoosterSoftStart, &[0x17, 0x17, 0x17])
+ .await?;
// power on
- self.command(spi, Command::PowerOn)?;
- delay.delay_us(5000);
- self.wait_until_idle(spi, delay)?;
+ self.command(spi, Command::PowerOn).await?;
+ delay.delay_us(5000).await;
+ self.wait_until_idle(spi, delay).await?;
// set the panel settings
- self.cmd_with_data(spi, Command::PanelSetting, &[0x0f, 0x0d])?;
+ self.cmd_with_data(spi, Command::PanelSetting, &[0x0f, 0x0d])
+ .await?;
// set resolution
- self.send_resolution(spi)?;
+ self.send_resolution(spi).await?;
- self.cmd_with_data(spi, Command::VcomAndDataIntervalSetting, &[0x77])?;
+ self.cmd_with_data(spi, Command::VcomAndDataIntervalSetting, &[0x77])
+ .await?;
Ok(())
}
}
+#[maybe_async::maybe_async(AFIT)]
impl WaveshareThreeColorDisplay
for Epd1in54c
where
@@ -85,42 +90,45 @@ where
RST: OutputPin,
DELAY: DelayNs,
{
- fn update_color_frame(
+ async fn update_color_frame(
&mut self,
spi: &mut SPI,
delay: &mut DELAY,
black: &[u8],
chromatic: &[u8],
) -> Result<(), SPI::Error> {
- self.update_achromatic_frame(spi, delay, black)?;
- self.update_chromatic_frame(spi, delay, chromatic)
+ self.update_achromatic_frame(spi, delay, black).await?;
+ self.update_chromatic_frame(spi, delay, chromatic).await
}
- fn update_achromatic_frame(
+ async fn update_achromatic_frame(
&mut self,
spi: &mut SPI,
delay: &mut DELAY,
black: &[u8],
) -> Result<(), SPI::Error> {
- self.wait_until_idle(spi, delay)?;
- self.cmd_with_data(spi, Command::DataStartTransmission1, black)?;
+ self.wait_until_idle(spi, delay).await?;
+ self.cmd_with_data(spi, Command::DataStartTransmission1, black)
+ .await?;
Ok(())
}
- fn update_chromatic_frame(
+ async fn update_chromatic_frame(
&mut self,
spi: &mut SPI,
delay: &mut DELAY,
chromatic: &[u8],
) -> Result<(), SPI::Error> {
- self.wait_until_idle(spi, delay)?;
- self.cmd_with_data(spi, Command::DataStartTransmission2, chromatic)?;
+ self.wait_until_idle(spi, delay).await?;
+ self.cmd_with_data(spi, Command::DataStartTransmission2, chromatic)
+ .await?;
Ok(())
}
}
+#[maybe_async::maybe_async(AFIT)]
impl WaveshareDisplay
for Epd1in54c
where
@@ -131,7 +139,7 @@ where
DELAY: DelayNs,
{
type DisplayColor = Color;
- fn new(
+ async fn new(
spi: &mut SPI,
busy: BUSY,
dc: DC,
@@ -144,23 +152,23 @@ where
let mut epd = Epd1in54c { interface, color };
- epd.init(spi, delay)?;
+ epd.init(spi, delay).await?;
Ok(epd)
}
- fn sleep(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
- self.wait_until_idle(spi, delay)?;
+ async fn sleep(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
+ self.wait_until_idle(spi, delay).await?;
- self.command(spi, Command::PowerOff)?;
- self.wait_until_idle(spi, delay)?;
- self.cmd_with_data(spi, Command::DeepSleep, &[0xa5])?;
+ self.command(spi, Command::PowerOff).await?;
+ self.wait_until_idle(spi, delay).await?;
+ self.cmd_with_data(spi, Command::DeepSleep, &[0xa5]).await?;
Ok(())
}
- fn wake_up(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
- self.init(spi, delay)
+ async fn wake_up(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
+ self.init(spi, delay).await
}
fn set_background_color(&mut self, color: Color) {
@@ -179,25 +187,27 @@ where
HEIGHT
}
- fn update_frame(
+ async fn update_frame(
&mut self,
spi: &mut SPI,
buffer: &[u8],
delay: &mut DELAY,
) -> Result<(), SPI::Error> {
- self.update_achromatic_frame(spi, delay, buffer)?;
+ self.update_achromatic_frame(spi, delay, buffer).await?;
// Clear the chromatic layer
let color = self.color.get_byte_value();
- self.command(spi, Command::DataStartTransmission2)?;
- self.interface.data_x_times(spi, color, NUM_DISPLAY_BITS)?;
+ self.command(spi, Command::DataStartTransmission2).await?;
+ self.interface
+ .data_x_times(spi, color, NUM_DISPLAY_BITS)
+ .await?;
Ok(())
}
#[allow(unused)]
- fn update_partial_frame(
+ async fn update_partial_frame(
&mut self,
spi: &mut SPI,
delay: &mut DELAY,
@@ -210,41 +220,45 @@ where
unimplemented!()
}
- fn display_frame(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
- self.command(spi, Command::DisplayRefresh)?;
- self.wait_until_idle(spi, delay)?;
+ async fn display_frame(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
+ self.command(spi, Command::DisplayRefresh).await?;
+ self.wait_until_idle(spi, delay).await?;
Ok(())
}
- fn update_and_display_frame(
+ async fn update_and_display_frame(
&mut self,
spi: &mut SPI,
buffer: &[u8],
delay: &mut DELAY,
) -> Result<(), SPI::Error> {
- self.update_frame(spi, buffer, delay)?;
- self.display_frame(spi, delay)?;
+ self.update_frame(spi, buffer, delay).await?;
+ self.display_frame(spi, delay).await?;
Ok(())
}
- fn clear_frame(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
- self.wait_until_idle(spi, delay)?;
+ async fn clear_frame(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
+ self.wait_until_idle(spi, delay).await?;
let color = DEFAULT_BACKGROUND_COLOR.get_byte_value();
// Clear the black
- self.command(spi, Command::DataStartTransmission1)?;
- self.interface.data_x_times(spi, color, NUM_DISPLAY_BITS)?;
+ self.command(spi, Command::DataStartTransmission1).await?;
+ self.interface
+ .data_x_times(spi, color, NUM_DISPLAY_BITS)
+ .await?;
// Clear the chromatic
- self.command(spi, Command::DataStartTransmission2)?;
- self.interface.data_x_times(spi, color, NUM_DISPLAY_BITS)?;
+ self.command(spi, Command::DataStartTransmission2).await?;
+ self.interface
+ .data_x_times(spi, color, NUM_DISPLAY_BITS)
+ .await?;
Ok(())
}
- fn set_lut(
+ async fn set_lut(
&mut self,
_spi: &mut SPI,
_delay: &mut DELAY,
@@ -253,12 +267,17 @@ where
Ok(())
}
- fn wait_until_idle(&mut self, _spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
- self.interface.wait_until_idle(delay, IS_BUSY_LOW);
+ async fn wait_until_idle(
+ &mut self,
+ _spi: &mut SPI,
+ delay: &mut DELAY,
+ ) -> Result<(), SPI::Error> {
+ self.interface.wait_until_idle(delay, IS_BUSY_LOW).await;
Ok(())
}
}
+#[maybe_async::maybe_async]
impl Epd1in54c
where
SPI: SpiDevice,
@@ -267,40 +286,40 @@ where
RST: OutputPin,
DELAY: DelayNs,
{
- fn command(&mut self, spi: &mut SPI, command: Command) -> Result<(), SPI::Error> {
- self.interface.cmd(spi, command)
+ async fn command(&mut self, spi: &mut SPI, command: Command) -> Result<(), SPI::Error> {
+ self.interface.cmd(spi, command).await
}
- fn send_data(&mut self, spi: &mut SPI, data: &[u8]) -> Result<(), SPI::Error> {
- self.interface.data(spi, data)
+ async fn send_data(&mut self, spi: &mut SPI, data: &[u8]) -> Result<(), SPI::Error> {
+ self.interface.data(spi, data).await
}
- fn cmd_with_data(
+ async fn cmd_with_data(
&mut self,
spi: &mut SPI,
command: Command,
data: &[u8],
) -> Result<(), SPI::Error> {
- self.interface.cmd_with_data(spi, command, data)
+ self.interface.cmd_with_data(spi, command, data).await
}
- fn send_resolution(&mut self, spi: &mut SPI) -> Result<(), SPI::Error> {
+ async fn send_resolution(&mut self, spi: &mut SPI) -> Result<(), SPI::Error> {
let w = self.width();
let h = self.height();
- self.command(spi, Command::ResolutionSetting)?;
+ self.command(spi, Command::ResolutionSetting).await?;
// | D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 |
// | HRES[7:3] | 0 | 0 | 0 |
- self.send_data(spi, &[(w as u8) & 0b1111_1000])?;
+ self.send_data(spi, &[(w as u8) & 0b1111_1000]).await?;
// | D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 |
// | - | - | - | - | - | - | - | VRES[8] |
- self.send_data(spi, &[(w >> 8) as u8])?;
+ self.send_data(spi, &[(w >> 8) as u8]).await?;
// | D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 |
// | VRES[7:0] |
// Specification shows C/D is zero while sending the last byte,
// but upstream code does not implement it like that. So for now
// we follow upstream code.
- self.send_data(spi, &[h as u8])
+ self.send_data(spi, &[h as u8]).await
}
}
diff --git a/src/epd2in13_v2/mod.rs b/src/epd2in13_v2/mod.rs
index 5d8d4e0b..49a7cc39 100644
--- a/src/epd2in13_v2/mod.rs
+++ b/src/epd2in13_v2/mod.rs
@@ -15,15 +15,11 @@
//! - [Controller Datasheet SS1780](http://www.e-paper-display.com/download_detail/downloadsId=682.html)
//!
-use embedded_hal::{
- delay::DelayNs,
- digital::{InputPin, OutputPin},
- spi::SpiDevice,
-};
+use embedded_hal::digital::{InputPin, OutputPin};
use crate::buffer_len;
use crate::color::Color;
-use crate::interface::DisplayInterface;
+use crate::interface::{DelayNs, DisplayInterface, SpiDevice};
use crate::traits::{InternalWiAdditions, RefreshLut, WaveshareDisplay};
pub(crate) mod command;
@@ -80,6 +76,7 @@ pub struct Epd2in13 {
refresh: RefreshLut,
}
+#[maybe_async::maybe_async(AFIT)]
impl InternalWiAdditions
for Epd2in13
where
@@ -89,27 +86,28 @@ where
RST: OutputPin,
DELAY: DelayNs,
{
- fn init(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
+ async fn init(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
// HW reset
- self.interface.reset(delay, 10_000, 10_000);
+ self.interface.reset(delay, 10_000, 10_000).await;
if self.refresh == RefreshLut::Quick {
- self.set_vcom_register(spi, (-9).vcom())?;
- self.wait_until_idle(spi, delay)?;
+ self.set_vcom_register(spi, (-9).vcom()).await?;
+ self.wait_until_idle(spi, delay).await?;
- self.set_lut(spi, delay, Some(self.refresh))?;
+ self.set_lut(spi, delay, Some(self.refresh)).await?;
// Python code does this, not sure why
- // self.cmd_with_data(spi, Command::WriteOtpSelection, &[0, 0, 0, 0, 0x40, 0, 0])?;
+ // self.cmd_with_data(spi, Command::WriteOtpSelection, &[0, 0, 0, 0, 0x40, 0, 0]).await?;
// During partial update, clock/analog are not disabled between 2
// updates.
self.set_display_update_control_2(
spi,
DisplayUpdateControl2::new().enable_analog().enable_clock(),
- )?;
- self.command(spi, Command::MasterActivation)?;
- self.wait_until_idle(spi, delay)?;
+ )
+ .await?;
+ self.command(spi, Command::MasterActivation).await?;
+ self.wait_until_idle(spi, delay).await?;
self.set_border_waveform(
spi,
@@ -118,11 +116,12 @@ where
fix_level: BorderWaveFormFixLevel::Vss,
gs_trans: BorderWaveFormGs::Lut1,
},
- )?;
+ )
+ .await?;
} else {
- self.wait_until_idle(spi, delay)?;
- self.command(spi, Command::SwReset)?;
- self.wait_until_idle(spi, delay)?;
+ self.wait_until_idle(spi, delay).await?;
+ self.command(spi, Command::SwReset).await?;
+ self.wait_until_idle(spi, delay).await?;
self.set_driver_output(
spi,
@@ -132,17 +131,19 @@ where
scan_dir_incr: true,
width: (HEIGHT - 1) as u16,
},
- )?;
+ )
+ .await?;
// These 2 are the reset values
- self.set_dummy_line_period(spi, 0x30)?;
- self.set_gate_scan_start_position(spi, 0)?;
+ self.set_dummy_line_period(spi, 0x30).await?;
+ self.set_gate_scan_start_position(spi, 0).await?;
- self.set_data_entry_mode(spi, DataEntryModeIncr::XIncrYIncr, DataEntryModeDir::XDir)?;
+ self.set_data_entry_mode(spi, DataEntryModeIncr::XIncrYIncr, DataEntryModeDir::XDir)
+ .await?;
// Use simple X/Y auto increase
- self.set_ram_area(spi, 0, 0, WIDTH - 1, HEIGHT - 1)?;
- self.set_ram_address_counters(spi, delay, 0, 0)?;
+ self.set_ram_area(spi, 0, 0, WIDTH - 1, HEIGHT - 1).await?;
+ self.set_ram_address_counters(spi, delay, 0, 0).await?;
self.set_border_waveform(
spi,
@@ -151,28 +152,32 @@ where
fix_level: BorderWaveFormFixLevel::Vss,
gs_trans: BorderWaveFormGs::Lut3,
},
- )?;
+ )
+ .await?;
- self.set_vcom_register(spi, (-21).vcom())?;
+ self.set_vcom_register(spi, (-21).vcom()).await?;
- self.set_gate_driving_voltage(spi, 190.gate_driving_decivolt())?;
+ self.set_gate_driving_voltage(spi, 190.gate_driving_decivolt())
+ .await?;
self.set_source_driving_voltage(
spi,
150.source_driving_decivolt(),
50.source_driving_decivolt(),
(-150).source_driving_decivolt(),
- )?;
+ )
+ .await?;
- self.set_gate_line_width(spi, 10)?;
+ self.set_gate_line_width(spi, 10).await?;
- self.set_lut(spi, delay, Some(self.refresh))?;
+ self.set_lut(spi, delay, Some(self.refresh)).await?;
}
- self.wait_until_idle(spi, delay)?;
+ self.wait_until_idle(spi, delay).await?;
Ok(())
}
}
+#[maybe_async::maybe_async(AFIT)]
impl WaveshareDisplay
for Epd2in13
where
@@ -183,7 +188,7 @@ where
DELAY: DelayNs,
{
type DisplayColor = Color;
- fn new(
+ async fn new(
spi: &mut SPI,
busy: BUSY,
dc: DC,
@@ -198,16 +203,16 @@ where
refresh: RefreshLut::Full,
};
- epd.init(spi, delay)?;
+ epd.init(spi, delay).await?;
Ok(epd)
}
- fn wake_up(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
- self.init(spi, delay)
+ async fn wake_up(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
+ self.init(spi, delay).await
}
- fn sleep(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
- self.wait_until_idle(spi, delay)?;
+ async fn sleep(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
+ self.wait_until_idle(spi, delay).await?;
// All sample code enables and disables analog/clocks...
self.set_display_update_control_2(
@@ -217,31 +222,33 @@ where
.enable_clock()
.disable_analog()
.disable_clock(),
- )?;
- self.command(spi, Command::MasterActivation)?;
+ )
+ .await?;
+ self.command(spi, Command::MasterActivation).await?;
- self.set_sleep_mode(spi, self.sleep_mode)?;
+ self.set_sleep_mode(spi, self.sleep_mode).await?;
Ok(())
}
- fn update_frame(
+ async fn update_frame(
&mut self,
spi: &mut SPI,
buffer: &[u8],
delay: &mut DELAY,
) -> Result<(), SPI::Error> {
assert!(buffer.len() == buffer_len(WIDTH as usize, HEIGHT as usize));
- self.set_ram_area(spi, 0, 0, WIDTH - 1, HEIGHT - 1)?;
- self.set_ram_address_counters(spi, delay, 0, 0)?;
+ self.set_ram_area(spi, 0, 0, WIDTH - 1, HEIGHT - 1).await?;
+ self.set_ram_address_counters(spi, delay, 0, 0).await?;
- self.cmd_with_data(spi, Command::WriteRam, buffer)?;
+ self.cmd_with_data(spi, Command::WriteRam, buffer).await?;
if self.refresh == RefreshLut::Full {
// Always keep the base buffer equal to current if not doing partial refresh.
- self.set_ram_area(spi, 0, 0, WIDTH - 1, HEIGHT - 1)?;
- self.set_ram_address_counters(spi, delay, 0, 0)?;
+ self.set_ram_area(spi, 0, 0, WIDTH - 1, HEIGHT - 1).await?;
+ self.set_ram_address_counters(spi, delay, 0, 0).await?;
- self.cmd_with_data(spi, Command::WriteRamRed, buffer)?;
+ self.cmd_with_data(spi, Command::WriteRamRed, buffer)
+ .await?;
}
Ok(())
}
@@ -249,7 +256,7 @@ where
/// Updating only a part of the frame is not supported when using the
/// partial refresh feature. The function will panic if called when set to
/// use partial refresh.
- fn update_partial_frame(
+ async fn update_partial_frame(
&mut self,
spi: &mut SPI,
delay: &mut DELAY,
@@ -269,17 +276,18 @@ where
// incorrect.
assert!(self.refresh == RefreshLut::Full);
- self.set_ram_area(spi, x, y, x + width, y + height)?;
- self.set_ram_address_counters(spi, delay, x, y)?;
+ self.set_ram_area(spi, x, y, x + width, y + height).await?;
+ self.set_ram_address_counters(spi, delay, x, y).await?;
- self.cmd_with_data(spi, Command::WriteRam, buffer)?;
+ self.cmd_with_data(spi, Command::WriteRam, buffer).await?;
if self.refresh == RefreshLut::Full {
// Always keep the base buffer equals to current if not doing partial refresh.
- self.set_ram_area(spi, x, y, x + width, y + height)?;
- self.set_ram_address_counters(spi, delay, x, y)?;
+ self.set_ram_area(spi, x, y, x + width, y + height).await?;
+ self.set_ram_address_counters(spi, delay, x, y).await?;
- self.cmd_with_data(spi, Command::WriteRamRed, buffer)?;
+ self.cmd_with_data(spi, Command::WriteRamRed, buffer)
+ .await?;
}
Ok(())
@@ -287,7 +295,7 @@ where
/// Never use directly this function when using partial refresh, or also
/// keep the base buffer in syncd using `set_partial_base_buffer` function.
- fn display_frame(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
+ async fn display_frame(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
if self.refresh == RefreshLut::Full {
self.set_display_update_control_2(
spi,
@@ -297,55 +305,61 @@ where
.display()
.disable_analog()
.disable_clock(),
- )?;
+ )
+ .await?;
} else {
- self.set_display_update_control_2(spi, DisplayUpdateControl2::new().display())?;
+ self.set_display_update_control_2(spi, DisplayUpdateControl2::new().display())
+ .await?;
}
- self.command(spi, Command::MasterActivation)?;
- self.wait_until_idle(spi, delay)?;
+ self.command(spi, Command::MasterActivation).await?;
+ self.wait_until_idle(spi, delay).await?;
Ok(())
}
- fn update_and_display_frame(
+ async fn update_and_display_frame(
&mut self,
spi: &mut SPI,
buffer: &[u8],
delay: &mut DELAY,
) -> Result<(), SPI::Error> {
- self.update_frame(spi, buffer, delay)?;
- self.display_frame(spi, delay)?;
+ self.update_frame(spi, buffer, delay).await?;
+ self.display_frame(spi, delay).await?;
if self.refresh == RefreshLut::Quick {
- self.set_partial_base_buffer(spi, delay, buffer)?;
+ self.set_partial_base_buffer(spi, delay, buffer).await?;
}
Ok(())
}
- fn clear_frame(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
+ async fn clear_frame(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
let color = self.background_color.get_byte_value();
- self.set_ram_area(spi, 0, 0, WIDTH - 1, HEIGHT - 1)?;
- self.set_ram_address_counters(spi, delay, 0, 0)?;
-
- self.command(spi, Command::WriteRam)?;
- self.interface.data_x_times(
- spi,
- color,
- buffer_len(WIDTH as usize, HEIGHT as usize) as u32,
- )?;
+ self.set_ram_area(spi, 0, 0, WIDTH - 1, HEIGHT - 1).await?;
+ self.set_ram_address_counters(spi, delay, 0, 0).await?;
- // Always keep the base buffer equals to current if not doing partial refresh.
- if self.refresh == RefreshLut::Full {
- self.set_ram_area(spi, 0, 0, WIDTH - 1, HEIGHT - 1)?;
- self.set_ram_address_counters(spi, delay, 0, 0)?;
-
- self.command(spi, Command::WriteRamRed)?;
- self.interface.data_x_times(
+ self.command(spi, Command::WriteRam).await?;
+ self.interface
+ .data_x_times(
spi,
color,
buffer_len(WIDTH as usize, HEIGHT as usize) as u32,
- )?;
+ )
+ .await?;
+
+ // Always keep the base buffer equals to current if not doing partial refresh.
+ if self.refresh == RefreshLut::Full {
+ self.set_ram_area(spi, 0, 0, WIDTH - 1, HEIGHT - 1).await?;
+ self.set_ram_address_counters(spi, delay, 0, 0).await?;
+
+ self.command(spi, Command::WriteRamRed).await?;
+ self.interface
+ .data_x_times(
+ spi,
+ color,
+ buffer_len(WIDTH as usize, HEIGHT as usize) as u32,
+ )
+ .await?;
}
Ok(())
}
@@ -366,7 +380,7 @@ where
HEIGHT
}
- fn set_lut(
+ async fn set_lut(
&mut self,
spi: &mut SPI,
_delay: &mut DELAY,
@@ -378,14 +392,20 @@ where
};
self.cmd_with_data(spi, Command::WriteLutRegister, buffer)
+ .await
}
- fn wait_until_idle(&mut self, _spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
- self.interface.wait_until_idle(delay, IS_BUSY_LOW);
+ async fn wait_until_idle(
+ &mut self,
+ _spi: &mut SPI,
+ delay: &mut DELAY,
+ ) -> Result<(), SPI::Error> {
+ self.interface.wait_until_idle(delay, IS_BUSY_LOW).await;
Ok(())
}
}
+#[maybe_async::maybe_async]
impl Epd2in13
where
SPI: SpiDevice,
@@ -396,17 +416,18 @@ where
{
/// When using partial refresh, the controller uses the provided buffer for
/// comparison with new buffer.
- pub fn set_partial_base_buffer(
+ pub async fn set_partial_base_buffer(
&mut self,
spi: &mut SPI,
delay: &mut DELAY,
buffer: &[u8],
) -> Result<(), SPI::Error> {
assert!(buffer_len(WIDTH as usize, HEIGHT as usize) == buffer.len());
- self.set_ram_area(spi, 0, 0, WIDTH - 1, HEIGHT - 1)?;
- self.set_ram_address_counters(spi, delay, 0, 0)?;
+ self.set_ram_area(spi, 0, 0, WIDTH - 1, HEIGHT - 1).await?;
+ self.set_ram_address_counters(spi, delay, 0, 0).await?;
- self.cmd_with_data(spi, Command::WriteRamRed, buffer)?;
+ self.cmd_with_data(spi, Command::WriteRamRed, buffer)
+ .await?;
Ok(())
}
@@ -417,7 +438,7 @@ where
/// Sets the refresh mode. When changing mode, the screen will be
/// re-initialized accordingly.
- pub fn set_refresh(
+ pub async fn set_refresh(
&mut self,
spi: &mut SPI,
delay: &mut DELAY,
@@ -425,12 +446,12 @@ where
) -> Result<(), SPI::Error> {
if self.refresh != refresh {
self.refresh = refresh;
- self.init(spi, delay)?;
+ self.init(spi, delay).await?;
}
Ok(())
}
- fn set_gate_scan_start_position(
+ async fn set_gate_scan_start_position(
&mut self,
spi: &mut SPI,
start: u16,
@@ -441,9 +462,10 @@ where
Command::GateScanStartPosition,
&[(start & 0xFF) as u8, ((start >> 8) & 0x1) as u8],
)
+ .await
}
- fn set_border_waveform(
+ async fn set_border_waveform(
&mut self,
spi: &mut SPI,
borderwaveform: BorderWaveForm,
@@ -453,35 +475,40 @@ where
Command::BorderWaveformControl,
&[borderwaveform.to_u8()],
)
+ .await
}
- fn set_vcom_register(&mut self, spi: &mut SPI, vcom: Vcom) -> Result<(), SPI::Error> {
+ async fn set_vcom_register(&mut self, spi: &mut SPI, vcom: Vcom) -> Result<(), SPI::Error> {
self.cmd_with_data(spi, Command::WriteVcomRegister, &[vcom.0])
+ .await
}
- fn set_gate_driving_voltage(
+ async fn set_gate_driving_voltage(
&mut self,
spi: &mut SPI,
voltage: GateDrivingVoltage,
) -> Result<(), SPI::Error> {
self.cmd_with_data(spi, Command::GateDrivingVoltageCtrl, &[voltage.0])
+ .await
}
- fn set_dummy_line_period(
+ async fn set_dummy_line_period(
&mut self,
spi: &mut SPI,
number_of_lines: u8,
) -> Result<(), SPI::Error> {
assert!(number_of_lines <= 127);
self.cmd_with_data(spi, Command::SetDummyLinePeriod, &[number_of_lines])
+ .await
}
- fn set_gate_line_width(&mut self, spi: &mut SPI, width: u8) -> Result<(), SPI::Error> {
+ async fn set_gate_line_width(&mut self, spi: &mut SPI, width: u8) -> Result<(), SPI::Error> {
self.cmd_with_data(spi, Command::SetGateLineWidth, &[width & 0x0F])
+ .await
}
/// Sets the source driving voltage value
- fn set_source_driving_voltage(
+ async fn set_source_driving_voltage(
&mut self,
spi: &mut SPI,
vsh1: SourceDrivingVoltage,
@@ -493,30 +520,42 @@ where
Command::SourceDrivingVoltageCtrl,
&[vsh1.0, vsh2.0, vsl.0],
)
+ .await
}
/// Prepare the actions that the next master activation command will
/// trigger.
- fn set_display_update_control_2(
+ async fn set_display_update_control_2(
&mut self,
spi: &mut SPI,
value: DisplayUpdateControl2,
) -> Result<(), SPI::Error> {
self.cmd_with_data(spi, Command::DisplayUpdateControl2, &[value.0])
+ .await
}
/// Triggers the deep sleep mode
- fn set_sleep_mode(&mut self, spi: &mut SPI, mode: DeepSleepMode) -> Result<(), SPI::Error> {
+ async fn set_sleep_mode(
+ &mut self,
+ spi: &mut SPI,
+ mode: DeepSleepMode,
+ ) -> Result<(), SPI::Error> {
self.cmd_with_data(spi, Command::DeepSleepMode, &[mode as u8])
+ .await
}
- fn set_driver_output(&mut self, spi: &mut SPI, output: DriverOutput) -> Result<(), SPI::Error> {
+ async fn set_driver_output(
+ &mut self,
+ spi: &mut SPI,
+ output: DriverOutput,
+ ) -> Result<(), SPI::Error> {
self.cmd_with_data(spi, Command::DriverOutputControl, &output.to_bytes())
+ .await
}
/// Sets the data entry mode (ie. how X and Y positions changes when writing
/// data to RAM)
- fn set_data_entry_mode(
+ async fn set_data_entry_mode(
&mut self,
spi: &mut SPI,
counter_incr_mode: DataEntryModeIncr,
@@ -524,10 +563,11 @@ where
) -> Result<(), SPI::Error> {
let mode = counter_incr_mode as u8 | counter_direction as u8;
self.cmd_with_data(spi, Command::DataEntryModeSetting, &[mode])
+ .await
}
/// Sets both X and Y pixels ranges
- fn set_ram_area(
+ async fn set_ram_area(
&mut self,
spi: &mut SPI,
start_x: u32,
@@ -539,7 +579,8 @@ where
spi,
Command::SetRamXAddressStartEndPosition,
&[(start_x >> 3) as u8, (end_x >> 3) as u8],
- )?;
+ )
+ .await?;
self.cmd_with_data(
spi,
@@ -551,38 +592,41 @@ where
(end_y >> 8) as u8,
],
)
+ .await
}
/// Sets both X and Y pixels counters when writing data to RAM
- fn set_ram_address_counters(
+ async fn set_ram_address_counters(
&mut self,
spi: &mut SPI,
delay: &mut DELAY,
x: u32,
y: u32,
) -> Result<(), SPI::Error> {
- self.wait_until_idle(spi, delay)?;
- self.cmd_with_data(spi, Command::SetRamXAddressCounter, &[(x >> 3) as u8])?;
+ self.wait_until_idle(spi, delay).await?;
+ self.cmd_with_data(spi, Command::SetRamXAddressCounter, &[(x >> 3) as u8])
+ .await?;
self.cmd_with_data(
spi,
Command::SetRamYAddressCounter,
&[y as u8, (y >> 8) as u8],
- )?;
+ )
+ .await?;
Ok(())
}
- fn command(&mut self, spi: &mut SPI, command: Command) -> Result<(), SPI::Error> {
- self.interface.cmd(spi, command)
+ async fn command(&mut self, spi: &mut SPI, command: Command) -> Result<(), SPI::Error> {
+ self.interface.cmd(spi, command).await
}
- fn cmd_with_data(
+ async fn cmd_with_data(
&mut self,
spi: &mut SPI,
command: Command,
data: &[u8],
) -> Result<(), SPI::Error> {
- self.interface.cmd_with_data(spi, command, data)
+ self.interface.cmd_with_data(spi, command, data).await
}
}
diff --git a/src/epd2in13b_v4/mod.rs b/src/epd2in13b_v4/mod.rs
index 5bedea9a..c7a24059 100644
--- a/src/epd2in13b_v4/mod.rs
+++ b/src/epd2in13b_v4/mod.rs
@@ -51,15 +51,11 @@
//!# }
//!```
// Original Waveforms from Waveshare
-use embedded_hal::{
- delay::DelayNs,
- digital::{InputPin, OutputPin},
- spi::SpiDevice,
-};
+use embedded_hal::digital::{InputPin, OutputPin};
use crate::buffer_len;
use crate::color::TriColor;
-use crate::interface::DisplayInterface;
+use crate::interface::{DelayNs, DisplayInterface, SpiDevice};
use crate::traits::{
InternalWiAdditions, RefreshLut, WaveshareDisplay, WaveshareThreeColorDisplay,
};
@@ -102,6 +98,7 @@ pub struct Epd2in13b {
background_color: TriColor,
}
+#[maybe_async::maybe_async(AFIT)]
impl InternalWiAdditions
for Epd2in13b
where
@@ -111,13 +108,13 @@ where
RST: OutputPin,
DELAY: DelayNs,
{
- fn init(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
+ async fn init(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
// HW reset
- self.interface.reset(delay, 10_000, 10_000);
+ self.interface.reset(delay, 10_000, 10_000).await;
- self.wait_until_idle(spi, delay)?;
- self.interface.cmd(spi, Command::SwReset)?;
- self.wait_until_idle(spi, delay)?;
+ self.wait_until_idle(spi, delay).await?;
+ self.interface.cmd(spi, Command::SwReset).await?;
+ self.wait_until_idle(spi, delay).await?;
self.set_driver_output(
spi,
@@ -127,13 +124,15 @@ where
scan_dir_incr: true,
width: (HEIGHT - 1) as u16,
},
- )?;
+ )
+ .await?;
- self.set_data_entry_mode(spi, DataEntryModeIncr::XIncrYIncr, DataEntryModeDir::XDir)?;
+ self.set_data_entry_mode(spi, DataEntryModeIncr::XIncrYIncr, DataEntryModeDir::XDir)
+ .await?;
// Use simple X/Y auto increase
- self.set_ram_area(spi, 0, 0, WIDTH - 1, HEIGHT - 1)?;
- self.set_ram_address_counters(spi, delay, 0, 0)?;
+ self.set_ram_area(spi, 0, 0, WIDTH - 1, HEIGHT - 1).await?;
+ self.set_ram_address_counters(spi, delay, 0, 0).await?;
self.set_border_waveform(
spi,
@@ -142,11 +141,15 @@ where
fix_level: BorderWaveFormFixLevel::Vss,
gs_trans: BorderWaveFormGs::Lut3,
},
- )?;
+ )
+ .await?;
- self.cmd_with_data(spi, Command::WriteVcomRegister, &[0x36])?;
- self.cmd_with_data(spi, Command::GateDrivingVoltageCtrl, &[0x17])?;
- self.cmd_with_data(spi, Command::SourceDrivingVoltageCtrl, &[0x41, 0x00, 0x32])?;
+ self.cmd_with_data(spi, Command::WriteVcomRegister, &[0x36])
+ .await?;
+ self.cmd_with_data(spi, Command::GateDrivingVoltageCtrl, &[0x17])
+ .await?;
+ self.cmd_with_data(spi, Command::SourceDrivingVoltageCtrl, &[0x41, 0x00, 0x32])
+ .await?;
self.set_display_update_control(
spi,
@@ -155,14 +158,16 @@ where
bw_ram_option: RamOption::Normal,
source_output_mode: true,
},
- )?;
+ )
+ .await?;
- self.wait_until_idle(spi, delay)?;
+ self.wait_until_idle(spi, delay).await?;
Ok(())
}
}
+#[maybe_async::maybe_async(AFIT)]
impl WaveshareThreeColorDisplay
for Epd2in13b
where
@@ -172,40 +177,41 @@ where
RST: OutputPin,
DELAY: DelayNs,
{
- fn update_color_frame(
+ async fn update_color_frame(
&mut self,
spi: &mut SPI,
delay: &mut DELAY,
black: &[u8],
chromatic: &[u8],
) -> Result<(), SPI::Error> {
- self.update_achromatic_frame(spi, delay, black)?;
- self.update_chromatic_frame(spi, delay, chromatic)
+ self.update_achromatic_frame(spi, delay, black).await?;
+ self.update_chromatic_frame(spi, delay, chromatic).await
}
- fn update_achromatic_frame(
+ async fn update_achromatic_frame(
&mut self,
spi: &mut SPI,
_delay: &mut DELAY,
black: &[u8],
) -> Result<(), SPI::Error> {
- self.interface.cmd(spi, Command::WriteRam)?;
- self.interface.data(spi, black)?;
+ self.interface.cmd(spi, Command::WriteRam).await?;
+ self.interface.data(spi, black).await?;
Ok(())
}
- fn update_chromatic_frame(
+ async fn update_chromatic_frame(
&mut self,
spi: &mut SPI,
_delay: &mut DELAY,
chromatic: &[u8],
) -> Result<(), SPI::Error> {
- self.interface.cmd(spi, Command::WriteRamRed)?;
- self.interface.data(spi, chromatic)?;
+ self.interface.cmd(spi, Command::WriteRamRed).await?;
+ self.interface.data(spi, chromatic).await?;
Ok(())
}
}
+#[maybe_async::maybe_async(AFIT)]
impl WaveshareDisplay
for Epd2in13b
where
@@ -216,7 +222,7 @@ where
DELAY: DelayNs,
{
type DisplayColor = TriColor;
- fn new(
+ async fn new(
spi: &mut SPI,
busy: BUSY,
dc: DC,
@@ -229,38 +235,40 @@ where
background_color: DEFAULT_BACKGROUND_COLOR,
};
- epd.init(spi, delay)?;
+ epd.init(spi, delay).await?;
Ok(epd)
}
- fn wake_up(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
- self.init(spi, delay)
+ async fn wake_up(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
+ self.init(spi, delay).await
}
- fn sleep(&mut self, spi: &mut SPI, _delay: &mut DELAY) -> Result<(), SPI::Error> {
- self.set_sleep_mode(spi, DeepSleepMode::Normal)?;
+ async fn sleep(&mut self, spi: &mut SPI, _delay: &mut DELAY) -> Result<(), SPI::Error> {
+ self.set_sleep_mode(spi, DeepSleepMode::Normal).await?;
Ok(())
}
- fn update_frame(
+ async fn update_frame(
&mut self,
spi: &mut SPI,
buffer: &[u8],
_delay: &mut DELAY,
) -> Result<(), SPI::Error> {
assert!(buffer.len() == buffer_len(WIDTH as usize, HEIGHT as usize));
- self.cmd_with_data(spi, Command::WriteRam, buffer)?;
-
- self.command(spi, Command::WriteRamRed)?;
- self.interface.data_x_times(
- spi,
- TriColor::Black.get_byte_value(),
- buffer_len(WIDTH as usize, HEIGHT as usize) as u32,
- )?;
+ self.cmd_with_data(spi, Command::WriteRam, buffer).await?;
+
+ self.command(spi, Command::WriteRamRed).await?;
+ self.interface
+ .data_x_times(
+ spi,
+ TriColor::Black.get_byte_value(),
+ buffer_len(WIDTH as usize, HEIGHT as usize) as u32,
+ )
+ .await?;
Ok(())
}
- fn update_partial_frame(
+ async fn update_partial_frame(
&mut self,
_spi: &mut SPI,
_delay: &mut DELAY,
@@ -273,27 +281,27 @@ where
unimplemented!();
}
- fn display_frame(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
- self.command(spi, Command::MasterActivation)?;
- self.wait_until_idle(spi, delay)?;
+ async fn display_frame(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
+ self.command(spi, Command::MasterActivation).await?;
+ self.wait_until_idle(spi, delay).await?;
Ok(())
}
- fn update_and_display_frame(
+ async fn update_and_display_frame(
&mut self,
spi: &mut SPI,
buffer: &[u8],
delay: &mut DELAY,
) -> Result<(), SPI::Error> {
- self.update_frame(spi, buffer, delay)?;
- self.display_frame(spi, delay)?;
+ self.update_frame(spi, buffer, delay).await?;
+ self.display_frame(spi, delay).await?;
Ok(())
}
- fn clear_frame(&mut self, spi: &mut SPI, _delay: &mut DELAY) -> Result<(), SPI::Error> {
- self.clear_achromatic_frame(spi)?;
- self.clear_chromatic_frame(spi)
+ async fn clear_frame(&mut self, spi: &mut SPI, _delay: &mut DELAY) -> Result<(), SPI::Error> {
+ self.clear_achromatic_frame(spi).await?;
+ self.clear_chromatic_frame(spi).await
}
fn set_background_color(&mut self, background_color: TriColor) {
@@ -312,7 +320,7 @@ where
HEIGHT
}
- fn set_lut(
+ async fn set_lut(
&mut self,
_spi: &mut SPI,
_delay: &mut DELAY,
@@ -321,12 +329,17 @@ where
unimplemented!()
}
- fn wait_until_idle(&mut self, _spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
- self.interface.wait_until_idle(delay, IS_BUSY_LOW);
+ async fn wait_until_idle(
+ &mut self,
+ _spi: &mut SPI,
+ delay: &mut DELAY,
+ ) -> Result<(), SPI::Error> {
+ self.interface.wait_until_idle(delay, IS_BUSY_LOW).await;
Ok(())
}
}
+#[maybe_async::maybe_async]
impl Epd2in13b
where
SPI: SpiDevice,
@@ -335,7 +348,7 @@ where
RST: OutputPin,
DELAY: DelayNs,
{
- fn set_display_update_control(
+ async fn set_display_update_control(
&mut self,
spi: &mut SPI,
display_update_control: DisplayUpdateControl,
@@ -345,9 +358,10 @@ where
Command::DisplayUpdateControl1,
&display_update_control.to_bytes(),
)
+ .await
}
- fn set_border_waveform(
+ async fn set_border_waveform(
&mut self,
spi: &mut SPI,
borderwaveform: BorderWaveForm,
@@ -357,20 +371,31 @@ where
Command::BorderWaveformControl,
&[borderwaveform.to_u8()],
)
+ .await
}
/// Triggers the deep sleep mode
- fn set_sleep_mode(&mut self, spi: &mut SPI, mode: DeepSleepMode) -> Result<(), SPI::Error> {
+ async fn set_sleep_mode(
+ &mut self,
+ spi: &mut SPI,
+ mode: DeepSleepMode,
+ ) -> Result<(), SPI::Error> {
self.cmd_with_data(spi, Command::DeepSleepMode, &[mode as u8])
+ .await
}
- fn set_driver_output(&mut self, spi: &mut SPI, output: DriverOutput) -> Result<(), SPI::Error> {
+ async fn set_driver_output(
+ &mut self,
+ spi: &mut SPI,
+ output: DriverOutput,
+ ) -> Result<(), SPI::Error> {
self.cmd_with_data(spi, Command::DriverOutputControl, &output.to_bytes())
+ .await
}
/// Sets the data entry mode (ie. how X and Y positions changes when writing
/// data to RAM)
- fn set_data_entry_mode(
+ async fn set_data_entry_mode(
&mut self,
spi: &mut SPI,
counter_incr_mode: DataEntryModeIncr,
@@ -378,10 +403,11 @@ where
) -> Result<(), SPI::Error> {
let mode = counter_incr_mode as u8 | counter_direction as u8;
self.cmd_with_data(spi, Command::DataEntryModeSetting, &[mode])
+ .await
}
/// Sets both X and Y pixels ranges
- fn set_ram_area(
+ async fn set_ram_area(
&mut self,
spi: &mut SPI,
start_x: u32,
@@ -393,7 +419,8 @@ where
spi,
Command::SetRamXAddressStartEndPosition,
&[(start_x >> 3) as u8, (end_x >> 3) as u8],
- )?;
+ )
+ .await?;
self.cmd_with_data(
spi,
@@ -405,96 +432,111 @@ where
(end_y >> 8) as u8,
],
)
+ .await
}
/// Sets both X and Y pixels counters when writing data to RAM
- fn set_ram_address_counters(
+ async fn set_ram_address_counters(
&mut self,
spi: &mut SPI,
delay: &mut DELAY,
x: u32,
y: u32,
) -> Result<(), SPI::Error> {
- self.wait_until_idle(spi, delay)?;
- self.cmd_with_data(spi, Command::SetRamXAddressCounter, &[(x >> 3) as u8])?;
+ self.wait_until_idle(spi, delay).await?;
+ self.cmd_with_data(spi, Command::SetRamXAddressCounter, &[(x >> 3) as u8])
+ .await?;
self.cmd_with_data(
spi,
Command::SetRamYAddressCounter,
&[y as u8, (y >> 8) as u8],
- )?;
+ )
+ .await?;
Ok(())
}
- fn command(&mut self, spi: &mut SPI, command: Command) -> Result<(), SPI::Error> {
- self.interface.cmd(spi, command)
+ async fn command(&mut self, spi: &mut SPI, command: Command) -> Result<(), SPI::Error> {
+ self.interface.cmd(spi, command).await
}
- fn cmd_with_data(
+ async fn cmd_with_data(
&mut self,
spi: &mut SPI,
command: Command,
data: &[u8],
) -> Result<(), SPI::Error> {
- self.interface.cmd_with_data(spi, command, data)
+ self.interface.cmd_with_data(spi, command, data).await
}
- fn clear_achromatic_frame(&mut self, spi: &mut SPI) -> Result<(), SPI::Error> {
+ async fn clear_achromatic_frame(&mut self, spi: &mut SPI) -> Result<(), SPI::Error> {
match self.background_color {
TriColor::White => {
- self.command(spi, Command::WriteRam)?;
- self.interface.data_x_times(
- spi,
- 0xFF,
- buffer_len(WIDTH as usize, HEIGHT as usize) as u32,
- )?;
+ self.command(spi, Command::WriteRam).await?;
+ self.interface
+ .data_x_times(
+ spi,
+ 0xFF,
+ buffer_len(WIDTH as usize, HEIGHT as usize) as u32,
+ )
+ .await?;
}
TriColor::Chromatic => {
- self.command(spi, Command::WriteRam)?;
- self.interface.data_x_times(
- spi,
- 0xFF,
- buffer_len(WIDTH as usize, HEIGHT as usize) as u32,
- )?;
+ self.command(spi, Command::WriteRam).await?;
+ self.interface
+ .data_x_times(
+ spi,
+ 0xFF,
+ buffer_len(WIDTH as usize, HEIGHT as usize) as u32,
+ )
+ .await?;
}
TriColor::Black => {
- self.command(spi, Command::WriteRam)?;
- self.interface.data_x_times(
- spi,
- 0x00,
- buffer_len(WIDTH as usize, HEIGHT as usize) as u32,
- )?;
+ self.command(spi, Command::WriteRam).await?;
+ self.interface
+ .data_x_times(
+ spi,
+ 0x00,
+ buffer_len(WIDTH as usize, HEIGHT as usize) as u32,
+ )
+ .await?;
}
}
Ok(())
}
- fn clear_chromatic_frame(&mut self, spi: &mut SPI) -> Result<(), SPI::Error> {
+ async fn clear_chromatic_frame(&mut self, spi: &mut SPI) -> Result<(), SPI::Error> {
match self.background_color {
TriColor::White => {
- self.command(spi, Command::WriteRam)?;
- self.interface.data_x_times(
- spi,
- 0x00,
- buffer_len(WIDTH as usize, HEIGHT as usize) as u32,
- )?;
+ self.command(spi, Command::WriteRam).await?;
+ self.interface
+ .data_x_times(
+ spi,
+ 0x00,
+ buffer_len(WIDTH as usize, HEIGHT as usize) as u32,
+ )
+ .await?;
}
TriColor::Chromatic => {
- self.command(spi, Command::WriteRam)?;
- self.interface.data_x_times(
- spi,
- 0xFF,
- buffer_len(WIDTH as usize, HEIGHT as usize) as u32,
- )?;
+ self.command(spi, Command::WriteRam).await?;
+ self.interface
+ .data_x_times(
+ spi,
+ 0xFF,
+ buffer_len(WIDTH as usize, HEIGHT as usize) as u32,
+ )
+ .await?;
}
TriColor::Black => {
- self.command(spi, Command::WriteRam)?;
- self.interface.data_x_times(
- spi,
- 0x00,
- buffer_len(WIDTH as usize, HEIGHT as usize) as u32,
- )?;
+ self.command(spi, Command::WriteRam).await?;
+ self.interface
+ .data_x_times(
+ spi,
+ 0x00,
+ buffer_len(WIDTH as usize, HEIGHT as usize) as u32,
+ )
+ .await?;
}
}
diff --git a/src/epd2in13bc/mod.rs b/src/epd2in13bc/mod.rs
index d1256c4c..dbc0f3fc 100644
--- a/src/epd2in13bc/mod.rs
+++ b/src/epd2in13bc/mod.rs
@@ -50,9 +50,9 @@
//!# Ok(())
//!# }
//!```
-use embedded_hal::{delay::*, digital::*, spi::SpiDevice};
+use embedded_hal::digital::*;
-use crate::interface::DisplayInterface;
+use crate::interface::{DelayNs, DisplayInterface, SpiDevice};
use crate::traits::{
InternalWiAdditions, RefreshLut, WaveshareDisplay, WaveshareThreeColorDisplay,
};
@@ -97,6 +97,7 @@ pub struct Epd2in13bc {
color: TriColor,
}
+#[maybe_async::maybe_async(AFIT)]
impl InternalWiAdditions
for Epd2in13bc
where
@@ -106,40 +107,45 @@ where
RST: OutputPin,
DELAY: DelayNs,
{
- fn init(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
+ async fn init(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
// Values taken from datasheet and sample code
- self.interface.reset(delay, 10_000, 10_000);
+ self.interface.reset(delay, 10_000, 10_000).await;
// start the booster
self.interface
- .cmd_with_data(spi, Command::BoosterSoftStart, &[0x17, 0x17, 0x17])?;
+ .cmd_with_data(spi, Command::BoosterSoftStart, &[0x17, 0x17, 0x17])
+ .await?;
// power on
- self.command(spi, Command::PowerOn)?;
- delay.delay_us(5000);
- self.wait_until_idle(spi, delay)?;
+ self.command(spi, Command::PowerOn).await?;
+ delay.delay_us(5000).await;
+ self.wait_until_idle(spi, delay).await?;
// set the panel settings
- self.cmd_with_data(spi, Command::PanelSetting, &[0x8F])?;
+ self.cmd_with_data(spi, Command::PanelSetting, &[0x8F])
+ .await?;
self.cmd_with_data(
spi,
Command::VcomAndDataIntervalSetting,
&[WHITE_BORDER | VCOM_DATA_INTERVAL],
- )?;
+ )
+ .await?;
// set resolution
- self.send_resolution(spi)?;
+ self.send_resolution(spi).await?;
- self.cmd_with_data(spi, Command::VcmDcSetting, &[0x0A])?;
+ self.cmd_with_data(spi, Command::VcmDcSetting, &[0x0A])
+ .await?;
- self.wait_until_idle(spi, delay)?;
+ self.wait_until_idle(spi, delay).await?;
Ok(())
}
}
+#[maybe_async::maybe_async(AFIT)]
impl WaveshareThreeColorDisplay
for Epd2in13bc
where
@@ -149,48 +155,53 @@ where
RST: OutputPin,
DELAY: DelayNs,
{
- fn update_color_frame(
+ async fn update_color_frame(
&mut self,
spi: &mut SPI,
delay: &mut DELAY,
black: &[u8],
chromatic: &[u8],
) -> Result<(), SPI::Error> {
- self.update_achromatic_frame(spi, delay, black)?;
- self.update_chromatic_frame(spi, delay, chromatic)
+ self.update_achromatic_frame(spi, delay, black).await?;
+ self.update_chromatic_frame(spi, delay, chromatic).await
}
/// Update only the black/white data of the display.
///
/// Finish by calling `update_chromatic_frame`.
- fn update_achromatic_frame(
+ async fn update_achromatic_frame(
&mut self,
spi: &mut SPI,
_delay: &mut DELAY,
black: &[u8],
) -> Result<(), SPI::Error> {
- self.interface.cmd(spi, Command::DataStartTransmission1)?;
- self.interface.data(spi, black)?;
+ self.interface
+ .cmd(spi, Command::DataStartTransmission1)
+ .await?;
+ self.interface.data(spi, black).await?;
Ok(())
}
/// Update only chromatic data of the display.
///
/// This data takes precedence over the black/white data.
- fn update_chromatic_frame(
+ async fn update_chromatic_frame(
&mut self,
spi: &mut SPI,
delay: &mut DELAY,
chromatic: &[u8],
) -> Result<(), SPI::Error> {
- self.interface.cmd(spi, Command::DataStartTransmission2)?;
- self.interface.data(spi, chromatic)?;
+ self.interface
+ .cmd(spi, Command::DataStartTransmission2)
+ .await?;
+ self.interface.data(spi, chromatic).await?;
- self.wait_until_idle(spi, delay)?;
+ self.wait_until_idle(spi, delay).await?;
Ok(())
}
}
+#[maybe_async::maybe_async(AFIT)]
impl WaveshareDisplay
for Epd2in13bc
where
@@ -201,7 +212,7 @@ where
DELAY: DelayNs,
{
type DisplayColor = TriColor;
- fn new(
+ async fn new(
spi: &mut SPI,
busy: BUSY,
dc: DC,
@@ -214,30 +225,32 @@ where
let mut epd = Epd2in13bc { interface, color };
- epd.init(spi, delay)?;
+ epd.init(spi, delay).await?;
Ok(epd)
}
- fn sleep(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
+ async fn sleep(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
// Section 8.2 from datasheet
- self.interface.cmd_with_data(
- spi,
- Command::VcomAndDataIntervalSetting,
- &[FLOATING_BORDER | VCOM_DATA_INTERVAL],
- )?;
-
- self.command(spi, Command::PowerOff)?;
+ self.interface
+ .cmd_with_data(
+ spi,
+ Command::VcomAndDataIntervalSetting,
+ &[FLOATING_BORDER | VCOM_DATA_INTERVAL],
+ )
+ .await?;
+
+ self.command(spi, Command::PowerOff).await?;
// The example STM code from Github has a wait after PowerOff
- self.wait_until_idle(spi, delay)?;
+ self.wait_until_idle(spi, delay).await?;
- self.cmd_with_data(spi, Command::DeepSleep, &[0xA5])?;
+ self.cmd_with_data(spi, Command::DeepSleep, &[0xA5]).await?;
Ok(())
}
- fn wake_up(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
- self.init(spi, delay)
+ async fn wake_up(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
+ self.init(spi, delay).await
}
fn set_background_color(&mut self, color: TriColor) {
@@ -256,28 +269,34 @@ where
HEIGHT
}
- fn update_frame(
+ async fn update_frame(
&mut self,
spi: &mut SPI,
buffer: &[u8],
delay: &mut DELAY,
) -> Result<(), SPI::Error> {
- self.interface.cmd(spi, Command::DataStartTransmission1)?;
+ self.interface
+ .cmd(spi, Command::DataStartTransmission1)
+ .await?;
- self.interface.data(spi, buffer)?;
+ self.interface.data(spi, buffer).await?;
// Clear the chromatic layer
let color = self.color.get_byte_value();
- self.interface.cmd(spi, Command::DataStartTransmission2)?;
- self.interface.data_x_times(spi, color, NUM_DISPLAY_BITS)?;
+ self.interface
+ .cmd(spi, Command::DataStartTransmission2)
+ .await?;
+ self.interface
+ .data_x_times(spi, color, NUM_DISPLAY_BITS)
+ .await?;
- self.wait_until_idle(spi, delay)?;
+ self.wait_until_idle(spi, delay).await?;
Ok(())
}
#[allow(unused)]
- fn update_partial_frame(
+ async fn update_partial_frame(
&mut self,
spi: &mut SPI,
delay: &mut DELAY,
@@ -290,43 +309,51 @@ where
Ok(())
}
- fn display_frame(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
- self.command(spi, Command::DisplayRefresh)?;
+ async fn display_frame(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
+ self.command(spi, Command::DisplayRefresh).await?;
- self.wait_until_idle(spi, delay)?;
+ self.wait_until_idle(spi, delay).await?;
Ok(())
}
- fn update_and_display_frame(
+ async fn update_and_display_frame(
&mut self,
spi: &mut SPI,
buffer: &[u8],
delay: &mut DELAY,
) -> Result<(), SPI::Error> {
- self.update_frame(spi, buffer, delay)?;
- self.display_frame(spi, delay)?;
+ self.update_frame(spi, buffer, delay).await?;
+ self.display_frame(spi, delay).await?;
Ok(())
}
- fn clear_frame(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
- self.send_resolution(spi)?;
+ async fn clear_frame(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
+ self.send_resolution(spi).await?;
let color = DEFAULT_BACKGROUND_COLOR.get_byte_value();
// Clear the black
- self.interface.cmd(spi, Command::DataStartTransmission1)?;
+ self.interface
+ .cmd(spi, Command::DataStartTransmission1)
+ .await?;
- self.interface.data_x_times(spi, color, NUM_DISPLAY_BITS)?;
+ self.interface
+ .data_x_times(spi, color, NUM_DISPLAY_BITS)
+ .await?;
// Clear the chromatic
- self.interface.cmd(spi, Command::DataStartTransmission2)?;
- self.interface.data_x_times(spi, color, NUM_DISPLAY_BITS)?;
+ self.interface
+ .cmd(spi, Command::DataStartTransmission2)
+ .await?;
+ self.interface
+ .data_x_times(spi, color, NUM_DISPLAY_BITS)
+ .await?;
- self.wait_until_idle(spi, delay)?;
+ self.wait_until_idle(spi, delay).await?;
Ok(())
}
- fn set_lut(
+ async fn set_lut(
&mut self,
_spi: &mut SPI,
_delay: &mut DELAY,
@@ -335,12 +362,17 @@ where
Ok(())
}
- fn wait_until_idle(&mut self, _spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
- self.interface.wait_until_idle(delay, IS_BUSY_LOW);
+ async fn wait_until_idle(
+ &mut self,
+ _spi: &mut SPI,
+ delay: &mut DELAY,
+ ) -> Result<(), SPI::Error> {
+ self.interface.wait_until_idle(delay, IS_BUSY_LOW).await;
Ok(())
}
}
+#[maybe_async::maybe_async]
impl Epd2in13bc
where
SPI: SpiDevice,
@@ -349,36 +381,40 @@ where
RST: OutputPin,
DELAY: DelayNs,
{
- fn command(&mut self, spi: &mut SPI, command: Command) -> Result<(), SPI::Error> {
- self.interface.cmd(spi, command)
+ async fn command(&mut self, spi: &mut SPI, command: Command) -> Result<(), SPI::Error> {
+ self.interface.cmd(spi, command).await
}
- fn send_data(&mut self, spi: &mut SPI, data: &[u8]) -> Result<(), SPI::Error> {
- self.interface.data(spi, data)
+ async fn send_data(&mut self, spi: &mut SPI, data: &[u8]) -> Result<(), SPI::Error> {
+ self.interface.data(spi, data).await
}
- fn cmd_with_data(
+ async fn cmd_with_data(
&mut self,
spi: &mut SPI,
command: Command,
data: &[u8],
) -> Result<(), SPI::Error> {
- self.interface.cmd_with_data(spi, command, data)
+ self.interface.cmd_with_data(spi, command, data).await
}
- fn send_resolution(&mut self, spi: &mut SPI) -> Result<(), SPI::Error> {
+ async fn send_resolution(&mut self, spi: &mut SPI) -> Result<(), SPI::Error> {
let w = self.width();
let h = self.height();
- self.command(spi, Command::ResolutionSetting)?;
+ self.command(spi, Command::ResolutionSetting).await?;
- self.send_data(spi, &[w as u8])?;
- self.send_data(spi, &[(h >> 8) as u8])?;
- self.send_data(spi, &[h as u8])
+ self.send_data(spi, &[w as u8]).await?;
+ self.send_data(spi, &[(h >> 8) as u8]).await?;
+ self.send_data(spi, &[h as u8]).await
}
/// Set the outer border of the display to the chosen color.
- pub fn set_border_color(&mut self, spi: &mut SPI, color: TriColor) -> Result<(), SPI::Error> {
+ pub async fn set_border_color(
+ &mut self,
+ spi: &mut SPI,
+ color: TriColor,
+ ) -> Result<(), SPI::Error> {
let border = match color {
TriColor::Black => BLACK_BORDER,
TriColor::White => WHITE_BORDER,
@@ -389,5 +425,6 @@ where
Command::VcomAndDataIntervalSetting,
&[border | VCOM_DATA_INTERVAL],
)
+ .await
}
}
diff --git a/src/epd2in66b/mod.rs b/src/epd2in66b/mod.rs
index 092fce3f..9fd419ee 100644
--- a/src/epd2in66b/mod.rs
+++ b/src/epd2in66b/mod.rs
@@ -166,14 +166,10 @@
//!}
//!```
-use embedded_hal::{
- delay::DelayNs,
- digital::{InputPin, OutputPin},
- spi::SpiDevice,
-};
+use embedded_hal::digital::{InputPin, OutputPin};
use crate::color::TriColor;
-use crate::interface::DisplayInterface;
+use crate::interface::{DelayNs, DisplayInterface, SpiDevice};
use crate::traits::{
InternalWiAdditions, RefreshLut, WaveshareDisplay, WaveshareThreeColorDisplay,
};
@@ -208,6 +204,7 @@ pub struct Epd2in66b {
background: TriColor,
}
+#[maybe_async::maybe_async(AFIT)]
impl InternalWiAdditions
for Epd2in66b
where
@@ -217,24 +214,28 @@ where
RST: OutputPin,
DELAY: DelayNs,
{
- fn init(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
+ async fn init(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
// We follow the sequence of the Pi-Pico hat example code.
- self.hw_reset(delay)?;
- self.sw_reset(spi, delay)?;
- self.data_entry_mode(spi, DataEntryRow::XMinor, DataEntrySign::IncYIncX)?;
- self.set_display_window(spi, 0, 0, WIDTH - 1, HEIGHT - 1)?;
+ self.hw_reset(delay).await?;
+ self.sw_reset(spi, delay).await?;
+ self.data_entry_mode(spi, DataEntryRow::XMinor, DataEntrySign::IncYIncX)
+ .await?;
+ self.set_display_window(spi, 0, 0, WIDTH - 1, HEIGHT - 1)
+ .await?;
self.update_control1(
spi,
WriteMode::Normal,
WriteMode::Normal,
OutputSource::S8ToS167,
- )?;
- self.set_cursor(spi, 0, 0)?;
+ )
+ .await?;
+ self.set_cursor(spi, 0, 0).await?;
Ok(())
}
}
+#[maybe_async::maybe_async(AFIT)]
impl WaveshareThreeColorDisplay
for Epd2in66b
where
@@ -244,40 +245,41 @@ where
RST: OutputPin,
DELAY: DelayNs,
{
- fn update_color_frame(
+ async fn update_color_frame(
&mut self,
spi: &mut SPI,
delay: &mut DELAY,
black: &[u8],
chromatic: &[u8],
) -> Result<(), SPI::Error> {
- self.update_achromatic_frame(spi, delay, black)?;
- self.update_chromatic_frame(spi, delay, chromatic)
+ self.update_achromatic_frame(spi, delay, black).await?;
+ self.update_chromatic_frame(spi, delay, chromatic).await
}
- fn update_achromatic_frame(
+ async fn update_achromatic_frame(
&mut self,
spi: &mut SPI,
_delay: &mut DELAY,
black: &[u8],
) -> Result<(), SPI::Error> {
- self.set_cursor(spi, 0, 0)?;
- self.interface.cmd(spi, Command::WriteBlackWhiteRAM)?;
- self.interface.data(spi, black)
+ self.set_cursor(spi, 0, 0).await?;
+ self.interface.cmd(spi, Command::WriteBlackWhiteRAM).await?;
+ self.interface.data(spi, black).await
}
- fn update_chromatic_frame(
+ async fn update_chromatic_frame(
&mut self,
spi: &mut SPI,
_delay: &mut DELAY,
chromatic: &[u8],
) -> Result<(), SPI::Error> {
- self.set_cursor(spi, 0, 0)?;
- self.interface.cmd(spi, Command::WriteRedRAM)?;
- self.interface.data(spi, chromatic)
+ self.set_cursor(spi, 0, 0).await?;
+ self.interface.cmd(spi, Command::WriteRedRAM).await?;
+ self.interface.data(spi, chromatic).await
}
}
+#[maybe_async::maybe_async(AFIT)]
impl WaveshareDisplay
for Epd2in66b
where
@@ -289,7 +291,7 @@ where
{
type DisplayColor = TriColor;
- fn new(
+ async fn new(
spi: &mut SPI,
busy: BUSY,
dc: DC,
@@ -304,20 +306,22 @@ where
interface: DisplayInterface::new(busy, dc, rst, delay_us),
background: DEFAULT_BACKGROUND_COLOR,
};
- epd.init(spi, delay)?;
+ epd.init(spi, delay).await?;
Ok(epd)
}
- fn sleep(&mut self, spi: &mut SPI, _delay: &mut DELAY) -> Result<(), SPI::Error> {
- self.interface.cmd_with_data(
- spi,
- Command::DeepSleepMode,
- &[DeepSleep::SleepLosingRAM as u8],
- )
+ async fn sleep(&mut self, spi: &mut SPI, _delay: &mut DELAY) -> Result<(), SPI::Error> {
+ self.interface
+ .cmd_with_data(
+ spi,
+ Command::DeepSleepMode,
+ &[DeepSleep::SleepLosingRAM as u8],
+ )
+ .await
}
- fn wake_up(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
- self.init(spi, delay)
+ async fn wake_up(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
+ self.init(spi, delay).await
}
fn set_background_color(&mut self, color: Self::DisplayColor) {
@@ -336,18 +340,19 @@ where
HEIGHT
}
- fn update_frame(
+ async fn update_frame(
&mut self,
spi: &mut SPI,
buffer: &[u8],
delay: &mut DELAY,
) -> Result<(), SPI::Error> {
- self.set_cursor(spi, 0, 0)?;
- self.update_achromatic_frame(spi, delay, buffer)?;
- self.red_pattern(spi, delay, PatW::W160, PatH::H296, StartWith::Zero) // do NOT consider background here since red overrides other colors
+ self.set_cursor(spi, 0, 0).await?;
+ self.update_achromatic_frame(spi, delay, buffer).await?;
+ self.red_pattern(spi, delay, PatW::W160, PatH::H296, StartWith::Zero)
+ .await // do NOT consider background here since red overrides other colors
}
- fn update_partial_frame(
+ async fn update_partial_frame(
&mut self,
spi: &mut SPI,
delay: &mut DELAY,
@@ -357,38 +362,41 @@ where
width: u32,
height: u32,
) -> Result<(), SPI::Error> {
- self.set_display_window(spi, x, y, x + width, y + height)?;
- self.set_cursor(spi, x, y)?;
- self.update_achromatic_frame(spi, delay, buffer)?;
- self.set_display_window(spi, 0, 0, WIDTH, HEIGHT)
+ self.set_display_window(spi, x, y, x + width, y + height)
+ .await?;
+ self.set_cursor(spi, x, y).await?;
+ self.update_achromatic_frame(spi, delay, buffer).await?;
+ self.set_display_window(spi, 0, 0, WIDTH, HEIGHT).await
}
- fn display_frame(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
- self.interface.cmd(spi, Command::MasterActivation)?;
- self.wait_until_idle(delay)
+ async fn display_frame(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
+ self.interface.cmd(spi, Command::MasterActivation).await?;
+ self.wait_until_idle(delay).await
}
- fn update_and_display_frame(
+ async fn update_and_display_frame(
&mut self,
spi: &mut SPI,
buffer: &[u8],
delay: &mut DELAY,
) -> Result<(), SPI::Error> {
- self.update_frame(spi, buffer, delay)?;
- self.display_frame(spi, delay)
+ self.update_frame(spi, buffer, delay).await?;
+ self.display_frame(spi, delay).await
}
- fn clear_frame(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
+ async fn clear_frame(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
let (white, red) = match self.background {
TriColor::Black => (StartWith::Zero, StartWith::Zero),
TriColor::White => (StartWith::One, StartWith::Zero),
TriColor::Chromatic => (StartWith::Zero, StartWith::One),
};
- self.black_white_pattern(spi, delay, PatW::W160, PatH::H296, white)?;
+ self.black_white_pattern(spi, delay, PatW::W160, PatH::H296, white)
+ .await?;
self.red_pattern(spi, delay, PatW::W160, PatH::H296, red)
+ .await
}
- fn set_lut(
+ async fn set_lut(
&mut self,
_spi: &mut SPI,
_delay: &mut DELAY,
@@ -397,12 +405,17 @@ where
Ok(())
}
- fn wait_until_idle(&mut self, _spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
- self.wait_until_idle(delay)
+ async fn wait_until_idle(
+ &mut self,
+ _spi: &mut SPI,
+ delay: &mut DELAY,
+ ) -> Result<(), SPI::Error> {
+ self.wait_until_idle(delay).await
}
}
// Helper functions that enforce some type and value constraints. Meant to help with code readability. They caught some of my silly errors -> yay rust!.
+#[maybe_async::maybe_async]
impl Epd2in66b
where
SPI: SpiDevice,
@@ -411,20 +424,20 @@ where
RST: OutputPin,
DELAY: DelayNs,
{
- fn wait_until_idle(&mut self, delay: &mut DELAY) -> Result<(), SPI::Error> {
- self.interface.wait_until_idle(delay, false);
+ async fn wait_until_idle(&mut self, delay: &mut DELAY) -> Result<(), SPI::Error> {
+ self.interface.wait_until_idle(delay, false).await;
Ok(())
}
- fn hw_reset(&mut self, delay: &mut DELAY) -> Result<(), SPI::Error> {
+ async fn hw_reset(&mut self, delay: &mut DELAY) -> Result<(), SPI::Error> {
// The initial delay is taken from other code here, the 2 ms comes from the SSD1675B datasheet.
- self.interface.reset(delay, 20_000, 2_000);
- self.wait_until_idle(delay)
+ self.interface.reset(delay, 20_000, 2_000).await;
+ self.wait_until_idle(delay).await
}
- fn sw_reset(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
- self.interface.cmd(spi, Command::Reset)?;
- self.wait_until_idle(delay)
+ async fn sw_reset(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
+ self.interface.cmd(spi, Command::Reset).await?;
+ self.wait_until_idle(delay).await
}
- fn data_entry_mode(
+ async fn data_entry_mode(
&mut self,
spi: &mut SPI,
row: DataEntryRow,
@@ -432,8 +445,9 @@ where
) -> Result<(), SPI::Error> {
self.interface
.cmd_with_data(spi, Command::DataEntryMode, &[row as u8 | sign as u8])
+ .await
}
- fn set_display_window(
+ async fn set_display_window(
&mut self,
spi: &mut SPI,
xstart: u32,
@@ -441,50 +455,56 @@ where
xend: u32,
yend: u32,
) -> Result<(), SPI::Error> {
- self.interface.cmd_with_data(
- spi,
- Command::SetXAddressRange,
- &[(((xstart >> 3) & 0x1f) as u8), (((xend >> 3) & 0x1f) as u8)],
- )?;
- self.interface.cmd_with_data(
- spi,
- Command::SetYAddressRange,
- &[
- ((ystart & 0xff) as u8),
- (((ystart >> 8) & 0x01) as u8),
- ((yend & 0xff) as u8),
- (((yend >> 8) & 0x01) as u8),
- ],
- )
+ self.interface
+ .cmd_with_data(
+ spi,
+ Command::SetXAddressRange,
+ &[(((xstart >> 3) & 0x1f) as u8), (((xend >> 3) & 0x1f) as u8)],
+ )
+ .await?;
+ self.interface
+ .cmd_with_data(
+ spi,
+ Command::SetYAddressRange,
+ &[
+ ((ystart & 0xff) as u8),
+ (((ystart >> 8) & 0x01) as u8),
+ ((yend & 0xff) as u8),
+ (((yend >> 8) & 0x01) as u8),
+ ],
+ )
+ .await
}
- fn update_control1(
+ async fn update_control1(
&mut self,
spi: &mut SPI,
red_mode: WriteMode,
bw_mode: WriteMode,
source: OutputSource,
) -> Result<(), SPI::Error> {
- self.interface.cmd_with_data(
- spi,
- Command::DisplayUpdateControl1,
- &[((red_mode as u8) << 4 | bw_mode as u8), (source as u8)],
- )
+ self.interface
+ .cmd_with_data(
+ spi,
+ Command::DisplayUpdateControl1,
+ &[((red_mode as u8) << 4 | bw_mode as u8), (source as u8)],
+ )
+ .await
}
- fn set_cursor(&mut self, spi: &mut SPI, x: u32, y: u32) -> Result<(), SPI::Error> {
- self.interface.cmd_with_data(
- spi,
- Command::SetXAddressCounter,
- &[((x >> 3) & 0x1f) as u8],
- )?;
- self.interface.cmd_with_data(
- spi,
- Command::SetYAddressCounter,
- &[((y & 0xff) as u8), (((y >> 8) & 0x01) as u8)],
- )
+ async fn set_cursor(&mut self, spi: &mut SPI, x: u32, y: u32) -> Result<(), SPI::Error> {
+ self.interface
+ .cmd_with_data(spi, Command::SetXAddressCounter, &[((x >> 3) & 0x1f) as u8])
+ .await?;
+ self.interface
+ .cmd_with_data(
+ spi,
+ Command::SetYAddressCounter,
+ &[((y & 0xff) as u8), (((y >> 8) & 0x01) as u8)],
+ )
+ .await
}
- fn black_white_pattern(
+ async fn black_white_pattern(
&mut self,
spi: &mut SPI,
delay: &mut DELAY,
@@ -492,14 +512,16 @@ where
h: PatH,
phase: StartWith,
) -> Result<(), SPI::Error> {
- self.interface.cmd_with_data(
- spi,
- Command::BlackWhiteRAMTestPattern,
- &[phase as u8 | h as u8 | w as u8],
- )?;
- self.wait_until_idle(delay)
+ self.interface
+ .cmd_with_data(
+ spi,
+ Command::BlackWhiteRAMTestPattern,
+ &[phase as u8 | h as u8 | w as u8],
+ )
+ .await?;
+ self.wait_until_idle(delay).await
}
- fn red_pattern(
+ async fn red_pattern(
&mut self,
spi: &mut SPI,
delay: &mut DELAY,
@@ -507,11 +529,13 @@ where
h: PatH,
phase: StartWith,
) -> Result<(), SPI::Error> {
- self.interface.cmd_with_data(
- spi,
- Command::RedRAMTestPattern,
- &[phase as u8 | h as u8 | w as u8],
- )?;
- self.wait_until_idle(delay)
+ self.interface
+ .cmd_with_data(
+ spi,
+ Command::RedRAMTestPattern,
+ &[phase as u8 | h as u8 | w as u8],
+ )
+ .await?;
+ self.wait_until_idle(delay).await
}
}
diff --git a/src/epd2in7/mod.rs b/src/epd2in7/mod.rs
index 77cccca0..50b0a36d 100644
--- a/src/epd2in7/mod.rs
+++ b/src/epd2in7/mod.rs
@@ -2,13 +2,9 @@
//!
//! [Documentation](https://www.waveshare.com/wiki/2.7inch_e-Paper_HAT)
-use embedded_hal::{
- delay::DelayNs,
- digital::{InputPin, OutputPin},
- spi::SpiDevice,
-};
+use embedded_hal::digital::{InputPin, OutputPin};
-use crate::interface::DisplayInterface;
+use crate::interface::{DelayNs, DisplayInterface, SpiDevice};
use crate::traits::{InternalWiAdditions, RefreshLut, WaveshareDisplay};
// The Lookup Tables for the Display
@@ -48,6 +44,7 @@ pub struct Epd2in7 {
color: Color,
}
+#[maybe_async::maybe_async(AFIT)]
impl InternalWiAdditions
for Epd2in7
where
@@ -57,42 +54,57 @@ where
RST: OutputPin,
DELAY: DelayNs,
{
- fn init(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
+ async fn init(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
// reset the device
- self.interface.reset(delay, 10_000, 2_000);
+ self.interface.reset(delay, 10_000, 2_000).await;
// power setting
- self.cmd_with_data(spi, Command::PowerSetting, &[0x03, 0x00, 0x2b, 0x2b, 0x09])?;
+ self.cmd_with_data(spi, Command::PowerSetting, &[0x03, 0x00, 0x2b, 0x2b, 0x09])
+ .await?;
// booster soft start
- self.cmd_with_data(spi, Command::BoosterSoftStart, &[0x07, 0x07, 0x17])?;
+ self.cmd_with_data(spi, Command::BoosterSoftStart, &[0x07, 0x07, 0x17])
+ .await?;
// power optimization
- self.cmd_with_data(spi, Command::PowerOptimization, &[0x60, 0xa5])?;
- self.cmd_with_data(spi, Command::PowerOptimization, &[0x89, 0xa5])?;
- self.cmd_with_data(spi, Command::PowerOptimization, &[0x90, 0x00])?;
- self.cmd_with_data(spi, Command::PowerOptimization, &[0x93, 0x2a])?;
- self.cmd_with_data(spi, Command::PowerOptimization, &[0xa0, 0xa5])?;
- self.cmd_with_data(spi, Command::PowerOptimization, &[0xa1, 0x00])?;
- self.cmd_with_data(spi, Command::PowerOptimization, &[0x73, 0x41])?;
+ self.cmd_with_data(spi, Command::PowerOptimization, &[0x60, 0xa5])
+ .await?;
+ self.cmd_with_data(spi, Command::PowerOptimization, &[0x89, 0xa5])
+ .await?;
+ self.cmd_with_data(spi, Command::PowerOptimization, &[0x90, 0x00])
+ .await?;
+ self.cmd_with_data(spi, Command::PowerOptimization, &[0x93, 0x2a])
+ .await?;
+ self.cmd_with_data(spi, Command::PowerOptimization, &[0xa0, 0xa5])
+ .await?;
+ self.cmd_with_data(spi, Command::PowerOptimization, &[0xa1, 0x00])
+ .await?;
+ self.cmd_with_data(spi, Command::PowerOptimization, &[0x73, 0x41])
+ .await?;
// partial display refresh
- self.cmd_with_data(spi, Command::PartialDisplayRefresh, &[0x00])?;
+ self.cmd_with_data(spi, Command::PartialDisplayRefresh, &[0x00])
+ .await?;
// power on
- self.command(spi, Command::PowerOn)?;
- delay.delay_us(5000);
- self.wait_until_idle(spi, delay)?;
+ self.command(spi, Command::PowerOn).await?;
+ delay.delay_us(5000).await;
+ self.wait_until_idle(spi, delay).await?;
// panel setting
- self.cmd_with_data(spi, Command::PanelSetting, &[0xaf])?;
+ self.cmd_with_data(spi, Command::PanelSetting, &[0xaf])
+ .await?;
// pll control
- self.cmd_with_data(spi, Command::PllControl, &[0x3a])?;
+ self.cmd_with_data(spi, Command::PllControl, &[0x3a])
+ .await?;
// vcom and data interval setting
- self.cmd_with_data(spi, Command::VcomAndDataIntervalSetting, &[0x57])?;
+ self.cmd_with_data(spi, Command::VcomAndDataIntervalSetting, &[0x57])
+ .await?;
// cvm dc setting register
- self.cmd_with_data(spi, Command::VcmDcSetting, &[0x12])?;
- self.set_lut(spi, delay, None)?;
- self.wait_until_idle(spi, delay)?;
+ self.cmd_with_data(spi, Command::VcmDcSetting, &[0x12])
+ .await?;
+ self.set_lut(spi, delay, None).await?;
+ self.wait_until_idle(spi, delay).await?;
Ok(())
}
}
+#[maybe_async::maybe_async(AFIT)]
impl WaveshareDisplay
for Epd2in7
where
@@ -103,7 +115,7 @@ where
DELAY: DelayNs,
{
type DisplayColor = Color;
- fn new(
+ async fn new(
spi: &mut SPI,
busy: BUSY,
dc: DC,
@@ -116,42 +128,49 @@ where
let mut epd = Epd2in7 { interface, color };
- epd.init(spi, delay)?;
+ epd.init(spi, delay).await?;
Ok(epd)
}
- fn wake_up(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
- self.init(spi, delay)
+ async fn wake_up(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
+ self.init(spi, delay).await
}
- fn sleep(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
- self.wait_until_idle(spi, delay)?;
+ async fn sleep(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
+ self.wait_until_idle(spi, delay).await?;
self.interface
- .cmd_with_data(spi, Command::VcomAndDataIntervalSetting, &[0xf7])?;
+ .cmd_with_data(spi, Command::VcomAndDataIntervalSetting, &[0xf7])
+ .await?;
- self.command(spi, Command::PowerOff)?;
- self.wait_until_idle(spi, delay)?;
+ self.command(spi, Command::PowerOff).await?;
+ self.wait_until_idle(spi, delay).await?;
self.interface
- .cmd_with_data(spi, Command::DeepSleep, &[0xA5])?;
+ .cmd_with_data(spi, Command::DeepSleep, &[0xA5])
+ .await?;
Ok(())
}
- fn update_frame(
+ async fn update_frame(
&mut self,
spi: &mut SPI,
buffer: &[u8],
_delay: &mut DELAY,
) -> Result<(), SPI::Error> {
- self.interface.cmd(spi, Command::DataStartTransmission1)?;
self.interface
- .data_x_times(spi, self.color.get_byte_value(), WIDTH * HEIGHT / 8)?;
- self.interface.cmd(spi, Command::DataStartTransmission2)?;
- self.send_data(spi, buffer)?;
+ .cmd(spi, Command::DataStartTransmission1)
+ .await?;
+ self.interface
+ .data_x_times(spi, self.color.get_byte_value(), WIDTH * HEIGHT / 8)
+ .await?;
+ self.interface
+ .cmd(spi, Command::DataStartTransmission2)
+ .await?;
+ self.send_data(spi, buffer).await?;
Ok(())
}
- fn update_partial_frame(
+ async fn update_partial_frame(
&mut self,
spi: &mut SPI,
delay: &mut DELAY,
@@ -162,47 +181,54 @@ where
height: u32,
) -> Result<(), SPI::Error> {
self.interface
- .cmd(spi, Command::PartialDataStartTransmission1)?;
-
- self.send_data(spi, &[(x >> 8) as u8])?;
- self.send_data(spi, &[(x & 0xf8) as u8])?;
- self.send_data(spi, &[(y >> 8) as u8])?;
- self.send_data(spi, &[(y & 0xff) as u8])?;
- self.send_data(spi, &[(width >> 8) as u8])?;
- self.send_data(spi, &[(width & 0xf8) as u8])?;
- self.send_data(spi, &[(height >> 8) as u8])?;
- self.send_data(spi, &[(height & 0xff) as u8])?;
- self.wait_until_idle(spi, delay)?;
- self.send_data(spi, buffer)
+ .cmd(spi, Command::PartialDataStartTransmission1)
+ .await?;
+
+ self.send_data(spi, &[(x >> 8) as u8]).await?;
+ self.send_data(spi, &[(x & 0xf8) as u8]).await?;
+ self.send_data(spi, &[(y >> 8) as u8]).await?;
+ self.send_data(spi, &[(y & 0xff) as u8]).await?;
+ self.send_data(spi, &[(width >> 8) as u8]).await?;
+ self.send_data(spi, &[(width & 0xf8) as u8]).await?;
+ self.send_data(spi, &[(height >> 8) as u8]).await?;
+ self.send_data(spi, &[(height & 0xff) as u8]).await?;
+ self.wait_until_idle(spi, delay).await?;
+ self.send_data(spi, buffer).await
}
- fn display_frame(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
- self.command(spi, Command::DisplayRefresh)?;
- self.wait_until_idle(spi, delay)?;
+ async fn display_frame(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
+ self.command(spi, Command::DisplayRefresh).await?;
+ self.wait_until_idle(spi, delay).await?;
Ok(())
}
- fn update_and_display_frame(
+ async fn update_and_display_frame(
&mut self,
spi: &mut SPI,
buffer: &[u8],
delay: &mut DELAY,
) -> Result<(), SPI::Error> {
- self.update_frame(spi, buffer, delay)?;
- self.command(spi, Command::DisplayRefresh)?;
+ self.update_frame(spi, buffer, delay).await?;
+ self.command(spi, Command::DisplayRefresh).await?;
Ok(())
}
- fn clear_frame(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
- self.wait_until_idle(spi, delay)?;
+ async fn clear_frame(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
+ self.wait_until_idle(spi, delay).await?;
let color_value = self.color.get_byte_value();
- self.interface.cmd(spi, Command::DataStartTransmission1)?;
self.interface
- .data_x_times(spi, color_value, WIDTH * HEIGHT / 8)?;
- self.interface.cmd(spi, Command::DataStartTransmission2)?;
+ .cmd(spi, Command::DataStartTransmission1)
+ .await?;
+ self.interface
+ .data_x_times(spi, color_value, WIDTH * HEIGHT / 8)
+ .await?;
+ self.interface
+ .cmd(spi, Command::DataStartTransmission2)
+ .await?;
self.interface
- .data_x_times(spi, color_value, WIDTH * HEIGHT / 8)?;
+ .data_x_times(spi, color_value, WIDTH * HEIGHT / 8)
+ .await?;
Ok(())
}
@@ -222,27 +248,37 @@ where
HEIGHT
}
- fn set_lut(
+ async fn set_lut(
&mut self,
spi: &mut SPI,
delay: &mut DELAY,
_refresh_rate: Option,
) -> Result<(), SPI::Error> {
- self.wait_until_idle(spi, delay)?;
- self.cmd_with_data(spi, Command::LutForVcom, &LUT_VCOM_DC)?;
- self.cmd_with_data(spi, Command::LutWhiteToWhite, &LUT_WW)?;
- self.cmd_with_data(spi, Command::LutBlackToWhite, &LUT_BW)?;
- self.cmd_with_data(spi, Command::LutWhiteToBlack, &LUT_WB)?;
- self.cmd_with_data(spi, Command::LutBlackToBlack, &LUT_BB)?;
+ self.wait_until_idle(spi, delay).await?;
+ self.cmd_with_data(spi, Command::LutForVcom, &LUT_VCOM_DC)
+ .await?;
+ self.cmd_with_data(spi, Command::LutWhiteToWhite, &LUT_WW)
+ .await?;
+ self.cmd_with_data(spi, Command::LutBlackToWhite, &LUT_BW)
+ .await?;
+ self.cmd_with_data(spi, Command::LutWhiteToBlack, &LUT_WB)
+ .await?;
+ self.cmd_with_data(spi, Command::LutBlackToBlack, &LUT_BB)
+ .await?;
Ok(())
}
- fn wait_until_idle(&mut self, _spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
- self.interface.wait_until_idle(delay, IS_BUSY_LOW);
+ async fn wait_until_idle(
+ &mut self,
+ _spi: &mut SPI,
+ delay: &mut DELAY,
+ ) -> Result<(), SPI::Error> {
+ self.interface.wait_until_idle(delay, IS_BUSY_LOW).await;
Ok(())
}
}
+#[maybe_async::maybe_async]
impl Epd2in7
where
SPI: SpiDevice,
@@ -251,21 +287,21 @@ where
RST: OutputPin,
DELAY: DelayNs,
{
- fn command(&mut self, spi: &mut SPI, command: Command) -> Result<(), SPI::Error> {
- self.interface.cmd(spi, command)
+ async fn command(&mut self, spi: &mut SPI, command: Command) -> Result<(), SPI::Error> {
+ self.interface.cmd(spi, command).await
}
- fn send_data(&mut self, spi: &mut SPI, data: &[u8]) -> Result<(), SPI::Error> {
- self.interface.data(spi, data)
+ async fn send_data(&mut self, spi: &mut SPI, data: &[u8]) -> Result<(), SPI::Error> {
+ self.interface.data(spi, data).await
}
- fn cmd_with_data(
+ async fn cmd_with_data(
&mut self,
spi: &mut SPI,
command: Command,
data: &[u8],
) -> Result<(), SPI::Error> {
- self.interface.cmd_with_data(spi, command, data)
+ self.interface.cmd_with_data(spi, command, data).await
}
}
diff --git a/src/epd2in7_v2/mod.rs b/src/epd2in7_v2/mod.rs
index b1687326..6d193e84 100644
--- a/src/epd2in7_v2/mod.rs
+++ b/src/epd2in7_v2/mod.rs
@@ -8,16 +8,12 @@
//! - [Waveshare C driver](https://github.com/waveshareteam/e-Paper/blob/master/RaspberryPi_JetsonNano/c/lib/e-Paper/EPD_2in7_V2.c)
//! - [Waveshare Python driver](https://github.com/waveshareteam/e-Paper/blob/master/RaspberryPi_JetsonNano/python/lib/waveshare_epd/epd2in7_V2.py)
-use embedded_hal::{
- delay::DelayNs,
- digital::{InputPin, OutputPin},
- spi::SpiDevice,
-};
+use embedded_hal::digital::{InputPin, OutputPin};
use crate::{
buffer_len,
color::Color,
- interface::DisplayInterface,
+ interface::{DelayNs, DisplayInterface, SpiDevice},
traits::{InternalWiAdditions, RefreshLut, WaveshareDisplay},
type_a::command::Command,
};
@@ -52,6 +48,7 @@ pub struct Epd2in7 {
refresh: RefreshLut,
}
+#[maybe_async::maybe_async(AFIT)]
impl InternalWiAdditions
for Epd2in7
where
@@ -61,23 +58,25 @@ where
RST: OutputPin,
DELAY: DelayNs,
{
- fn init(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
+ async fn init(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
// reset the device
- self.interface.reset(delay, 200_000, 2_000);
+ self.interface.reset(delay, 200_000, 2_000).await;
- self.wait_until_idle(spi, delay)?;
- self.command(spi, Command::SwReset)?;
- self.wait_until_idle(spi, delay)?;
+ self.wait_until_idle(spi, delay).await?;
+ self.command(spi, Command::SwReset).await?;
+ self.wait_until_idle(spi, delay).await?;
- self.use_full_frame(spi, delay)?;
+ self.use_full_frame(spi, delay).await?;
self.interface
- .cmd_with_data(spi, Command::DataEntryModeSetting, &[0x03])?;
+ .cmd_with_data(spi, Command::DataEntryModeSetting, &[0x03])
+ .await?;
Ok(())
}
}
+#[maybe_async::maybe_async(AFIT)]
impl WaveshareDisplay
for Epd2in7
where
@@ -88,7 +87,7 @@ where
DELAY: DelayNs,
{
type DisplayColor = Color;
- fn new(
+ async fn new(
spi: &mut SPI,
busy: BUSY,
dc: DC,
@@ -105,36 +104,38 @@ where
refresh: RefreshLut::Full,
};
- epd.init(spi, delay)?;
+ epd.init(spi, delay).await?;
Ok(epd)
}
- fn wake_up(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
- self.init(spi, delay)
+ async fn wake_up(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
+ self.init(spi, delay).await
}
- fn sleep(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
- self.wait_until_idle(spi, delay)?;
+ async fn sleep(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
+ self.wait_until_idle(spi, delay).await?;
self.interface
- .cmd_with_data(spi, Command::DeepSleepMode, &[0x01])?;
+ .cmd_with_data(spi, Command::DeepSleepMode, &[0x01])
+ .await?;
Ok(())
}
- fn update_frame(
+ async fn update_frame(
&mut self,
spi: &mut SPI,
buffer: &[u8],
delay: &mut DELAY,
) -> Result<(), SPI::Error> {
- self.wait_until_idle(spi, delay)?;
- self.use_full_frame(spi, delay)?;
+ self.wait_until_idle(spi, delay).await?;
+ self.use_full_frame(spi, delay).await?;
self.interface
- .cmd_with_data(spi, Command::WriteRam, buffer)?;
+ .cmd_with_data(spi, Command::WriteRam, buffer)
+ .await?;
Ok(())
}
- fn update_partial_frame(
+ async fn update_partial_frame(
&mut self,
spi: &mut SPI,
delay: &mut DELAY,
@@ -144,51 +145,55 @@ where
width: u32,
height: u32,
) -> Result<(), SPI::Error> {
- self.wait_until_idle(spi, delay)?;
- self.set_ram_area(spi, x, y, x + width, y + height)?;
- self.set_ram_counter(spi, delay, x, y)?;
+ self.wait_until_idle(spi, delay).await?;
+ self.set_ram_area(spi, x, y, x + width, y + height).await?;
+ self.set_ram_counter(spi, delay, x, y).await?;
self.interface
- .cmd_with_data(spi, Command::WriteRam, buffer)?;
+ .cmd_with_data(spi, Command::WriteRam, buffer)
+ .await?;
Ok(())
}
- fn display_frame(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
- self.wait_until_idle(spi, delay)?;
+ async fn display_frame(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
+ self.wait_until_idle(spi, delay).await?;
if self.refresh == RefreshLut::Full {
self.interface
- .cmd_with_data(spi, Command::DisplayUpdateControl2, &[0xF7])?;
+ .cmd_with_data(spi, Command::DisplayUpdateControl2, &[0xF7])
+ .await?;
} else if self.refresh == RefreshLut::Quick {
self.interface
- .cmd_with_data(spi, Command::DisplayUpdateControl2, &[0xC7])?;
+ .cmd_with_data(spi, Command::DisplayUpdateControl2, &[0xC7])
+ .await?;
}
- self.interface.cmd(spi, Command::MasterActivation)?;
- self.wait_until_idle(spi, delay)?;
+ self.interface.cmd(spi, Command::MasterActivation).await?;
+ self.wait_until_idle(spi, delay).await?;
Ok(())
}
- fn update_and_display_frame(
+ async fn update_and_display_frame(
&mut self,
spi: &mut SPI,
buffer: &[u8],
delay: &mut DELAY,
) -> Result<(), SPI::Error> {
- self.update_frame(spi, buffer, delay)?;
- self.display_frame(spi, delay)?;
+ self.update_frame(spi, buffer, delay).await?;
+ self.display_frame(spi, delay).await?;
Ok(())
}
- fn clear_frame(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
- self.wait_until_idle(spi, delay)?;
- self.use_full_frame(spi, delay)?;
+ async fn clear_frame(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
+ self.wait_until_idle(spi, delay).await?;
+ self.use_full_frame(spi, delay).await?;
let color = self.color.get_byte_value();
- self.interface.cmd(spi, Command::WriteRam)?;
+ self.interface.cmd(spi, Command::WriteRam).await?;
self.interface
- .data_x_times(spi, color, WIDTH / 8 * HEIGHT)?;
+ .data_x_times(spi, color, WIDTH / 8 * HEIGHT)
+ .await?;
Ok(())
}
@@ -209,7 +214,7 @@ where
HEIGHT
}
- fn set_lut(
+ async fn set_lut(
&mut self,
_spi: &mut SPI,
_delay: &mut DELAY,
@@ -221,12 +226,17 @@ where
Ok(())
}
- fn wait_until_idle(&mut self, _spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
- self.interface.wait_until_idle(delay, IS_BUSY_LOW);
+ async fn wait_until_idle(
+ &mut self,
+ _spi: &mut SPI,
+ delay: &mut DELAY,
+ ) -> Result<(), SPI::Error> {
+ self.interface.wait_until_idle(delay, IS_BUSY_LOW).await;
Ok(())
}
}
+#[maybe_async::maybe_async]
impl Epd2in7
where
SPI: SpiDevice,
@@ -235,11 +245,11 @@ where
RST: OutputPin,
DELAY: DelayNs,
{
- fn command(&mut self, spi: &mut SPI, command: Command) -> Result<(), SPI::Error> {
- self.interface.cmd(spi, command)
+ async fn command(&mut self, spi: &mut SPI, command: Command) -> Result<(), SPI::Error> {
+ self.interface.cmd(spi, command).await
}
- fn set_ram_area(
+ async fn set_ram_area(
&mut self,
spi: &mut SPI,
start_x: u32,
@@ -250,50 +260,57 @@ where
assert!(start_x < end_x);
assert!(start_y < end_y);
- self.interface.cmd_with_data(
- spi,
- Command::SetRamXAddressStartEndPosition,
- &[(start_x >> 3) as u8, (end_x >> 3) as u8],
- )?;
-
- self.interface.cmd_with_data(
- spi,
- Command::SetRamYAddressStartEndPosition,
- &[
- (start_y & 0xFF) as u8,
- ((start_y >> 8) & 0x01) as u8,
- (end_y & 0xFF) as u8,
- ((end_y >> 8) & 0x01) as u8,
- ],
- )?;
+ self.interface
+ .cmd_with_data(
+ spi,
+ Command::SetRamXAddressStartEndPosition,
+ &[(start_x >> 3) as u8, (end_x >> 3) as u8],
+ )
+ .await?;
+
+ self.interface
+ .cmd_with_data(
+ spi,
+ Command::SetRamYAddressStartEndPosition,
+ &[
+ (start_y & 0xFF) as u8,
+ ((start_y >> 8) & 0x01) as u8,
+ (end_y & 0xFF) as u8,
+ ((end_y >> 8) & 0x01) as u8,
+ ],
+ )
+ .await?;
Ok(())
}
- fn set_ram_counter(
+ async fn set_ram_counter(
&mut self,
spi: &mut SPI,
delay: &mut DELAY,
x: u32,
y: u32,
) -> Result<(), SPI::Error> {
- self.wait_until_idle(spi, delay)?;
+ self.wait_until_idle(spi, delay).await?;
self.interface
- .cmd_with_data(spi, Command::SetRamXAddressCounter, &[(x & 0xFF) as u8])?;
+ .cmd_with_data(spi, Command::SetRamXAddressCounter, &[(x & 0xFF) as u8])
+ .await?;
- self.interface.cmd_with_data(
- spi,
- Command::SetRamYAddressCounter,
- &[(y & 0xFF) as u8, ((y >> 8) & 0x01) as u8],
- )?;
+ self.interface
+ .cmd_with_data(
+ spi,
+ Command::SetRamYAddressCounter,
+ &[(y & 0xFF) as u8, ((y >> 8) & 0x01) as u8],
+ )
+ .await?;
Ok(())
}
- fn use_full_frame(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
+ async fn use_full_frame(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
// choose full frame/ram
- self.set_ram_area(spi, 0, 0, WIDTH - 1, HEIGHT - 1)?;
+ self.set_ram_area(spi, 0, 0, WIDTH - 1, HEIGHT - 1).await?;
// start from the beginning
- self.set_ram_counter(spi, delay, 0, 0)
+ self.set_ram_counter(spi, delay, 0, 0).await
}
}
diff --git a/src/epd2in7b/mod.rs b/src/epd2in7b/mod.rs
index 42f25f19..2bd73632 100644
--- a/src/epd2in7b/mod.rs
+++ b/src/epd2in7b/mod.rs
@@ -2,9 +2,9 @@
//!
//! [Documentation](https://www.waveshare.com/wiki/2.7inch_e-Paper_HAT_(B))
-use embedded_hal::{delay::*, digital::*, spi::SpiDevice};
+use embedded_hal::digital::*;
-use crate::interface::DisplayInterface;
+use crate::interface::{DelayNs, DisplayInterface, SpiDevice};
use crate::traits::{
InternalWiAdditions, RefreshLut, WaveshareDisplay, WaveshareThreeColorDisplay,
};
@@ -47,6 +47,7 @@ pub struct Epd2in7b {
color: Color,
}
+#[maybe_async::maybe_async(AFIT)]
impl InternalWiAdditions
for Epd2in7b
where
@@ -56,62 +57,72 @@ where
RST: OutputPin,
DELAY: DelayNs,
{
- fn init(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
+ async fn init(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
// reset the device
- self.interface.reset(delay, 10_000, 2_000);
+ self.interface.reset(delay, 10_000, 2_000).await;
// power on
- self.command(spi, Command::PowerOn)?;
- delay.delay_us(5000);
- self.wait_until_idle(spi, delay)?;
+ self.command(spi, Command::PowerOn).await?;
+ delay.delay_us(5000).await;
+ self.wait_until_idle(spi, delay).await?;
// set panel settings, 0xbf is bw, 0xaf is multi-color
self.interface
- .cmd_with_data(spi, Command::PanelSetting, &[0xaf])?;
+ .cmd_with_data(spi, Command::PanelSetting, &[0xaf])
+ .await?;
// pll control
self.interface
- .cmd_with_data(spi, Command::PllControl, &[0x3a])?;
+ .cmd_with_data(spi, Command::PllControl, &[0x3a])
+ .await?;
// set the power settings
- self.interface.cmd_with_data(
- spi,
- Command::PowerSetting,
- &[0x03, 0x00, 0x2b, 0x2b, 0x09],
- )?;
+ self.interface
+ .cmd_with_data(spi, Command::PowerSetting, &[0x03, 0x00, 0x2b, 0x2b, 0x09])
+ .await?;
// start the booster
self.interface
- .cmd_with_data(spi, Command::BoosterSoftStart, &[0x07, 0x07, 0x17])?;
+ .cmd_with_data(spi, Command::BoosterSoftStart, &[0x07, 0x07, 0x17])
+ .await?;
// power optimization
self.interface
- .cmd_with_data(spi, Command::PowerOptimization, &[0x60, 0xa5])?;
+ .cmd_with_data(spi, Command::PowerOptimization, &[0x60, 0xa5])
+ .await?;
self.interface
- .cmd_with_data(spi, Command::PowerOptimization, &[0x89, 0xa5])?;
+ .cmd_with_data(spi, Command::PowerOptimization, &[0x89, 0xa5])
+ .await?;
self.interface
- .cmd_with_data(spi, Command::PowerOptimization, &[0x90, 0x00])?;
+ .cmd_with_data(spi, Command::PowerOptimization, &[0x90, 0x00])
+ .await?;
self.interface
- .cmd_with_data(spi, Command::PowerOptimization, &[0x93, 0x2a])?;
+ .cmd_with_data(spi, Command::PowerOptimization, &[0x93, 0x2a])
+ .await?;
self.interface
- .cmd_with_data(spi, Command::PowerOptimization, &[0x73, 0x41])?;
+ .cmd_with_data(spi, Command::PowerOptimization, &[0x73, 0x41])
+ .await?;
self.interface
- .cmd_with_data(spi, Command::VcmDcSetting, &[0x12])?;
+ .cmd_with_data(spi, Command::VcmDcSetting, &[0x12])
+ .await?;
self.interface
- .cmd_with_data(spi, Command::VcomAndDataIntervalSetting, &[0x87])?;
+ .cmd_with_data(spi, Command::VcomAndDataIntervalSetting, &[0x87])
+ .await?;
- self.set_lut(spi, delay, None)?;
+ self.set_lut(spi, delay, None).await?;
self.interface
- .cmd_with_data(spi, Command::PartialDisplayRefresh, &[0x00])?;
+ .cmd_with_data(spi, Command::PartialDisplayRefresh, &[0x00])
+ .await?;
- self.wait_until_idle(spi, delay)?;
+ self.wait_until_idle(spi, delay).await?;
Ok(())
}
}
+#[maybe_async::maybe_async(AFIT)]
impl WaveshareDisplay
for Epd2in7b
where
@@ -122,7 +133,7 @@ where
DELAY: DelayNs,
{
type DisplayColor = Color;
- fn new(
+ async fn new(
spi: &mut SPI,
busy: BUSY,
dc: DC,
@@ -135,46 +146,53 @@ where
let mut epd = Epd2in7b { interface, color };
- epd.init(spi, delay)?;
+ epd.init(spi, delay).await?;
Ok(epd)
}
- fn wake_up(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
- self.init(spi, delay)
+ async fn wake_up(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
+ self.init(spi, delay).await
}
- fn sleep(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
- self.wait_until_idle(spi, delay)?;
+ async fn sleep(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
+ self.wait_until_idle(spi, delay).await?;
self.interface
- .cmd_with_data(spi, Command::VcomAndDataIntervalSetting, &[0xf7])?;
+ .cmd_with_data(spi, Command::VcomAndDataIntervalSetting, &[0xf7])
+ .await?;
- self.command(spi, Command::PowerOff)?;
- self.wait_until_idle(spi, delay)?;
+ self.command(spi, Command::PowerOff).await?;
+ self.wait_until_idle(spi, delay).await?;
self.interface
- .cmd_with_data(spi, Command::DeepSleep, &[0xA5])?;
+ .cmd_with_data(spi, Command::DeepSleep, &[0xA5])
+ .await?;
Ok(())
}
- fn update_frame(
+ async fn update_frame(
&mut self,
spi: &mut SPI,
buffer: &[u8],
_delay: &mut DELAY,
) -> Result<(), SPI::Error> {
- self.interface.cmd(spi, Command::DataStartTransmission1)?;
- self.send_buffer_helper(spi, buffer)?;
+ self.interface
+ .cmd(spi, Command::DataStartTransmission1)
+ .await?;
+ self.send_buffer_helper(spi, buffer).await?;
// Clear chromatic layer since we won't be using it here
- self.interface.cmd(spi, Command::DataStartTransmission2)?;
self.interface
- .data_x_times(spi, !self.color.get_byte_value(), WIDTH / 8 * HEIGHT)?;
+ .cmd(spi, Command::DataStartTransmission2)
+ .await?;
+ self.interface
+ .data_x_times(spi, !self.color.get_byte_value(), WIDTH / 8 * HEIGHT)
+ .await?;
- self.interface.cmd(spi, Command::DataStop)?;
+ self.interface.cmd(spi, Command::DataStop).await?;
Ok(())
}
- fn update_partial_frame(
+ async fn update_partial_frame(
&mut self,
spi: &mut SPI,
delay: &mut DELAY,
@@ -185,54 +203,61 @@ where
height: u32,
) -> Result<(), SPI::Error> {
self.interface
- .cmd(spi, Command::PartialDataStartTransmission1)?;
-
- self.send_data(spi, &[(x >> 8) as u8])?;
- self.send_data(spi, &[(x & 0xf8) as u8])?;
- self.send_data(spi, &[(y >> 8) as u8])?;
- self.send_data(spi, &[(y & 0xff) as u8])?;
- self.send_data(spi, &[(width >> 8) as u8])?;
- self.send_data(spi, &[(width & 0xf8) as u8])?;
- self.send_data(spi, &[(height >> 8) as u8])?;
- self.send_data(spi, &[(height & 0xff) as u8])?;
- self.wait_until_idle(spi, delay)?;
-
- self.send_buffer_helper(spi, buffer)?;
-
- self.interface.cmd(spi, Command::DataStop)
+ .cmd(spi, Command::PartialDataStartTransmission1)
+ .await?;
+
+ self.send_data(spi, &[(x >> 8) as u8]).await?;
+ self.send_data(spi, &[(x & 0xf8) as u8]).await?;
+ self.send_data(spi, &[(y >> 8) as u8]).await?;
+ self.send_data(spi, &[(y & 0xff) as u8]).await?;
+ self.send_data(spi, &[(width >> 8) as u8]).await?;
+ self.send_data(spi, &[(width & 0xf8) as u8]).await?;
+ self.send_data(spi, &[(height >> 8) as u8]).await?;
+ self.send_data(spi, &[(height & 0xff) as u8]).await?;
+ self.wait_until_idle(spi, delay).await?;
+
+ self.send_buffer_helper(spi, buffer).await?;
+
+ self.interface.cmd(spi, Command::DataStop).await
}
- fn display_frame(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
- self.command(spi, Command::DisplayRefresh)?;
- self.wait_until_idle(spi, delay)?;
+ async fn display_frame(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
+ self.command(spi, Command::DisplayRefresh).await?;
+ self.wait_until_idle(spi, delay).await?;
Ok(())
}
- fn update_and_display_frame(
+ async fn update_and_display_frame(
&mut self,
spi: &mut SPI,
buffer: &[u8],
delay: &mut DELAY,
) -> Result<(), SPI::Error> {
- self.update_frame(spi, buffer, delay)?;
- self.command(spi, Command::DisplayRefresh)?;
+ self.update_frame(spi, buffer, delay).await?;
+ self.command(spi, Command::DisplayRefresh).await?;
Ok(())
}
- fn clear_frame(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
- self.wait_until_idle(spi, delay)?;
+ async fn clear_frame(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
+ self.wait_until_idle(spi, delay).await?;
let color_value = self.color.get_byte_value();
- self.interface.cmd(spi, Command::DataStartTransmission1)?;
self.interface
- .data_x_times(spi, color_value, WIDTH / 8 * HEIGHT)?;
+ .cmd(spi, Command::DataStartTransmission1)
+ .await?;
+ self.interface
+ .data_x_times(spi, color_value, WIDTH / 8 * HEIGHT)
+ .await?;
- self.interface.cmd(spi, Command::DataStop)?;
+ self.interface.cmd(spi, Command::DataStop).await?;
- self.interface.cmd(spi, Command::DataStartTransmission2)?;
self.interface
- .data_x_times(spi, color_value, WIDTH / 8 * HEIGHT)?;
- self.interface.cmd(spi, Command::DataStop)?;
+ .cmd(spi, Command::DataStartTransmission2)
+ .await?;
+ self.interface
+ .data_x_times(spi, color_value, WIDTH / 8 * HEIGHT)
+ .await?;
+ self.interface.cmd(spi, Command::DataStop).await?;
Ok(())
}
@@ -252,27 +277,37 @@ where
HEIGHT
}
- fn set_lut(
+ async fn set_lut(
&mut self,
spi: &mut SPI,
delay: &mut DELAY,
_refresh_rate: Option,
) -> Result<(), SPI::Error> {
- self.wait_until_idle(spi, delay)?;
- self.cmd_with_data(spi, Command::LutForVcom, &LUT_VCOM_DC)?;
- self.cmd_with_data(spi, Command::LutWhiteToWhite, &LUT_WW)?;
- self.cmd_with_data(spi, Command::LutBlackToWhite, &LUT_BW)?;
- self.cmd_with_data(spi, Command::LutWhiteToBlack, &LUT_WB)?;
- self.cmd_with_data(spi, Command::LutBlackToBlack, &LUT_BB)?;
+ self.wait_until_idle(spi, delay).await?;
+ self.cmd_with_data(spi, Command::LutForVcom, &LUT_VCOM_DC)
+ .await?;
+ self.cmd_with_data(spi, Command::LutWhiteToWhite, &LUT_WW)
+ .await?;
+ self.cmd_with_data(spi, Command::LutBlackToWhite, &LUT_BW)
+ .await?;
+ self.cmd_with_data(spi, Command::LutWhiteToBlack, &LUT_WB)
+ .await?;
+ self.cmd_with_data(spi, Command::LutBlackToBlack, &LUT_BB)
+ .await?;
Ok(())
}
- fn wait_until_idle(&mut self, _spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
- self.interface.wait_until_idle(delay, IS_BUSY_LOW);
+ async fn wait_until_idle(
+ &mut self,
+ _spi: &mut SPI,
+ delay: &mut DELAY,
+ ) -> Result<(), SPI::Error> {
+ self.interface.wait_until_idle(delay, IS_BUSY_LOW).await;
Ok(())
}
}
+#[maybe_async::maybe_async(AFIT)]
impl WaveshareThreeColorDisplay
for Epd2in7b
where
@@ -282,53 +317,58 @@ where
RST: OutputPin,
DELAY: DelayNs,
{
- fn update_color_frame(
+ async fn update_color_frame(
&mut self,
spi: &mut SPI,
delay: &mut DELAY,
black: &[u8],
chromatic: &[u8],
) -> Result<(), SPI::Error> {
- self.update_achromatic_frame(spi, delay, black)?;
- self.update_chromatic_frame(spi, delay, chromatic)
+ self.update_achromatic_frame(spi, delay, black).await?;
+ self.update_chromatic_frame(spi, delay, chromatic).await
}
/// Update only the black/white data of the display.
///
/// Finish by calling `update_chromatic_frame`.
- fn update_achromatic_frame(
+ async fn update_achromatic_frame(
&mut self,
spi: &mut SPI,
_delay: &mut DELAY,
achromatic: &[u8],
) -> Result<(), SPI::Error> {
- self.interface.cmd(spi, Command::DataStartTransmission1)?;
+ self.interface
+ .cmd(spi, Command::DataStartTransmission1)
+ .await?;
- self.send_buffer_helper(spi, achromatic)?;
+ self.send_buffer_helper(spi, achromatic).await?;
- self.interface.cmd(spi, Command::DataStop)
+ self.interface.cmd(spi, Command::DataStop).await
}
/// Update only chromatic data of the display.
///
/// This data takes precedence over the black/white data.
- fn update_chromatic_frame(
+ async fn update_chromatic_frame(
&mut self,
spi: &mut SPI,
delay: &mut DELAY,
chromatic: &[u8],
) -> Result<(), SPI::Error> {
- self.interface.cmd(spi, Command::DataStartTransmission2)?;
+ self.interface
+ .cmd(spi, Command::DataStartTransmission2)
+ .await?;
- self.send_buffer_helper(spi, chromatic)?;
+ self.send_buffer_helper(spi, chromatic).await?;
- self.interface.cmd(spi, Command::DataStop)?;
- self.wait_until_idle(spi, delay)?;
+ self.interface.cmd(spi, Command::DataStop).await?;
+ self.wait_until_idle(spi, delay).await?;
Ok(())
}
}
+#[maybe_async::maybe_async]
impl Epd2in7b
where
SPI: SpiDevice,
@@ -337,34 +377,34 @@ where
RST: OutputPin,
DELAY: DelayNs,
{
- fn command(&mut self, spi: &mut SPI, command: Command) -> Result<(), SPI::Error> {
- self.interface.cmd(spi, command)
+ async fn command(&mut self, spi: &mut SPI, command: Command) -> Result<(), SPI::Error> {
+ self.interface.cmd(spi, command).await
}
- fn send_data(&mut self, spi: &mut SPI, data: &[u8]) -> Result<(), SPI::Error> {
- self.interface.data(spi, data)
+ async fn send_data(&mut self, spi: &mut SPI, data: &[u8]) -> Result<(), SPI::Error> {
+ self.interface.data(spi, data).await
}
- fn send_buffer_helper(&mut self, spi: &mut SPI, buffer: &[u8]) -> Result<(), SPI::Error> {
+ async fn send_buffer_helper(&mut self, spi: &mut SPI, buffer: &[u8]) -> Result<(), SPI::Error> {
// Based on the waveshare implementation, all data for color values is flipped. This helper
// method makes that transmission easier
for b in buffer.iter() {
- self.send_data(spi, &[!b])?;
+ self.send_data(spi, &[!b]).await?;
}
Ok(())
}
- fn cmd_with_data(
+ async fn cmd_with_data(
&mut self,
spi: &mut SPI,
command: Command,
data: &[u8],
) -> Result<(), SPI::Error> {
- self.interface.cmd_with_data(spi, command, data)
+ self.interface.cmd_with_data(spi, command, data).await
}
/// Refresh display for partial frame
- pub fn display_partial_frame(
+ pub async fn display_partial_frame(
&mut self,
spi: &mut SPI,
delay: &mut DELAY,
@@ -373,22 +413,22 @@ where
width: u32,
height: u32,
) -> Result<(), SPI::Error> {
- self.command(spi, Command::PartialDisplayRefresh)?;
- self.send_data(spi, &[(x >> 8) as u8])?;
- self.send_data(spi, &[(x & 0xf8) as u8])?;
- self.send_data(spi, &[(y >> 8) as u8])?;
- self.send_data(spi, &[(y & 0xff) as u8])?;
- self.send_data(spi, &[(width >> 8) as u8])?;
- self.send_data(spi, &[(width & 0xf8) as u8])?;
- self.send_data(spi, &[(height >> 8) as u8])?;
- self.send_data(spi, &[(height & 0xff) as u8])?;
- self.wait_until_idle(spi, delay)?;
+ self.command(spi, Command::PartialDisplayRefresh).await?;
+ self.send_data(spi, &[(x >> 8) as u8]).await?;
+ self.send_data(spi, &[(x & 0xf8) as u8]).await?;
+ self.send_data(spi, &[(y >> 8) as u8]).await?;
+ self.send_data(spi, &[(y & 0xff) as u8]).await?;
+ self.send_data(spi, &[(width >> 8) as u8]).await?;
+ self.send_data(spi, &[(width & 0xf8) as u8]).await?;
+ self.send_data(spi, &[(height >> 8) as u8]).await?;
+ self.send_data(spi, &[(height & 0xff) as u8]).await?;
+ self.wait_until_idle(spi, delay).await?;
Ok(())
}
/// Update black/achromatic frame
#[allow(clippy::too_many_arguments)]
- pub fn update_partial_achromatic_frame(
+ pub async fn update_partial_achromatic_frame(
&mut self,
spi: &mut SPI,
delay: &mut DELAY,
@@ -399,20 +439,21 @@ where
height: u32,
) -> Result<(), SPI::Error> {
self.interface
- .cmd(spi, Command::PartialDataStartTransmission1)?;
- self.send_data(spi, &[(x >> 8) as u8])?;
- self.send_data(spi, &[(x & 0xf8) as u8])?;
- self.send_data(spi, &[(y >> 8) as u8])?;
- self.send_data(spi, &[(y & 0xff) as u8])?;
- self.send_data(spi, &[(width >> 8) as u8])?;
- self.send_data(spi, &[(width & 0xf8) as u8])?;
- self.send_data(spi, &[(height >> 8) as u8])?;
- self.send_data(spi, &[(height & 0xff) as u8])?;
- self.wait_until_idle(spi, delay)?;
+ .cmd(spi, Command::PartialDataStartTransmission1)
+ .await?;
+ self.send_data(spi, &[(x >> 8) as u8]).await?;
+ self.send_data(spi, &[(x & 0xf8) as u8]).await?;
+ self.send_data(spi, &[(y >> 8) as u8]).await?;
+ self.send_data(spi, &[(y & 0xff) as u8]).await?;
+ self.send_data(spi, &[(width >> 8) as u8]).await?;
+ self.send_data(spi, &[(width & 0xf8) as u8]).await?;
+ self.send_data(spi, &[(height >> 8) as u8]).await?;
+ self.send_data(spi, &[(height & 0xff) as u8]).await?;
+ self.wait_until_idle(spi, delay).await?;
for b in achromatic.iter() {
// Flipping based on waveshare implementation
- self.send_data(spi, &[!b])?;
+ self.send_data(spi, &[!b]).await?;
}
Ok(())
@@ -420,7 +461,7 @@ where
/// Update partial chromatic/red frame
#[allow(clippy::too_many_arguments)]
- pub fn update_partial_chromatic_frame(
+ pub async fn update_partial_chromatic_frame(
&mut self,
spi: &mut SPI,
delay: &mut DELAY,
@@ -431,20 +472,21 @@ where
height: u32,
) -> Result<(), SPI::Error> {
self.interface
- .cmd(spi, Command::PartialDataStartTransmission2)?;
- self.send_data(spi, &[(x >> 8) as u8])?;
- self.send_data(spi, &[(x & 0xf8) as u8])?;
- self.send_data(spi, &[(y >> 8) as u8])?;
- self.send_data(spi, &[(y & 0xff) as u8])?;
- self.send_data(spi, &[(width >> 8) as u8])?;
- self.send_data(spi, &[(width & 0xf8) as u8])?;
- self.send_data(spi, &[(height >> 8) as u8])?;
- self.send_data(spi, &[(height & 0xff) as u8])?;
- self.wait_until_idle(spi, delay)?;
+ .cmd(spi, Command::PartialDataStartTransmission2)
+ .await?;
+ self.send_data(spi, &[(x >> 8) as u8]).await?;
+ self.send_data(spi, &[(x & 0xf8) as u8]).await?;
+ self.send_data(spi, &[(y >> 8) as u8]).await?;
+ self.send_data(spi, &[(y & 0xff) as u8]).await?;
+ self.send_data(spi, &[(width >> 8) as u8]).await?;
+ self.send_data(spi, &[(width & 0xf8) as u8]).await?;
+ self.send_data(spi, &[(height >> 8) as u8]).await?;
+ self.send_data(spi, &[(height & 0xff) as u8]).await?;
+ self.wait_until_idle(spi, delay).await?;
for b in chromatic.iter() {
// Flipping based on waveshare implementation
- self.send_data(spi, &[!b])?;
+ self.send_data(spi, &[!b]).await?;
}
Ok(())
diff --git a/src/epd2in9/mod.rs b/src/epd2in9/mod.rs
index 0ad3d771..8cb3ae35 100644
--- a/src/epd2in9/mod.rs
+++ b/src/epd2in9/mod.rs
@@ -50,7 +50,7 @@ pub const DEFAULT_BACKGROUND_COLOR: Color = Color::White;
const IS_BUSY_LOW: bool = false;
const SINGLE_BYTE_WRITE: bool = true;
-use embedded_hal::{delay::*, digital::*, spi::SpiDevice};
+use embedded_hal::digital::*;
use crate::type_a::{
command::Command,
@@ -62,7 +62,7 @@ use crate::color::Color;
use crate::traits::*;
use crate::buffer_len;
-use crate::interface::DisplayInterface;
+use crate::interface::{DelayNs, DisplayInterface, SpiDevice};
/// Display with Fullsize buffer for use with the 2in9 EPD
#[cfg(feature = "graphics")]
@@ -85,6 +85,7 @@ pub struct Epd2in9 {
refresh: RefreshLut,
}
+#[maybe_async::maybe_async]
impl Epd2in9
where
SPI: SpiDevice,
@@ -93,10 +94,10 @@ where
RST: OutputPin,
DELAY: DelayNs,
{
- fn init(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
- self.interface.reset(delay, 10_000, 10_000);
+ async fn init(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
+ self.interface.reset(delay, 10_000, 10_000).await;
- self.wait_until_idle(spi, delay)?;
+ self.wait_until_idle(spi, delay).await?;
// 3 Databytes:
// A[7:0]
@@ -104,7 +105,8 @@ where
// 0.. B[2:0]
// Default Values: A = Height of Screen (0x127), B = 0x00 (GD, SM and TB=0?)
self.interface
- .cmd_with_data(spi, Command::DriverOutputControl, &[0x27, 0x01, 0x00])?;
+ .cmd_with_data(spi, Command::DriverOutputControl, &[0x27, 0x01, 0x00])
+ .await?;
// 3 Databytes: (and default values from datasheet and arduino)
// 1 .. A[6:0] = 0xCF | 0xD7
@@ -112,29 +114,35 @@ where
// 1 .. C[6:0] = 0x8D | 0x9D
//TODO: test
self.interface
- .cmd_with_data(spi, Command::BoosterSoftStartControl, &[0xD7, 0xD6, 0x9D])?;
+ .cmd_with_data(spi, Command::BoosterSoftStartControl, &[0xD7, 0xD6, 0x9D])
+ .await?;
// One Databyte with value 0xA8 for 7V VCOM
self.interface
- .cmd_with_data(spi, Command::WriteVcomRegister, &[0xA8])?;
+ .cmd_with_data(spi, Command::WriteVcomRegister, &[0xA8])
+ .await?;
// One Databyte with default value 0x1A for 4 dummy lines per gate
self.interface
- .cmd_with_data(spi, Command::SetDummyLinePeriod, &[0x1A])?;
+ .cmd_with_data(spi, Command::SetDummyLinePeriod, &[0x1A])
+ .await?;
// One Databyte with default value 0x08 for 2us per line
self.interface
- .cmd_with_data(spi, Command::SetGateLineWidth, &[0x08])?;
+ .cmd_with_data(spi, Command::SetGateLineWidth, &[0x08])
+ .await?;
// One Databyte with default value 0x03
// -> address: x increment, y increment, address counter is updated in x direction
self.interface
- .cmd_with_data(spi, Command::DataEntryModeSetting, &[0x03])?;
+ .cmd_with_data(spi, Command::DataEntryModeSetting, &[0x03])
+ .await?;
- self.set_lut(spi, delay, None)
+ self.set_lut(spi, delay, None).await
}
}
+#[maybe_async::maybe_async(AFIT)]
impl WaveshareDisplay
for Epd2in9
where
@@ -153,7 +161,7 @@ where
HEIGHT
}
- fn new(
+ async fn new(
spi: &mut SPI,
busy: BUSY,
dc: DC,
@@ -169,42 +177,44 @@ where
refresh: RefreshLut::Full,
};
- epd.init(spi, delay)?;
+ epd.init(spi, delay).await?;
Ok(epd)
}
- fn sleep(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
- self.wait_until_idle(spi, delay)?;
+ async fn sleep(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
+ self.wait_until_idle(spi, delay).await?;
// 0x00 for Normal mode (Power on Reset), 0x01 for Deep Sleep Mode
//TODO: is 0x00 needed here? (see also epd1in54)
self.interface
- .cmd_with_data(spi, Command::DeepSleepMode, &[0x00])?;
+ .cmd_with_data(spi, Command::DeepSleepMode, &[0x00])
+ .await?;
Ok(())
}
- fn wake_up(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
- self.wait_until_idle(spi, delay)?;
- self.init(spi, delay)?;
+ async fn wake_up(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
+ self.wait_until_idle(spi, delay).await?;
+ self.init(spi, delay).await?;
Ok(())
}
- fn update_frame(
+ async fn update_frame(
&mut self,
spi: &mut SPI,
buffer: &[u8],
delay: &mut DELAY,
) -> Result<(), SPI::Error> {
- self.wait_until_idle(spi, delay)?;
- self.use_full_frame(spi, delay)?;
+ self.wait_until_idle(spi, delay).await?;
+ self.use_full_frame(spi, delay).await?;
self.interface
- .cmd_with_data(spi, Command::WriteRam, buffer)?;
+ .cmd_with_data(spi, Command::WriteRam, buffer)
+ .await?;
Ok(())
}
//TODO: update description: last 3 bits will be ignored for width and x_pos
- fn update_partial_frame(
+ async fn update_partial_frame(
&mut self,
spi: &mut SPI,
delay: &mut DELAY,
@@ -214,50 +224,53 @@ where
width: u32,
height: u32,
) -> Result<(), SPI::Error> {
- self.wait_until_idle(spi, delay)?;
- self.set_ram_area(spi, x, y, x + width, y + height)?;
- self.set_ram_counter(spi, delay, x, y)?;
+ self.wait_until_idle(spi, delay).await?;
+ self.set_ram_area(spi, x, y, x + width, y + height).await?;
+ self.set_ram_counter(spi, delay, x, y).await?;
self.interface
- .cmd_with_data(spi, Command::WriteRam, buffer)?;
+ .cmd_with_data(spi, Command::WriteRam, buffer)
+ .await?;
Ok(())
}
- fn display_frame(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
- self.wait_until_idle(spi, delay)?;
+ async fn display_frame(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
+ self.wait_until_idle(spi, delay).await?;
// enable clock signal, enable cp, display pattern -> 0xC4 (tested with the arduino version)
//TODO: test control_1 or control_2 with default value 0xFF (from the datasheet)
self.interface
- .cmd_with_data(spi, Command::DisplayUpdateControl2, &[0xC4])?;
+ .cmd_with_data(spi, Command::DisplayUpdateControl2, &[0xC4])
+ .await?;
- self.interface.cmd(spi, Command::MasterActivation)?;
+ self.interface.cmd(spi, Command::MasterActivation).await?;
// MASTER Activation should not be interupted to avoid currption of panel images
// therefore a terminate command is send
- self.interface.cmd(spi, Command::Nop)?;
+ self.interface.cmd(spi, Command::Nop).await?;
Ok(())
}
- fn update_and_display_frame(
+ async fn update_and_display_frame(
&mut self,
spi: &mut SPI,
buffer: &[u8],
delay: &mut DELAY,
) -> Result<(), SPI::Error> {
- self.update_frame(spi, buffer, delay)?;
- self.display_frame(spi, delay)?;
+ self.update_frame(spi, buffer, delay).await?;
+ self.display_frame(spi, delay).await?;
Ok(())
}
- fn clear_frame(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
- self.wait_until_idle(spi, delay)?;
- self.use_full_frame(spi, delay)?;
+ async fn clear_frame(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
+ self.wait_until_idle(spi, delay).await?;
+ self.use_full_frame(spi, delay).await?;
// clear the ram with the background color
let color = self.background_color.get_byte_value();
- self.interface.cmd(spi, Command::WriteRam)?;
+ self.interface.cmd(spi, Command::WriteRam).await?;
self.interface
- .data_x_times(spi, color, WIDTH / 8 * HEIGHT)?;
+ .data_x_times(spi, color, WIDTH / 8 * HEIGHT)
+ .await?;
Ok(())
}
@@ -269,7 +282,7 @@ where
&self.background_color
}
- fn set_lut(
+ async fn set_lut(
&mut self,
spi: &mut SPI,
delay: &mut DELAY,
@@ -282,14 +295,20 @@ where
RefreshLut::Full => self.set_lut_helper(spi, delay, &LUT_FULL_UPDATE),
RefreshLut::Quick => self.set_lut_helper(spi, delay, &LUT_PARTIAL_UPDATE),
}
+ .await
}
- fn wait_until_idle(&mut self, _spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
- self.interface.wait_until_idle(delay, IS_BUSY_LOW);
+ async fn wait_until_idle(
+ &mut self,
+ _spi: &mut SPI,
+ delay: &mut DELAY,
+ ) -> Result<(), SPI::Error> {
+ self.interface.wait_until_idle(delay, IS_BUSY_LOW).await;
Ok(())
}
}
+#[maybe_async::maybe_async]
impl Epd2in9
where
SPI: SpiDevice,
@@ -298,15 +317,15 @@ where
RST: OutputPin,
DELAY: DelayNs,
{
- fn use_full_frame(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
+ async fn use_full_frame(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
// choose full frame/ram
- self.set_ram_area(spi, 0, 0, WIDTH - 1, HEIGHT - 1)?;
+ self.set_ram_area(spi, 0, 0, WIDTH - 1, HEIGHT - 1).await?;
// start from the beginning
- self.set_ram_counter(spi, delay, 0, 0)
+ self.set_ram_counter(spi, delay, 0, 0).await
}
- fn set_ram_area(
+ async fn set_ram_area(
&mut self,
spi: &mut SPI,
start_x: u32,
@@ -319,58 +338,66 @@ where
// x is positioned in bytes, so the last 3 bits which show the position inside a byte in the ram
// aren't relevant
- self.interface.cmd_with_data(
- spi,
- Command::SetRamXAddressStartEndPosition,
- &[(start_x >> 3) as u8, (end_x >> 3) as u8],
- )?;
+ self.interface
+ .cmd_with_data(
+ spi,
+ Command::SetRamXAddressStartEndPosition,
+ &[(start_x >> 3) as u8, (end_x >> 3) as u8],
+ )
+ .await?;
// 2 Databytes: A[7:0] & 0..A[8] for each - start and end
- self.interface.cmd_with_data(
- spi,
- Command::SetRamYAddressStartEndPosition,
- &[
- start_y as u8,
- (start_y >> 8) as u8,
- end_y as u8,
- (end_y >> 8) as u8,
- ],
- )
+ self.interface
+ .cmd_with_data(
+ spi,
+ Command::SetRamYAddressStartEndPosition,
+ &[
+ start_y as u8,
+ (start_y >> 8) as u8,
+ end_y as u8,
+ (end_y >> 8) as u8,
+ ],
+ )
+ .await
}
- fn set_ram_counter(
+ async fn set_ram_counter(
&mut self,
spi: &mut SPI,
delay: &mut DELAY,
x: u32,
y: u32,
) -> Result<(), SPI::Error> {
- self.wait_until_idle(spi, delay)?;
+ self.wait_until_idle(spi, delay).await?;
// x is positioned in bytes, so the last 3 bits which show the position inside a byte in the ram
// aren't relevant
self.interface
- .cmd_with_data(spi, Command::SetRamXAddressCounter, &[(x >> 3) as u8])?;
+ .cmd_with_data(spi, Command::SetRamXAddressCounter, &[(x >> 3) as u8])
+ .await?;
// 2 Databytes: A[7:0] & 0..A[8]
- self.interface.cmd_with_data(
- spi,
- Command::SetRamYAddressCounter,
- &[y as u8, (y >> 8) as u8],
- )?;
+ self.interface
+ .cmd_with_data(
+ spi,
+ Command::SetRamYAddressCounter,
+ &[y as u8, (y >> 8) as u8],
+ )
+ .await?;
Ok(())
}
/// Set your own LUT, this function is also used internally for set_lut
- fn set_lut_helper(
+ async fn set_lut_helper(
&mut self,
spi: &mut SPI,
delay: &mut DELAY,
buffer: &[u8],
) -> Result<(), SPI::Error> {
- self.wait_until_idle(spi, delay)?;
+ self.wait_until_idle(spi, delay).await?;
assert!(buffer.len() == 30);
self.interface
- .cmd_with_data(spi, Command::WriteLutRegister, buffer)?;
+ .cmd_with_data(spi, Command::WriteLutRegister, buffer)
+ .await?;
Ok(())
}
}
diff --git a/src/epd2in9_v2/mod.rs b/src/epd2in9_v2/mod.rs
index df466cba..f92ba742 100644
--- a/src/epd2in9_v2/mod.rs
+++ b/src/epd2in9_v2/mod.rs
@@ -87,7 +87,7 @@ const WS_20_30: [u8; 159] = [
0x44, 0x44, 0x0, 0x0, 0x0, 0x22, 0x17, 0x41, 0x0, 0x32, 0x36,
];
-use embedded_hal::{delay::*, digital::*, spi::SpiDevice};
+use embedded_hal::digital::*;
use crate::type_a::command::Command;
@@ -96,7 +96,7 @@ use crate::color::Color;
use crate::traits::*;
use crate::buffer_len;
-use crate::interface::DisplayInterface;
+use crate::interface::{DelayNs, DisplayInterface, SpiDevice};
use crate::traits::QuickRefresh;
/// Display with Fullsize buffer for use with the 2in9 EPD V2
@@ -120,6 +120,7 @@ pub struct Epd2in9 {
refresh: RefreshLut,
}
+#[maybe_async::maybe_async]
impl Epd2in9
where
SPI: SpiDevice,
@@ -128,12 +129,12 @@ where
RST: OutputPin,
DELAY: DelayNs,
{
- fn init(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
- self.interface.reset(delay, 10_000, 2_000);
+ async fn init(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
+ self.interface.reset(delay, 10_000, 2_000).await;
- self.wait_until_idle(spi, delay)?;
- self.interface.cmd(spi, Command::SwReset)?;
- self.wait_until_idle(spi, delay)?;
+ self.wait_until_idle(spi, delay).await?;
+ self.interface.cmd(spi, Command::SwReset).await?;
+ self.wait_until_idle(spi, delay).await?;
// 3 Databytes:
// A[7:0]
@@ -141,37 +142,45 @@ where
// 0.. B[2:0]
// Default Values: A = Height of Screen (0x127), B = 0x00 (GD, SM and TB=0?)
self.interface
- .cmd_with_data(spi, Command::DriverOutputControl, &[0x27, 0x01, 0x00])?;
+ .cmd_with_data(spi, Command::DriverOutputControl, &[0x27, 0x01, 0x00])
+ .await?;
// One Databyte with default value 0x03
// -> address: x increment, y increment, address counter is updated in x direction
self.interface
- .cmd_with_data(spi, Command::DataEntryModeSetting, &[0x03])?;
+ .cmd_with_data(spi, Command::DataEntryModeSetting, &[0x03])
+ .await?;
- self.set_ram_area(spi, 0, 0, WIDTH - 1, HEIGHT - 1)?;
+ self.set_ram_area(spi, 0, 0, WIDTH - 1, HEIGHT - 1).await?;
self.interface
- .cmd_with_data(spi, Command::DisplayUpdateControl1, &[0x00, 0x80])?;
+ .cmd_with_data(spi, Command::DisplayUpdateControl1, &[0x00, 0x80])
+ .await?;
- self.set_ram_counter(spi, delay, 0, 0)?;
+ self.set_ram_counter(spi, delay, 0, 0).await?;
- self.wait_until_idle(spi, delay)?;
+ self.wait_until_idle(spi, delay).await?;
// set LUT by host
- self.set_lut_helper(spi, delay, &WS_20_30[0..153])?;
+ self.set_lut_helper(spi, delay, &WS_20_30[0..153]).await?;
self.interface
- .cmd_with_data(spi, Command::WriteLutRegisterEnd, &WS_20_30[153..154])?;
+ .cmd_with_data(spi, Command::WriteLutRegisterEnd, &WS_20_30[153..154])
+ .await?;
self.interface
- .cmd_with_data(spi, Command::GateDrivingVoltage, &WS_20_30[154..155])?;
+ .cmd_with_data(spi, Command::GateDrivingVoltage, &WS_20_30[154..155])
+ .await?;
self.interface
- .cmd_with_data(spi, Command::SourceDrivingVoltage, &WS_20_30[155..158])?;
+ .cmd_with_data(spi, Command::SourceDrivingVoltage, &WS_20_30[155..158])
+ .await?;
self.interface
- .cmd_with_data(spi, Command::WriteVcomRegister, &WS_20_30[158..159])?;
+ .cmd_with_data(spi, Command::WriteVcomRegister, &WS_20_30[158..159])
+ .await?;
Ok(())
}
}
+#[maybe_async::maybe_async(AFIT)]
impl WaveshareDisplay
for Epd2in9
where
@@ -190,7 +199,7 @@ where
HEIGHT
}
- fn new(
+ async fn new(
spi: &mut SPI,
busy: BUSY,
dc: DC,
@@ -206,35 +215,38 @@ where
refresh: RefreshLut::Full,
};
- epd.init(spi, delay)?;
+ epd.init(spi, delay).await?;
Ok(epd)
}
- fn sleep(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
- self.wait_until_idle(spi, delay)?;
+ async fn sleep(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
+ self.wait_until_idle(spi, delay).await?;
// 0x00 for Normal mode (Power on Reset), 0x01 for Deep Sleep Mode
self.interface
- .cmd_with_data(spi, Command::DeepSleepMode, &[0x01])?;
+ .cmd_with_data(spi, Command::DeepSleepMode, &[0x01])
+ .await?;
Ok(())
}
- fn wake_up(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
- self.init(spi, delay)?;
+ async fn wake_up(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
+ self.init(spi, delay).await?;
Ok(())
}
- fn update_frame(
+ async fn update_frame(
&mut self,
spi: &mut SPI,
buffer: &[u8],
delay: &mut DELAY,
) -> Result<(), SPI::Error> {
- self.wait_until_idle(spi, delay)?;
- self.interface.cmd_with_data(spi, Command::WriteRam, buffer)
+ self.wait_until_idle(spi, delay).await?;
+ self.interface
+ .cmd_with_data(spi, Command::WriteRam, buffer)
+ .await
}
- fn update_partial_frame(
+ async fn update_partial_frame(
&mut self,
spi: &mut SPI,
delay: &mut DELAY,
@@ -245,48 +257,53 @@ where
height: u32,
) -> Result<(), SPI::Error> {
//TODO This is copied from epd2in9 but it seems not working. Partial refresh supported by version 2?
- self.wait_until_idle(spi, delay)?;
- self.set_ram_area(spi, x, y, x + width, y + height)?;
- self.set_ram_counter(spi, delay, x, y)?;
+ self.wait_until_idle(spi, delay).await?;
+ self.set_ram_area(spi, x, y, x + width, y + height).await?;
+ self.set_ram_counter(spi, delay, x, y).await?;
self.interface
- .cmd_with_data(spi, Command::WriteRam, buffer)?;
+ .cmd_with_data(spi, Command::WriteRam, buffer)
+ .await?;
Ok(())
}
/// actually is the "Turn on Display" sequence
- fn display_frame(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
- self.wait_until_idle(spi, delay)?;
+ async fn display_frame(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
+ self.wait_until_idle(spi, delay).await?;
// Enable clock signal, Enable Analog, Load temperature value, DISPLAY with DISPLAY Mode 1, Disable Analog, Disable OSC
self.interface
- .cmd_with_data(spi, Command::DisplayUpdateControl2, &[0xC7])?;
- self.interface.cmd(spi, Command::MasterActivation)?;
- self.wait_until_idle(spi, delay)?;
+ .cmd_with_data(spi, Command::DisplayUpdateControl2, &[0xC7])
+ .await?;
+ self.interface.cmd(spi, Command::MasterActivation).await?;
+ self.wait_until_idle(spi, delay).await?;
Ok(())
}
- fn update_and_display_frame(
+ async fn update_and_display_frame(
&mut self,
spi: &mut SPI,
buffer: &[u8],
delay: &mut DELAY,
) -> Result<(), SPI::Error> {
- self.update_frame(spi, buffer, delay)?;
- self.display_frame(spi, delay)?;
+ self.update_frame(spi, buffer, delay).await?;
+ self.display_frame(spi, delay).await?;
Ok(())
}
- fn clear_frame(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
- self.wait_until_idle(spi, delay)?;
+ async fn clear_frame(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
+ self.wait_until_idle(spi, delay).await?;
// clear the ram with the background color
let color = self.background_color.get_byte_value();
- self.interface.cmd(spi, Command::WriteRam)?;
+ self.interface.cmd(spi, Command::WriteRam).await?;
+ self.interface
+ .data_x_times(spi, color, WIDTH / 8 * HEIGHT)
+ .await?;
+ self.interface.cmd(spi, Command::WriteRam2).await?;
self.interface
- .data_x_times(spi, color, WIDTH / 8 * HEIGHT)?;
- self.interface.cmd(spi, Command::WriteRam2)?;
- self.interface.data_x_times(spi, color, WIDTH / 8 * HEIGHT)
+ .data_x_times(spi, color, WIDTH / 8 * HEIGHT)
+ .await
}
fn set_background_color(&mut self, background_color: Color) {
@@ -297,7 +314,7 @@ where
&self.background_color
}
- fn set_lut(
+ async fn set_lut(
&mut self,
_spi: &mut SPI,
_delay: &mut DELAY,
@@ -309,12 +326,17 @@ where
Ok(())
}
- fn wait_until_idle(&mut self, _spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
- self.interface.wait_until_idle(delay, IS_BUSY_LOW);
+ async fn wait_until_idle(
+ &mut self,
+ _spi: &mut SPI,
+ delay: &mut DELAY,
+ ) -> Result<(), SPI::Error> {
+ self.interface.wait_until_idle(delay, IS_BUSY_LOW).await;
Ok(())
}
}
+#[maybe_async::maybe_async]
impl Epd2in9
where
SPI: SpiDevice,
@@ -323,15 +345,15 @@ where
RST: OutputPin,
DELAY: DelayNs,
{
- fn use_full_frame(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
+ async fn use_full_frame(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
// choose full frame/ram
- self.set_ram_area(spi, 0, 0, WIDTH - 1, HEIGHT - 1)?;
+ self.set_ram_area(spi, 0, 0, WIDTH - 1, HEIGHT - 1).await?;
// start from the beginning
- self.set_ram_counter(spi, delay, 0, 0)
+ self.set_ram_counter(spi, delay, 0, 0).await
}
- fn set_ram_area(
+ async fn set_ram_area(
&mut self,
spi: &mut SPI,
start_x: u32,
@@ -344,62 +366,71 @@ where
// x is positioned in bytes, so the last 3 bits which show the position inside a byte in the ram
// aren't relevant
- self.interface.cmd_with_data(
- spi,
- Command::SetRamXAddressStartEndPosition,
- &[(start_x >> 3) as u8, (end_x >> 3) as u8],
- )?;
+ self.interface
+ .cmd_with_data(
+ spi,
+ Command::SetRamXAddressStartEndPosition,
+ &[(start_x >> 3) as u8, (end_x >> 3) as u8],
+ )
+ .await?;
// 2 Databytes: A[7:0] & 0..A[8] for each - start and end
- self.interface.cmd_with_data(
- spi,
- Command::SetRamYAddressStartEndPosition,
- &[
- start_y as u8,
- (start_y >> 8) as u8,
- end_y as u8,
- (end_y >> 8) as u8,
- ],
- )
+ self.interface
+ .cmd_with_data(
+ spi,
+ Command::SetRamYAddressStartEndPosition,
+ &[
+ start_y as u8,
+ (start_y >> 8) as u8,
+ end_y as u8,
+ (end_y >> 8) as u8,
+ ],
+ )
+ .await
}
- fn set_ram_counter(
+ async fn set_ram_counter(
&mut self,
spi: &mut SPI,
delay: &mut DELAY,
x: u32,
y: u32,
) -> Result<(), SPI::Error> {
- self.wait_until_idle(spi, delay)?;
+ self.wait_until_idle(spi, delay).await?;
// x is positioned in bytes, so the last 3 bits which show the position inside a byte in the ram
// aren't relevant
self.interface
- .cmd_with_data(spi, Command::SetRamXAddressCounter, &[x as u8])?;
+ .cmd_with_data(spi, Command::SetRamXAddressCounter, &[x as u8])
+ .await?;
// 2 Databytes: A[7:0] & 0..A[8]
- self.interface.cmd_with_data(
- spi,
- Command::SetRamYAddressCounter,
- &[y as u8, (y >> 8) as u8],
- )?;
+ self.interface
+ .cmd_with_data(
+ spi,
+ Command::SetRamYAddressCounter,
+ &[y as u8, (y >> 8) as u8],
+ )
+ .await?;
Ok(())
}
/// Set your own LUT, this function is also used internally for set_lut
- fn set_lut_helper(
+ async fn set_lut_helper(
&mut self,
spi: &mut SPI,
delay: &mut DELAY,
buffer: &[u8],
) -> Result<(), SPI::Error> {
- self.wait_until_idle(spi, delay)?;
+ self.wait_until_idle(spi, delay).await?;
self.interface
- .cmd_with_data(spi, Command::WriteLutRegister, buffer)?;
- self.wait_until_idle(spi, delay)?;
+ .cmd_with_data(spi, Command::WriteLutRegister, buffer)
+ .await?;
+ self.wait_until_idle(spi, delay).await?;
Ok(())
}
}
+#[maybe_async::maybe_async(AFIT)]
impl QuickRefresh
for Epd2in9
where
@@ -410,75 +441,87 @@ where
DELAY: DelayNs,
{
/// To be followed immediately by `update_new_frame`.
- fn update_old_frame(
+ async fn update_old_frame(
&mut self,
spi: &mut SPI,
buffer: &[u8],
delay: &mut DELAY,
) -> Result<(), SPI::Error> {
- self.wait_until_idle(spi, delay)?;
+ self.wait_until_idle(spi, delay).await?;
self.interface
- .cmd_with_data(spi, Command::WriteRam, buffer)?;
+ .cmd_with_data(spi, Command::WriteRam, buffer)
+ .await?;
self.interface
.cmd_with_data(spi, Command::WriteRam2, buffer)
+ .await
}
/// To be used immediately after `update_old_frame`.
- fn update_new_frame(
+ async fn update_new_frame(
&mut self,
spi: &mut SPI,
buffer: &[u8],
delay: &mut DELAY,
) -> Result<(), SPI::Error> {
- self.wait_until_idle(spi, delay)?;
- self.interface.reset(delay, 10_000, 2_000);
-
- self.set_lut_helper(spi, delay, &LUT_PARTIAL_2IN9)?;
- self.interface.cmd_with_data(
- spi,
- Command::WriteOtpSelection,
- &[0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00],
- )?;
+ self.wait_until_idle(spi, delay).await?;
+ self.interface.reset(delay, 10_000, 2_000).await;
+
+ self.set_lut_helper(spi, delay, &LUT_PARTIAL_2IN9).await?;
self.interface
- .cmd_with_data(spi, Command::BorderWaveformControl, &[0x80])?;
+ .cmd_with_data(
+ spi,
+ Command::WriteOtpSelection,
+ &[0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00],
+ )
+ .await?;
self.interface
- .cmd_with_data(spi, Command::DisplayUpdateControl2, &[0xC0])?;
- self.interface.cmd(spi, Command::MasterActivation)?;
+ .cmd_with_data(spi, Command::BorderWaveformControl, &[0x80])
+ .await?;
+ self.interface
+ .cmd_with_data(spi, Command::DisplayUpdateControl2, &[0xC0])
+ .await?;
+ self.interface.cmd(spi, Command::MasterActivation).await?;
- self.wait_until_idle(spi, delay)?;
+ self.wait_until_idle(spi, delay).await?;
- self.use_full_frame(spi, delay)?;
+ self.use_full_frame(spi, delay).await?;
self.interface
- .cmd_with_data(spi, Command::WriteRam, buffer)?;
+ .cmd_with_data(spi, Command::WriteRam, buffer)
+ .await?;
Ok(())
}
/// For a quick refresh of the new updated frame. To be used immediately after `update_new_frame`
- fn display_new_frame(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
- self.wait_until_idle(spi, delay)?;
+ async fn display_new_frame(
+ &mut self,
+ spi: &mut SPI,
+ delay: &mut DELAY,
+ ) -> Result<(), SPI::Error> {
+ self.wait_until_idle(spi, delay).await?;
self.interface
- .cmd_with_data(spi, Command::DisplayUpdateControl2, &[0x0F])?;
- self.interface.cmd(spi, Command::MasterActivation)?;
- self.wait_until_idle(spi, delay)?;
+ .cmd_with_data(spi, Command::DisplayUpdateControl2, &[0x0F])
+ .await?;
+ self.interface.cmd(spi, Command::MasterActivation).await?;
+ self.wait_until_idle(spi, delay).await?;
Ok(())
}
/// Updates and displays the new frame.
- fn update_and_display_new_frame(
+ async fn update_and_display_new_frame(
&mut self,
spi: &mut SPI,
buffer: &[u8],
delay: &mut DELAY,
) -> Result<(), SPI::Error> {
- self.update_new_frame(spi, buffer, delay)?;
- self.display_new_frame(spi, delay)?;
+ self.update_new_frame(spi, buffer, delay).await?;
+ self.display_new_frame(spi, delay).await?;
Ok(())
}
/// Partial quick refresh not supported yet
#[allow(unused)]
- fn update_partial_old_frame(
+ async fn update_partial_old_frame(
&mut self,
spi: &mut SPI,
delay: &mut DELAY,
@@ -494,7 +537,7 @@ where
/// Partial quick refresh not supported yet
#[allow(unused)]
- fn update_partial_new_frame(
+ async fn update_partial_new_frame(
&mut self,
spi: &mut SPI,
delay: &mut DELAY,
@@ -510,7 +553,7 @@ where
/// Partial quick refresh not supported yet
#[allow(unused)]
- fn clear_partial_frame(
+ async fn clear_partial_frame(
&mut self,
spi: &mut SPI,
delay: &mut DELAY,
diff --git a/src/epd2in9b_v4/mod.rs b/src/epd2in9b_v4/mod.rs
index 12cfdd90..bda98bcd 100644
--- a/src/epd2in9b_v4/mod.rs
+++ b/src/epd2in9b_v4/mod.rs
@@ -7,14 +7,10 @@
use crate::{
buffer_len,
color::TriColor,
- interface::DisplayInterface,
+ interface::{DelayNs, DisplayInterface, SpiDevice},
traits::{InternalWiAdditions, WaveshareDisplay, WaveshareThreeColorDisplay},
};
-use embedded_hal::{
- delay::DelayNs,
- digital::{InputPin, OutputPin},
- spi::SpiDevice,
-};
+use embedded_hal::digital::{InputPin, OutputPin};
pub(crate) mod command;
use self::command::Command;
@@ -56,6 +52,7 @@ enum DisplayMode {
Base,
}
+#[maybe_async::maybe_async]
impl Epd2in9b
where
SPI: SpiDevice,
@@ -67,22 +64,22 @@ where
/// set the base image before partially update
///
///
- pub fn update_and_display_frame_base(
+ pub async fn update_and_display_frame_base(
&mut self,
spi: &mut SPI,
black: &[u8],
chromatic: Option<&[u8]>,
delay: &mut DELAY,
) -> Result<(), ::Error> {
- self.update_frame(spi, black, delay)?;
+ self.update_frame(spi, black, delay).await?;
if let Some(chromatic) = chromatic {
- self.update_chromatic_frame(spi, delay, chromatic)?;
+ self.update_chromatic_frame(spi, delay, chromatic).await?;
}
- self.turn_on_display(spi, delay, DisplayMode::Base)?;
+ self.turn_on_display(spi, delay, DisplayMode::Base).await?;
- self.command(spi, Command::WriteRedData)?;
- self.send_data(spi, black)?;
+ self.command(spi, Command::WriteRedData).await?;
+ self.send_data(spi, black).await?;
Ok(())
}
@@ -91,30 +88,31 @@ where
///
/// To perform partial update, it need to call update_and_display_frame_base
/// than call update_partial_frame before call display_frame_partial
- pub fn display_frame_partial(
+ pub async fn display_frame_partial(
&mut self,
spi: &mut SPI,
delay: &mut DELAY,
) -> Result<(), ::Error> {
- self.turn_on_display(spi, delay, DisplayMode::Partial)?;
+ self.turn_on_display(spi, delay, DisplayMode::Partial)
+ .await?;
Ok(())
}
- fn command(&mut self, spi: &mut SPI, command: Command) -> Result<(), SPI::Error> {
- self.interface.cmd(spi, command)
+ async fn command(&mut self, spi: &mut SPI, command: Command) -> Result<(), SPI::Error> {
+ self.interface.cmd(spi, command).await
}
- fn send_data(&mut self, spi: &mut SPI, data: &[u8]) -> Result<(), SPI::Error> {
- self.interface.data(spi, data)
+ async fn send_data(&mut self, spi: &mut SPI, data: &[u8]) -> Result<(), SPI::Error> {
+ self.interface.data(spi, data).await
}
- fn turn_on_display(
+ async fn turn_on_display(
&mut self,
spi: &mut SPI,
delay: &mut DELAY,
mode: DisplayMode,
) -> Result<(), SPI::Error> {
- self.command(spi, Command::TurnOnDisplay)?;
+ self.command(spi, Command::TurnOnDisplay).await?;
let data = match mode {
DisplayMode::Default => 0xf7,
@@ -123,13 +121,15 @@ where
DisplayMode::Base => 0xf4,
};
- self.send_data(spi, &[data])?;
- self.command(spi, Command::ActivateDisplayUpdateSequence)?;
- self.wait_until_idle(spi, delay)?;
+ self.send_data(spi, &[data]).await?;
+ self.command(spi, Command::ActivateDisplayUpdateSequence)
+ .await?;
+ self.wait_until_idle(spi, delay).await?;
Ok(())
}
}
+#[maybe_async::maybe_async(AFIT)]
impl InternalWiAdditions
for Epd2in9b
where
@@ -139,56 +139,58 @@ where
RST: OutputPin,
DELAY: DelayNs,
{
- fn init(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
+ async fn init(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
let w = self.width();
let h = self.height();
- self.interface.reset(delay, 200_000, 2_000);
+ self.interface.reset(delay, 200_000, 2_000).await;
- self.wait_until_idle(spi, delay)?;
- self.command(spi, Command::SwReset)?;
- self.wait_until_idle(spi, delay)?;
+ self.wait_until_idle(spi, delay).await?;
+ self.command(spi, Command::SwReset).await?;
+ self.wait_until_idle(spi, delay).await?;
- self.command(spi, Command::DriverOutputControl)?;
- self.send_data(spi, &[((h - 1) % 256) as u8])?;
- self.send_data(spi, &[((h - 1) / 256) as u8])?;
- self.send_data(spi, &[0])?;
+ self.command(spi, Command::DriverOutputControl).await?;
+ self.send_data(spi, &[((h - 1) % 256) as u8]).await?;
+ self.send_data(spi, &[((h - 1) / 256) as u8]).await?;
+ self.send_data(spi, &[0]).await?;
- self.command(spi, Command::DataEntryMode)?;
- self.send_data(spi, &[0x03])?;
+ self.command(spi, Command::DataEntryMode).await?;
+ self.send_data(spi, &[0x03]).await?;
- self.command(spi, Command::RamXPosition)?;
- self.send_data(spi, &[0])?;
- self.send_data(spi, &[(w / 8 - 1) as u8])?;
+ self.command(spi, Command::RamXPosition).await?;
+ self.send_data(spi, &[0]).await?;
+ self.send_data(spi, &[(w / 8 - 1) as u8]).await?;
- self.command(spi, Command::RamYPosition)?;
- self.send_data(spi, &[0])?;
- self.send_data(spi, &[0])?;
- self.send_data(spi, &[((h - 1) % 256) as u8])?;
- self.send_data(spi, &[((h - 1) / 256) as u8])?;
+ self.command(spi, Command::RamYPosition).await?;
+ self.send_data(spi, &[0]).await?;
+ self.send_data(spi, &[0]).await?;
+ self.send_data(spi, &[((h - 1) % 256) as u8]).await?;
+ self.send_data(spi, &[((h - 1) / 256) as u8]).await?;
- self.command(spi, Command::BorderWavefrom)?;
- self.send_data(spi, &[0x05])?;
+ self.command(spi, Command::BorderWavefrom).await?;
+ self.send_data(spi, &[0x05]).await?;
- self.command(spi, Command::DisplayUpdateControl)?;
- self.send_data(spi, &[0x00])?;
- self.send_data(spi, &[0x80])?;
+ self.command(spi, Command::DisplayUpdateControl).await?;
+ self.send_data(spi, &[0x00]).await?;
+ self.send_data(spi, &[0x80]).await?;
- self.command(spi, Command::ReadBuiltInTemperatureSensor)?;
- self.send_data(spi, &[0x80])?;
+ self.command(spi, Command::ReadBuiltInTemperatureSensor)
+ .await?;
+ self.send_data(spi, &[0x80]).await?;
- self.command(spi, Command::RamXAddressCount)?;
- self.send_data(spi, &[0x00])?; // set RAM x address count to 0
- self.command(spi, Command::RamYAddressCount)?; // set RAM y address count to 0X199
- self.send_data(spi, &[0x00])?;
- self.send_data(spi, &[0x00])?;
+ self.command(spi, Command::RamXAddressCount).await?;
+ self.send_data(spi, &[0x00]).await?; // set RAM x address count to 0
+ self.command(spi, Command::RamYAddressCount).await?; // set RAM y address count to 0X199
+ self.send_data(spi, &[0x00]).await?;
+ self.send_data(spi, &[0x00]).await?;
- self.wait_until_idle(spi, delay)?;
+ self.wait_until_idle(spi, delay).await?;
Ok(())
}
}
+#[maybe_async::maybe_async(AFIT)]
impl WaveshareThreeColorDisplay
for Epd2in9b
where
@@ -198,41 +200,42 @@ where
RST: OutputPin,
DELAY: DelayNs,
{
- fn update_color_frame(
+ async fn update_color_frame(
&mut self,
spi: &mut SPI,
delay: &mut DELAY,
black: &[u8],
chromatic: &[u8],
) -> Result<(), ::Error> {
- self.update_achromatic_frame(spi, delay, black)?;
- self.update_chromatic_frame(spi, delay, chromatic)?;
+ self.update_achromatic_frame(spi, delay, black).await?;
+ self.update_chromatic_frame(spi, delay, chromatic).await?;
Ok(())
}
- fn update_achromatic_frame(
+ async fn update_achromatic_frame(
&mut self,
spi: &mut SPI,
_delay: &mut DELAY,
black: &[u8],
) -> Result<(), ::Error> {
- self.command(spi, Command::WriteBlackData)?;
- self.send_data(spi, black)?;
+ self.command(spi, Command::WriteBlackData).await?;
+ self.send_data(spi, black).await?;
Ok(())
}
- fn update_chromatic_frame(
+ async fn update_chromatic_frame(
&mut self,
spi: &mut SPI,
_delay: &mut DELAY,
chromatic: &[u8],
) -> Result<(), ::Error> {
- self.command(spi, Command::WriteRedData)?;
- self.send_data(spi, chromatic)?;
+ self.command(spi, Command::WriteRedData).await?;
+ self.send_data(spi, chromatic).await?;
Ok(())
}
}
+#[maybe_async::maybe_async(AFIT)]
impl WaveshareDisplay
for Epd2in9b
where
@@ -244,7 +247,7 @@ where
{
type DisplayColor = TriColor;
- fn new(
+ async fn new(
spi: &mut SPI,
busy: BUSY,
dc: DC,
@@ -263,21 +266,21 @@ where
background_color,
};
- epd.init(spi, delay)?;
+ epd.init(spi, delay).await?;
Ok(epd)
}
- fn sleep(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), ::Error> {
- self.command(spi, Command::DeepSleep)?;
- self.send_data(spi, &[1])?;
- delay.delay_ms(100);
+ async fn sleep(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), ::Error> {
+ self.command(spi, Command::DeepSleep).await?;
+ self.send_data(spi, &[1]).await?;
+ delay.delay_ms(100).await;
Ok(())
}
- fn wake_up(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), ::Error> {
- self.init(spi, delay)?;
+ async fn wake_up(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), ::Error> {
+ self.init(spi, delay).await?;
Ok(())
}
@@ -297,21 +300,23 @@ where
HEIGHT
}
- fn update_frame(
+ async fn update_frame(
&mut self,
spi: &mut SPI,
buffer: &[u8],
_delay: &mut DELAY,
) -> Result<(), ::Error> {
- self.command(spi, Command::WriteBlackData)?;
- self.send_data(spi, buffer)?;
+ self.command(spi, Command::WriteBlackData).await?;
+ self.send_data(spi, buffer).await?;
- self.command(spi, Command::WriteRedData)?;
- self.interface.data_x_times(spi, 0x00, WIDTH / 8 * HEIGHT)?;
+ self.command(spi, Command::WriteRedData).await?;
+ self.interface
+ .data_x_times(spi, 0x00, WIDTH / 8 * HEIGHT)
+ .await?;
Ok(())
}
- fn update_partial_frame(
+ async fn update_partial_frame(
&mut self,
spi: &mut SPI,
_delay: &mut DELAY,
@@ -355,55 +360,60 @@ where
let y_end_1 = y_end as u8;
let y_end_2 = (y_end >> 8) as u8;
- self.command(spi, Command::RamXPosition)?;
- self.send_data(spi, &[x_start, x_end])?;
- self.command(spi, Command::RamYPosition)?;
- self.send_data(spi, &[y_start_1, y_start_2])?;
- self.send_data(spi, &[y_end_1, y_end_2])?;
+ self.command(spi, Command::RamXPosition).await?;
+ self.send_data(spi, &[x_start, x_end]).await?;
+ self.command(spi, Command::RamYPosition).await?;
+ self.send_data(spi, &[y_start_1, y_start_2]).await?;
+ self.send_data(spi, &[y_end_1, y_end_2]).await?;
- self.command(spi, Command::RamXAddressCount)?;
- self.send_data(spi, &[x_start])?;
- self.command(spi, Command::RamYAddressCount)?;
- self.send_data(spi, &[y_start_1, y_start_2])?;
+ self.command(spi, Command::RamXAddressCount).await?;
+ self.send_data(spi, &[x_start]).await?;
+ self.command(spi, Command::RamYAddressCount).await?;
+ self.send_data(spi, &[y_start_1, y_start_2]).await?;
- self.command(spi, Command::WriteBlackData)?;
- self.send_data(spi, buffer)?;
+ self.command(spi, Command::WriteBlackData).await?;
+ self.send_data(spi, buffer).await?;
Ok(())
}
- fn display_frame(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), ::Error> {
- self.turn_on_display(spi, delay, DisplayMode::Default)?;
+ async fn display_frame(
+ &mut self,
+ spi: &mut SPI,
+ delay: &mut DELAY,
+ ) -> Result<(), ::Error> {
+ self.turn_on_display(spi, delay, DisplayMode::Default)
+ .await?;
Ok(())
}
- fn update_and_display_frame(
+ async fn update_and_display_frame(
&mut self,
spi: &mut SPI,
buffer: &[u8],
delay: &mut DELAY,
) -> Result<(), ::Error> {
- self.update_frame(spi, buffer, delay)?;
- self.display_frame(spi, delay)?;
+ self.update_frame(spi, buffer, delay).await?;
+ self.display_frame(spi, delay).await?;
Ok(())
}
- fn clear_frame(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), ::Error> {
+ async fn clear_frame(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), ::Error> {
const SIZE: u32 = WIDTH / 8 * HEIGHT;
- self.command(spi, Command::WriteBlackData)?;
- self.interface.data_x_times(spi, 0xff, SIZE)?;
+ self.command(spi, Command::WriteBlackData).await?;
+ self.interface.data_x_times(spi, 0xff, SIZE).await?;
- self.command(spi, Command::WriteRedData)?;
- self.interface.data_x_times(spi, 0, SIZE)?;
+ self.command(spi, Command::WriteRedData).await?;
+ self.interface.data_x_times(spi, 0, SIZE).await?;
- self.display_frame(spi, delay)?;
+ self.display_frame(spi, delay).await?;
Ok(())
}
- fn set_lut(
+ async fn set_lut(
&mut self,
_spi: &mut SPI,
_delay: &mut DELAY,
@@ -412,8 +422,12 @@ where
Ok(())
}
- fn wait_until_idle(&mut self, _spi: &mut SPI, delay: &mut DELAY) -> Result<(), ::Error> {
- self.interface.wait_until_idle(delay, IS_BUSY_LOW);
+ async fn wait_until_idle(
+ &mut self,
+ _spi: &mut SPI,
+ delay: &mut DELAY,
+ ) -> Result<(), ::Error> {
+ self.interface.wait_until_idle(delay, IS_BUSY_LOW).await;
Ok(())
}
}
diff --git a/src/epd2in9bc/mod.rs b/src/epd2in9bc/mod.rs
index 7a4ba92c..5c5439f1 100644
--- a/src/epd2in9bc/mod.rs
+++ b/src/epd2in9bc/mod.rs
@@ -54,9 +54,9 @@
//!# Ok(())
//!# }
//!```
-use embedded_hal::{delay::*, digital::*, spi::SpiDevice};
+use embedded_hal::digital::*;
-use crate::interface::DisplayInterface;
+use crate::interface::{DelayNs, DisplayInterface, SpiDevice};
use crate::traits::{
InternalWiAdditions, RefreshLut, WaveshareDisplay, WaveshareThreeColorDisplay,
};
@@ -101,6 +101,7 @@ pub struct Epd2in9bc {
color: Color,
}
+#[maybe_async::maybe_async(AFIT)]
impl InternalWiAdditions
for Epd2in9bc
where
@@ -110,40 +111,45 @@ where
RST: OutputPin,
DELAY: DelayNs,
{
- fn init(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
+ async fn init(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
// Values taken from datasheet and sample code
- self.interface.reset(delay, 10_000, 10_000);
+ self.interface.reset(delay, 10_000, 10_000).await;
// start the booster
self.interface
- .cmd_with_data(spi, Command::BoosterSoftStart, &[0x17, 0x17, 0x17])?;
+ .cmd_with_data(spi, Command::BoosterSoftStart, &[0x17, 0x17, 0x17])
+ .await?;
// power on
- self.command(spi, Command::PowerOn)?;
- delay.delay_us(5000);
- self.wait_until_idle(spi, delay)?;
+ self.command(spi, Command::PowerOn).await?;
+ delay.delay_us(5000).await;
+ self.wait_until_idle(spi, delay).await?;
// set the panel settings
- self.cmd_with_data(spi, Command::PanelSetting, &[0x8F])?;
+ self.cmd_with_data(spi, Command::PanelSetting, &[0x8F])
+ .await?;
self.cmd_with_data(
spi,
Command::VcomAndDataIntervalSetting,
&[WHITE_BORDER | VCOM_DATA_INTERVAL],
- )?;
+ )
+ .await?;
// set resolution
- self.send_resolution(spi)?;
+ self.send_resolution(spi).await?;
- self.cmd_with_data(spi, Command::VcmDcSetting, &[0x0A])?;
+ self.cmd_with_data(spi, Command::VcmDcSetting, &[0x0A])
+ .await?;
- self.wait_until_idle(spi, delay)?;
+ self.wait_until_idle(spi, delay).await?;
Ok(())
}
}
+#[maybe_async::maybe_async(AFIT)]
impl WaveshareThreeColorDisplay
for Epd2in9bc
where
@@ -153,48 +159,53 @@ where
RST: OutputPin,
DELAY: DelayNs,
{
- fn update_color_frame(
+ async fn update_color_frame(
&mut self,
spi: &mut SPI,
delay: &mut DELAY,
black: &[u8],
chromatic: &[u8],
) -> Result<(), SPI::Error> {
- self.update_achromatic_frame(spi, delay, black)?;
- self.update_chromatic_frame(spi, delay, chromatic)
+ self.update_achromatic_frame(spi, delay, black).await?;
+ self.update_chromatic_frame(spi, delay, chromatic).await
}
/// Update only the black/white data of the display.
///
/// Finish by calling `update_chromatic_frame`.
- fn update_achromatic_frame(
+ async fn update_achromatic_frame(
&mut self,
spi: &mut SPI,
_delay: &mut DELAY,
black: &[u8],
) -> Result<(), SPI::Error> {
- self.interface.cmd(spi, Command::DataStartTransmission1)?;
- self.interface.data(spi, black)?;
+ self.interface
+ .cmd(spi, Command::DataStartTransmission1)
+ .await?;
+ self.interface.data(spi, black).await?;
Ok(())
}
/// Update only chromatic data of the display.
///
/// This data takes precedence over the black/white data.
- fn update_chromatic_frame(
+ async fn update_chromatic_frame(
&mut self,
spi: &mut SPI,
delay: &mut DELAY,
chromatic: &[u8],
) -> Result<(), SPI::Error> {
- self.interface.cmd(spi, Command::DataStartTransmission2)?;
- self.interface.data(spi, chromatic)?;
+ self.interface
+ .cmd(spi, Command::DataStartTransmission2)
+ .await?;
+ self.interface.data(spi, chromatic).await?;
- self.wait_until_idle(spi, delay)?;
+ self.wait_until_idle(spi, delay).await?;
Ok(())
}
}
+#[maybe_async::maybe_async(AFIT)]
impl WaveshareDisplay
for Epd2in9bc
where
@@ -205,7 +216,7 @@ where
DELAY: DelayNs,
{
type DisplayColor = Color;
- fn new(
+ async fn new(
spi: &mut SPI,
busy: BUSY,
dc: DC,
@@ -218,30 +229,32 @@ where
let mut epd = Epd2in9bc { interface, color };
- epd.init(spi, delay)?;
+ epd.init(spi, delay).await?;
Ok(epd)
}
- fn sleep(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
+ async fn sleep(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
// Section 8.2 from datasheet
- self.interface.cmd_with_data(
- spi,
- Command::VcomAndDataIntervalSetting,
- &[FLOATING_BORDER | VCOM_DATA_INTERVAL],
- )?;
-
- self.command(spi, Command::PowerOff)?;
+ self.interface
+ .cmd_with_data(
+ spi,
+ Command::VcomAndDataIntervalSetting,
+ &[FLOATING_BORDER | VCOM_DATA_INTERVAL],
+ )
+ .await?;
+
+ self.command(spi, Command::PowerOff).await?;
// The example STM code from Github has a wait after PowerOff
- self.wait_until_idle(spi, delay)?;
+ self.wait_until_idle(spi, delay).await?;
- self.cmd_with_data(spi, Command::DeepSleep, &[0xA5])?;
+ self.cmd_with_data(spi, Command::DeepSleep, &[0xA5]).await?;
Ok(())
}
- fn wake_up(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
- self.init(spi, delay)
+ async fn wake_up(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
+ self.init(spi, delay).await
}
fn set_background_color(&mut self, color: Color) {
@@ -260,28 +273,34 @@ where
HEIGHT
}
- fn update_frame(
+ async fn update_frame(
&mut self,
spi: &mut SPI,
buffer: &[u8],
delay: &mut DELAY,
) -> Result<(), SPI::Error> {
- self.interface.cmd(spi, Command::DataStartTransmission1)?;
+ self.interface
+ .cmd(spi, Command::DataStartTransmission1)
+ .await?;
- self.interface.data(spi, buffer)?;
+ self.interface.data(spi, buffer).await?;
// Clear the chromatic layer
let color = self.color.get_byte_value();
- self.interface.cmd(spi, Command::DataStartTransmission2)?;
- self.interface.data_x_times(spi, color, NUM_DISPLAY_BITS)?;
+ self.interface
+ .cmd(spi, Command::DataStartTransmission2)
+ .await?;
+ self.interface
+ .data_x_times(spi, color, NUM_DISPLAY_BITS)
+ .await?;
- self.wait_until_idle(spi, delay)?;
+ self.wait_until_idle(spi, delay).await?;
Ok(())
}
#[allow(unused)]
- fn update_partial_frame(
+ async fn update_partial_frame(
&mut self,
spi: &mut SPI,
delay: &mut DELAY,
@@ -294,43 +313,51 @@ where
Ok(())
}
- fn display_frame(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
- self.command(spi, Command::DisplayRefresh)?;
+ async fn display_frame(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
+ self.command(spi, Command::DisplayRefresh).await?;
- self.wait_until_idle(spi, delay)?;
+ self.wait_until_idle(spi, delay).await?;
Ok(())
}
- fn update_and_display_frame(
+ async fn update_and_display_frame(
&mut self,
spi: &mut SPI,
buffer: &[u8],
delay: &mut DELAY,
) -> Result<(), SPI::Error> {
- self.update_frame(spi, buffer, delay)?;
- self.display_frame(spi, delay)?;
+ self.update_frame(spi, buffer, delay).await?;
+ self.display_frame(spi, delay).await?;
Ok(())
}
- fn clear_frame(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
- self.send_resolution(spi)?;
+ async fn clear_frame(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
+ self.send_resolution(spi).await?;
let color = DEFAULT_BACKGROUND_COLOR.get_byte_value();
// Clear the black
- self.interface.cmd(spi, Command::DataStartTransmission1)?;
+ self.interface
+ .cmd(spi, Command::DataStartTransmission1)
+ .await?;
- self.interface.data_x_times(spi, color, NUM_DISPLAY_BITS)?;
+ self.interface
+ .data_x_times(spi, color, NUM_DISPLAY_BITS)
+ .await?;
// Clear the chromatic
- self.interface.cmd(spi, Command::DataStartTransmission2)?;
- self.interface.data_x_times(spi, color, NUM_DISPLAY_BITS)?;
+ self.interface
+ .cmd(spi, Command::DataStartTransmission2)
+ .await?;
+ self.interface
+ .data_x_times(spi, color, NUM_DISPLAY_BITS)
+ .await?;
- self.wait_until_idle(spi, delay)?;
+ self.wait_until_idle(spi, delay).await?;
Ok(())
}
- fn set_lut(
+ async fn set_lut(
&mut self,
_spi: &mut SPI,
_delay: &mut DELAY,
@@ -339,12 +366,17 @@ where
Ok(())
}
- fn wait_until_idle(&mut self, _spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
- self.interface.wait_until_idle(delay, IS_BUSY_LOW);
+ async fn wait_until_idle(
+ &mut self,
+ _spi: &mut SPI,
+ delay: &mut DELAY,
+ ) -> Result<(), SPI::Error> {
+ self.interface.wait_until_idle(delay, IS_BUSY_LOW).await;
Ok(())
}
}
+#[maybe_async::maybe_async]
impl Epd2in9bc
where
SPI: SpiDevice,
@@ -353,36 +385,40 @@ where
RST: OutputPin,
DELAY: DelayNs,
{
- fn command(&mut self, spi: &mut SPI, command: Command) -> Result<(), SPI::Error> {
- self.interface.cmd(spi, command)
+ async fn command(&mut self, spi: &mut SPI, command: Command) -> Result<(), SPI::Error> {
+ self.interface.cmd(spi, command).await
}
- fn send_data(&mut self, spi: &mut SPI, data: &[u8]) -> Result<(), SPI::Error> {
- self.interface.data(spi, data)
+ async fn send_data(&mut self, spi: &mut SPI, data: &[u8]) -> Result<(), SPI::Error> {
+ self.interface.data(spi, data).await
}
- fn cmd_with_data(
+ async fn cmd_with_data(
&mut self,
spi: &mut SPI,
command: Command,
data: &[u8],
) -> Result<(), SPI::Error> {
- self.interface.cmd_with_data(spi, command, data)
+ self.interface.cmd_with_data(spi, command, data).await
}
- fn send_resolution(&mut self, spi: &mut SPI) -> Result<(), SPI::Error> {
+ async fn send_resolution(&mut self, spi: &mut SPI) -> Result<(), SPI::Error> {
let w = self.width();
let h = self.height();
- self.command(spi, Command::ResolutionSetting)?;
+ self.command(spi, Command::ResolutionSetting).await?;
- self.send_data(spi, &[w as u8])?;
- self.send_data(spi, &[(h >> 8) as u8])?;
- self.send_data(spi, &[h as u8])
+ self.send_data(spi, &[w as u8]).await?;
+ self.send_data(spi, &[(h >> 8) as u8]).await?;
+ self.send_data(spi, &[h as u8]).await
}
/// Set the outer border of the display to the chosen color.
- pub fn set_border_color(&mut self, spi: &mut SPI, color: TriColor) -> Result<(), SPI::Error> {
+ pub async fn set_border_color(
+ &mut self,
+ spi: &mut SPI,
+ color: TriColor,
+ ) -> Result<(), SPI::Error> {
let border = match color {
TriColor::Black => BLACK_BORDER,
TriColor::White => WHITE_BORDER,
@@ -393,5 +429,6 @@ where
Command::VcomAndDataIntervalSetting,
&[border | VCOM_DATA_INTERVAL],
)
+ .await
}
}
diff --git a/src/epd2in9d/mod.rs b/src/epd2in9d/mod.rs
index 50619060..7e4b2440 100644
--- a/src/epd2in9d/mod.rs
+++ b/src/epd2in9d/mod.rs
@@ -7,13 +7,9 @@
use core::slice::from_raw_parts;
-use embedded_hal::{
- delay::DelayNs,
- digital::{InputPin, OutputPin},
- spi::SpiDevice,
-};
+use embedded_hal::digital::{InputPin, OutputPin};
-use crate::interface::DisplayInterface;
+use crate::interface::{DelayNs, DisplayInterface, SpiDevice};
use crate::traits::{InternalWiAdditions, RefreshLut, WaveshareDisplay};
//The Lookup Tables for the Display
@@ -64,6 +60,7 @@ pub struct Epd2in9d<'a, SPI, BUSY, DC, RST, DELAY> {
is_partial_refresh: bool,
}
+#[maybe_async::maybe_async(AFIT)]
impl InternalWiAdditions
for Epd2in9d<'_, SPI, BUSY, DC, RST, DELAY>
where
@@ -73,29 +70,33 @@ where
RST: OutputPin,
DELAY: DelayNs,
{
- fn init(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
- self.interface.reset(delay, 10_000, 2_000);
+ async fn init(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
+ self.interface.reset(delay, 10_000, 2_000).await;
//panel setting
//LUT from OTP,KW-BF KWR-AF BWROTP 0f BWOTP 1f
self.interface
- .cmd_with_data(spi, Command::PanelSetting, &[0x1f, 0x0D])?;
+ .cmd_with_data(spi, Command::PanelSetting, &[0x1f, 0x0D])
+ .await?;
//resolution setting
self.interface
- .cmd_with_data(spi, Command::ResolutionSetting, &[0x80, 0x01, 0x28])?;
+ .cmd_with_data(spi, Command::ResolutionSetting, &[0x80, 0x01, 0x28])
+ .await?;
- self.interface.cmd(spi, Command::PowerOn)?;
- self.wait_until_idle(spi, delay)?;
+ self.interface.cmd(spi, Command::PowerOn).await?;
+ self.wait_until_idle(spi, delay).await?;
//VCOM AND DATA INTERVAL SETTING
self.interface
- .cmd_with_data(spi, Command::VcomAndDataIntervalSetting, &[0x97])?;
+ .cmd_with_data(spi, Command::VcomAndDataIntervalSetting, &[0x97])
+ .await?;
Ok(())
}
}
+#[maybe_async::maybe_async(AFIT)]
impl WaveshareDisplay
for Epd2in9d<'_, SPI, BUSY, DC, RST, DELAY>
where
@@ -106,7 +107,7 @@ where
DELAY: DelayNs,
{
type DisplayColor = Color;
- fn new(
+ async fn new(
spi: &mut SPI,
busy: BUSY,
dc: DC,
@@ -127,26 +128,28 @@ where
is_partial_refresh,
};
- epd.init(spi, delay)?;
+ epd.init(spi, delay).await?;
Ok(epd)
}
- fn sleep(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
+ async fn sleep(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
self.is_partial_refresh = false;
self.interface
- .cmd_with_data(spi, Command::VcomAndDataIntervalSetting, &[0xf7])?;
- self.interface.cmd(spi, Command::PowerOff)?;
- self.wait_until_idle(spi, delay)?;
- delay.delay_us(100_000);
+ .cmd_with_data(spi, Command::VcomAndDataIntervalSetting, &[0xf7])
+ .await?;
+ self.interface.cmd(spi, Command::PowerOff).await?;
+ self.wait_until_idle(spi, delay).await?;
+ delay.delay_us(100_000).await;
self.interface
- .cmd_with_data(spi, Command::DeepSleep, &[0xA5])?;
+ .cmd_with_data(spi, Command::DeepSleep, &[0xA5])
+ .await?;
Ok(())
}
- fn wake_up(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
- self.init(spi, delay)?;
+ async fn wake_up(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
+ self.init(spi, delay).await?;
Ok(())
}
@@ -168,7 +171,7 @@ where
// Corresponds to the Display function.
// Used to write the data to be displayed to the screen SRAM.
- fn update_frame(
+ async fn update_frame(
&mut self,
spi: &mut SPI,
buffer: &[u8],
@@ -178,20 +181,23 @@ where
// Modify local refresh status if full refresh is performed.
self.is_partial_refresh = false;
}
- self.wait_until_idle(spi, delay)?;
+ self.wait_until_idle(spi, delay).await?;
- self.interface.cmd(spi, Command::DataStartTransmission1)?;
- self.interface.data_x_times(spi, 0xFF, EPD_ARRAY)?;
+ self.interface
+ .cmd(spi, Command::DataStartTransmission1)
+ .await?;
+ self.interface.data_x_times(spi, 0xFF, EPD_ARRAY).await?;
self.interface
- .cmd_with_data(spi, Command::DataStartTransmission2, buffer)?;
+ .cmd_with_data(spi, Command::DataStartTransmission2, buffer)
+ .await?;
self.old_data = unsafe { from_raw_parts(buffer.as_ptr(), buffer.len()) };
Ok(())
}
// 这个是DisplayPart
// Partial refresh write address and data
- fn update_partial_frame(
+ async fn update_partial_frame(
&mut self,
spi: &mut SPI,
delay: &mut DELAY,
@@ -203,65 +209,74 @@ where
) -> Result<(), SPI::Error> {
if !self.is_partial_refresh {
// Initialize only on first call
- self.set_part_reg(spi, delay)?;
+ self.set_part_reg(spi, delay).await?;
self.is_partial_refresh = true;
}
- self.interface.cmd(spi, Command::PartialIn)?;
+ self.interface.cmd(spi, Command::PartialIn).await?;
- self.interface.cmd(spi, Command::PartialWindow)?;
- self.interface.data(spi, &[(x - x % 8) as u8])?;
+ self.interface.cmd(spi, Command::PartialWindow).await?;
+ self.interface.data(spi, &[(x - x % 8) as u8]).await?;
self.interface
- .data(spi, &[(((x - x % 8) + width - 1) - 1) as u8])?;
- self.interface.data(spi, &[(y / 256) as u8])?;
- self.interface.data(spi, &[(y % 256) as u8])?;
+ .data(spi, &[(((x - x % 8) + width - 1) - 1) as u8])
+ .await?;
+ self.interface.data(spi, &[(y / 256) as u8]).await?;
+ self.interface.data(spi, &[(y % 256) as u8]).await?;
self.interface
- .data(spi, &[((y + height - 1) / 256) as u8])?;
+ .data(spi, &[((y + height - 1) / 256) as u8])
+ .await?;
self.interface
- .data(spi, &[((y + height - 1) % 256 - 1) as u8])?;
- self.interface.data(spi, &[0x28])?;
+ .data(spi, &[((y + height - 1) % 256 - 1) as u8])
+ .await?;
+ self.interface.data(spi, &[0x28]).await?;
self.interface
- .cmd_with_data(spi, Command::DataStartTransmission1, self.old_data)?;
+ .cmd_with_data(spi, Command::DataStartTransmission1, self.old_data)
+ .await?;
self.interface
- .cmd_with_data(spi, Command::DataStartTransmission2, buffer)?;
+ .cmd_with_data(spi, Command::DataStartTransmission2, buffer)
+ .await?;
self.old_data = unsafe { from_raw_parts(buffer.as_ptr(), buffer.len()) };
Ok(())
}
/// actually is the "Turn on Display" sequence
- fn display_frame(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
- self.interface.cmd(spi, Command::DisplayRefresh)?;
- delay.delay_us(1_000);
- self.wait_until_idle(spi, delay)?;
+ async fn display_frame(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
+ self.interface.cmd(spi, Command::DisplayRefresh).await?;
+ delay.delay_us(1_000).await;
+ self.wait_until_idle(spi, delay).await?;
Ok(())
}
- fn update_and_display_frame(
+ async fn update_and_display_frame(
&mut self,
spi: &mut SPI,
buffer: &[u8],
delay: &mut DELAY,
) -> Result<(), SPI::Error> {
- self.update_frame(spi, buffer, delay)?;
- self.display_frame(spi, delay)?;
+ self.update_frame(spi, buffer, delay).await?;
+ self.display_frame(spi, delay).await?;
Ok(())
}
- fn clear_frame(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
- self.interface.cmd(spi, Command::DataStartTransmission1)?;
- self.interface.data_x_times(spi, 0x00, EPD_ARRAY)?;
+ async fn clear_frame(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
+ self.interface
+ .cmd(spi, Command::DataStartTransmission1)
+ .await?;
+ self.interface.data_x_times(spi, 0x00, EPD_ARRAY).await?;
- self.interface.cmd(spi, Command::DataStartTransmission2)?;
- self.interface.data_x_times(spi, 0xFF, EPD_ARRAY)?;
+ self.interface
+ .cmd(spi, Command::DataStartTransmission2)
+ .await?;
+ self.interface.data_x_times(spi, 0xFF, EPD_ARRAY).await?;
- self.display_frame(spi, delay)?;
+ self.display_frame(spi, delay).await?;
Ok(())
}
- fn set_lut(
+ async fn set_lut(
&mut self,
spi: &mut SPI,
delay: &mut DELAY,
@@ -272,17 +287,23 @@ where
}
self.set_lut_helper(
spi, delay, &LUT_VCOM1, &LUT_WW1, &LUT_BW1, &LUT_WB1, &LUT_BB1,
- )?;
+ )
+ .await?;
Ok(())
}
- fn wait_until_idle(&mut self, _spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
- self.interface.wait_until_idle(delay, IS_BUSY_LOW);
+ async fn wait_until_idle(
+ &mut self,
+ _spi: &mut SPI,
+ delay: &mut DELAY,
+ ) -> Result<(), SPI::Error> {
+ self.interface.wait_until_idle(delay, IS_BUSY_LOW).await;
Ok(())
}
}
+#[maybe_async::maybe_async]
impl Epd2in9d<'_, SPI, BUSY, DC, RST, DELAY>
where
SPI: SpiDevice,
@@ -297,8 +318,8 @@ where
// /// Wake the screen.
// fn awaken(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
// // reset the device
- // self.interface.reset(delay, 20_000, 2_000);
- // self.wait_until_idle(spi, delay)?;
+ // self.interface.reset(delay, 20_000, 2_000).await;
+ // self.wait_until_idle(spi, delay).await?;
// // panel setting
// // LUT from OTP,KW-BF KWR-AF BWROTP 0f BWOTP 1f
@@ -315,42 +336,45 @@ where
// Ok(())
// }
- fn set_part_reg(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
+ async fn set_part_reg(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
// Reset the EPD driver circuit
//TODO: 这里在微雪的例程中反复刷新了3次,后面有显示问题再进行修改
- self.interface.reset(delay, 10_000, 2_000);
+ self.interface.reset(delay, 10_000, 2_000).await;
// Power settings
//TODO: The data in the document is [0x03,0x00,0x2b,0x2b,0x09].
- self.interface.cmd_with_data(
- spi,
- Command::PowerSetting,
- &[0x03, 0x00, 0x2b, 0x2b, 0x03],
- )?;
+ self.interface
+ .cmd_with_data(spi, Command::PowerSetting, &[0x03, 0x00, 0x2b, 0x2b, 0x03])
+ .await?;
// Soft start
self.interface
- .cmd_with_data(spi, Command::BoosterSoftStart, &[0x17, 0x17, 0x17])?;
+ .cmd_with_data(spi, Command::BoosterSoftStart, &[0x17, 0x17, 0x17])
+ .await?;
// Panel settings
self.interface
- .cmd_with_data(spi, Command::PanelSetting, &[0xbf, 0x0D])?;
+ .cmd_with_data(spi, Command::PanelSetting, &[0xbf, 0x0D])
+ .await?;
// Setting the refresh rate
// 3a 100HZ | 29 150Hz | 39 200HZ | 31 171HZ
// 3a is used in the example
self.interface
- .cmd_with_data(spi, Command::PllControl, &[0x3C])?;
+ .cmd_with_data(spi, Command::PllControl, &[0x3C])
+ .await?;
// Resolution Settings
self.interface
- .cmd_with_data(spi, Command::ResolutionSetting, &[0x80, 0x01, 0x28])?;
+ .cmd_with_data(spi, Command::ResolutionSetting, &[0x80, 0x01, 0x28])
+ .await?;
// vcom_DC settings
self.interface
- .cmd_with_data(spi, Command::VcmDcSetting, &[0x12])?;
+ .cmd_with_data(spi, Command::VcmDcSetting, &[0x12])
+ .await?;
- self.set_lut(spi, delay, None)?;
+ self.set_lut(spi, delay, None).await?;
// Power on
// self.interface.cmd_with_data(
@@ -358,11 +382,11 @@ where
// Command::PowerOn,
// &[0x04],
// );
- self.interface.cmd(spi, Command::PowerOn)?;
+ self.interface.cmd(spi, Command::PowerOn).await?;
// Get the BUSY level, high to continue, low to wait for the screen to respond.
//TODO: This is the recommended step in the documentation, but I've ignored it since I've seen other screens that don't wait.
- self.wait_until_idle(spi, delay)?;
+ self.wait_until_idle(spi, delay).await?;
// vcom and data interval settings
// self.interface
@@ -372,7 +396,7 @@ where
}
#[allow(clippy::too_many_arguments)]
- fn set_lut_helper(
+ async fn set_lut_helper(
&mut self,
spi: &mut SPI,
delay: &mut DELAY,
@@ -385,23 +409,28 @@ where
let _ = delay;
// LUT VCOM
self.interface
- .cmd_with_data(spi, Command::LutForVcom, lut_vcom)?;
+ .cmd_with_data(spi, Command::LutForVcom, lut_vcom)
+ .await?;
// LUT WHITE to WHITE
self.interface
- .cmd_with_data(spi, Command::LutWhiteToWhite, lut_ww)?;
+ .cmd_with_data(spi, Command::LutWhiteToWhite, lut_ww)
+ .await?;
// LUT BLACK to WHITE
self.interface
- .cmd_with_data(spi, Command::LutBlackToWhite, lut_bw)?;
+ .cmd_with_data(spi, Command::LutBlackToWhite, lut_bw)
+ .await?;
// LUT WHITE to BLACK
self.interface
- .cmd_with_data(spi, Command::LutWhiteToBlack, lut_wb)?;
+ .cmd_with_data(spi, Command::LutWhiteToBlack, lut_wb)
+ .await?;
// LUT BLACK to BLACK
self.interface
- .cmd_with_data(spi, Command::LutBlackToBlack, lut_bb)?;
+ .cmd_with_data(spi, Command::LutBlackToBlack, lut_bb)
+ .await?;
Ok(())
}
}
diff --git a/src/epd3in7/mod.rs b/src/epd3in7/mod.rs
index c01c49fa..00155d76 100644
--- a/src/epd3in7/mod.rs
+++ b/src/epd3in7/mod.rs
@@ -2,11 +2,7 @@
//!
//!
//! Build with the help of documentation/code from [Waveshare](https://www.waveshare.com/wiki/3.7inch_e-Paper_HAT),
-use embedded_hal::{
- delay::DelayNs,
- digital::{InputPin, OutputPin},
- spi::SpiDevice,
-};
+use embedded_hal::digital::{InputPin, OutputPin};
pub(crate) mod command;
mod constants;
@@ -16,7 +12,7 @@ use self::constants::*;
use crate::buffer_len;
use crate::color::Color;
-use crate::interface::DisplayInterface;
+use crate::interface::{DelayNs, DisplayInterface, SpiDevice};
use crate::traits::{InternalWiAdditions, RefreshLut, WaveshareDisplay};
/// Width of the display.
@@ -50,6 +46,7 @@ pub struct EPD3in7 {
background_color: Color,
}
+#[maybe_async::maybe_async(AFIT)]
impl InternalWiAdditions
for EPD3in7
where
@@ -59,70 +56,89 @@ where
RST: OutputPin,
DELAY: DelayNs,
{
- fn init(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
+ async fn init(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
// reset the device
- self.interface.reset(delay, 30, 10);
+ self.interface.reset(delay, 30, 10).await;
- self.interface.cmd(spi, Command::SwReset)?;
- delay.delay_us(300000u32);
+ self.interface.cmd(spi, Command::SwReset).await?;
+ delay.delay_us(300000u32).await;
self.interface
- .cmd_with_data(spi, Command::AutoWriteRedRamRegularPattern, &[0xF7])?;
- self.interface.wait_until_idle(delay, IS_BUSY_LOW);
+ .cmd_with_data(spi, Command::AutoWriteRedRamRegularPattern, &[0xF7])
+ .await?;
+ self.interface.wait_until_idle(delay, IS_BUSY_LOW).await;
self.interface
- .cmd_with_data(spi, Command::AutoWriteBwRamRegularPattern, &[0xF7])?;
- self.interface.wait_until_idle(delay, IS_BUSY_LOW);
+ .cmd_with_data(spi, Command::AutoWriteBwRamRegularPattern, &[0xF7])
+ .await?;
+ self.interface.wait_until_idle(delay, IS_BUSY_LOW).await;
self.interface
- .cmd_with_data(spi, Command::GateSetting, &[0xDF, 0x01, 0x00])?;
+ .cmd_with_data(spi, Command::GateSetting, &[0xDF, 0x01, 0x00])
+ .await?;
self.interface
- .cmd_with_data(spi, Command::GateVoltage, &[0x00])?;
+ .cmd_with_data(spi, Command::GateVoltage, &[0x00])
+ .await?;
self.interface
- .cmd_with_data(spi, Command::GateVoltageSource, &[0x41, 0xA8, 0x32])?;
+ .cmd_with_data(spi, Command::GateVoltageSource, &[0x41, 0xA8, 0x32])
+ .await?;
self.interface
- .cmd_with_data(spi, Command::DataEntrySequence, &[0x03])?;
+ .cmd_with_data(spi, Command::DataEntrySequence, &[0x03])
+ .await?;
self.interface
- .cmd_with_data(spi, Command::BorderWaveformControl, &[0x03])?;
+ .cmd_with_data(spi, Command::BorderWaveformControl, &[0x03])
+ .await?;
- self.interface.cmd_with_data(
- spi,
- Command::BoosterSoftStartControl,
- &[0xAE, 0xC7, 0xC3, 0xC0, 0xC0],
- )?;
+ self.interface
+ .cmd_with_data(
+ spi,
+ Command::BoosterSoftStartControl,
+ &[0xAE, 0xC7, 0xC3, 0xC0, 0xC0],
+ )
+ .await?;
+
+ self.interface
+ .cmd_with_data(spi, Command::TemperatureSensorSelection, &[0x80])
+ .await?;
self.interface
- .cmd_with_data(spi, Command::TemperatureSensorSelection, &[0x80])?;
+ .cmd_with_data(spi, Command::WriteVcomRegister, &[0x44])
+ .await?;
self.interface
- .cmd_with_data(spi, Command::WriteVcomRegister, &[0x44])?;
-
- self.interface.cmd_with_data(
- spi,
- Command::DisplayOption,
- &[0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x4F, 0xFF, 0xFF, 0xFF, 0xFF],
- )?;
-
- self.interface.cmd_with_data(
- spi,
- Command::SetRamXAddressStartEndPosition,
- &[0x00, 0x00, 0x17, 0x01],
- )?;
- self.interface.cmd_with_data(
- spi,
- Command::SetRamYAddressStartEndPosition,
- &[0x00, 0x00, 0xDF, 0x01],
- )?;
+ .cmd_with_data(
+ spi,
+ Command::DisplayOption,
+ &[0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x4F, 0xFF, 0xFF, 0xFF, 0xFF],
+ )
+ .await?;
+
+ self.interface
+ .cmd_with_data(
+ spi,
+ Command::SetRamXAddressStartEndPosition,
+ &[0x00, 0x00, 0x17, 0x01],
+ )
+ .await?;
+ self.interface
+ .cmd_with_data(
+ spi,
+ Command::SetRamYAddressStartEndPosition,
+ &[0x00, 0x00, 0xDF, 0x01],
+ )
+ .await?;
self.interface
- .cmd_with_data(spi, Command::DisplayUpdateSequenceSetting, &[0xCF])?;
+ .cmd_with_data(spi, Command::DisplayUpdateSequenceSetting, &[0xCF])
+ .await?;
- self.set_lut(spi, delay, Some(RefreshLut::Full))?;
+ self.set_lut(spi, delay, Some(RefreshLut::Full)).await?;
Ok(())
}
}
+#[maybe_async::maybe_async(AFIT)]
impl WaveshareDisplay
for EPD3in7
where
@@ -134,7 +150,7 @@ where
{
type DisplayColor = Color;
- fn new(
+ async fn new(
spi: &mut SPI,
busy: BUSY,
dc: DC,
@@ -147,19 +163,22 @@ where
background_color: DEFAULT_BACKGROUND_COLOR,
};
- epd.init(spi, delay)?;
+ epd.init(spi, delay).await?;
Ok(epd)
}
- fn wake_up(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
- self.init(spi, delay)
+ async fn wake_up(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
+ self.init(spi, delay).await
}
- fn sleep(&mut self, spi: &mut SPI, _delay: &mut DELAY) -> Result<(), SPI::Error> {
- self.interface.cmd_with_data(spi, Command::Sleep, &[0xF7])?;
- self.interface.cmd(spi, Command::PowerOff)?;
+ async fn sleep(&mut self, spi: &mut SPI, _delay: &mut DELAY) -> Result<(), SPI::Error> {
self.interface
- .cmd_with_data(spi, Command::Sleep2, &[0xA5])?;
+ .cmd_with_data(spi, Command::Sleep, &[0xF7])
+ .await?;
+ self.interface.cmd(spi, Command::PowerOff).await?;
+ self.interface
+ .cmd_with_data(spi, Command::Sleep2, &[0xA5])
+ .await?;
Ok(())
}
@@ -179,7 +198,7 @@ where
HEIGHT
}
- fn update_frame(
+ async fn update_frame(
&mut self,
spi: &mut SPI,
buffer: &[u8],
@@ -187,18 +206,21 @@ where
) -> Result<(), SPI::Error> {
assert!(buffer.len() == buffer_len(WIDTH as usize, HEIGHT as usize));
self.interface
- .cmd_with_data(spi, Command::SetRamXAddressCounter, &[0x00, 0x00])?;
+ .cmd_with_data(spi, Command::SetRamXAddressCounter, &[0x00, 0x00])
+ .await?;
self.interface
- .cmd_with_data(spi, Command::SetRamYAddressCounter, &[0x00, 0x00])?;
+ .cmd_with_data(spi, Command::SetRamYAddressCounter, &[0x00, 0x00])
+ .await?;
self.interface
- .cmd_with_data(spi, Command::WriteRam, buffer)?;
+ .cmd_with_data(spi, Command::WriteRam, buffer)
+ .await?;
Ok(())
}
#[allow(unused)]
- fn update_partial_frame(
+ async fn update_partial_frame(
&mut self,
spi: &mut SPI,
delay: &mut DELAY,
@@ -211,39 +233,45 @@ where
todo!()
}
- fn display_frame(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
+ async fn display_frame(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
//self.interface
// .cmd_with_data(spi, Command::WRITE_LUT_REGISTER, &LUT_1GRAY_GC)?;
- self.interface.cmd(spi, Command::DisplayUpdateSequence)?;
- self.interface.wait_until_idle(delay, IS_BUSY_LOW);
+ self.interface
+ .cmd(spi, Command::DisplayUpdateSequence)
+ .await?;
+ self.interface.wait_until_idle(delay, IS_BUSY_LOW).await;
Ok(())
}
- fn update_and_display_frame(
+ async fn update_and_display_frame(
&mut self,
spi: &mut SPI,
buffer: &[u8],
delay: &mut DELAY,
) -> Result<(), SPI::Error> {
- self.update_frame(spi, buffer, delay)?;
- self.display_frame(spi, delay)?;
+ self.update_frame(spi, buffer, delay).await?;
+ self.display_frame(spi, delay).await?;
Ok(())
}
- fn clear_frame(&mut self, spi: &mut SPI, _delay: &mut DELAY) -> Result<(), SPI::Error> {
+ async fn clear_frame(&mut self, spi: &mut SPI, _delay: &mut DELAY) -> Result<(), SPI::Error> {
self.interface
- .cmd_with_data(spi, Command::SetRamXAddressCounter, &[0x00, 0x00])?;
+ .cmd_with_data(spi, Command::SetRamXAddressCounter, &[0x00, 0x00])
+ .await?;
self.interface
- .cmd_with_data(spi, Command::SetRamYAddressCounter, &[0x00, 0x00])?;
+ .cmd_with_data(spi, Command::SetRamYAddressCounter, &[0x00, 0x00])
+ .await?;
let color = self.background_color.get_byte_value();
- self.interface.cmd(spi, Command::WriteRam)?;
- self.interface.data_x_times(spi, color, WIDTH * HEIGHT)?;
+ self.interface.cmd(spi, Command::WriteRam).await?;
+ self.interface
+ .data_x_times(spi, color, WIDTH * HEIGHT)
+ .await?;
Ok(())
}
- fn set_lut(
+ async fn set_lut(
&mut self,
spi: &mut SPI,
_delay: &mut DELAY,
@@ -255,12 +283,17 @@ where
};
self.interface
- .cmd_with_data(spi, Command::WriteLutRegister, buffer)?;
+ .cmd_with_data(spi, Command::WriteLutRegister, buffer)
+ .await?;
Ok(())
}
- fn wait_until_idle(&mut self, _spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
- self.interface.wait_until_idle(delay, IS_BUSY_LOW);
+ async fn wait_until_idle(
+ &mut self,
+ _spi: &mut SPI,
+ delay: &mut DELAY,
+ ) -> Result<(), SPI::Error> {
+ self.interface.wait_until_idle(delay, IS_BUSY_LOW).await;
Ok(())
}
}
diff --git a/src/epd4in2/mod.rs b/src/epd4in2/mod.rs
index 6de676e6..cf6d8e73 100644
--- a/src/epd4in2/mod.rs
+++ b/src/epd4in2/mod.rs
@@ -49,9 +49,9 @@
//!
//! BE CAREFUL! The screen can get ghosting/burn-ins through the Partial Fast Update Drawing.
-use embedded_hal::{delay::*, digital::*, spi::SpiDevice};
+use embedded_hal::digital::*;
-use crate::interface::DisplayInterface;
+use crate::interface::{DelayNs, DisplayInterface, SpiDevice};
use crate::traits::{InternalWiAdditions, QuickRefresh, RefreshLut, WaveshareDisplay};
//The Lookup Tables for the Display
@@ -94,6 +94,7 @@ pub struct Epd4in2 {
refresh: RefreshLut,
}
+#[maybe_async::maybe_async(AFIT)]
impl InternalWiAdditions
for Epd4in2
where
@@ -103,51 +104,55 @@ where
RST: OutputPin,
DELAY: DelayNs,
{
- fn init(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
+ async fn init(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
// reset the device
- self.interface.reset(delay, 10_000, 10_000);
+ self.interface.reset(delay, 10_000, 10_000).await;
// set the power settings
- self.interface.cmd_with_data(
- spi,
- Command::PowerSetting,
- &[0x03, 0x00, 0x2b, 0x2b, 0xff],
- )?;
+ self.interface
+ .cmd_with_data(spi, Command::PowerSetting, &[0x03, 0x00, 0x2b, 0x2b, 0xff])
+ .await?;
// start the booster
self.interface
- .cmd_with_data(spi, Command::BoosterSoftStart, &[0x17, 0x17, 0x17])?;
+ .cmd_with_data(spi, Command::BoosterSoftStart, &[0x17, 0x17, 0x17])
+ .await?;
// power on
- self.command(spi, Command::PowerOn)?;
- delay.delay_us(5000);
- self.wait_until_idle(spi, delay)?;
+ self.command(spi, Command::PowerOn).await?;
+ delay.delay_us(5000).await;
+ self.wait_until_idle(spi, delay).await?;
// set the panel settings
- self.cmd_with_data(spi, Command::PanelSetting, &[0x3F])?;
+ self.cmd_with_data(spi, Command::PanelSetting, &[0x3F])
+ .await?;
// Set Frequency, 200 Hz didn't work on my board
// 150Hz and 171Hz wasn't tested yet
// TODO: Test these other frequencies
// 3A 100HZ 29 150Hz 39 200HZ 31 171HZ DEFAULT: 3c 50Hz
- self.cmd_with_data(spi, Command::PllControl, &[0x3A])?;
+ self.cmd_with_data(spi, Command::PllControl, &[0x3A])
+ .await?;
- self.send_resolution(spi)?;
+ self.send_resolution(spi).await?;
self.interface
- .cmd_with_data(spi, Command::VcmDcSetting, &[0x12])?;
+ .cmd_with_data(spi, Command::VcmDcSetting, &[0x12])
+ .await?;
//VBDF 17|D7 VBDW 97 VBDB 57 VBDF F7 VBDW 77 VBDB 37 VBDR B7
self.interface
- .cmd_with_data(spi, Command::VcomAndDataIntervalSetting, &[0x97])?;
+ .cmd_with_data(spi, Command::VcomAndDataIntervalSetting, &[0x97])
+ .await?;
- self.set_lut(spi, delay, None)?;
+ self.set_lut(spi, delay, None).await?;
- self.wait_until_idle(spi, delay)?;
+ self.wait_until_idle(spi, delay).await?;
Ok(())
}
}
+#[maybe_async::maybe_async(AFIT)]
impl WaveshareDisplay
for Epd4in2
where
@@ -158,7 +163,7 @@ where
DELAY: DelayNs,
{
type DisplayColor = Color;
- fn new(
+ async fn new(
spi: &mut SPI,
busy: BUSY,
dc: DC,
@@ -175,32 +180,34 @@ where
refresh: RefreshLut::Full,
};
- epd.init(spi, delay)?;
+ epd.init(spi, delay).await?;
Ok(epd)
}
- fn sleep(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
- self.wait_until_idle(spi, delay)?;
+ async fn sleep(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
+ self.wait_until_idle(spi, delay).await?;
self.interface
- .cmd_with_data(spi, Command::VcomAndDataIntervalSetting, &[0x17])?; //border floating
- self.command(spi, Command::VcmDcSetting)?; // VCOM to 0V
- self.command(spi, Command::PanelSetting)?;
+ .cmd_with_data(spi, Command::VcomAndDataIntervalSetting, &[0x17])
+ .await?; //border floating
+ self.command(spi, Command::VcmDcSetting).await?; // VCOM to 0V
+ self.command(spi, Command::PanelSetting).await?;
- self.command(spi, Command::PowerSetting)?; //VG&VS to 0V fast
+ self.command(spi, Command::PowerSetting).await?; //VG&VS to 0V fast
for _ in 0..4 {
- self.send_data(spi, &[0x00])?;
+ self.send_data(spi, &[0x00]).await?;
}
- self.command(spi, Command::PowerOff)?;
- self.wait_until_idle(spi, delay)?;
+ self.command(spi, Command::PowerOff).await?;
+ self.wait_until_idle(spi, delay).await?;
self.interface
- .cmd_with_data(spi, Command::DeepSleep, &[0xA5])?;
+ .cmd_with_data(spi, Command::DeepSleep, &[0xA5])
+ .await?;
Ok(())
}
- fn wake_up(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
- self.init(spi, delay)
+ async fn wake_up(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
+ self.init(spi, delay).await
}
fn set_background_color(&mut self, color: Color) {
@@ -219,25 +226,29 @@ where
HEIGHT
}
- fn update_frame(
+ async fn update_frame(
&mut self,
spi: &mut SPI,
buffer: &[u8],
delay: &mut DELAY,
) -> Result<(), SPI::Error> {
- self.wait_until_idle(spi, delay)?;
+ self.wait_until_idle(spi, delay).await?;
let color_value = self.color.get_byte_value();
- self.interface.cmd(spi, Command::DataStartTransmission1)?;
self.interface
- .data_x_times(spi, color_value, WIDTH / 8 * HEIGHT)?;
+ .cmd(spi, Command::DataStartTransmission1)
+ .await?;
+ self.interface
+ .data_x_times(spi, color_value, WIDTH / 8 * HEIGHT)
+ .await?;
self.interface
- .cmd_with_data(spi, Command::DataStartTransmission2, buffer)?;
+ .cmd_with_data(spi, Command::DataStartTransmission2, buffer)
+ .await?;
Ok(())
}
- fn update_partial_frame(
+ async fn update_partial_frame(
&mut self,
spi: &mut SPI,
delay: &mut DELAY,
@@ -247,77 +258,84 @@ where
width: u32,
height: u32,
) -> Result<(), SPI::Error> {
- self.wait_until_idle(spi, delay)?;
+ self.wait_until_idle(spi, delay).await?;
if buffer.len() as u32 != width / 8 * height {
//TODO: panic!! or sth like that
//return Err("Wrong buffersize");
}
- self.command(spi, Command::PartialIn)?;
- self.command(spi, Command::PartialWindow)?;
- self.send_data(spi, &[(x >> 8) as u8])?;
+ self.command(spi, Command::PartialIn).await?;
+ self.command(spi, Command::PartialWindow).await?;
+ self.send_data(spi, &[(x >> 8) as u8]).await?;
let tmp = x & 0xf8;
- self.send_data(spi, &[tmp as u8])?; // x should be the multiple of 8, the last 3 bit will always be ignored
+ self.send_data(spi, &[tmp as u8]).await?; // x should be the multiple of 8, the last 3 bit will always be ignored
let tmp = tmp + width - 1;
- self.send_data(spi, &[(tmp >> 8) as u8])?;
- self.send_data(spi, &[(tmp | 0x07) as u8])?;
+ self.send_data(spi, &[(tmp >> 8) as u8]).await?;
+ self.send_data(spi, &[(tmp | 0x07) as u8]).await?;
- self.send_data(spi, &[(y >> 8) as u8])?;
- self.send_data(spi, &[y as u8])?;
+ self.send_data(spi, &[(y >> 8) as u8]).await?;
+ self.send_data(spi, &[y as u8]).await?;
- self.send_data(spi, &[((y + height - 1) >> 8) as u8])?;
- self.send_data(spi, &[(y + height - 1) as u8])?;
+ self.send_data(spi, &[((y + height - 1) >> 8) as u8])
+ .await?;
+ self.send_data(spi, &[(y + height - 1) as u8]).await?;
- self.send_data(spi, &[0x01])?; // Gates scan both inside and outside of the partial window. (default)
+ self.send_data(spi, &[0x01]).await?; // Gates scan both inside and outside of the partial window. (default)
//TODO: handle dtm somehow
let is_dtm1 = false;
if is_dtm1 {
- self.command(spi, Command::DataStartTransmission1)? //TODO: check if data_start transmission 1 also needs "old"/background data here
+ self.command(spi, Command::DataStartTransmission1).await? //TODO: check if data_start transmission 1 also needs "old"/background data here
} else {
- self.command(spi, Command::DataStartTransmission2)?
+ self.command(spi, Command::DataStartTransmission2).await?
}
- self.send_data(spi, buffer)?;
+ self.send_data(spi, buffer).await?;
- self.command(spi, Command::PartialOut)?;
+ self.command(spi, Command::PartialOut).await?;
Ok(())
}
- fn display_frame(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
- self.wait_until_idle(spi, delay)?;
- self.command(spi, Command::DisplayRefresh)?;
+ async fn display_frame(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
+ self.wait_until_idle(spi, delay).await?;
+ self.command(spi, Command::DisplayRefresh).await?;
Ok(())
}
- fn update_and_display_frame(
+ async fn update_and_display_frame(
&mut self,
spi: &mut SPI,
buffer: &[u8],
delay: &mut DELAY,
) -> Result<(), SPI::Error> {
- self.update_frame(spi, buffer, delay)?;
- self.command(spi, Command::DisplayRefresh)?;
+ self.update_frame(spi, buffer, delay).await?;
+ self.command(spi, Command::DisplayRefresh).await?;
Ok(())
}
- fn clear_frame(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
- self.wait_until_idle(spi, delay)?;
- self.send_resolution(spi)?;
+ async fn clear_frame(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
+ self.wait_until_idle(spi, delay).await?;
+ self.send_resolution(spi).await?;
let color_value = self.color.get_byte_value();
- self.interface.cmd(spi, Command::DataStartTransmission1)?;
self.interface
- .data_x_times(spi, color_value, WIDTH / 8 * HEIGHT)?;
+ .cmd(spi, Command::DataStartTransmission1)
+ .await?;
+ self.interface
+ .data_x_times(spi, color_value, WIDTH / 8 * HEIGHT)
+ .await?;
- self.interface.cmd(spi, Command::DataStartTransmission2)?;
self.interface
- .data_x_times(spi, color_value, WIDTH / 8 * HEIGHT)?;
+ .cmd(spi, Command::DataStartTransmission2)
+ .await?;
+ self.interface
+ .data_x_times(spi, color_value, WIDTH / 8 * HEIGHT)
+ .await?;
Ok(())
}
- fn set_lut(
+ async fn set_lut(
&mut self,
spi: &mut SPI,
delay: &mut DELAY,
@@ -340,14 +358,20 @@ where
&LUT_BB_QUICK,
),
}
+ .await
}
- fn wait_until_idle(&mut self, _spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
- self.interface.wait_until_idle(delay, IS_BUSY_LOW);
+ async fn wait_until_idle(
+ &mut self,
+ _spi: &mut SPI,
+ delay: &mut DELAY,
+ ) -> Result<(), SPI::Error> {
+ self.interface.wait_until_idle(delay, IS_BUSY_LOW).await;
Ok(())
}
}
+#[maybe_async::maybe_async]
impl Epd4in2
where
SPI: SpiDevice,
@@ -356,36 +380,36 @@ where
RST: OutputPin,
DELAY: DelayNs,
{
- fn command(&mut self, spi: &mut SPI, command: Command) -> Result<(), SPI::Error> {
- self.interface.cmd(spi, command)
+ async fn command(&mut self, spi: &mut SPI, command: Command) -> Result<(), SPI::Error> {
+ self.interface.cmd(spi, command).await
}
- fn send_data(&mut self, spi: &mut SPI, data: &[u8]) -> Result<(), SPI::Error> {
- self.interface.data(spi, data)
+ async fn send_data(&mut self, spi: &mut SPI, data: &[u8]) -> Result<(), SPI::Error> {
+ self.interface.data(spi, data).await
}
- fn cmd_with_data(
+ async fn cmd_with_data(
&mut self,
spi: &mut SPI,
command: Command,
data: &[u8],
) -> Result<(), SPI::Error> {
- self.interface.cmd_with_data(spi, command, data)
+ self.interface.cmd_with_data(spi, command, data).await
}
- fn send_resolution(&mut self, spi: &mut SPI) -> Result<(), SPI::Error> {
+ async fn send_resolution(&mut self, spi: &mut SPI) -> Result<(), SPI::Error> {
let w = self.width();
let h = self.height();
- self.command(spi, Command::ResolutionSetting)?;
- self.send_data(spi, &[(w >> 8) as u8])?;
- self.send_data(spi, &[w as u8])?;
- self.send_data(spi, &[(h >> 8) as u8])?;
- self.send_data(spi, &[h as u8])
+ self.command(spi, Command::ResolutionSetting).await?;
+ self.send_data(spi, &[(w >> 8) as u8]).await?;
+ self.send_data(spi, &[w as u8]).await?;
+ self.send_data(spi, &[(h >> 8) as u8]).await?;
+ self.send_data(spi, &[h as u8]).await
}
#[allow(clippy::too_many_arguments)]
- fn set_lut_helper(
+ async fn set_lut_helper(
&mut self,
spi: &mut SPI,
delay: &mut DELAY,
@@ -395,27 +419,32 @@ where
lut_wb: &[u8],
lut_bb: &[u8],
) -> Result<(), SPI::Error> {
- self.wait_until_idle(spi, delay)?;
+ self.wait_until_idle(spi, delay).await?;
// LUT VCOM
- self.cmd_with_data(spi, Command::LutForVcom, lut_vcom)?;
+ self.cmd_with_data(spi, Command::LutForVcom, lut_vcom)
+ .await?;
// LUT WHITE to WHITE
- self.cmd_with_data(spi, Command::LutWhiteToWhite, lut_ww)?;
+ self.cmd_with_data(spi, Command::LutWhiteToWhite, lut_ww)
+ .await?;
// LUT BLACK to WHITE
- self.cmd_with_data(spi, Command::LutBlackToWhite, lut_bw)?;
+ self.cmd_with_data(spi, Command::LutBlackToWhite, lut_bw)
+ .await?;
// LUT WHITE to BLACK
- self.cmd_with_data(spi, Command::LutWhiteToBlack, lut_wb)?;
+ self.cmd_with_data(spi, Command::LutWhiteToBlack, lut_wb)
+ .await?;
// LUT BLACK to BLACK
- self.cmd_with_data(spi, Command::LutBlackToBlack, lut_bb)?;
+ self.cmd_with_data(spi, Command::LutBlackToBlack, lut_bb)
+ .await?;
Ok(())
}
/// Helper function. Sets up the display to send pixel data to a custom
/// starting point.
- pub fn shift_display(
+ pub async fn shift_display(
&mut self,
spi: &mut SPI,
x: u32,
@@ -423,25 +452,27 @@ where
width: u32,
height: u32,
) -> Result<(), SPI::Error> {
- self.send_data(spi, &[(x >> 8) as u8])?;
+ self.send_data(spi, &[(x >> 8) as u8]).await?;
let tmp = x & 0xf8;
- self.send_data(spi, &[tmp as u8])?; // x should be the multiple of 8, the last 3 bit will always be ignored
+ self.send_data(spi, &[tmp as u8]).await?; // x should be the multiple of 8, the last 3 bit will always be ignored
let tmp = tmp + width - 1;
- self.send_data(spi, &[(tmp >> 8) as u8])?;
- self.send_data(spi, &[(tmp | 0x07) as u8])?;
+ self.send_data(spi, &[(tmp >> 8) as u8]).await?;
+ self.send_data(spi, &[(tmp | 0x07) as u8]).await?;
- self.send_data(spi, &[(y >> 8) as u8])?;
- self.send_data(spi, &[y as u8])?;
+ self.send_data(spi, &[(y >> 8) as u8]).await?;
+ self.send_data(spi, &[y as u8]).await?;
- self.send_data(spi, &[((y + height - 1) >> 8) as u8])?;
- self.send_data(spi, &[(y + height - 1) as u8])?;
+ self.send_data(spi, &[((y + height - 1) >> 8) as u8])
+ .await?;
+ self.send_data(spi, &[(y + height - 1) as u8]).await?;
- self.send_data(spi, &[0x01])?; // Gates scan both inside and outside of the partial window. (default)
+ self.send_data(spi, &[0x01]).await?; // Gates scan both inside and outside of the partial window. (default)
Ok(())
}
}
+#[maybe_async::maybe_async(AFIT)]
impl QuickRefresh
for Epd4in2
where
@@ -452,59 +483,67 @@ where
DELAY: DelayNs,
{
/// To be followed immediately after by `update_old_frame`.
- fn update_old_frame(
+ async fn update_old_frame(
&mut self,
spi: &mut SPI,
buffer: &[u8],
delay: &mut DELAY,
) -> Result<(), SPI::Error> {
- self.wait_until_idle(spi, delay)?;
+ self.wait_until_idle(spi, delay).await?;
- self.interface.cmd(spi, Command::DataStartTransmission1)?;
+ self.interface
+ .cmd(spi, Command::DataStartTransmission1)
+ .await?;
- self.interface.data(spi, buffer)?;
+ self.interface.data(spi, buffer).await?;
Ok(())
}
/// To be used immediately after `update_old_frame`.
- fn update_new_frame(
+ async fn update_new_frame(
&mut self,
spi: &mut SPI,
buffer: &[u8],
delay: &mut DELAY,
) -> Result<(), SPI::Error> {
- self.wait_until_idle(spi, delay)?;
- // self.send_resolution(spi)?;
+ self.wait_until_idle(spi, delay).await?;
+ // self.send_resolution(spi).await?;
- self.interface.cmd(spi, Command::DataStartTransmission2)?;
+ self.interface
+ .cmd(spi, Command::DataStartTransmission2)
+ .await?;
- self.interface.data(spi, buffer)?;
+ self.interface.data(spi, buffer).await?;
Ok(())
}
/// This is a wrapper around `display_frame` for using this device as a true
/// `QuickRefresh` device.
- fn display_new_frame(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
- self.display_frame(spi, delay)
+ async fn display_new_frame(
+ &mut self,
+ spi: &mut SPI,
+ delay: &mut DELAY,
+ ) -> Result<(), SPI::Error> {
+ self.display_frame(spi, delay).await
}
/// This is wrapper around `update_new_frame` and `display_frame` for using
/// this device as a true `QuickRefresh` device.
///
/// To be used immediately after `update_old_frame`.
- fn update_and_display_new_frame(
+ async fn update_and_display_new_frame(
&mut self,
spi: &mut SPI,
buffer: &[u8],
delay: &mut DELAY,
) -> Result<(), SPI::Error> {
- self.update_new_frame(spi, buffer, delay)?;
- self.display_frame(spi, delay)
+ self.update_new_frame(spi, buffer, delay).await?;
+ self.display_frame(spi, delay).await
}
- fn update_partial_old_frame(
+ async fn update_partial_old_frame(
&mut self,
spi: &mut SPI,
delay: &mut DELAY,
@@ -514,28 +553,30 @@ where
width: u32,
height: u32,
) -> Result<(), SPI::Error> {
- self.wait_until_idle(spi, delay)?;
+ self.wait_until_idle(spi, delay).await?;
if buffer.len() as u32 != width / 8 * height {
//TODO: panic!! or sth like that
//return Err("Wrong buffersize");
}
- self.interface.cmd(spi, Command::PartialIn)?;
- self.interface.cmd(spi, Command::PartialWindow)?;
+ self.interface.cmd(spi, Command::PartialIn).await?;
+ self.interface.cmd(spi, Command::PartialWindow).await?;
- self.shift_display(spi, x, y, width, height)?;
+ self.shift_display(spi, x, y, width, height).await?;
- self.interface.cmd(spi, Command::DataStartTransmission1)?;
+ self.interface
+ .cmd(spi, Command::DataStartTransmission1)
+ .await?;
- self.interface.data(spi, buffer)?;
+ self.interface.data(spi, buffer).await?;
Ok(())
}
/// Always call `update_partial_old_frame` before this, with buffer-updating code
/// between the calls.
- fn update_partial_new_frame(
+ async fn update_partial_new_frame(
&mut self,
spi: &mut SPI,
delay: &mut DELAY,
@@ -545,23 +586,25 @@ where
width: u32,
height: u32,
) -> Result<(), SPI::Error> {
- self.wait_until_idle(spi, delay)?;
+ self.wait_until_idle(spi, delay).await?;
if buffer.len() as u32 != width / 8 * height {
//TODO: panic!! or sth like that
//return Err("Wrong buffersize");
}
- self.shift_display(spi, x, y, width, height)?;
+ self.shift_display(spi, x, y, width, height).await?;
- self.interface.cmd(spi, Command::DataStartTransmission2)?;
+ self.interface
+ .cmd(spi, Command::DataStartTransmission2)
+ .await?;
- self.interface.data(spi, buffer)?;
+ self.interface.data(spi, buffer).await?;
- self.interface.cmd(spi, Command::PartialOut)?;
+ self.interface.cmd(spi, Command::PartialOut).await?;
Ok(())
}
- fn clear_partial_frame(
+ async fn clear_partial_frame(
&mut self,
spi: &mut SPI,
delay: &mut DELAY,
@@ -570,25 +613,31 @@ where
width: u32,
height: u32,
) -> Result<(), SPI::Error> {
- self.wait_until_idle(spi, delay)?;
- self.send_resolution(spi)?;
+ self.wait_until_idle(spi, delay).await?;
+ self.send_resolution(spi).await?;
let color_value = self.color.get_byte_value();
- self.interface.cmd(spi, Command::PartialIn)?;
- self.interface.cmd(spi, Command::PartialWindow)?;
+ self.interface.cmd(spi, Command::PartialIn).await?;
+ self.interface.cmd(spi, Command::PartialWindow).await?;
- self.shift_display(spi, x, y, width, height)?;
+ self.shift_display(spi, x, y, width, height).await?;
- self.interface.cmd(spi, Command::DataStartTransmission1)?;
self.interface
- .data_x_times(spi, color_value, width / 8 * height)?;
+ .cmd(spi, Command::DataStartTransmission1)
+ .await?;
+ self.interface
+ .data_x_times(spi, color_value, width / 8 * height)
+ .await?;
- self.interface.cmd(spi, Command::DataStartTransmission2)?;
self.interface
- .data_x_times(spi, color_value, width / 8 * height)?;
+ .cmd(spi, Command::DataStartTransmission2)
+ .await?;
+ self.interface
+ .data_x_times(spi, color_value, width / 8 * height)
+ .await?;
- self.interface.cmd(spi, Command::PartialOut)?;
+ self.interface.cmd(spi, Command::PartialOut).await?;
Ok(())
}
}
diff --git a/src/epd5in65f/mod.rs b/src/epd5in65f/mod.rs
index 1a70b78a..9dafa513 100644
--- a/src/epd5in65f/mod.rs
+++ b/src/epd5in65f/mod.rs
@@ -6,14 +6,10 @@
//! - [Waveshare C driver](https://github.com/waveshare/e-Paper/blob/master/RaspberryPi%26JetsonNano/c/lib/e-Paper/EPD_5in65f.c)
//! - [Waveshare Python driver](https://github.com/waveshare/e-Paper/blob/master/RaspberryPi%26JetsonNano/python/lib/waveshare_epd/epd5in65f.py)
-use embedded_hal::{
- delay::DelayNs,
- digital::{InputPin, OutputPin},
- spi::SpiDevice,
-};
+use embedded_hal::digital::{InputPin, OutputPin};
use crate::color::OctColor;
-use crate::interface::DisplayInterface;
+use crate::interface::{DelayNs, DisplayInterface, SpiDevice};
use crate::traits::{InternalWiAdditions, RefreshLut, WaveshareDisplay};
pub(crate) mod command;
@@ -48,6 +44,7 @@ pub struct Epd5in65f {
color: OctColor,
}
+#[maybe_async::maybe_async(AFIT)]
impl InternalWiAdditions
for Epd5in65f
where
@@ -57,29 +54,37 @@ where
RST: OutputPin,
DELAY: DelayNs,
{
- fn init(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
+ async fn init(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
// Reset the device
- self.interface.reset(delay, 10_000, 2_000);
-
- self.cmd_with_data(spi, Command::PanelSetting, &[0xEF, 0x08])?;
- self.cmd_with_data(spi, Command::PowerSetting, &[0x37, 0x00, 0x23, 0x23])?;
- self.cmd_with_data(spi, Command::PowerOffSequenceSetting, &[0x00])?;
- self.cmd_with_data(spi, Command::BoosterSoftStart, &[0xC7, 0xC7, 0x1D])?;
- self.cmd_with_data(spi, Command::PllControl, &[0x3C])?;
- self.cmd_with_data(spi, Command::TemperatureSensor, &[0x00])?;
- self.update_vcom(spi)?;
- self.cmd_with_data(spi, Command::TconSetting, &[0x22])?;
- self.send_resolution(spi)?;
-
- self.cmd_with_data(spi, Command::FlashMode, &[0xAA])?;
-
- delay.delay_us(100_000);
-
- self.update_vcom(spi)?;
+ self.interface.reset(delay, 10_000, 2_000).await;
+
+ self.cmd_with_data(spi, Command::PanelSetting, &[0xEF, 0x08])
+ .await?;
+ self.cmd_with_data(spi, Command::PowerSetting, &[0x37, 0x00, 0x23, 0x23])
+ .await?;
+ self.cmd_with_data(spi, Command::PowerOffSequenceSetting, &[0x00])
+ .await?;
+ self.cmd_with_data(spi, Command::BoosterSoftStart, &[0xC7, 0xC7, 0x1D])
+ .await?;
+ self.cmd_with_data(spi, Command::PllControl, &[0x3C])
+ .await?;
+ self.cmd_with_data(spi, Command::TemperatureSensor, &[0x00])
+ .await?;
+ self.update_vcom(spi).await?;
+ self.cmd_with_data(spi, Command::TconSetting, &[0x22])
+ .await?;
+ self.send_resolution(spi).await?;
+
+ self.cmd_with_data(spi, Command::FlashMode, &[0xAA]).await?;
+
+ delay.delay_us(100_000).await;
+
+ self.update_vcom(spi).await?;
Ok(())
}
}
+#[maybe_async::maybe_async(AFIT)]
impl WaveshareDisplay
for Epd5in65f
where
@@ -90,7 +95,7 @@ where
DELAY: DelayNs,
{
type DisplayColor = OctColor;
- fn new(
+ async fn new(
spi: &mut SPI,
busy: BUSY,
dc: DC,
@@ -103,34 +108,35 @@ where
let mut epd = Epd5in65f { interface, color };
- epd.init(spi, delay)?;
+ epd.init(spi, delay).await?;
Ok(epd)
}
- fn wake_up(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
- self.init(spi, delay)
+ async fn wake_up(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
+ self.init(spi, delay).await
}
- fn sleep(&mut self, spi: &mut SPI, _delay: &mut DELAY) -> Result<(), SPI::Error> {
- self.cmd_with_data(spi, Command::DeepSleep, &[0xA5])?;
+ async fn sleep(&mut self, spi: &mut SPI, _delay: &mut DELAY) -> Result<(), SPI::Error> {
+ self.cmd_with_data(spi, Command::DeepSleep, &[0xA5]).await?;
Ok(())
}
- fn update_frame(
+ async fn update_frame(
&mut self,
spi: &mut SPI,
buffer: &[u8],
delay: &mut DELAY,
) -> Result<(), SPI::Error> {
- self.wait_until_idle(spi, delay)?;
- self.update_vcom(spi)?;
- self.send_resolution(spi)?;
- self.cmd_with_data(spi, Command::DataStartTransmission1, buffer)?;
+ self.wait_until_idle(spi, delay).await?;
+ self.update_vcom(spi).await?;
+ self.send_resolution(spi).await?;
+ self.cmd_with_data(spi, Command::DataStartTransmission1, buffer)
+ .await?;
Ok(())
}
- fn update_partial_frame(
+ async fn update_partial_frame(
&mut self,
_spi: &mut SPI,
_delay: &mut DELAY,
@@ -143,36 +149,38 @@ where
unimplemented!();
}
- fn display_frame(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
- self.wait_until_idle(spi, delay)?;
- self.command(spi, Command::PowerOn)?;
- self.wait_until_idle(spi, delay)?;
- self.command(spi, Command::DisplayRefresh)?;
- self.wait_until_idle(spi, delay)?;
- self.command(spi, Command::PowerOff)?;
- self.wait_busy_low(delay);
+ async fn display_frame(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
+ self.wait_until_idle(spi, delay).await?;
+ self.command(spi, Command::PowerOn).await?;
+ self.wait_until_idle(spi, delay).await?;
+ self.command(spi, Command::DisplayRefresh).await?;
+ self.wait_until_idle(spi, delay).await?;
+ self.command(spi, Command::PowerOff).await?;
+ self.wait_busy_low(delay).await;
Ok(())
}
- fn update_and_display_frame(
+ async fn update_and_display_frame(
&mut self,
spi: &mut SPI,
buffer: &[u8],
delay: &mut DELAY,
) -> Result<(), SPI::Error> {
- self.update_frame(spi, buffer, delay)?;
- self.display_frame(spi, delay)?;
+ self.update_frame(spi, buffer, delay).await?;
+ self.display_frame(spi, delay).await?;
Ok(())
}
- fn clear_frame(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
+ async fn clear_frame(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
let bg = OctColor::colors_byte(self.color, self.color);
- self.wait_until_idle(spi, delay)?;
- self.update_vcom(spi)?;
- self.send_resolution(spi)?;
- self.command(spi, Command::DataStartTransmission1)?;
- self.interface.data_x_times(spi, bg, WIDTH * HEIGHT / 2)?;
- self.display_frame(spi, delay)?;
+ self.wait_until_idle(spi, delay).await?;
+ self.update_vcom(spi).await?;
+ self.send_resolution(spi).await?;
+ self.command(spi, Command::DataStartTransmission1).await?;
+ self.interface
+ .data_x_times(spi, bg, WIDTH * HEIGHT / 2)
+ .await?;
+ self.display_frame(spi, delay).await?;
Ok(())
}
@@ -192,7 +200,7 @@ where
HEIGHT
}
- fn set_lut(
+ async fn set_lut(
&mut self,
_spi: &mut SPI,
_delay: &mut DELAY,
@@ -201,12 +209,17 @@ where
unimplemented!();
}
- fn wait_until_idle(&mut self, _spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
- self.interface.wait_until_idle(delay, true);
+ async fn wait_until_idle(
+ &mut self,
+ _spi: &mut SPI,
+ delay: &mut DELAY,
+ ) -> Result<(), SPI::Error> {
+ self.interface.wait_until_idle(delay, true).await;
Ok(())
}
}
+#[maybe_async::maybe_async]
impl Epd5in65f
where
SPI: SpiDevice,
@@ -215,40 +228,41 @@ where
RST: OutputPin,
DELAY: DelayNs,
{
- fn command(&mut self, spi: &mut SPI, command: Command) -> Result<(), SPI::Error> {
- self.interface.cmd(spi, command)
+ async fn command(&mut self, spi: &mut SPI, command: Command) -> Result<(), SPI::Error> {
+ self.interface.cmd(spi, command).await
}
- fn send_data(&mut self, spi: &mut SPI, data: &[u8]) -> Result<(), SPI::Error> {
- self.interface.data(spi, data)
+ async fn send_data(&mut self, spi: &mut SPI, data: &[u8]) -> Result<(), SPI::Error> {
+ self.interface.data(spi, data).await
}
- fn cmd_with_data(
+ async fn cmd_with_data(
&mut self,
spi: &mut SPI,
command: Command,
data: &[u8],
) -> Result<(), SPI::Error> {
- self.interface.cmd_with_data(spi, command, data)
+ self.interface.cmd_with_data(spi, command, data).await
}
- fn wait_busy_low(&mut self, delay: &mut DELAY) {
- self.interface.wait_until_idle(delay, false);
+ async fn wait_busy_low(&mut self, delay: &mut DELAY) {
+ self.interface.wait_until_idle(delay, false).await;
}
- fn send_resolution(&mut self, spi: &mut SPI) -> Result<(), SPI::Error> {
+ async fn send_resolution(&mut self, spi: &mut SPI) -> Result<(), SPI::Error> {
let w = self.width();
let h = self.height();
- self.command(spi, Command::TconResolution)?;
- self.send_data(spi, &[(w >> 8) as u8])?;
- self.send_data(spi, &[w as u8])?;
- self.send_data(spi, &[(h >> 8) as u8])?;
- self.send_data(spi, &[h as u8])
+ self.command(spi, Command::TconResolution).await?;
+ self.send_data(spi, &[(w >> 8) as u8]).await?;
+ self.send_data(spi, &[w as u8]).await?;
+ self.send_data(spi, &[(h >> 8) as u8]).await?;
+ self.send_data(spi, &[h as u8]).await
}
- fn update_vcom(&mut self, spi: &mut SPI) -> Result<(), SPI::Error> {
+ async fn update_vcom(&mut self, spi: &mut SPI) -> Result<(), SPI::Error> {
let bg_color = (self.color.get_nibble() & 0b111) << 5;
- self.cmd_with_data(spi, Command::VcomAndDataIntervalSetting, &[0x17 | bg_color])?;
+ self.cmd_with_data(spi, Command::VcomAndDataIntervalSetting, &[0x17 | bg_color])
+ .await?;
Ok(())
}
}
diff --git a/src/epd5in83_v2/mod.rs b/src/epd5in83_v2/mod.rs
index 58909b2c..28caad3c 100644
--- a/src/epd5in83_v2/mod.rs
+++ b/src/epd5in83_v2/mod.rs
@@ -6,14 +6,10 @@
//! - [Waveshare C driver](https://github.com/waveshare/e-Paper/blob/master/RaspberryPi_JetsonNano/c/lib/e-Paper/EPD_5in83_V2.c)
//! - [Waveshare Python driver](https://github.com/waveshare/e-Paper/blob/master/RaspberryPi_JetsonNano/python/lib/waveshare_epd/epd5in83_V2.py)
-use embedded_hal::{
- delay::DelayNs,
- digital::{InputPin, OutputPin},
- spi::SpiDevice,
-};
+use embedded_hal::digital::{InputPin, OutputPin};
use crate::color::Color;
-use crate::interface::DisplayInterface;
+use crate::interface::{DelayNs, DisplayInterface, SpiDevice};
use crate::prelude::WaveshareDisplay;
use crate::traits::{InternalWiAdditions, RefreshLut};
@@ -50,6 +46,7 @@ pub struct Epd5in83 {
color: Color,
}
+#[maybe_async::maybe_async(AFIT)]
impl InternalWiAdditions
for Epd5in83
where
@@ -59,38 +56,43 @@ where
RST: OutputPin,
DELAY: DelayNs,
{
- fn init(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
+ async fn init(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
// Reset the device
- self.interface.reset(delay, 2000, 50);
+ self.interface.reset(delay, 2000, 50).await;
// Set the power settings: VGH=20V,VGL=-20V,VDH=15V,VDL=-15V
- self.cmd_with_data(spi, Command::PowerSetting, &[0x07, 0x07, 0x3F, 0x3F])?;
+ self.cmd_with_data(spi, Command::PowerSetting, &[0x07, 0x07, 0x3F, 0x3F])
+ .await?;
// Power on
- self.command(spi, Command::PowerOn)?;
- delay.delay_us(5000);
- self.wait_until_idle(spi, delay)?;
+ self.command(spi, Command::PowerOn).await?;
+ delay.delay_us(5000).await;
+ self.wait_until_idle(spi, delay).await?;
// Set the panel settings: BWOTP
- self.cmd_with_data(spi, Command::PanelSetting, &[0x1F])?;
+ self.cmd_with_data(spi, Command::PanelSetting, &[0x1F])
+ .await?;
// Set the real resolution
- self.send_resolution(spi)?;
+ self.send_resolution(spi).await?;
// Disable dual SPI
- self.cmd_with_data(spi, Command::DualSPI, &[0x00])?;
+ self.cmd_with_data(spi, Command::DualSPI, &[0x00]).await?;
// Set Vcom and data interval
- self.cmd_with_data(spi, Command::VcomAndDataIntervalSetting, &[0x10, 0x07])?;
+ self.cmd_with_data(spi, Command::VcomAndDataIntervalSetting, &[0x10, 0x07])
+ .await?;
// Set S2G and G2S non-overlap periods to 12 (default)
- self.cmd_with_data(spi, Command::TconSetting, &[0x22])?;
+ self.cmd_with_data(spi, Command::TconSetting, &[0x22])
+ .await?;
- self.wait_until_idle(spi, delay)?;
+ self.wait_until_idle(spi, delay).await?;
Ok(())
}
}
+#[maybe_async::maybe_async(AFIT)]
impl WaveshareDisplay
for Epd5in83
where
@@ -101,7 +103,7 @@ where
DELAY: DelayNs,
{
type DisplayColor = Color;
- fn new(
+ async fn new(
spi: &mut SPI,
busy: BUSY,
dc: DC,
@@ -114,21 +116,21 @@ where
let mut epd = Epd5in83 { interface, color };
- epd.init(spi, delay)?;
+ epd.init(spi, delay).await?;
Ok(epd)
}
- fn sleep(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
- self.wait_until_idle(spi, delay)?;
- self.command(spi, Command::PowerOff)?;
- self.wait_until_idle(spi, delay)?;
- self.cmd_with_data(spi, Command::DeepSleep, &[0xA5])?;
+ async fn sleep(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
+ self.wait_until_idle(spi, delay).await?;
+ self.command(spi, Command::PowerOff).await?;
+ self.wait_until_idle(spi, delay).await?;
+ self.cmd_with_data(spi, Command::DeepSleep, &[0xA5]).await?;
Ok(())
}
- fn wake_up(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
- self.init(spi, delay)
+ async fn wake_up(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
+ self.init(spi, delay).await
}
fn set_background_color(&mut self, color: Color) {
@@ -147,25 +149,29 @@ where
HEIGHT
}
- fn update_frame(
+ async fn update_frame(
&mut self,
spi: &mut SPI,
buffer: &[u8],
delay: &mut DELAY,
) -> Result<(), SPI::Error> {
- self.wait_until_idle(spi, delay)?;
+ self.wait_until_idle(spi, delay).await?;
let color_value = self.color.get_byte_value();
- self.interface.cmd(spi, Command::DataStartTransmission1)?;
self.interface
- .data_x_times(spi, color_value, WIDTH / 8 * HEIGHT)?;
+ .cmd(spi, Command::DataStartTransmission1)
+ .await?;
+ self.interface
+ .data_x_times(spi, color_value, WIDTH / 8 * HEIGHT)
+ .await?;
self.interface
- .cmd_with_data(spi, Command::DataStartTransmission2, buffer)?;
+ .cmd_with_data(spi, Command::DataStartTransmission2, buffer)
+ .await?;
Ok(())
}
- fn update_partial_frame(
+ async fn update_partial_frame(
&mut self,
_spi: &mut SPI,
_delay: &mut DELAY,
@@ -178,36 +184,40 @@ where
unimplemented!()
}
- fn display_frame(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
- self.command(spi, Command::DisplayRefresh)?;
- self.wait_until_idle(spi, delay)?;
+ async fn display_frame(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
+ self.command(spi, Command::DisplayRefresh).await?;
+ self.wait_until_idle(spi, delay).await?;
Ok(())
}
- fn update_and_display_frame(
+ async fn update_and_display_frame(
&mut self,
spi: &mut SPI,
buffer: &[u8],
delay: &mut DELAY,
) -> Result<(), SPI::Error> {
- self.update_frame(spi, buffer, delay)?;
- self.display_frame(spi, delay)?;
+ self.update_frame(spi, buffer, delay).await?;
+ self.display_frame(spi, delay).await?;
Ok(())
}
- fn clear_frame(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
- self.wait_until_idle(spi, delay)?;
+ async fn clear_frame(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
+ self.wait_until_idle(spi, delay).await?;
- self.command(spi, Command::DataStartTransmission1)?;
- self.interface.data_x_times(spi, 0xFF, NUM_DISPLAY_BITS)?;
+ self.command(spi, Command::DataStartTransmission1).await?;
+ self.interface
+ .data_x_times(spi, 0xFF, NUM_DISPLAY_BITS)
+ .await?;
- self.command(spi, Command::DataStartTransmission2)?;
- self.interface.data_x_times(spi, 0x00, NUM_DISPLAY_BITS)?;
+ self.command(spi, Command::DataStartTransmission2).await?;
+ self.interface
+ .data_x_times(spi, 0x00, NUM_DISPLAY_BITS)
+ .await?;
Ok(())
}
- fn set_lut(
+ async fn set_lut(
&mut self,
_spi: &mut SPI,
_delay: &mut DELAY,
@@ -216,12 +226,17 @@ where
unimplemented!();
}
- fn wait_until_idle(&mut self, _spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
- self.interface.wait_until_idle(delay, IS_BUSY_LOW);
+ async fn wait_until_idle(
+ &mut self,
+ _spi: &mut SPI,
+ delay: &mut DELAY,
+ ) -> Result<(), SPI::Error> {
+ self.interface.wait_until_idle(delay, IS_BUSY_LOW).await;
Ok(())
}
}
+#[maybe_async::maybe_async]
impl Epd5in83
where
SPI: SpiDevice,
@@ -230,32 +245,32 @@ where
RST: OutputPin,
DELAY: DelayNs,
{
- fn command(&mut self, spi: &mut SPI, command: Command) -> Result<(), SPI::Error> {
- self.interface.cmd(spi, command)
+ async fn command(&mut self, spi: &mut SPI, command: Command) -> Result<(), SPI::Error> {
+ self.interface.cmd(spi, command).await
}
- fn send_data(&mut self, spi: &mut SPI, data: &[u8]) -> Result<(), SPI::Error> {
- self.interface.data(spi, data)
+ async fn send_data(&mut self, spi: &mut SPI, data: &[u8]) -> Result<(), SPI::Error> {
+ self.interface.data(spi, data).await
}
- fn cmd_with_data(
+ async fn cmd_with_data(
&mut self,
spi: &mut SPI,
command: Command,
data: &[u8],
) -> Result<(), SPI::Error> {
- self.interface.cmd_with_data(spi, command, data)
+ self.interface.cmd_with_data(spi, command, data).await
}
- fn send_resolution(&mut self, spi: &mut SPI) -> Result<(), SPI::Error> {
+ async fn send_resolution(&mut self, spi: &mut SPI) -> Result<(), SPI::Error> {
let w = self.width();
let h = self.height();
- self.command(spi, Command::TconResolution)?;
- self.send_data(spi, &[(w >> 8) as u8])?;
- self.send_data(spi, &[w as u8])?;
- self.send_data(spi, &[(h >> 8) as u8])?;
- self.send_data(spi, &[h as u8])
+ self.command(spi, Command::TconResolution).await?;
+ self.send_data(spi, &[(w >> 8) as u8]).await?;
+ self.send_data(spi, &[w as u8]).await?;
+ self.send_data(spi, &[(h >> 8) as u8]).await?;
+ self.send_data(spi, &[h as u8]).await
}
}
diff --git a/src/epd5in83b_v2/mod.rs b/src/epd5in83b_v2/mod.rs
index 625b1e7c..7138018f 100644
--- a/src/epd5in83b_v2/mod.rs
+++ b/src/epd5in83b_v2/mod.rs
@@ -6,14 +6,10 @@
//! - [Waveshare C driver](https://github.com/waveshare/e-Paper/blob/master/RaspberryPi_JetsonNano/c/lib/e-Paper/EPD_5in83b_V2.c)
//! - [Waveshare Python driver](https://github.com/waveshare/e-Paper/blob/master/RaspberryPi_JetsonNano/python/lib/waveshare_epd/epd5in83b_V2.py)
-use embedded_hal::{
- delay::DelayNs,
- digital::{InputPin, OutputPin},
- spi::SpiDevice,
-};
+use embedded_hal::digital::{InputPin, OutputPin};
use crate::color::Color;
-use crate::interface::DisplayInterface;
+use crate::interface::{DelayNs, DisplayInterface, SpiDevice};
use crate::prelude::{TriColor, WaveshareDisplay, WaveshareThreeColorDisplay};
use crate::traits::{InternalWiAdditions, RefreshLut};
@@ -50,6 +46,7 @@ pub struct Epd5in83 {
color: Color,
}
+#[maybe_async::maybe_async(AFIT)]
impl InternalWiAdditions
for Epd5in83
where
@@ -59,41 +56,47 @@ where
RST: OutputPin,
DELAY: DelayNs,
{
- fn init(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
+ async fn init(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
// Reset the device
- self.interface.reset(delay, 10_000, 10_000);
+ self.interface.reset(delay, 10_000, 10_000).await;
// Start the booster
- self.cmd_with_data(spi, Command::BoosterSoftStart, &[0x17, 0x17, 0x1e, 0x17])?;
+ self.cmd_with_data(spi, Command::BoosterSoftStart, &[0x17, 0x17, 0x1e, 0x17])
+ .await?;
// Set the power settings: VGH=20V,VGL=-20V,VDH=15V,VDL=-15V
- self.cmd_with_data(spi, Command::PowerSetting, &[0x07, 0x07, 0x3F, 0x3F])?;
+ self.cmd_with_data(spi, Command::PowerSetting, &[0x07, 0x07, 0x3F, 0x3F])
+ .await?;
// Power on
- self.command(spi, Command::PowerOn)?;
- delay.delay_us(5000);
- self.wait_until_idle(spi, delay)?;
+ self.command(spi, Command::PowerOn).await?;
+ delay.delay_us(5000).await;
+ self.wait_until_idle(spi, delay).await?;
// Set the panel settings: BWROTP
- self.cmd_with_data(spi, Command::PanelSetting, &[0x0F])?;
+ self.cmd_with_data(spi, Command::PanelSetting, &[0x0F])
+ .await?;
// Set the real resolution
- self.send_resolution(spi)?;
+ self.send_resolution(spi).await?;
// Disable dual SPI
- self.cmd_with_data(spi, Command::DualSPI, &[0x00])?;
+ self.cmd_with_data(spi, Command::DualSPI, &[0x00]).await?;
// Set Vcom and data interval
- self.cmd_with_data(spi, Command::VcomAndDataIntervalSetting, &[0x11, 0x07])?;
+ self.cmd_with_data(spi, Command::VcomAndDataIntervalSetting, &[0x11, 0x07])
+ .await?;
// Set S2G and G2S non-overlap periods to 12 (default)
- self.cmd_with_data(spi, Command::TconSetting, &[0x22])?;
+ self.cmd_with_data(spi, Command::TconSetting, &[0x22])
+ .await?;
- self.wait_until_idle(spi, delay)?;
+ self.wait_until_idle(spi, delay).await?;
Ok(())
}
}
+#[maybe_async::maybe_async(AFIT)]
impl WaveshareThreeColorDisplay
for Epd5in83
where
@@ -103,41 +106,44 @@ where
RST: OutputPin,
DELAY: DelayNs,
{
- fn update_color_frame(
+ async fn update_color_frame(
&mut self,
spi: &mut SPI,
delay: &mut DELAY,
black: &[u8],
chromatic: &[u8],
) -> Result<(), SPI::Error> {
- self.update_achromatic_frame(spi, delay, black)?;
- self.update_chromatic_frame(spi, delay, chromatic)?;
+ self.update_achromatic_frame(spi, delay, black).await?;
+ self.update_chromatic_frame(spi, delay, chromatic).await?;
Ok(())
}
- fn update_achromatic_frame(
+ async fn update_achromatic_frame(
&mut self,
spi: &mut SPI,
delay: &mut DELAY,
black: &[u8],
) -> Result<(), SPI::Error> {
- self.wait_until_idle(spi, delay)?;
- self.cmd_with_data(spi, Command::DataStartTransmission1, black)?;
+ self.wait_until_idle(spi, delay).await?;
+ self.cmd_with_data(spi, Command::DataStartTransmission1, black)
+ .await?;
Ok(())
}
- fn update_chromatic_frame(
+ async fn update_chromatic_frame(
&mut self,
spi: &mut SPI,
delay: &mut DELAY,
chromatic: &[u8],
) -> Result<(), SPI::Error> {
- self.wait_until_idle(spi, delay)?;
- self.cmd_with_data(spi, Command::DataStartTransmission2, chromatic)?;
+ self.wait_until_idle(spi, delay).await?;
+ self.cmd_with_data(spi, Command::DataStartTransmission2, chromatic)
+ .await?;
Ok(())
}
}
+#[maybe_async::maybe_async(AFIT)]
impl WaveshareDisplay
for Epd5in83
where
@@ -148,7 +154,7 @@ where
DELAY: DelayNs,
{
type DisplayColor = Color;
- fn new(
+ async fn new(
spi: &mut SPI,
busy: BUSY,
dc: DC,
@@ -161,21 +167,21 @@ where
let mut epd = Epd5in83 { interface, color };
- epd.init(spi, delay)?;
+ epd.init(spi, delay).await?;
Ok(epd)
}
- fn sleep(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
- self.wait_until_idle(spi, delay)?;
- self.command(spi, Command::PowerOff)?;
- self.wait_until_idle(spi, delay)?;
- self.cmd_with_data(spi, Command::DeepSleep, &[0xA5])?;
+ async fn sleep(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
+ self.wait_until_idle(spi, delay).await?;
+ self.command(spi, Command::PowerOff).await?;
+ self.wait_until_idle(spi, delay).await?;
+ self.cmd_with_data(spi, Command::DeepSleep, &[0xA5]).await?;
Ok(())
}
- fn wake_up(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
- self.init(spi, delay)
+ async fn wake_up(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
+ self.init(spi, delay).await
}
fn set_background_color(&mut self, color: Color) {
@@ -194,21 +200,23 @@ where
HEIGHT
}
- fn update_frame(
+ async fn update_frame(
&mut self,
spi: &mut SPI,
buffer: &[u8],
delay: &mut DELAY,
) -> Result<(), SPI::Error> {
- self.wait_until_idle(spi, delay)?;
- self.update_achromatic_frame(spi, delay, buffer)?;
+ self.wait_until_idle(spi, delay).await?;
+ self.update_achromatic_frame(spi, delay, buffer).await?;
let color = self.color.get_byte_value();
- self.command(spi, Command::DataStartTransmission2)?;
- self.interface.data_x_times(spi, color, NUM_DISPLAY_BITS)?;
+ self.command(spi, Command::DataStartTransmission2).await?;
+ self.interface
+ .data_x_times(spi, color, NUM_DISPLAY_BITS)
+ .await?;
Ok(())
}
- fn update_partial_frame(
+ async fn update_partial_frame(
&mut self,
spi: &mut SPI,
delay: &mut DELAY,
@@ -218,7 +226,7 @@ where
width: u32,
height: u32,
) -> Result<(), SPI::Error> {
- self.wait_until_idle(spi, delay)?;
+ self.wait_until_idle(spi, delay).await?;
if buffer.len() as u32 != width / 8 * height {
//TODO panic or error
}
@@ -233,61 +241,67 @@ where
let vred_lower = (y + height) as u8;
let pt_scan = 0x01; // Gates scan both inside and outside of the partial window. (default)
- self.command(spi, Command::PartialIn)?;
- self.command(spi, Command::PartialWindow)?;
+ self.command(spi, Command::PartialIn).await?;
+ self.command(spi, Command::PartialWindow).await?;
self.send_data(
spi,
&[
hrst_upper, hrst_lower, hred_upper, hred_lower, vrst_upper, vrst_lower, vred_upper,
vred_lower, pt_scan,
],
- )?;
- self.command(spi, Command::DataStartTransmission1)?;
- self.send_data(spi, buffer)?;
+ )
+ .await?;
+ self.command(spi, Command::DataStartTransmission1).await?;
+ self.send_data(spi, buffer).await?;
let color = TriColor::Black.get_byte_value(); //We need it black, so red channel will be rendered transparent
- self.command(spi, Command::DataStartTransmission2)?;
+ self.command(spi, Command::DataStartTransmission2).await?;
self.interface
- .data_x_times(spi, color, width * height / 8)?;
+ .data_x_times(spi, color, width * height / 8)
+ .await?;
- self.command(spi, Command::DisplayRefresh)?;
- self.wait_until_idle(spi, delay)?;
+ self.command(spi, Command::DisplayRefresh).await?;
+ self.wait_until_idle(spi, delay).await?;
- self.command(spi, Command::PartialOut)?;
+ self.command(spi, Command::PartialOut).await?;
Ok(())
}
- fn display_frame(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
- self.command(spi, Command::DisplayRefresh)?;
- self.wait_until_idle(spi, delay)?;
+ async fn display_frame(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
+ self.command(spi, Command::DisplayRefresh).await?;
+ self.wait_until_idle(spi, delay).await?;
Ok(())
}
- fn update_and_display_frame(
+ async fn update_and_display_frame(
&mut self,
spi: &mut SPI,
buffer: &[u8],
delay: &mut DELAY,
) -> Result<(), SPI::Error> {
- self.update_frame(spi, buffer, delay)?;
- self.display_frame(spi, delay)?;
+ self.update_frame(spi, buffer, delay).await?;
+ self.display_frame(spi, delay).await?;
Ok(())
}
- fn clear_frame(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
- self.wait_until_idle(spi, delay)?;
+ async fn clear_frame(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
+ self.wait_until_idle(spi, delay).await?;
// The Waveshare controllers all implement clear using 0x33
- self.command(spi, Command::DataStartTransmission1)?;
- self.interface.data_x_times(spi, 0xFF, NUM_DISPLAY_BITS)?;
+ self.command(spi, Command::DataStartTransmission1).await?;
+ self.interface
+ .data_x_times(spi, 0xFF, NUM_DISPLAY_BITS)
+ .await?;
- self.command(spi, Command::DataStartTransmission2)?;
- self.interface.data_x_times(spi, 0x00, NUM_DISPLAY_BITS)?;
+ self.command(spi, Command::DataStartTransmission2).await?;
+ self.interface
+ .data_x_times(spi, 0x00, NUM_DISPLAY_BITS)
+ .await?;
Ok(())
}
- fn set_lut(
+ async fn set_lut(
&mut self,
_spi: &mut SPI,
_delay: &mut DELAY,
@@ -296,12 +310,17 @@ where
unimplemented!();
}
- fn wait_until_idle(&mut self, _spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
- self.interface.wait_until_idle(delay, IS_BUSY_LOW);
+ async fn wait_until_idle(
+ &mut self,
+ _spi: &mut SPI,
+ delay: &mut DELAY,
+ ) -> Result<(), SPI::Error> {
+ self.interface.wait_until_idle(delay, IS_BUSY_LOW).await;
Ok(())
}
}
+#[maybe_async::maybe_async]
impl Epd5in83
where
SPI: SpiDevice,
@@ -310,32 +329,32 @@ where
RST: OutputPin,
DELAY: DelayNs,
{
- fn command(&mut self, spi: &mut SPI, command: Command) -> Result<(), SPI::Error> {
- self.interface.cmd(spi, command)
+ async fn command(&mut self, spi: &mut SPI, command: Command) -> Result<(), SPI::Error> {
+ self.interface.cmd(spi, command).await
}
- fn send_data(&mut self, spi: &mut SPI, data: &[u8]) -> Result<(), SPI::Error> {
- self.interface.data(spi, data)
+ async fn send_data(&mut self, spi: &mut SPI, data: &[u8]) -> Result<(), SPI::Error> {
+ self.interface.data(spi, data).await
}
- fn cmd_with_data(
+ async fn cmd_with_data(
&mut self,
spi: &mut SPI,
command: Command,
data: &[u8],
) -> Result<(), SPI::Error> {
- self.interface.cmd_with_data(spi, command, data)
+ self.interface.cmd_with_data(spi, command, data).await
}
- fn send_resolution(&mut self, spi: &mut SPI) -> Result<(), SPI::Error> {
+ async fn send_resolution(&mut self, spi: &mut SPI) -> Result<(), SPI::Error> {
let w = self.width();
let h = self.height();
- self.command(spi, Command::TconResolution)?;
- self.send_data(spi, &[(w >> 8) as u8])?;
- self.send_data(spi, &[w as u8])?;
- self.send_data(spi, &[(h >> 8) as u8])?;
- self.send_data(spi, &[h as u8])
+ self.command(spi, Command::TconResolution).await?;
+ self.send_data(spi, &[(w >> 8) as u8]).await?;
+ self.send_data(spi, &[w as u8]).await?;
+ self.send_data(spi, &[(h >> 8) as u8]).await?;
+ self.send_data(spi, &[h as u8]).await
}
}
diff --git a/src/epd7in3f/mod.rs b/src/epd7in3f/mod.rs
index 11a733df..98f6c2d5 100644
--- a/src/epd7in3f/mod.rs
+++ b/src/epd7in3f/mod.rs
@@ -6,16 +6,12 @@
//! - [Waveshare C driver](https://github.com/waveshareteam/e-Paper/blob/8be47b27f1a6808fd82ea9ceeac04c172e4ee9a8/RaspberryPi_JetsonNano/c/lib/e-Paper/EPD_7in3f.c)
//! - [Waveshare Python driver](https://github.com/waveshareteam/e-Paper/blob/8be47b27f1a6808fd82ea9ceeac04c172e4ee9a8/RaspberryPi_JetsonNano/python/lib/waveshare_epd/epd7in3f.py)
-use embedded_hal::{
- delay::DelayNs,
- digital::{InputPin, OutputPin},
- spi::SpiDevice,
-};
+use embedded_hal::digital::{InputPin, OutputPin};
use crate::{
buffer_len,
color::OctColor,
- interface::DisplayInterface,
+ interface::{DelayNs, DisplayInterface, SpiDevice},
traits::{InternalWiAdditions, WaveshareDisplay},
};
@@ -50,6 +46,7 @@ pub struct Epd7in3f {
color: OctColor,
}
+#[maybe_async::maybe_async(AFIT)]
impl InternalWiAdditions
for Epd7in3f
where
@@ -59,33 +56,43 @@ where
RST: OutputPin,
DELAY: DelayNs,
{
- fn init(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), ::Error> {
- self.interface.reset(delay, 20_000, 2_000);
- self.wait_busy_low(delay);
- delay.delay_ms(30);
-
- self.cmd_with_data(spi, Command::CMDH, &[0x49, 0x55, 0x20, 0x08, 0x09, 0x18])?;
- self.cmd_with_data(spi, Command::Ox01, &[0x3F, 0x00, 0x32, 0x2A, 0x0E, 0x2A])?;
- self.cmd_with_data(spi, Command::Ox00, &[0x5F, 0x69])?;
- self.cmd_with_data(spi, Command::Ox03, &[0x00, 0x54, 0x00, 0x44])?;
- self.cmd_with_data(spi, Command::Ox05, &[0x40, 0x1F, 0x1F, 0x2C])?;
- self.cmd_with_data(spi, Command::Ox06, &[0x6F, 0x1F, 0x1F, 0x22])?;
- self.cmd_with_data(spi, Command::Ox08, &[0x6F, 0x1F, 0x1F, 0x22])?;
- self.cmd_with_data(spi, Command::IPC, &[0x00, 0x04])?;
- self.cmd_with_data(spi, Command::Ox30, &[0x3C])?;
- self.cmd_with_data(spi, Command::TSE, &[0x00])?;
- self.cmd_with_data(spi, Command::Ox50, &[0x3F])?;
- self.cmd_with_data(spi, Command::Ox60, &[0x02, 0x00])?;
- self.cmd_with_data(spi, Command::Ox61, &[0x03, 0x20, 0x01, 0xE0])?;
- self.cmd_with_data(spi, Command::Ox82, &[0x1E])?;
- self.cmd_with_data(spi, Command::Ox84, &[0x00])?;
- self.cmd_with_data(spi, Command::AGID, &[0x00])?;
- self.cmd_with_data(spi, Command::OxE3, &[0x2F])?;
- self.cmd_with_data(spi, Command::CCSET, &[0x00])?;
- self.cmd_with_data(spi, Command::TSSET, &[0x00])
+ async fn init(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), ::Error> {
+ self.interface.reset(delay, 20_000, 2_000).await;
+ self.wait_busy_low(delay).await;
+ delay.delay_ms(30).await;
+
+ self.cmd_with_data(spi, Command::CMDH, &[0x49, 0x55, 0x20, 0x08, 0x09, 0x18])
+ .await?;
+ self.cmd_with_data(spi, Command::Ox01, &[0x3F, 0x00, 0x32, 0x2A, 0x0E, 0x2A])
+ .await?;
+ self.cmd_with_data(spi, Command::Ox00, &[0x5F, 0x69])
+ .await?;
+ self.cmd_with_data(spi, Command::Ox03, &[0x00, 0x54, 0x00, 0x44])
+ .await?;
+ self.cmd_with_data(spi, Command::Ox05, &[0x40, 0x1F, 0x1F, 0x2C])
+ .await?;
+ self.cmd_with_data(spi, Command::Ox06, &[0x6F, 0x1F, 0x1F, 0x22])
+ .await?;
+ self.cmd_with_data(spi, Command::Ox08, &[0x6F, 0x1F, 0x1F, 0x22])
+ .await?;
+ self.cmd_with_data(spi, Command::IPC, &[0x00, 0x04]).await?;
+ self.cmd_with_data(spi, Command::Ox30, &[0x3C]).await?;
+ self.cmd_with_data(spi, Command::TSE, &[0x00]).await?;
+ self.cmd_with_data(spi, Command::Ox50, &[0x3F]).await?;
+ self.cmd_with_data(spi, Command::Ox60, &[0x02, 0x00])
+ .await?;
+ self.cmd_with_data(spi, Command::Ox61, &[0x03, 0x20, 0x01, 0xE0])
+ .await?;
+ self.cmd_with_data(spi, Command::Ox82, &[0x1E]).await?;
+ self.cmd_with_data(spi, Command::Ox84, &[0x00]).await?;
+ self.cmd_with_data(spi, Command::AGID, &[0x00]).await?;
+ self.cmd_with_data(spi, Command::OxE3, &[0x2F]).await?;
+ self.cmd_with_data(spi, Command::CCSET, &[0x00]).await?;
+ self.cmd_with_data(spi, Command::TSSET, &[0x00]).await
}
}
+#[maybe_async::maybe_async(AFIT)]
impl WaveshareDisplay
for Epd7in3f
where
@@ -97,7 +104,7 @@ where
{
type DisplayColor = OctColor;
- fn new(
+ async fn new(
spi: &mut SPI,
busy: BUSY,
dc: DC,
@@ -113,17 +120,17 @@ where
let mut epd = Epd7in3f { interface, color };
- epd.init(spi, delay)?;
+ epd.init(spi, delay).await?;
Ok(epd)
}
- fn sleep(&mut self, spi: &mut SPI, _delay: &mut DELAY) -> Result<(), ::Error> {
- self.cmd_with_data(spi, Command::DeepSleep, &[0xA5])
+ async fn sleep(&mut self, spi: &mut SPI, _delay: &mut DELAY) -> Result<(),