capsules_extra/
lpm013m126.rs

1// Licensed under the Apache License, Version 2.0 or the MIT License.
2// SPDX-License-Identifier: Apache-2.0 OR MIT
3// Copyright Tock Contributors 2022.
4
5//! Frame buffer driver for the Japan Display LPM013M126 display
6//!
7//! Used in Bangle.js 2 and [Jazda](https://jazda.org).
8//! The driver is configured for the above devices:
9//! EXTCOM inversion is driven with EXTCOMIN.
10//!
11//! This driver supports monochrome mode only.
12//!
13//! Written by Dorota <gihu.dcz@porcupinefactory.org>
14
15use 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
27/// 4-bit frame buffer bytes.
28///
29/// 176 rows, of 176 4-bit pixels and a 2-byte command header, plus a
30/// trailing 2 byte transfer period
31const 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
118/// Arranges frame data in a buffer
119/// whose portions can be sent directly to the device.
120struct FrameBuffer<'a> {
121    data: SubSliceMut<'a, u8>,
122}
123
124impl<'a> FrameBuffer<'a> {
125    /// Turns a regular buffer (back) into a FrameBuffer.
126    /// If the buffer is fresh, and the display is initialized,
127    /// this *MUST* be initialized after the call to `new`.
128    fn new(mut frame_buffer: SubSliceMut<'a, u8>) -> Self {
129        frame_buffer.reset();
130        Self { data: frame_buffer }
131    }
132
133    /// Initialize header bytes for each line.
134    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    /// Copy pixels from the buffer. The buffer may be shorter than frame.
147    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                        // are red five bits more than 50%?
165                        0b1000
166                    } else {
167                        0
168                    };
169
170                    let green = if (buf_p >> 5) & 0b111111 >= 64 / 2 {
171                        // green 6 bits more than 50%?
172                        0b0100
173                    } else {
174                        0
175                    };
176
177                    let blue = if buf_p & 0b11111 >= 32 / 2 {
178                        // blue five bits more than 50%?
179                        0b0010
180                    } else {
181                        0
182                    };
183
184                    *pixel = red | green | blue;
185                });
186            }
187        }
188    }
189
190    /// Copy pixels from the buffer. The buffer may be shorter than frame.
191    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                        // are red three bits more than 50%?
208                        0b1000
209                    } else {
210                        0
211                    };
212
213                    let green = if (buf_p >> 2) & 0b111 >= 7 / 2 {
214                        // green three bits more than 50%?
215                        0b0100
216                    } else {
217                        0
218                    };
219
220                    let blue = if buf_p & 0b11 >= 3 / 2 {
221                        // blue two bits more than 50%?
222                        0b0010
223                    } else {
224                        0
225                    };
226
227                    *pixel = red | green | blue;
228                });
229            }
230        }
231    }
232
233    /// Copy pixels from the buffer. The buffer may be shorter than frame.
234    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                        // transform from sRGB to the LPM native 4-bit format.
251                        //
252                        // 4-bit sRGB is encoded as `| B | G | R | s |`, where
253                        // `s` is something like intensity.  We'll interpret
254                        // intensity `0` to mean transparent, and intensity
255                        // `1` to mean opaque.  Meanwhile LPM native 4-bit is
256                        // encoded as `| R | G | B | x |`, where `x` is
257                        // ignored.  So we need to swap the R & B bits, and
258                        // only apply the pixel if `s` is 1.
259                        *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/// Modes are 6-bit, network order.
283/// They use a tree-ish encoding, so only the ones in use are listed here.
284#[allow(dead_code)]
285#[derive(Clone, Copy)]
286enum Mode {
287    /// Clear memory
288    /// bits: 0 Function, X, 1 Clear, 0 Blink off, X, X
289    AllClear = 0b001000,
290    /// Input 1-bit data
291    /// bits: 1 No function, X, 0 Data Update, 01 1-bit, X
292    Input1Bit = 0b100_01_0,
293    Input4Bit = 0b100100,
294    NoUpdate = 0b101000,
295}
296
297/// Command header is composed of a 6-bit mode and 10 bits of address,
298/// network bit order.
299struct CommandHeader {
300    mode: Mode,
301    gate_line: u16,
302}
303
304impl CommandHeader {
305    /// Formats header for transfer
306    fn encode(&self) -> [u8; 2] {
307        ((self.gate_line & 0b1111111111) | ((self.mode as u16) << 10)).to_be_bytes()
308    }
309}
310
311/// Area of the screen to which data is written
312#[derive(Debug, Copy, Clone)]
313struct WriteFrame {
314    row: u16,
315    column: u16,
316    width: u16,
317    height: u16,
318}
319
320/// Internal state of the driver.
321/// Each state can lead to the next one in order of appearance.
322#[derive(Debug, Copy, Clone)]
323enum State {
324    /// Data structures not ready, call `setup`
325    Uninitialized,
326
327    /// Display hardware is off, uninitialized.
328    Off,
329    InitializingPixelMemory,
330    /// COM polarity and internal latch circuits
331    InitializingRest,
332
333    // Normal operation
334    Idle,
335    AllClearing,
336    Writing,
337
338    /// This driver is buggy. Turning off and on will try to recover it.
339    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    /// Fields responsible for sending callbacks
358    /// for actions completed in software.
359    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    /// The HIL requires updates to arbitrary rectangles.
365    /// The display supports only updating entire rows,
366    /// so edges need to be cached.
367    frame_buffer: OptionalCell<FrameBuffer<'static>>,
368
369    client: OptionalCell<&'a dyn ScreenClient>,
370    /// Buffer for incoming pixel data, coming from the client.
371    /// It's not submitted directly anywhere.
372    buffer: TakeCell<'static, [u8]>,
373
374    /// Needed for init and to flip the EXTCOMIN pin at regular intervals
375    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    /// Set up internal data structures.
413    /// Does not touch the hardware.
414    /// Idempotent.
415    pub fn setup(&'static self) -> Result<(), ErrorCode> {
416        // Needed this way to avoid exposing accessors to deferred callers.
417        // That would be unnecessary, no external data is needed.
418        // At the same time, self must be static for client registration.
419        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                // Even if we took Pin type that implements Output,
438                // it's still possible that it is *not configured as a output*
439                // at the moment.
440                // To ensure outputness, output must be configured at runtime,
441                // even though this eliminates pins
442                // which don't implement Configure due to being
443                // simple, unconfigurable outputs.
444                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                        // Cheating a little:
453                        // the frame buffer does not yet contain pixels,
454                        // so use its beginning to send the clear command.
455                        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                // TODO: investigate clearing pixels asynchronously,
487                // like the datasheet asks.
488                // It seems to turn off fine without clearing, but
489                // perhaps the state of the buffer affects power draw when off.
490
491                // The following stops extcomin timer.
492                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        // Datasheet says 2Hz or more often flipping is required
504        // for transmissive mode.
505        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        // Thankfully, this is the only command that results in the callback,
515        // so there's no danger that this will get attributed
516        // to a command that's not finished yet.
517        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            //return Err(ErrorCode::INVAL);
547        }
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 the device is in the desired state by now,
639        // then a callback needs to be sent manually.
640        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        // TODO: add LED PWM
650        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                // Better flip it once too many than go out of spec
718                // by stretching the flip period.
719                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                // Rather than initialize them separately, wait longer and do both
761                // for 2 reasons:
762                // 1. the upper limit of waiting is only specified for both,
763                // 2. and state flipping code is annoying and bug-friendly.
764                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            // can't get more buggy than buggy
797            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            // Device frame buffer is now up to date, return pixel buffer to client.
808            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
818// DeferredCall requires a unique client for each DeferredCall so that different callbacks
819// can be distinguished.
820struct 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}