1use embedded_hal::{delay::*, digital::*, spi::SpiDevice};
4
5use crate::interface::DisplayInterface;
6use crate::traits::{
7 InternalWiAdditions, RefreshLut, WaveshareDisplay, WaveshareThreeColorDisplay,
8};
9
10mod constants;
12use crate::epd1in54b::constants::*;
13
14pub const WIDTH: u32 = 200;
16pub const HEIGHT: u32 = 200;
18pub const DEFAULT_BACKGROUND_COLOR: Color = Color::White;
20const IS_BUSY_LOW: bool = true;
21const SINGLE_BYTE_WRITE: bool = true;
22
23use crate::color::Color;
24
25pub(crate) mod command;
26use self::command::Command;
27use crate::buffer_len;
28
29#[cfg(feature = "graphics")]
32pub type Display1in54b = crate::graphics::Display<
33 WIDTH,
34 HEIGHT,
35 false,
36 { buffer_len(WIDTH as usize, HEIGHT as usize) },
37 Color,
38>;
39
40pub struct Epd1in54b<SPI, BUSY, DC, RST, DELAY> {
42 interface: DisplayInterface<SPI, BUSY, DC, RST, DELAY, SINGLE_BYTE_WRITE>,
43 color: Color,
44}
45
46impl<SPI, BUSY, DC, RST, DELAY> InternalWiAdditions<SPI, BUSY, DC, RST, DELAY>
47 for Epd1in54b<SPI, BUSY, DC, RST, DELAY>
48where
49 SPI: SpiDevice,
50 BUSY: InputPin,
51 DC: OutputPin,
52 RST: OutputPin,
53 DELAY: DelayNs,
54{
55 fn init(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
56 self.interface.reset(delay, 10_000, 10_000);
57
58 self.interface
60 .cmd_with_data(spi, Command::PowerSetting, &[0x07, 0x00, 0x08, 0x00])?;
61
62 self.interface
64 .cmd_with_data(spi, Command::BoosterSoftStart, &[0x07, 0x07, 0x07])?;
65
66 self.command(spi, Command::PowerOn)?;
68 delay.delay_us(5000);
69 self.wait_until_idle(spi, delay)?;
70
71 self.cmd_with_data(spi, Command::PanelSetting, &[0xCF])?;
73
74 self.cmd_with_data(spi, Command::VcomAndDataIntervalSetting, &[0x37])?;
75
76 self.cmd_with_data(spi, Command::PllControl, &[0x39])?;
78
79 self.send_resolution(spi)?;
81
82 self.cmd_with_data(spi, Command::VcmDcSetting, &[0x0E])?;
83
84 self.set_lut(spi, delay, None)?;
85
86 self.wait_until_idle(spi, delay)?;
87
88 Ok(())
89 }
90}
91
92impl<SPI, BUSY, DC, RST, DELAY> WaveshareThreeColorDisplay<SPI, BUSY, DC, RST, DELAY>
93 for Epd1in54b<SPI, BUSY, DC, RST, DELAY>
94where
95 SPI: SpiDevice,
96 BUSY: InputPin,
97 DC: OutputPin,
98 RST: OutputPin,
99 DELAY: DelayNs,
100{
101 fn update_color_frame(
102 &mut self,
103 spi: &mut SPI,
104 delay: &mut DELAY,
105 black: &[u8],
106 chromatic: &[u8],
107 ) -> Result<(), SPI::Error> {
108 self.update_achromatic_frame(spi, delay, black)?;
109 self.update_chromatic_frame(spi, delay, chromatic)
110 }
111
112 fn update_achromatic_frame(
113 &mut self,
114 spi: &mut SPI,
115 delay: &mut DELAY,
116 black: &[u8],
117 ) -> Result<(), SPI::Error> {
118 self.wait_until_idle(spi, delay)?;
119 self.send_resolution(spi)?;
120
121 self.interface.cmd(spi, Command::DataStartTransmission1)?;
122
123 for b in black {
124 let expanded = expand_bits(*b);
125 self.interface.data(spi, &expanded)?;
126 }
127 Ok(())
128 }
129
130 fn update_chromatic_frame(
131 &mut self,
132 spi: &mut SPI,
133 _delay: &mut DELAY,
134 chromatic: &[u8],
135 ) -> Result<(), SPI::Error> {
136 self.interface.cmd(spi, Command::DataStartTransmission2)?;
137 self.interface.data(spi, chromatic)?;
138 Ok(())
139 }
140}
141
142impl<SPI, BUSY, DC, RST, DELAY> WaveshareDisplay<SPI, BUSY, DC, RST, DELAY>
143 for Epd1in54b<SPI, BUSY, DC, RST, DELAY>
144where
145 SPI: SpiDevice,
146 BUSY: InputPin,
147 DC: OutputPin,
148 RST: OutputPin,
149 DELAY: DelayNs,
150{
151 type DisplayColor = Color;
152 fn new(
153 spi: &mut SPI,
154 busy: BUSY,
155 dc: DC,
156 rst: RST,
157 delay: &mut DELAY,
158 delay_us: Option<u32>,
159 ) -> Result<Self, SPI::Error> {
160 let interface = DisplayInterface::new(busy, dc, rst, delay_us);
161 let color = DEFAULT_BACKGROUND_COLOR;
162
163 let mut epd = Epd1in54b { interface, color };
164
165 epd.init(spi, delay)?;
166
167 Ok(epd)
168 }
169
170 fn sleep(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
171 self.wait_until_idle(spi, delay)?;
172 self.interface
173 .cmd_with_data(spi, Command::VcomAndDataIntervalSetting, &[0x17])?; self.interface
176 .cmd_with_data(spi, Command::VcmDcSetting, &[0x00])?; self.interface
179 .cmd_with_data(spi, Command::PowerSetting, &[0x02, 0x00, 0x00, 0x00])?; self.wait_until_idle(spi, delay)?;
182
183 self.command(spi, Command::PowerOff)?;
186
187 Ok(())
188 }
189
190 fn wake_up(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
191 self.init(spi, delay)
192 }
193
194 fn set_background_color(&mut self, color: Color) {
195 self.color = color;
196 }
197
198 fn background_color(&self) -> &Color {
199 &self.color
200 }
201
202 fn width(&self) -> u32 {
203 WIDTH
204 }
205
206 fn height(&self) -> u32 {
207 HEIGHT
208 }
209
210 fn update_frame(
211 &mut self,
212 spi: &mut SPI,
213 buffer: &[u8],
214 delay: &mut DELAY,
215 ) -> Result<(), SPI::Error> {
216 self.wait_until_idle(spi, delay)?;
217 self.send_resolution(spi)?;
218
219 self.interface.cmd(spi, Command::DataStartTransmission1)?;
220
221 for b in buffer {
222 let expanded = expand_bits(*b);
224 self.interface.data(spi, &expanded)?;
225 }
226
227 let color = self.color.get_byte_value();
231 let nbits = WIDTH * (HEIGHT / 8);
232
233 self.interface.cmd(spi, Command::DataStartTransmission2)?;
234 self.interface.data_x_times(spi, color, nbits)?;
235
236 Ok(())
238 }
239
240 #[allow(unused)]
241 fn update_partial_frame(
242 &mut self,
243 spi: &mut SPI,
244 delay: &mut DELAY,
245 buffer: &[u8],
246 x: u32,
247 y: u32,
248 width: u32,
249 height: u32,
250 ) -> Result<(), SPI::Error> {
251 unimplemented!()
252 }
253
254 fn display_frame(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
255 self.wait_until_idle(spi, delay)?;
256 self.command(spi, Command::DisplayRefresh)?;
257 Ok(())
258 }
259
260 fn update_and_display_frame(
261 &mut self,
262 spi: &mut SPI,
263 buffer: &[u8],
264 delay: &mut DELAY,
265 ) -> Result<(), SPI::Error> {
266 self.update_frame(spi, buffer, delay)?;
267 self.display_frame(spi, delay)?;
268 Ok(())
269 }
270
271 fn clear_frame(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
272 self.wait_until_idle(spi, delay)?;
273 self.send_resolution(spi)?;
274
275 let color = DEFAULT_BACKGROUND_COLOR.get_byte_value();
276
277 self.interface.cmd(spi, Command::DataStartTransmission1)?;
279
280 self.interface
282 .data_x_times(spi, color, 2 * (WIDTH / 8 * HEIGHT))?;
283
284 self.interface.cmd(spi, Command::DataStartTransmission2)?;
286 self.interface
287 .data_x_times(spi, color, WIDTH / 8 * HEIGHT)?;
288 Ok(())
289 }
290
291 fn set_lut(
292 &mut self,
293 spi: &mut SPI,
294 _delay: &mut DELAY,
295 _refresh_rate: Option<RefreshLut>,
296 ) -> Result<(), SPI::Error> {
297 self.interface
298 .cmd_with_data(spi, Command::LutForVcom, LUT_VCOM0)?;
299 self.interface
300 .cmd_with_data(spi, Command::LutWhiteToWhite, LUT_WHITE_TO_WHITE)?;
301 self.interface
302 .cmd_with_data(spi, Command::LutBlackToWhite, LUT_BLACK_TO_WHITE)?;
303 self.interface.cmd_with_data(spi, Command::LutG0, LUT_G1)?;
304 self.interface.cmd_with_data(spi, Command::LutG1, LUT_G2)?;
305 self.interface
306 .cmd_with_data(spi, Command::LutRedVcom, LUT_RED_VCOM)?;
307 self.interface
308 .cmd_with_data(spi, Command::LutRed0, LUT_RED0)?;
309 self.interface
310 .cmd_with_data(spi, Command::LutRed1, LUT_RED1)?;
311
312 Ok(())
313 }
314
315 fn wait_until_idle(&mut self, _spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
316 self.interface.wait_until_idle(delay, IS_BUSY_LOW);
317 Ok(())
318 }
319}
320
321impl<SPI, BUSY, DC, RST, DELAY> Epd1in54b<SPI, BUSY, DC, RST, DELAY>
322where
323 SPI: SpiDevice,
324 BUSY: InputPin,
325 DC: OutputPin,
326 RST: OutputPin,
327 DELAY: DelayNs,
328{
329 fn command(&mut self, spi: &mut SPI, command: Command) -> Result<(), SPI::Error> {
330 self.interface.cmd(spi, command)
331 }
332
333 fn send_data(&mut self, spi: &mut SPI, data: &[u8]) -> Result<(), SPI::Error> {
334 self.interface.data(spi, data)
335 }
336
337 fn cmd_with_data(
338 &mut self,
339 spi: &mut SPI,
340 command: Command,
341 data: &[u8],
342 ) -> Result<(), SPI::Error> {
343 self.interface.cmd_with_data(spi, command, data)
344 }
345
346 fn send_resolution(&mut self, spi: &mut SPI) -> Result<(), SPI::Error> {
347 let w = self.width();
348 let h = self.height();
349
350 self.command(spi, Command::ResolutionSetting)?;
351
352 self.send_data(spi, &[w as u8])?;
353 self.send_data(spi, &[(h >> 8) as u8])?;
354 self.send_data(spi, &[h as u8])
355 }
356}
357
358fn expand_bits(bits: u8) -> [u8; 2] {
359 let mut x = bits as u16;
360
361 x = (x | (x << 4)) & 0x0F0F;
362 x = (x | (x << 2)) & 0x3333;
363 x = (x | (x << 1)) & 0x5555;
364 x = x | (x << 1);
365
366 [(x >> 8) as u8, (x & 0xFF) as u8]
367}
368
369#[cfg(test)]
370mod tests {
371 use super::*;
372
373 #[test]
374 fn epd_size() {
375 assert_eq!(WIDTH, 200);
376 assert_eq!(HEIGHT, 200);
377 assert_eq!(DEFAULT_BACKGROUND_COLOR, Color::White);
378 }
379}