1use core::cell::Cell;
16use core::cmp;
17use kernel::debug;
18use kernel::deferred_call::{DeferredCall, DeferredCallClient};
19use kernel::hil::gpio::Pin;
20use kernel::hil::screen::{Screen, ScreenClient, ScreenPixelFormat, ScreenRotation, ScreenSetup};
21use kernel::hil::spi::{SpiMasterClient, SpiMasterDevice};
22use kernel::hil::time::{Alarm, AlarmClient, ConvertTicks};
23use kernel::utilities::cells::{OptionalCell, TakeCell};
24use kernel::utilities::leasable_buffer::SubSliceMut;
25use kernel::ErrorCode;
26
27const ROWS: usize = 176;
32const COLS: usize = 176;
33const ROW_BYTES: usize = COLS / 2;
34const LINE_LEN: usize = ROW_BYTES + 2;
35pub const BUF_LEN: usize = ROWS * LINE_LEN + 2;
36
37struct InputBuffer<'a, const PIXEL_BITS: usize> {
38 data: &'a [u8],
39 frame: &'a WriteFrame,
40}
41
42impl<const PIXEL_BITS: usize> InputBuffer<'_, PIXEL_BITS> {
43 fn rows(&self) -> impl Iterator<Item = Row> {
44 let chunk_width = if PIXEL_BITS < 8 {
45 self.frame.width as usize / (8 / PIXEL_BITS)
46 } else {
47 self.frame.width as usize * (PIXEL_BITS / 8)
48 };
49 self.data.chunks(chunk_width).map(|data| Row { data })
50 }
51}
52
53struct Pixel<'a> {
54 data: &'a u8,
55 top: bool,
56}
57
58impl Pixel<'_> {
59 fn get(&self) -> u8 {
60 if self.top {
61 (*self.data >> 4) & 0xf
62 } else {
63 *self.data & 0xf
64 }
65 }
66}
67
68struct PixelMut<'a> {
69 data: &'a Cell<u8>,
70 top: bool,
71}
72
73impl PixelMut<'_> {
74 fn transform<F>(&self, f: F)
75 where
76 F: FnOnce(&mut u8),
77 {
78 let mut data = if self.top {
79 (self.data.get() & 0xf0) >> 4
80 } else {
81 self.data.get() & 0x0f
82 };
83
84 f(&mut data);
85
86 if self.top {
87 self.data.set(self.data.get() & 0x0f | ((data << 4) & 0xf0));
88 } else {
89 self.data.set(self.data.get() & 0xf0 | (data & 0x0f));
90 }
91 }
92}
93
94struct Row<'a> {
95 data: &'a [u8],
96}
97
98impl<'a> Row<'a> {
99 fn iter<'b>(&'b self) -> impl Iterator<Item = Pixel<'a>> {
100 self.data
101 .iter()
102 .flat_map(|data| [Pixel { data, top: true }, Pixel { data, top: false }])
103 }
104}
105
106struct RowMut<'a> {
107 data: &'a [Cell<u8>],
108}
109
110impl RowMut<'_> {
111 fn iter_mut(&self) -> impl Iterator<Item = PixelMut> {
112 self.data
113 .iter()
114 .flat_map(|data| [PixelMut { data, top: true }, PixelMut { data, top: false }])
115 }
116}
117
118struct FrameBuffer<'a> {
121 data: SubSliceMut<'a, u8>,
122}
123
124impl<'a> FrameBuffer<'a> {
125 fn new(mut frame_buffer: SubSliceMut<'a, u8>) -> Self {
129 frame_buffer.reset();
130 Self { data: frame_buffer }
131 }
132
133 fn initialize(&mut self) {
135 for i in 0..ROWS {
136 self.set_line_header(
137 i,
138 &CommandHeader {
139 mode: Mode::Input4Bit,
140 gate_line: (i + 1) as u16,
141 },
142 );
143 }
144 }
145
146 fn blit_rgb565(&mut self, buffer: InputBuffer<16>) {
148 let frame_rows = self
149 .rows()
150 .skip(buffer.frame.row as usize)
151 .take(buffer.frame.height as usize);
152 let buf_rows = buffer.rows();
153
154 for (frame_row, buf_row) in frame_rows.zip(buf_rows) {
155 for (frame_pixel, buf_pixel) in frame_row
156 .iter_mut()
157 .skip(buffer.frame.column as usize)
158 .zip(buf_row.data.chunks_exact(2))
159 {
160 let buf_pixel = [buf_pixel[0], buf_pixel[1]];
161 let buf_p = u16::from_le_bytes(buf_pixel);
162 frame_pixel.transform(|pixel| {
163 let red = if (buf_p >> 11) & 0b11111 >= 32 / 2 {
164 0b1000
166 } else {
167 0
168 };
169
170 let green = if (buf_p >> 5) & 0b111111 >= 64 / 2 {
171 0b0100
173 } else {
174 0
175 };
176
177 let blue = if buf_p & 0b11111 >= 32 / 2 {
178 0b0010
180 } else {
181 0
182 };
183
184 *pixel = red | green | blue;
185 });
186 }
187 }
188 }
189
190 fn blit_rgb332(&mut self, buffer: InputBuffer<8>) {
192 let frame_rows = self
193 .rows()
194 .skip(buffer.frame.row as usize)
195 .take(buffer.frame.height as usize);
196 let buf_rows = buffer.rows();
197
198 for (frame_row, buf_row) in frame_rows.zip(buf_rows) {
199 for (frame_pixel, buf_pixel) in frame_row
200 .iter_mut()
201 .skip(buffer.frame.column as usize)
202 .zip(buf_row.data.iter())
203 {
204 let buf_p: u8 = *buf_pixel;
205 frame_pixel.transform(|pixel| {
206 let red = if (buf_p >> 5) & 0b111 >= 7 / 2 {
207 0b1000
209 } else {
210 0
211 };
212
213 let green = if (buf_p >> 2) & 0b111 >= 7 / 2 {
214 0b0100
216 } else {
217 0
218 };
219
220 let blue = if buf_p & 0b11 >= 3 / 2 {
221 0b0010
223 } else {
224 0
225 };
226
227 *pixel = red | green | blue;
228 });
229 }
230 }
231 }
232
233 fn blit_4bit_srgb(&mut self, buffer: InputBuffer<4>) {
235 let frame_rows = self
236 .rows()
237 .skip(buffer.frame.row as usize)
238 .take(buffer.frame.height as usize);
239 let buf_rows = buffer.rows();
240
241 for (frame_row, buf_row) in frame_rows.zip(buf_rows) {
242 for (frame_pixel, buf_pixel) in frame_row
243 .iter_mut()
244 .skip(buffer.frame.column as usize)
245 .zip(buf_row.iter())
246 {
247 let buf_p: u8 = buf_pixel.get();
248 if buf_p & 0b1 != 0 {
249 frame_pixel.transform(|pixel| {
250 *pixel = ((buf_p & 0b10) << 2) | (buf_p & 0b100) | ((buf_p & 0b1000) >> 2);
260 });
261 }
262 }
263 }
264 }
265
266 fn set_line_header(&mut self, index: usize, header: &CommandHeader) {
267 const CMD: usize = 2;
268 if let Some(buf) = self.data[(LINE_LEN * index)..].first_chunk_mut::<CMD>() {
269 *buf = header.encode();
270 }
271 }
272
273 fn rows(&mut self) -> impl Iterator<Item = RowMut> {
274 self.data.as_slice().chunks_mut(LINE_LEN).map_while(|c| {
275 c.get_mut(2..).map(|data| RowMut {
276 data: Cell::from_mut(data).as_slice_of_cells(),
277 })
278 })
279 }
280}
281
282#[allow(dead_code)]
285#[derive(Clone, Copy)]
286enum Mode {
287 AllClear = 0b001000,
290 Input1Bit = 0b100_01_0,
293 Input4Bit = 0b100100,
294 NoUpdate = 0b101000,
295}
296
297struct CommandHeader {
300 mode: Mode,
301 gate_line: u16,
302}
303
304impl CommandHeader {
305 fn encode(&self) -> [u8; 2] {
307 ((self.gate_line & 0b1111111111) | ((self.mode as u16) << 10)).to_be_bytes()
308 }
309}
310
311#[derive(Debug, Copy, Clone)]
313struct WriteFrame {
314 row: u16,
315 column: u16,
316 width: u16,
317 height: u16,
318}
319
320#[derive(Debug, Copy, Clone)]
323enum State {
324 Uninitialized,
326
327 Off,
329 InitializingPixelMemory,
330 InitializingRest,
332
333 Idle,
335 AllClearing,
336 Writing,
337
338 Bug,
340}
341
342#[derive(Debug)]
343pub enum InitError {
344 BufferTooSmall,
345}
346
347pub struct Lpm013m126<'a, A: Alarm<'a>, P: Pin, S: SpiMasterDevice<'a>> {
348 spi: &'a S,
349 extcomin: &'a P,
350 disp: &'a P,
351
352 state: Cell<State>,
353
354 pixel_format: Cell<ScreenPixelFormat>,
355 frame: Cell<WriteFrame>,
356
357 ready_callback: DeferredCall,
360 ready_callback_handler: ReadyCallbackHandler<'a, A, P, S>,
361 command_complete_callback: DeferredCall,
362 command_complete_callback_handler: CommandCompleteCallbackHandler<'a, A, P, S>,
363
364 frame_buffer: OptionalCell<FrameBuffer<'static>>,
368
369 client: OptionalCell<&'a dyn ScreenClient>,
370 buffer: TakeCell<'static, [u8]>,
373
374 alarm: &'a A,
376}
377
378impl<'a, A: Alarm<'a>, P: Pin, S: SpiMasterDevice<'a>> Lpm013m126<'a, A, P, S>
379where
380 Self: 'static,
381{
382 pub fn new(
383 spi: &'a S,
384 extcomin: &'a P,
385 disp: &'a P,
386 alarm: &'a A,
387 frame_buffer: &'static mut [u8; BUF_LEN],
388 ) -> Result<Self, InitError> {
389 Ok(Self {
390 spi,
391 alarm,
392 disp,
393 extcomin,
394 ready_callback: DeferredCall::new(),
395 ready_callback_handler: ReadyCallbackHandler::new(),
396 command_complete_callback: DeferredCall::new(),
397 command_complete_callback_handler: CommandCompleteCallbackHandler::new(),
398 frame_buffer: OptionalCell::new(FrameBuffer::new((frame_buffer as &mut [u8]).into())),
399 pixel_format: Cell::new(ScreenPixelFormat::RGB_565),
400 buffer: TakeCell::empty(),
401 client: OptionalCell::empty(),
402 state: Cell::new(State::Uninitialized),
403 frame: Cell::new(WriteFrame {
404 row: 0,
405 column: 0,
406 width: COLS as u16,
407 height: ROWS as u16,
408 }),
409 })
410 }
411
412 pub fn setup(&'static self) -> Result<(), ErrorCode> {
416 match self.state.get() {
420 State::Uninitialized => {
421 self.ready_callback_handler.lpm.set(self);
422 self.ready_callback.register(&self.ready_callback_handler);
423 self.command_complete_callback_handler.lpm.set(self);
424 self.command_complete_callback
425 .register(&self.command_complete_callback_handler);
426
427 self.state.set(State::Off);
428 Ok(())
429 }
430 _ => Err(ErrorCode::ALREADY),
431 }
432 }
433
434 fn initialize(&self) -> Result<(), ErrorCode> {
435 match self.state.get() {
436 State::Off | State::Bug => {
437 self.extcomin.make_output();
445 self.extcomin.clear();
446 self.disp.make_output();
447 self.disp.clear();
448
449 match self.frame_buffer.take() {
450 None => Err(ErrorCode::NOMEM),
451 Some(mut frame_buffer) => {
452 frame_buffer.set_line_header(
456 0,
457 &CommandHeader {
458 mode: Mode::AllClear,
459 gate_line: 0,
460 },
461 );
462 let mut l = frame_buffer.data;
463 l.slice(0..2);
464 let res = self.spi.read_write_bytes(l, None);
465
466 let (res, new_state) = match res {
467 Ok(()) => (Ok(()), State::InitializingPixelMemory),
468 Err((e, buf, _)) => {
469 self.frame_buffer.replace(FrameBuffer::new(buf));
470 (Err(e), State::Bug)
471 }
472 };
473 self.state.set(new_state);
474 res
475 }
476 }
477 }
478 _ => Err(ErrorCode::ALREADY),
479 }
480 }
481
482 fn uninitialize(&self) -> Result<(), ErrorCode> {
483 match self.state.get() {
484 State::Off => Err(ErrorCode::ALREADY),
485 _ => {
486 self.alarm.disarm()?;
493 self.disp.clear();
494 self.state.set(State::Off);
495
496 self.ready_callback.set();
497 Ok(())
498 }
499 }
500 }
501
502 fn arm_alarm(&self) {
503 let delay = self.alarm.ticks_from_ms(100);
506 self.alarm.set_alarm(self.alarm.now(), delay);
507 }
508
509 fn handle_ready_callback(&self) {
510 self.client.map(|client| client.screen_is_ready());
511 }
512
513 fn handle_command_complete_callback(&self) {
514 self.client.map(|client| client.command_complete(Ok(())));
518 }
519}
520
521impl<'a, A: Alarm<'a>, P: Pin, S: SpiMasterDevice<'a>> Screen<'a> for Lpm013m126<'a, A, P, S>
522where
523 Self: 'static,
524{
525 fn get_resolution(&self) -> (usize, usize) {
526 (ROWS, COLS)
527 }
528
529 fn get_pixel_format(&self) -> ScreenPixelFormat {
530 self.pixel_format.get()
531 }
532
533 fn get_rotation(&self) -> ScreenRotation {
534 ScreenRotation::Normal
535 }
536
537 fn set_write_frame(
538 &self,
539 x: usize,
540 y: usize,
541 width: usize,
542 height: usize,
543 ) -> Result<(), ErrorCode> {
544 let (columns, rows) = self.get_resolution();
545 if y >= rows || y + height > rows || x >= columns || x + width > columns {
546 }
548
549 let frame = WriteFrame {
550 row: y as u16,
551 column: x as u16,
552 width: width as u16,
553 height: height as u16,
554 };
555 self.frame.set(frame);
556
557 self.command_complete_callback.set();
558
559 Ok(())
560 }
561
562 fn write(
563 &self,
564 data: SubSliceMut<'static, u8>,
565 _continue_write: bool,
566 ) -> Result<(), ErrorCode> {
567 let len = data.len();
568 let buffer = data.take();
569
570 let ret = match self.state.get() {
571 State::Uninitialized | State::Off => Err(ErrorCode::OFF),
572 State::InitializingPixelMemory | State::InitializingRest => Err(ErrorCode::BUSY),
573 State::Idle => {
574 self.frame_buffer
575 .take()
576 .map_or(Err(ErrorCode::NOMEM), |mut frame_buffer| {
577 match self.pixel_format.get() {
578 ScreenPixelFormat::RGB_332 => {
579 frame_buffer.blit_rgb332(InputBuffer {
580 data: &buffer[..cmp::min(buffer.len(), len)],
581 frame: &self.frame.get(),
582 });
583 }
584 ScreenPixelFormat::RGB_565 => {
585 frame_buffer.blit_rgb565(InputBuffer {
586 data: &buffer[..cmp::min(buffer.len(), len)],
587 frame: &self.frame.get(),
588 });
589 }
590 _ => frame_buffer.blit_4bit_srgb(InputBuffer {
591 data: &buffer[..cmp::min(buffer.len(), len)],
592 frame: &self.frame.get(),
593 }),
594 }
595
596 frame_buffer.set_line_header(
597 0,
598 &CommandHeader {
599 mode: Mode::NoUpdate,
600 gate_line: 0,
601 },
602 );
603 let mut l = frame_buffer.data;
604 l.slice(0..2);
605 let sent = self.spi.read_write_bytes(l, None);
606
607 let (ret, new_state) = match sent {
608 Ok(()) => (Ok(()), State::AllClearing),
609 Err((e, buf, _)) => {
610 self.frame_buffer.replace(FrameBuffer::new(buf));
611 (Err(e), State::Idle)
612 }
613 };
614 self.state.set(new_state);
615 ret
616 })
617 }
618 State::AllClearing | State::Writing => Err(ErrorCode::BUSY),
619 State::Bug => Err(ErrorCode::FAIL),
620 };
621
622 self.buffer.replace(buffer);
623
624 ret
625 }
626
627 fn set_client(&self, client: &'a dyn ScreenClient) {
628 self.client.set(client);
629 }
630
631 fn set_power(&self, enable: bool) -> Result<(), ErrorCode> {
632 let ret = if enable {
633 self.initialize()
634 } else {
635 self.uninitialize()
636 };
637
638 if let Err(ErrorCode::ALREADY) = ret {
641 self.ready_callback.set();
642 Ok(())
643 } else {
644 ret
645 }
646 }
647
648 fn set_brightness(&self, _brightness: u16) -> Result<(), ErrorCode> {
649 Err(ErrorCode::NOSUPPORT)
651 }
652
653 fn set_invert(&self, _inverted: bool) -> Result<(), ErrorCode> {
654 Err(ErrorCode::NOSUPPORT)
655 }
656}
657
658impl<'a, A: Alarm<'a>, P: Pin, S: SpiMasterDevice<'a>> ScreenSetup<'a> for Lpm013m126<'a, A, P, S> {
659 fn set_client(&self, _client: &'a dyn kernel::hil::screen::ScreenSetupClient) {
660 todo!()
661 }
662
663 fn set_resolution(&self, resolution: (usize, usize)) -> Result<(), ErrorCode> {
664 if resolution == (ROWS, COLS) {
665 Ok(())
666 } else {
667 Err(ErrorCode::NOSUPPORT)
668 }
669 }
670
671 fn set_pixel_format(&self, format: ScreenPixelFormat) -> Result<(), ErrorCode> {
672 match format {
673 ScreenPixelFormat::RGB_4BIT | ScreenPixelFormat::RGB_332 => {
674 self.pixel_format.set(format);
675 Ok(())
676 }
677 _ => Err(ErrorCode::NOSUPPORT),
678 }
679 }
680
681 fn set_rotation(&self, _rotation: ScreenRotation) -> Result<(), ErrorCode> {
682 todo!()
683 }
684
685 fn get_num_supported_resolutions(&self) -> usize {
686 1
687 }
688
689 fn get_supported_resolution(&self, index: usize) -> Option<(usize, usize)> {
690 match index {
691 0 => Some((ROWS, COLS)),
692 _ => None,
693 }
694 }
695
696 fn get_num_supported_pixel_formats(&self) -> usize {
697 3
698 }
699
700 fn get_supported_pixel_format(&self, index: usize) -> Option<ScreenPixelFormat> {
701 match index {
702 0 => Some(ScreenPixelFormat::RGB_4BIT),
703 1 => Some(ScreenPixelFormat::RGB_332),
704 2 => Some(ScreenPixelFormat::RGB_565),
705 _ => None,
706 }
707 }
708}
709
710impl<'a, A: Alarm<'a>, P: Pin, S: SpiMasterDevice<'a>> AlarmClient for Lpm013m126<'a, A, P, S>
711where
712 Self: 'static,
713{
714 fn alarm(&self) {
715 match self.state.get() {
716 State::InitializingRest => {
717 self.extcomin.set();
720 self.disp.set();
721 self.arm_alarm();
722 let new_state = self.frame_buffer.take().map_or_else(
723 || {
724 debug!(
725 "LPM013M126 driver lost its frame buffer in state {:?}",
726 self.state.get()
727 );
728 State::Bug
729 },
730 |mut buffer| {
731 buffer.initialize();
732 self.frame_buffer.replace(buffer);
733 State::Idle
734 },
735 );
736
737 self.state.set(new_state);
738
739 if let State::Idle = new_state {
740 self.client.map(|client| client.screen_is_ready());
741 }
742 }
743 _ => {
744 self.extcomin.toggle();
745 }
746 }
747 }
748}
749
750impl<'a, A: Alarm<'a>, P: Pin, S: SpiMasterDevice<'a>> SpiMasterClient for Lpm013m126<'a, A, P, S> {
751 fn read_write_done(
752 &self,
753 write_buffer: SubSliceMut<'static, u8>,
754 _read_buffer: Option<SubSliceMut<'static, u8>>,
755 status: Result<usize, ErrorCode>,
756 ) {
757 self.frame_buffer.replace(FrameBuffer::new(write_buffer));
758 self.state.set(match self.state.get() {
759 State::InitializingPixelMemory => {
760 let delay = self.alarm.ticks_from_us(150);
765 self.alarm.set_alarm(self.alarm.now(), delay);
766 State::InitializingRest
767 }
768 State::AllClearing => {
769 if let Some(mut fb) = self.frame_buffer.take() {
770 fb.set_line_header(
771 0,
772 &CommandHeader {
773 mode: Mode::Input4Bit,
774 gate_line: 1,
775 },
776 );
777 let mut send_buf = fb.data;
778
779 let first_row = cmp::min(ROWS as u16, self.frame.get().row);
780 let offset = first_row as usize * LINE_LEN;
781 let len = cmp::min(ROWS as u16 - first_row, self.frame.get().height) as usize
782 * LINE_LEN;
783 send_buf.slice(offset..(offset + len + 2));
784
785 let _ = self.spi.read_write_bytes(send_buf, None);
786 }
787 State::Writing
788 }
789 State::Writing => {
790 if let Some(mut fb) = self.frame_buffer.take() {
791 fb.initialize();
792 self.frame_buffer.set(fb);
793 }
794 State::Idle
795 }
796 other => {
798 debug!(
799 "LPM013M126 received unexpected SPI complete in state {:?}",
800 other
801 );
802 State::Bug
803 }
804 });
805
806 if let State::Idle = self.state.get() {
807 self.client.map(|client| {
809 self.buffer.take().map(|buf| {
810 let data = SubSliceMut::new(buf);
811 client.write_complete(data, status.map(|_| ()))
812 })
813 });
814 }
815 }
816}
817
818struct ReadyCallbackHandler<'a, A: Alarm<'a>, P: Pin, S: SpiMasterDevice<'a>> {
821 lpm: OptionalCell<&'a Lpm013m126<'a, A, P, S>>,
822}
823
824impl<'a, A: Alarm<'a>, P: Pin, S: SpiMasterDevice<'a>> ReadyCallbackHandler<'a, A, P, S> {
825 fn new() -> Self {
826 Self {
827 lpm: OptionalCell::empty(),
828 }
829 }
830}
831
832impl<'a, A: Alarm<'a>, P: Pin, S: SpiMasterDevice<'a>> DeferredCallClient
833 for ReadyCallbackHandler<'a, A, P, S>
834where
835 Self: 'static,
836{
837 fn handle_deferred_call(&self) {
838 self.lpm.map(|l| l.handle_ready_callback());
839 }
840
841 fn register(&'static self) {
842 self.lpm.map(|l| l.ready_callback.register(self));
843 }
844}
845
846struct CommandCompleteCallbackHandler<'a, A: Alarm<'a>, P: Pin, S: SpiMasterDevice<'a>> {
847 lpm: OptionalCell<&'a Lpm013m126<'a, A, P, S>>,
848}
849
850impl<'a, A: Alarm<'a>, P: Pin, S: SpiMasterDevice<'a>> CommandCompleteCallbackHandler<'a, A, P, S> {
851 fn new() -> Self {
852 Self {
853 lpm: OptionalCell::empty(),
854 }
855 }
856}
857
858impl<'a, A: Alarm<'a>, P: Pin, S: SpiMasterDevice<'a>> DeferredCallClient
859 for CommandCompleteCallbackHandler<'a, A, P, S>
860where
861 Self: 'static,
862{
863 fn handle_deferred_call(&self) {
864 self.lpm.map(|l| l.handle_command_complete_callback());
865 }
866
867 fn register(&'static self) {
868 self.lpm.map(|l| l.command_complete_callback.register(self));
869 }
870}