1use embedded_hal::{delay::*, digital::*, spi::SpiDevice};
54
55use crate::interface::DisplayInterface;
56use crate::traits::{
57 InternalWiAdditions, RefreshLut, WaveshareDisplay, WaveshareThreeColorDisplay,
58};
59
60pub const WIDTH: u32 = 104;
62pub const HEIGHT: u32 = 212;
64pub const DEFAULT_BACKGROUND_COLOR: TriColor = TriColor::White;
66
67const NUM_DISPLAY_BITS: u32 = WIDTH / 8 * HEIGHT;
69
70const IS_BUSY_LOW: bool = true;
71const VCOM_DATA_INTERVAL: u8 = 0x07;
72const WHITE_BORDER: u8 = 0x70;
73const BLACK_BORDER: u8 = 0x30;
74const CHROMATIC_BORDER: u8 = 0xb0;
75const FLOATING_BORDER: u8 = 0xF0;
76const SINGLE_BYTE_WRITE: bool = true;
77
78use crate::color::TriColor;
79
80pub(crate) mod command;
81use self::command::Command;
82use crate::buffer_len;
83
84#[cfg(feature = "graphics")]
86pub type Display2in13bc = crate::graphics::Display<
87 WIDTH,
88 HEIGHT,
89 true,
90 { buffer_len(WIDTH as usize, HEIGHT as usize * 2) },
91 TriColor,
92>;
93
94pub struct Epd2in13bc<SPI, BUSY, DC, RST, DELAY> {
96 interface: DisplayInterface<SPI, BUSY, DC, RST, DELAY, SINGLE_BYTE_WRITE>,
97 color: TriColor,
98}
99
100impl<SPI, BUSY, DC, RST, DELAY> InternalWiAdditions<SPI, BUSY, DC, RST, DELAY>
101 for Epd2in13bc<SPI, BUSY, DC, RST, DELAY>
102where
103 SPI: SpiDevice,
104 BUSY: InputPin,
105 DC: OutputPin,
106 RST: OutputPin,
107 DELAY: DelayNs,
108{
109 fn init(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
110 self.interface.reset(delay, 10_000, 10_000);
113
114 self.interface
116 .cmd_with_data(spi, Command::BoosterSoftStart, &[0x17, 0x17, 0x17])?;
117
118 self.command(spi, Command::PowerOn)?;
120 delay.delay_us(5000);
121 self.wait_until_idle(spi, delay)?;
122
123 self.cmd_with_data(spi, Command::PanelSetting, &[0x8F])?;
125
126 self.cmd_with_data(
127 spi,
128 Command::VcomAndDataIntervalSetting,
129 &[WHITE_BORDER | VCOM_DATA_INTERVAL],
130 )?;
131
132 self.send_resolution(spi)?;
134
135 self.cmd_with_data(spi, Command::VcmDcSetting, &[0x0A])?;
136
137 self.wait_until_idle(spi, delay)?;
138
139 Ok(())
140 }
141}
142
143impl<SPI, BUSY, DC, RST, DELAY> WaveshareThreeColorDisplay<SPI, BUSY, DC, RST, DELAY>
144 for Epd2in13bc<SPI, BUSY, DC, RST, DELAY>
145where
146 SPI: SpiDevice,
147 BUSY: InputPin,
148 DC: OutputPin,
149 RST: OutputPin,
150 DELAY: DelayNs,
151{
152 fn update_color_frame(
153 &mut self,
154 spi: &mut SPI,
155 delay: &mut DELAY,
156 black: &[u8],
157 chromatic: &[u8],
158 ) -> Result<(), SPI::Error> {
159 self.update_achromatic_frame(spi, delay, black)?;
160 self.update_chromatic_frame(spi, delay, chromatic)
161 }
162
163 fn update_achromatic_frame(
167 &mut self,
168 spi: &mut SPI,
169 _delay: &mut DELAY,
170 black: &[u8],
171 ) -> Result<(), SPI::Error> {
172 self.interface.cmd(spi, Command::DataStartTransmission1)?;
173 self.interface.data(spi, black)?;
174 Ok(())
175 }
176
177 fn update_chromatic_frame(
181 &mut self,
182 spi: &mut SPI,
183 delay: &mut DELAY,
184 chromatic: &[u8],
185 ) -> Result<(), SPI::Error> {
186 self.interface.cmd(spi, Command::DataStartTransmission2)?;
187 self.interface.data(spi, chromatic)?;
188
189 self.wait_until_idle(spi, delay)?;
190 Ok(())
191 }
192}
193
194impl<SPI, BUSY, DC, RST, DELAY> WaveshareDisplay<SPI, BUSY, DC, RST, DELAY>
195 for Epd2in13bc<SPI, BUSY, DC, RST, DELAY>
196where
197 SPI: SpiDevice,
198 BUSY: InputPin,
199 DC: OutputPin,
200 RST: OutputPin,
201 DELAY: DelayNs,
202{
203 type DisplayColor = TriColor;
204 fn new(
205 spi: &mut SPI,
206 busy: BUSY,
207 dc: DC,
208 rst: RST,
209 delay: &mut DELAY,
210 delay_us: Option<u32>,
211 ) -> Result<Self, SPI::Error> {
212 let interface = DisplayInterface::new(busy, dc, rst, delay_us);
213 let color = DEFAULT_BACKGROUND_COLOR;
214
215 let mut epd = Epd2in13bc { interface, color };
216
217 epd.init(spi, delay)?;
218
219 Ok(epd)
220 }
221
222 fn sleep(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
223 self.interface.cmd_with_data(
225 spi,
226 Command::VcomAndDataIntervalSetting,
227 &[FLOATING_BORDER | VCOM_DATA_INTERVAL],
228 )?;
229
230 self.command(spi, Command::PowerOff)?;
231 self.wait_until_idle(spi, delay)?;
233
234 self.cmd_with_data(spi, Command::DeepSleep, &[0xA5])?;
235
236 Ok(())
237 }
238
239 fn wake_up(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
240 self.init(spi, delay)
241 }
242
243 fn set_background_color(&mut self, color: TriColor) {
244 self.color = color;
245 }
246
247 fn background_color(&self) -> &TriColor {
248 &self.color
249 }
250
251 fn width(&self) -> u32 {
252 WIDTH
253 }
254
255 fn height(&self) -> u32 {
256 HEIGHT
257 }
258
259 fn update_frame(
260 &mut self,
261 spi: &mut SPI,
262 buffer: &[u8],
263 delay: &mut DELAY,
264 ) -> Result<(), SPI::Error> {
265 self.interface.cmd(spi, Command::DataStartTransmission1)?;
266
267 self.interface.data(spi, buffer)?;
268
269 let color = self.color.get_byte_value();
271
272 self.interface.cmd(spi, Command::DataStartTransmission2)?;
273 self.interface.data_x_times(spi, color, NUM_DISPLAY_BITS)?;
274
275 self.wait_until_idle(spi, delay)?;
276 Ok(())
277 }
278
279 #[allow(unused)]
280 fn update_partial_frame(
281 &mut self,
282 spi: &mut SPI,
283 delay: &mut DELAY,
284 buffer: &[u8],
285 x: u32,
286 y: u32,
287 width: u32,
288 height: u32,
289 ) -> Result<(), SPI::Error> {
290 Ok(())
291 }
292
293 fn display_frame(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
294 self.command(spi, Command::DisplayRefresh)?;
295
296 self.wait_until_idle(spi, delay)?;
297 Ok(())
298 }
299
300 fn update_and_display_frame(
301 &mut self,
302 spi: &mut SPI,
303 buffer: &[u8],
304 delay: &mut DELAY,
305 ) -> Result<(), SPI::Error> {
306 self.update_frame(spi, buffer, delay)?;
307 self.display_frame(spi, delay)?;
308 Ok(())
309 }
310
311 fn clear_frame(&mut self, spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
312 self.send_resolution(spi)?;
313
314 let color = DEFAULT_BACKGROUND_COLOR.get_byte_value();
315
316 self.interface.cmd(spi, Command::DataStartTransmission1)?;
318
319 self.interface.data_x_times(spi, color, NUM_DISPLAY_BITS)?;
320
321 self.interface.cmd(spi, Command::DataStartTransmission2)?;
323 self.interface.data_x_times(spi, color, NUM_DISPLAY_BITS)?;
324
325 self.wait_until_idle(spi, delay)?;
326 Ok(())
327 }
328
329 fn set_lut(
330 &mut self,
331 _spi: &mut SPI,
332 _delay: &mut DELAY,
333 _refresh_rate: Option<RefreshLut>,
334 ) -> Result<(), SPI::Error> {
335 Ok(())
336 }
337
338 fn wait_until_idle(&mut self, _spi: &mut SPI, delay: &mut DELAY) -> Result<(), SPI::Error> {
339 self.interface.wait_until_idle(delay, IS_BUSY_LOW);
340 Ok(())
341 }
342}
343
344impl<SPI, BUSY, DC, RST, DELAY> Epd2in13bc<SPI, BUSY, DC, RST, DELAY>
345where
346 SPI: SpiDevice,
347 BUSY: InputPin,
348 DC: OutputPin,
349 RST: OutputPin,
350 DELAY: DelayNs,
351{
352 fn command(&mut self, spi: &mut SPI, command: Command) -> Result<(), SPI::Error> {
353 self.interface.cmd(spi, command)
354 }
355
356 fn send_data(&mut self, spi: &mut SPI, data: &[u8]) -> Result<(), SPI::Error> {
357 self.interface.data(spi, data)
358 }
359
360 fn cmd_with_data(
361 &mut self,
362 spi: &mut SPI,
363 command: Command,
364 data: &[u8],
365 ) -> Result<(), SPI::Error> {
366 self.interface.cmd_with_data(spi, command, data)
367 }
368
369 fn send_resolution(&mut self, spi: &mut SPI) -> Result<(), SPI::Error> {
370 let w = self.width();
371 let h = self.height();
372
373 self.command(spi, Command::ResolutionSetting)?;
374
375 self.send_data(spi, &[w as u8])?;
376 self.send_data(spi, &[(h >> 8) as u8])?;
377 self.send_data(spi, &[h as u8])
378 }
379
380 pub fn set_border_color(&mut self, spi: &mut SPI, color: TriColor) -> Result<(), SPI::Error> {
382 let border = match color {
383 TriColor::Black => BLACK_BORDER,
384 TriColor::White => WHITE_BORDER,
385 TriColor::Chromatic => CHROMATIC_BORDER,
386 };
387 self.cmd_with_data(
388 spi,
389 Command::VcomAndDataIntervalSetting,
390 &[border | VCOM_DATA_INTERVAL],
391 )
392 }
393}