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
275 .as_mut_slice()
276 .chunks_mut(LINE_LEN)
277 .map_while(|c| {
278 c.get_mut(2..).map(|data| RowMut {
279 data: Cell::from_mut(data).as_slice_of_cells(),
280 })
281 })
282 }
283}
284
285#[allow(dead_code)]
288#[derive(Clone, Copy)]
289enum Mode {
290 AllClear = 0b001000,
293 Input1Bit = 0b100_01_0,
296 Input4Bit = 0b100100,
297 NoUpdate = 0b101000,
298}
299
300struct CommandHeader {
303 mode: Mode,
304 gate_line: u16,
305}
306
307impl CommandHeader {
308 fn encode(&self) -> [u8; 2] {
310 ((self.gate_line & 0b1111111111) | ((self.mode as u16) << 10)).to_be_bytes()
311 }
312}
313
314#[derive(Debug, Copy, Clone)]
316struct WriteFrame {
317 row: u16,
318 column: u16,
319 width: u16,
320 height: u16,
321}
322
323#[derive(Debug, Copy, Clone)]
326enum State {
327 Uninitialized,
329
330 Off,
332 InitializingPixelMemory,
333 InitializingRest,
335
336 Idle,
338 AllClearing,
339 Writing,
340
341 Bug,
343}
344
345#[derive(Debug)]
346pub enum InitError {
347 BufferTooSmall,
348}
349
350pub struct Lpm013m126<'a, A: Alarm<'a>, P: Pin, S: SpiMasterDevice<'a>> {
351 spi: &'a S,
352 extcomin: &'a P,
353 disp: &'a P,
354
355 state: Cell<State>,
356
357 pixel_format: Cell<ScreenPixelFormat>,
358 frame: Cell<WriteFrame>,
359
360 ready_callback: DeferredCall,
363 ready_callback_handler: ReadyCallbackHandler<'a, A, P, S>,
364 command_complete_callback: DeferredCall,
365 command_complete_callback_handler: CommandCompleteCallbackHandler<'a, A, P, S>,
366
367 frame_buffer: OptionalCell<FrameBuffer<'static>>,
371
372 client: OptionalCell<&'a dyn ScreenClient>,
373 buffer: TakeCell<'static, [u8]>,
376
377 alarm: &'a A,
379}
380
381impl<'a, A: Alarm<'a>, P: Pin, S: SpiMasterDevice<'a>> Lpm013m126<'a, A, P, S>
382where
383 Self: 'static,
384{
385 pub fn new(
386 spi: &'a S,
387 extcomin: &'a P,
388 disp: &'a P,
389 alarm: &'a A,
390 frame_buffer: &'static mut [u8; BUF_LEN],
391 ) -> Result<Self, InitError> {
392 Ok(Self {
393 spi,
394 alarm,
395 disp,
396 extcomin,
397 ready_callback: DeferredCall::new(),
398 ready_callback_handler: ReadyCallbackHandler::new(),
399 command_complete_callback: DeferredCall::new(),
400 command_complete_callback_handler: CommandCompleteCallbackHandler::new(),
401 frame_buffer: OptionalCell::new(FrameBuffer::new((frame_buffer as &mut [u8]).into())),
402 pixel_format: Cell::new(ScreenPixelFormat::RGB_565),
403 buffer: TakeCell::empty(),
404 client: OptionalCell::empty(),
405 state: Cell::new(State::Uninitialized),
406 frame: Cell::new(WriteFrame {
407 row: 0,
408 column: 0,
409 width: COLS as u16,
410 height: ROWS as u16,
411 }),
412 })
413 }
414
415 pub fn setup(&'static self) -> Result<(), ErrorCode> {
419 match self.state.get() {
423 State::Uninitialized => {
424 self.ready_callback_handler.lpm.set(self);
425 self.ready_callback.register(&self.ready_callback_handler);
426 self.command_complete_callback_handler.lpm.set(self);
427 self.command_complete_callback
428 .register(&self.command_complete_callback_handler);
429
430 self.state.set(State::Off);
431 Ok(())
432 }
433 _ => Err(ErrorCode::ALREADY),
434 }
435 }
436
437 fn initialize(&self) -> Result<(), ErrorCode> {
438 match self.state.get() {
439 State::Off | State::Bug => {
440 self.extcomin.make_output();
448 self.extcomin.clear();
449 self.disp.make_output();
450 self.disp.clear();
451
452 match self.frame_buffer.take() {
453 None => Err(ErrorCode::NOMEM),
454 Some(mut frame_buffer) => {
455 frame_buffer.set_line_header(
459 0,
460 &CommandHeader {
461 mode: Mode::AllClear,
462 gate_line: 0,
463 },
464 );
465 let mut l = frame_buffer.data;
466 l.slice(0..2);
467 let res = self.spi.read_write_bytes(l, None);
468
469 let (res, new_state) = match res {
470 Ok(()) => (Ok(()), State::InitializingPixelMemory),
471 Err((e, buf, _)) => {
472 self.frame_buffer.replace(FrameBuffer::new(buf));
473 (Err(e), State::Bug)
474 }
475 };
476 self.state.set(new_state);
477 res
478 }
479 }
480 }
481 _ => Err(ErrorCode::ALREADY),
482 }
483 }
484
485 fn uninitialize(&self) -> Result<(), ErrorCode> {
486 match self.state.get() {
487 State::Off => Err(ErrorCode::ALREADY),
488 _ => {
489 self.alarm.disarm()?;
496 self.disp.clear();
497 self.state.set(State::Off);
498
499 self.ready_callback.set();
500 Ok(())
501 }
502 }
503 }
504
505 fn arm_alarm(&self) {
506 let delay = self.alarm.ticks_from_ms(100);
509 self.alarm.set_alarm(self.alarm.now(), delay);
510 }
511
512 fn handle_ready_callback(&self) {
513 self.client.map(|client| client.screen_is_ready());
514 }
515
516 fn handle_command_complete_callback(&self) {
517 self.client.map(|client| client.command_complete(Ok(())));
521 }
522}
523
524impl<'a, A: Alarm<'a>, P: Pin, S: SpiMasterDevice<'a>> Screen<'a> for Lpm013m126<'a, A, P, S>
525where
526 Self: 'static,
527{
528 fn get_resolution(&self) -> (usize, usize) {
529 (ROWS, COLS)
530 }
531
532 fn get_pixel_format(&self) -> ScreenPixelFormat {
533 self.pixel_format.get()
534 }
535
536 fn get_rotation(&self) -> ScreenRotation {
537 ScreenRotation::Normal
538 }
539
540 fn set_write_frame(
541 &self,
542 x: usize,
543 y: usize,
544 width: usize,
545 height: usize,
546 ) -> Result<(), ErrorCode> {
547 let (columns, rows) = self.get_resolution();
548 if y >= rows || y + height > rows || x >= columns || x + width > columns {
549 }
551
552 let frame = WriteFrame {
553 row: y as u16,
554 column: x as u16,
555 width: width as u16,
556 height: height as u16,
557 };
558 self.frame.set(frame);
559
560 self.command_complete_callback.set();
561
562 Ok(())
563 }
564
565 fn write(
566 &self,
567 data: SubSliceMut<'static, u8>,
568 _continue_write: bool,
569 ) -> Result<(), ErrorCode> {
570 let len = data.len();
571 let buffer = data.take();
572
573 let ret = match self.state.get() {
574 State::Uninitialized | State::Off => Err(ErrorCode::OFF),
575 State::InitializingPixelMemory | State::InitializingRest => Err(ErrorCode::BUSY),
576 State::Idle => {
577 self.frame_buffer
578 .take()
579 .map_or(Err(ErrorCode::NOMEM), |mut frame_buffer| {
580 match self.pixel_format.get() {
581 ScreenPixelFormat::RGB_332 => {
582 frame_buffer.blit_rgb332(InputBuffer {
583 data: &buffer[..cmp::min(buffer.len(), len)],
584 frame: &self.frame.get(),
585 });
586 }
587 ScreenPixelFormat::RGB_565 => {
588 frame_buffer.blit_rgb565(InputBuffer {
589 data: &buffer[..cmp::min(buffer.len(), len)],
590 frame: &self.frame.get(),
591 });
592 }
593 _ => frame_buffer.blit_4bit_srgb(InputBuffer {
594 data: &buffer[..cmp::min(buffer.len(), len)],
595 frame: &self.frame.get(),
596 }),
597 }
598
599 frame_buffer.set_line_header(
600 0,
601 &CommandHeader {
602 mode: Mode::NoUpdate,
603 gate_line: 0,
604 },
605 );
606 let mut l = frame_buffer.data;
607 l.slice(0..2);
608 let sent = self.spi.read_write_bytes(l, None);
609
610 let (ret, new_state) = match sent {
611 Ok(()) => (Ok(()), State::AllClearing),
612 Err((e, buf, _)) => {
613 self.frame_buffer.replace(FrameBuffer::new(buf));
614 (Err(e), State::Idle)
615 }
616 };
617 self.state.set(new_state);
618 ret
619 })
620 }
621 State::AllClearing | State::Writing => Err(ErrorCode::BUSY),
622 State::Bug => Err(ErrorCode::FAIL),
623 };
624
625 self.buffer.replace(buffer);
626
627 ret
628 }
629
630 fn set_client(&self, client: &'a dyn ScreenClient) {
631 self.client.set(client);
632 }
633
634 fn set_power(&self, enable: bool) -> Result<(), ErrorCode> {
635 let ret = if enable {
636 self.initialize()
637 } else {
638 self.uninitialize()
639 };
640
641 if let Err(ErrorCode::ALREADY) = ret {
644 self.ready_callback.set();
645 Ok(())
646 } else {
647 ret
648 }
649 }
650
651 fn set_brightness(&self, _brightness: u16) -> Result<(), ErrorCode> {
652 Err(ErrorCode::NOSUPPORT)
654 }
655
656 fn set_invert(&self, _inverted: bool) -> Result<(), ErrorCode> {
657 Err(ErrorCode::NOSUPPORT)
658 }
659}
660
661impl<'a, A: Alarm<'a>, P: Pin, S: SpiMasterDevice<'a>> ScreenSetup<'a> for Lpm013m126<'a, A, P, S> {
662 fn set_client(&self, _client: &'a dyn kernel::hil::screen::ScreenSetupClient) {
663 todo!()
664 }
665
666 fn set_resolution(&self, resolution: (usize, usize)) -> Result<(), ErrorCode> {
667 if resolution == (ROWS, COLS) {
668 Ok(())
669 } else {
670 Err(ErrorCode::NOSUPPORT)
671 }
672 }
673
674 fn set_pixel_format(&self, format: ScreenPixelFormat) -> Result<(), ErrorCode> {
675 match format {
676 ScreenPixelFormat::RGB_4BIT
677 | ScreenPixelFormat::RGB_332
678 | ScreenPixelFormat::RGB_565 => {
679 self.pixel_format.set(format);
680 Ok(())
681 }
682 _ => Err(ErrorCode::NOSUPPORT),
683 }
684 }
685
686 fn set_rotation(&self, _rotation: ScreenRotation) -> Result<(), ErrorCode> {
687 todo!()
688 }
689
690 fn get_num_supported_resolutions(&self) -> usize {
691 1
692 }
693
694 fn get_supported_resolution(&self, index: usize) -> Option<(usize, usize)> {
695 match index {
696 0 => Some((ROWS, COLS)),
697 _ => None,
698 }
699 }
700
701 fn get_num_supported_pixel_formats(&self) -> usize {
702 3
703 }
704
705 fn get_supported_pixel_format(&self, index: usize) -> Option<ScreenPixelFormat> {
706 match index {
707 0 => Some(ScreenPixelFormat::RGB_4BIT),
708 1 => Some(ScreenPixelFormat::RGB_332),
709 2 => Some(ScreenPixelFormat::RGB_565),
710 _ => None,
711 }
712 }
713}
714
715impl<'a, A: Alarm<'a>, P: Pin, S: SpiMasterDevice<'a>> AlarmClient for Lpm013m126<'a, A, P, S>
716where
717 Self: 'static,
718{
719 fn alarm(&self) {
720 match self.state.get() {
721 State::InitializingRest => {
722 self.extcomin.set();
725 self.disp.set();
726 self.arm_alarm();
727 let new_state = self.frame_buffer.take().map_or_else(
728 || {
729 debug!(
730 "LPM013M126 driver lost its frame buffer in state {:?}",
731 self.state.get()
732 );
733 State::Bug
734 },
735 |mut buffer| {
736 buffer.initialize();
737 self.frame_buffer.replace(buffer);
738 State::Idle
739 },
740 );
741
742 self.state.set(new_state);
743
744 if let State::Idle = new_state {
745 self.client.map(|client| client.screen_is_ready());
746 }
747 }
748 _ => {
749 self.extcomin.toggle();
750 }
751 }
752 }
753}
754
755impl<'a, A: Alarm<'a>, P: Pin, S: SpiMasterDevice<'a>> SpiMasterClient for Lpm013m126<'a, A, P, S> {
756 fn read_write_done(
757 &self,
758 write_buffer: SubSliceMut<'static, u8>,
759 _read_buffer: Option<SubSliceMut<'static, u8>>,
760 status: Result<usize, ErrorCode>,
761 ) {
762 self.frame_buffer.replace(FrameBuffer::new(write_buffer));
763 self.state.set(match self.state.get() {
764 State::InitializingPixelMemory => {
765 let delay = self.alarm.ticks_from_us(150);
770 self.alarm.set_alarm(self.alarm.now(), delay);
771 State::InitializingRest
772 }
773 State::AllClearing => {
774 if let Some(mut fb) = self.frame_buffer.take() {
775 fb.set_line_header(
776 0,
777 &CommandHeader {
778 mode: Mode::Input4Bit,
779 gate_line: 1,
780 },
781 );
782 let mut send_buf = fb.data;
783
784 let first_row = cmp::min(ROWS as u16, self.frame.get().row);
785 let offset = first_row as usize * LINE_LEN;
786 let len = cmp::min(ROWS as u16 - first_row, self.frame.get().height) as usize
787 * LINE_LEN;
788 send_buf.slice(offset..(offset + len + 2));
789
790 let _ = self.spi.read_write_bytes(send_buf, None);
791 }
792 State::Writing
793 }
794 State::Writing => {
795 if let Some(mut fb) = self.frame_buffer.take() {
796 fb.initialize();
797 self.frame_buffer.set(fb);
798 }
799 State::Idle
800 }
801 other => {
803 debug!(
804 "LPM013M126 received unexpected SPI complete in state {:?}",
805 other
806 );
807 State::Bug
808 }
809 });
810
811 if let State::Idle = self.state.get() {
812 self.client.map(|client| {
814 self.buffer.take().map(|buf| {
815 let data = SubSliceMut::new(buf);
816 client.write_complete(data, status.map(|_| ()))
817 })
818 });
819 }
820 }
821}
822
823struct ReadyCallbackHandler<'a, A: Alarm<'a>, P: Pin, S: SpiMasterDevice<'a>> {
826 lpm: OptionalCell<&'a Lpm013m126<'a, A, P, S>>,
827}
828
829impl<'a, A: Alarm<'a>, P: Pin, S: SpiMasterDevice<'a>> ReadyCallbackHandler<'a, A, P, S> {
830 fn new() -> Self {
831 Self {
832 lpm: OptionalCell::empty(),
833 }
834 }
835}
836
837impl<'a, A: Alarm<'a>, P: Pin, S: SpiMasterDevice<'a>> DeferredCallClient
838 for ReadyCallbackHandler<'a, A, P, S>
839where
840 Self: 'static,
841{
842 fn handle_deferred_call(&self) {
843 self.lpm.map(|l| l.handle_ready_callback());
844 }
845
846 fn register(&'static self) {
847 self.lpm.map(|l| l.ready_callback.register(self));
848 }
849}
850
851struct CommandCompleteCallbackHandler<'a, A: Alarm<'a>, P: Pin, S: SpiMasterDevice<'a>> {
852 lpm: OptionalCell<&'a Lpm013m126<'a, A, P, S>>,
853}
854
855impl<'a, A: Alarm<'a>, P: Pin, S: SpiMasterDevice<'a>> CommandCompleteCallbackHandler<'a, A, P, S> {
856 fn new() -> Self {
857 Self {
858 lpm: OptionalCell::empty(),
859 }
860 }
861}
862
863impl<'a, A: Alarm<'a>, P: Pin, S: SpiMasterDevice<'a>> DeferredCallClient
864 for CommandCompleteCallbackHandler<'a, A, P, S>
865where
866 Self: 'static,
867{
868 fn handle_deferred_call(&self) {
869 self.lpm.map(|l| l.handle_command_complete_callback());
870 }
871
872 fn register(&'static self) {
873 self.lpm.map(|l| l.command_complete_callback.register(self));
874 }
875}