1use embedded_hal::{delay::*, digital::*, spi::SpiDevice};
4
5use crate::interface::DisplayInterface;
6use crate::traits::{
7 InternalWiAdditions, RefreshLut, WaveshareDisplay, WaveshareThreeColorDisplay,
8};
9
10pub const WIDTH: u32 = 152;
12pub const HEIGHT: u32 = 152;
14pub const DEFAULT_BACKGROUND_COLOR: Color = Color::White;
16const IS_BUSY_LOW: bool = true;
17const NUM_DISPLAY_BITS: u32 = WIDTH / 8 * HEIGHT;
18const SINGLE_BYTE_WRITE: bool = true;
19
20use crate::color::Color;
21
22pub(crate) mod command;
23use self::command::Command;
24use crate::buffer_len;
25
26#[cfg(feature = "graphics")]
29pub type Display1in54c = crate::graphics::Display<
30 WIDTH,
31 HEIGHT,
32 false,
33 { buffer_len(WIDTH as usize, HEIGHT as usize) },
34 Color,
35>;
36
37pub struct Epd1in54c<SPI, BUSY, DC, RST, DELAY> {
39 interface: DisplayInterface<SPI, BUSY, DC, RST, DELAY, SINGLE_BYTE_WRITE>,
40 color: Color,
41}
42
43impl<SPI, BUSY, DC, RST, DELAY> InternalWiAdditions<SPI, BUSY, DC, RST, DELAY>
44 for Epd1in54c<SPI, BUSY, DC, RST, DELAY>
45where
46 SPI: SpiDevice,
47 BUSY: InputPin,
48 DC: OutputPin,
49 RST: OutputPin,
50 DELAY: DelayNs,
51{
52 fn init(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
53 self.interface.reset(delay, 10_000, 2_000);
58
59 self.cmd_with_data(spi, Command::BoosterSoftStart, &[0x17, 0x17, 0x17])?;
61
62 self.command(spi, Command::PowerOn)?;
64 delay.delay_us(5000);
65 self.wait_until_idle(spi, delay)?;
66
67 self.cmd_with_data(spi, Command::PanelSetting, &[0x0f, 0x0d])?;
69
70 self.send_resolution(spi)?;
72
73 self.cmd_with_data(spi, Command::VcomAndDataIntervalSetting, &[0x77])?;
74
75 Ok(())
76 }
77}
78
79impl<SPI, BUSY, DC, RST, DELAY> WaveshareThreeColorDisplay<SPI, BUSY, DC, RST, DELAY>
80 for Epd1in54c<SPI, BUSY, DC, RST, DELAY>
81where
82 SPI: SpiDevice,
83 BUSY: InputPin,
84 DC: OutputPin,
85 RST: OutputPin,
86 DELAY: DelayNs,
87{
88 fn update_color_frame(
89 &mut self,
90 spi: &mut SPI,
91 delay: &mut DELAY,
92 black: &[u8],
93 chromatic: &[u8],
94 ) -> Result<(), SPI::Error> {
95 self.update_achromatic_frame(spi, delay, black)?;
96 self.update_chromatic_frame(spi, delay, chromatic)
97 }
98
99 fn update_achromatic_frame(
100 &mut self,
101 spi: &mut SPI,
102 delay: &mut DELAY,
103 black: &[u8],
104 ) -> Result<(), SPI::Error> {
105 self.wait_until_idle(spi, delay)?;
106 self.cmd_with_data(spi, Command::DataStartTransmission1, black)?;
107
108 Ok(())
109 }
110
111 fn update_chromatic_frame(
112 &mut self,
113 spi: &mut SPI,
114 delay: &mut DELAY,
115 chromatic: &[u8],
116 ) -> Result<(), SPI::Error> {
117 self.wait_until_idle(spi, delay)?;
118 self.cmd_with_data(spi, Command::DataStartTransmission2, chromatic)?;
119
120 Ok(())
121 }
122}
123
124impl<SPI, BUSY, DC, RST, DELAY> WaveshareDisplay<SPI, BUSY, DC, RST, DELAY>
125 for Epd1in54c<SPI, BUSY, DC, RST, DELAY>
126where
127 SPI: SpiDevice,
128 BUSY: InputPin,
129 DC: OutputPin,
130 RST: OutputPin,
131 DELAY: DelayNs,
132{
133 type DisplayColor = Color;
134 fn new(
135 spi: &mut SPI,
136 busy: BUSY,
137 dc: DC,
138 rst: RST,
139 delay: &mut DELAY,
140 delay_us: Option<u32>,
141 ) -> Result<Self, SPI::Error> {
142 let interface = DisplayInterface::new(busy, dc, rst, delay_us);
143 let color = DEFAULT_BACKGROUND_COLOR;
144
145 let mut epd = Epd1in54c { interface, color };
146
147 epd.init(spi, delay)?;
148
149 Ok(epd)
150 }
151
152 fn sleep(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
153 self.wait_until_idle(spi, delay)?;
154
155 self.command(spi, Command::PowerOff)?;
156 self.wait_until_idle(spi, delay)?;
157 self.cmd_with_data(spi, Command::DeepSleep, &[0xa5])?;
158
159 Ok(())
160 }
161
162 fn wake_up(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
163 self.init(spi, delay)
164 }
165
166 fn set_background_color(&mut self, color: Color) {
167 self.color = color;
168 }
169
170 fn background_color(&self) -> &Color {
171 &self.color
172 }
173
174 fn width(&self) -> u32 {
175 WIDTH
176 }
177
178 fn height(&self) -> u32 {
179 HEIGHT
180 }
181
182 fn update_frame(
183 &mut self,
184 spi: &mut SPI,
185 buffer: &[u8],
186 delay: &mut DELAY,
187 ) -> Result<(), SPI::Error> {
188 self.update_achromatic_frame(spi, delay, buffer)?;
189
190 let color = self.color.get_byte_value();
192
193 self.command(spi, Command::DataStartTransmission2)?;
194 self.interface.data_x_times(spi, color, NUM_DISPLAY_BITS)?;
195
196 Ok(())
197 }
198
199 #[allow(unused)]
200 fn update_partial_frame(
201 &mut self,
202 spi: &mut SPI,
203 delay: &mut DELAY,
204 buffer: &[u8],
205 x: u32,
206 y: u32,
207 width: u32,
208 height: u32,
209 ) -> Result<(), SPI::Error> {
210 unimplemented!()
211 }
212
213 fn display_frame(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
214 self.command(spi, Command::DisplayRefresh)?;
215 self.wait_until_idle(spi, delay)?;
216
217 Ok(())
218 }
219
220 fn update_and_display_frame(
221 &mut self,
222 spi: &mut SPI,
223 buffer: &[u8],
224 delay: &mut DELAY,
225 ) -> Result<(), SPI::Error> {
226 self.update_frame(spi, buffer, delay)?;
227 self.display_frame(spi, delay)?;
228
229 Ok(())
230 }
231
232 fn clear_frame(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
233 self.wait_until_idle(spi, delay)?;
234 let color = DEFAULT_BACKGROUND_COLOR.get_byte_value();
235
236 self.command(spi, Command::DataStartTransmission1)?;
238 self.interface.data_x_times(spi, color, NUM_DISPLAY_BITS)?;
239
240 self.command(spi, Command::DataStartTransmission2)?;
242 self.interface.data_x_times(spi, color, NUM_DISPLAY_BITS)?;
243
244 Ok(())
245 }
246
247 fn set_lut(
248 &mut self,
249 _spi: &mut SPI,
250 _delay: &mut DELAY,
251 _refresh_rate: Option<RefreshLut>,
252 ) -> Result<(), SPI::Error> {
253 Ok(())
254 }
255
256 fn wait_until_idle(&mut self, _spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
257 self.interface.wait_until_idle(delay, IS_BUSY_LOW);
258 Ok(())
259 }
260}
261
262impl<SPI, BUSY, DC, RST, DELAY> Epd1in54c<SPI, BUSY, DC, RST, DELAY>
263where
264 SPI: SpiDevice,
265 BUSY: InputPin,
266 DC: OutputPin,
267 RST: OutputPin,
268 DELAY: DelayNs,
269{
270 fn command(&mut self, spi: &mut SPI, command: Command) -> Result<(), SPI::Error> {
271 self.interface.cmd(spi, command)
272 }
273
274 fn send_data(&mut self, spi: &mut SPI, data: &[u8]) -> Result<(), SPI::Error> {
275 self.interface.data(spi, data)
276 }
277
278 fn cmd_with_data(
279 &mut self,
280 spi: &mut SPI,
281 command: Command,
282 data: &[u8],
283 ) -> Result<(), SPI::Error> {
284 self.interface.cmd_with_data(spi, command, data)
285 }
286
287 fn send_resolution(&mut self, spi: &mut SPI) -> Result<(), SPI::Error> {
288 let w = self.width();
289 let h = self.height();
290
291 self.command(spi, Command::ResolutionSetting)?;
292
293 self.send_data(spi, &[(w as u8) & 0b1111_1000])?;
296 self.send_data(spi, &[(w >> 8) as u8])?;
299 self.send_data(spi, &[h as u8])
305 }
306}