Skip to content

Commit 83878fc

Browse files
committed
make everything async
1 parent 2c58432 commit 83878fc

23 files changed

Lines changed: 2167 additions & 1638 deletions

File tree

Cargo.toml

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,7 @@ edition = "2021"
1717

1818
[dependencies]
1919
embedded-graphics-core = { version = "0.4", optional = true }
20-
2120
embedded-hal = { version = "1.0.0-rc.1" }
22-
embedded-hal-bus = { version = "0.1.0-rc.1", git="https://github.com/rust-embedded/embedded-hal" }
2321
embedded-hal-async = { optional = true, version = "1.0.0-rc.1", git="https://github.com/rust-embedded/embedded-hal" }
2422

2523
bit_field = "0.10.1"
@@ -58,13 +56,13 @@ required-features = ["linux-dev"]
5856

5957
[features]
6058
# Remove the linux-dev feature to build the tests on non unix systems
61-
default = ["async", "epd2in13_v3"] #["dep:embedded-hal", "graphics", "linux-dev", "epd2in13_v3"]
59+
default = ["async", "graphics", "linux-dev", "epd2in13_v3"]
6260

6361
graphics = ["embedded-graphics-core"]
6462
epd2in13_v2 = []
6563
epd2in13_v3 = []
6664
linux-dev = []
67-
async = ["dep:embedded-hal-async", "embedded-hal-bus/async"]
65+
async = ["dep:embedded-hal-async"]
6866

6967
# Offers an alternative fast full lut for type_a displays, but the refreshed screen isnt as clean looking
7068
type_a_alternative_faster_lut = []

src/epd1in54/mod.rs

Lines changed: 107 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,8 @@ pub const DEFAULT_BACKGROUND_COLOR: Color = Color::White;
5454
const IS_BUSY_LOW: bool = false;
5555
const SINGLE_BYTE_WRITE: bool = true;
5656

57-
use embedded_hal::{delay::*, digital::*, spi::SpiDevice};
57+
use embedded_hal::digital::{InputPin, OutputPin};
58+
use embedded_hal_async::{delay::DelayUs, spi::SpiDevice};
5859

5960
use crate::type_a::{
6061
command::Command,
@@ -96,48 +97,55 @@ where
9697
RST: OutputPin,
9798
DELAY: DelayUs,
9899
{
99-
fn init(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
100-
self.interface.reset(delay, 10_000, 10_000);
100+
async fn init(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
101+
self.interface.reset(delay, 10_000, 10_000).await;
101102

102103
// 3 Databytes:
103104
// A[7:0]
104105
// 0.. A[8]
105106
// 0.. B[2:0]
106107
// Default Values: A = Height of Screen (0x127), B = 0x00 (GD, SM and TB=0?)
107-
self.interface.cmd_with_data(
108-
spi,
109-
Command::DriverOutputControl,
110-
&[HEIGHT as u8, (HEIGHT >> 8) as u8, 0x00],
111-
)?;
108+
self.interface
109+
.cmd_with_data(
110+
spi,
111+
Command::DriverOutputControl,
112+
&[HEIGHT as u8, (HEIGHT >> 8) as u8, 0x00],
113+
)
114+
.await?;
112115

113116
// 3 Databytes: (and default values from datasheet and arduino)
114117
// 1 .. A[6:0] = 0xCF | 0xD7
115118
// 1 .. B[6:0] = 0xCE | 0xD6
116119
// 1 .. C[6:0] = 0x8D | 0x9D
117120
//TODO: test
118121
self.interface
119-
.cmd_with_data(spi, Command::BoosterSoftStartControl, &[0xD7, 0xD6, 0x9D])?;
122+
.cmd_with_data(spi, Command::BoosterSoftStartControl, &[0xD7, 0xD6, 0x9D])
123+
.await?;
120124

121125
// One Databyte with value 0xA8 for 7V VCOM
122126
self.interface
123-
.cmd_with_data(spi, Command::WriteVcomRegister, &[0xA8])?;
127+
.cmd_with_data(spi, Command::WriteVcomRegister, &[0xA8])
128+
.await?;
124129

125130
// One Databyte with default value 0x1A for 4 dummy lines per gate
126131
self.interface
127-
.cmd_with_data(spi, Command::SetDummyLinePeriod, &[0x1A])?;
132+
.cmd_with_data(spi, Command::SetDummyLinePeriod, &[0x1A])
133+
.await?;
128134

129135
// One Databyte with default value 0x08 for 2us per line
130136
self.interface
131-
.cmd_with_data(spi, Command::SetGateLineWidth, &[0x08])?;
137+
.cmd_with_data(spi, Command::SetGateLineWidth, &[0x08])
138+
.await?;
132139

133140
// One Databyte with default value 0x03
134141
// -> address: x increment, y increment, address counter is updated in x direction
135142
self.interface
136-
.cmd_with_data(spi, Command::DataEntryModeSetting, &[0x03])?;
143+
.cmd_with_data(spi, Command::DataEntryModeSetting, &[0x03])
144+
.await?;
137145

138-
self.set_lut(spi, delay, None)?;
146+
self.set_lut(spi, delay, None).await?;
139147

140-
self.wait_until_idle(spi, delay)?;
148+
self.wait_until_idle(spi, delay).await?;
141149
Ok(())
142150
}
143151
}
@@ -160,7 +168,7 @@ where
160168
HEIGHT
161169
}
162170

163-
fn new(
171+
async fn new(
164172
spi: &mut SPI,
165173
busy: BUSY,
166174
dc: DC,
@@ -176,39 +184,41 @@ where
176184
refresh: RefreshLut::Full,
177185
};
178186

179-
epd.init(spi, delay)?;
187+
epd.init(spi, delay).await?;
180188

181189
Ok(epd)
182190
}
183191

184-
fn wake_up(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
185-
self.init(spi, delay)
192+
async fn wake_up(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
193+
self.init(spi, delay).await
186194
}
187195

188-
fn sleep(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
189-
self.wait_until_idle(spi, delay)?;
196+
async fn sleep(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
197+
self.wait_until_idle(spi, delay).await?;
190198
// 0x00 for Normal mode (Power on Reset), 0x01 for Deep Sleep Mode
191199
//TODO: is 0x00 needed here or would 0x01 be even more efficient?
192200
self.interface
193-
.cmd_with_data(spi, Command::DeepSleepMode, &[0x00])?;
201+
.cmd_with_data(spi, Command::DeepSleepMode, &[0x00])
202+
.await?;
194203
Ok(())
195204
}
196205

197-
fn update_frame(
206+
async fn update_frame(
198207
&mut self,
199208
spi: &mut SPI,
200209
buffer: &[u8],
201210
delay: &mut DELAY,
202211
) -> Result<(), SPI::Error> {
203-
self.wait_until_idle(spi, delay)?;
204-
self.use_full_frame(spi, delay)?;
212+
self.wait_until_idle(spi, delay).await?;
213+
self.use_full_frame(spi, delay).await?;
205214
self.interface
206-
.cmd_with_data(spi, Command::WriteRam, buffer)?;
215+
.cmd_with_data(spi, Command::WriteRam, buffer)
216+
.await?;
207217
Ok(())
208218
}
209219

210220
//TODO: update description: last 3 bits will be ignored for width and x_pos
211-
fn update_partial_frame(
221+
async fn update_partial_frame(
212222
&mut self,
213223
spi: &mut SPI,
214224
delay: &mut DELAY,
@@ -218,50 +228,54 @@ where
218228
width: u32,
219229
height: u32,
220230
) -> Result<(), SPI::Error> {
221-
self.wait_until_idle(spi, delay)?;
222-
self.set_ram_area(spi, delay, x, y, x + width, y + height)?;
223-
self.set_ram_counter(spi, delay, x, y)?;
231+
self.wait_until_idle(spi, delay).await?;
232+
self.set_ram_area(spi, delay, x, y, x + width, y + height)
233+
.await?;
234+
self.set_ram_counter(spi, delay, x, y).await?;
224235

225236
self.interface
226-
.cmd_with_data(spi, Command::WriteRam, buffer)?;
237+
.cmd_with_data(spi, Command::WriteRam, buffer)
238+
.await?;
227239
Ok(())
228240
}
229241

230-
fn display_frame(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
231-
self.wait_until_idle(spi, delay)?;
242+
async fn display_frame(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
243+
self.wait_until_idle(spi, delay).await?;
232244
// enable clock signal, enable cp, display pattern -> 0xC4 (tested with the arduino version)
233245
//TODO: test control_1 or control_2 with default value 0xFF (from the datasheet)
234246
self.interface
235-
.cmd_with_data(spi, Command::DisplayUpdateControl2, &[0xC4])?;
247+
.cmd_with_data(spi, Command::DisplayUpdateControl2, &[0xC4])
248+
.await?;
236249

237-
self.interface.cmd(spi, Command::MasterActivation)?;
250+
self.interface.cmd(spi, Command::MasterActivation).await?;
238251
// MASTER Activation should not be interupted to avoid currption of panel images
239252
// therefore a terminate command is send
240-
self.interface.cmd(spi, Command::Nop)?;
253+
self.interface.cmd(spi, Command::Nop).await?;
241254
Ok(())
242255
}
243256

244-
fn update_and_display_frame(
257+
async fn update_and_display_frame(
245258
&mut self,
246259
spi: &mut SPI,
247260
buffer: &[u8],
248261
delay: &mut DELAY,
249262
) -> Result<(), SPI::Error> {
250-
self.update_frame(spi, buffer, delay)?;
251-
self.display_frame(spi, delay)?;
263+
self.update_frame(spi, buffer, delay).await?;
264+
self.display_frame(spi, delay).await?;
252265
Ok(())
253266
}
254267

255-
fn clear_frame(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
256-
self.wait_until_idle(spi, delay)?;
257-
self.use_full_frame(spi, delay)?;
268+
async fn clear_frame(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
269+
self.wait_until_idle(spi, delay).await?;
270+
self.use_full_frame(spi, delay).await?;
258271

259272
// clear the ram with the background color
260273
let color = self.background_color.get_byte_value();
261274

262-
self.interface.cmd(spi, Command::WriteRam)?;
275+
self.interface.cmd(spi, Command::WriteRam).await?;
263276
self.interface
264-
.data_x_times(spi, color, WIDTH / 8 * HEIGHT)?;
277+
.data_x_times(spi, color, WIDTH / 8 * HEIGHT)
278+
.await?;
265279
Ok(())
266280
}
267281

@@ -273,7 +287,7 @@ where
273287
&self.background_color
274288
}
275289

276-
fn set_lut(
290+
async fn set_lut(
277291
&mut self,
278292
spi: &mut SPI,
279293
delay: &mut DELAY,
@@ -283,13 +297,17 @@ where
283297
self.refresh = refresh_lut;
284298
}
285299
match self.refresh {
286-
RefreshLut::Full => self.set_lut_helper(spi, delay, &LUT_FULL_UPDATE),
287-
RefreshLut::Quick => self.set_lut_helper(spi, delay, &LUT_PARTIAL_UPDATE),
300+
RefreshLut::Full => self.set_lut_helper(spi, delay, &LUT_FULL_UPDATE).await,
301+
RefreshLut::Quick => self.set_lut_helper(spi, delay, &LUT_PARTIAL_UPDATE).await,
288302
}
289303
}
290304

291-
fn wait_until_idle(&mut self, _spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
292-
self.interface.wait_until_idle(delay, IS_BUSY_LOW);
305+
async fn wait_until_idle(
306+
&mut self,
307+
_spi: &mut SPI,
308+
delay: &mut DELAY,
309+
) -> Result<(), SPI::Error> {
310+
let _ = self.interface.wait_until_idle(delay, IS_BUSY_LOW).await;
293311
Ok(())
294312
}
295313
}
@@ -302,19 +320,20 @@ where
302320
RST: OutputPin,
303321
DELAY: DelayUs,
304322
{
305-
pub(crate) fn use_full_frame(
323+
pub(crate) async fn use_full_frame(
306324
&mut self,
307325
spi: &mut SPI,
308326
delay: &mut DELAY,
309327
) -> Result<(), SPI::Error> {
310328
// choose full frame/ram
311-
self.set_ram_area(spi, delay, 0, 0, WIDTH - 1, HEIGHT - 1)?;
329+
self.set_ram_area(spi, delay, 0, 0, WIDTH - 1, HEIGHT - 1)
330+
.await?;
312331

313332
// start from the beginning
314-
self.set_ram_counter(spi, delay, 0, 0)
333+
self.set_ram_counter(spi, delay, 0, 0).await
315334
}
316335

317-
pub(crate) fn set_ram_area(
336+
pub(crate) async fn set_ram_area(
318337
&mut self,
319338
spi: &mut SPI,
320339
delay: &mut DELAY,
@@ -323,65 +342,73 @@ where
323342
end_x: u32,
324343
end_y: u32,
325344
) -> Result<(), SPI::Error> {
326-
self.wait_until_idle(spi, delay)?;
345+
let _ = self.wait_until_idle(spi, delay).await;
327346
assert!(start_x < end_x);
328347
assert!(start_y < end_y);
329348

330349
// x is positioned in bytes, so the last 3 bits which show the position inside a byte in the ram
331350
// aren't relevant
332-
self.interface.cmd_with_data(
333-
spi,
334-
Command::SetRamXAddressStartEndPosition,
335-
&[(start_x >> 3) as u8, (end_x >> 3) as u8],
336-
)?;
351+
self.interface
352+
.cmd_with_data(
353+
spi,
354+
Command::SetRamXAddressStartEndPosition,
355+
&[(start_x >> 3) as u8, (end_x >> 3) as u8],
356+
)
357+
.await?;
337358

338359
// 2 Databytes: A[7:0] & 0..A[8] for each - start and end
339-
self.interface.cmd_with_data(
340-
spi,
341-
Command::SetRamYAddressStartEndPosition,
342-
&[
343-
start_y as u8,
344-
(start_y >> 8) as u8,
345-
end_y as u8,
346-
(end_y >> 8) as u8,
347-
],
348-
)?;
360+
self.interface
361+
.cmd_with_data(
362+
spi,
363+
Command::SetRamYAddressStartEndPosition,
364+
&[
365+
start_y as u8,
366+
(start_y >> 8) as u8,
367+
end_y as u8,
368+
(end_y >> 8) as u8,
369+
],
370+
)
371+
.await?;
349372
Ok(())
350373
}
351374

352-
pub(crate) fn set_ram_counter(
375+
pub(crate) async fn set_ram_counter(
353376
&mut self,
354377
spi: &mut SPI,
355378
delay: &mut DELAY,
356379
x: u32,
357380
y: u32,
358381
) -> Result<(), SPI::Error> {
359-
self.wait_until_idle(spi, delay)?;
382+
self.wait_until_idle(spi, delay).await?;
360383
// x is positioned in bytes, so the last 3 bits which show the position inside a byte in the ram
361384
// aren't relevant
362385
self.interface
363-
.cmd_with_data(spi, Command::SetRamXAddressCounter, &[(x >> 3) as u8])?;
386+
.cmd_with_data(spi, Command::SetRamXAddressCounter, &[(x >> 3) as u8])
387+
.await?;
364388

365389
// 2 Databytes: A[7:0] & 0..A[8]
366-
self.interface.cmd_with_data(
367-
spi,
368-
Command::SetRamYAddressCounter,
369-
&[y as u8, (y >> 8) as u8],
370-
)?;
390+
self.interface
391+
.cmd_with_data(
392+
spi,
393+
Command::SetRamYAddressCounter,
394+
&[y as u8, (y >> 8) as u8],
395+
)
396+
.await?;
371397
Ok(())
372398
}
373399

374-
fn set_lut_helper(
400+
async fn set_lut_helper(
375401
&mut self,
376402
spi: &mut SPI,
377403
delay: &mut DELAY,
378404
buffer: &[u8],
379405
) -> Result<(), SPI::Error> {
380-
self.wait_until_idle(spi, delay)?;
406+
self.wait_until_idle(spi, delay).await?;
381407
assert!(buffer.len() == 30);
382408

383409
self.interface
384-
.cmd_with_data(spi, Command::WriteLutRegister, buffer)?;
410+
.cmd_with_data(spi, Command::WriteLutRegister, buffer)
411+
.await?;
385412
Ok(())
386413
}
387414
}

0 commit comments

Comments
 (0)