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
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/// Modes are 6-bit, network order.
286/// They use a tree-ish encoding, so only the ones in use are listed here.
287#[allow(dead_code)]
288#[derive(Clone, Copy)]
289enum Mode {
290    /// Clear memory
291    /// bits: 0 Function, X, 1 Clear, 0 Blink off, X, X
292    AllClear = 0b001000,
293    /// Input 1-bit data
294    /// bits: 1 No function, X, 0 Data Update, 01 1-bit, X
295    Input1Bit = 0b100_01_0,
296    Input4Bit = 0b100100,
297    NoUpdate = 0b101000,
298}
299
300/// Command header is composed of a 6-bit mode and 10 bits of address,
301/// network bit order.
302struct CommandHeader {
303    mode: Mode,
304    gate_line: u16,
305}
306
307impl CommandHeader {
308    /// Formats header for transfer
309    fn encode(&self) -> [u8; 2] {
310        ((self.gate_line & 0b1111111111) | ((self.mode as u16) << 10)).to_be_bytes()
311    }
312}
313
314/// Area of the screen to which data is written
315#[derive(Debug, Copy, Clone)]
316struct WriteFrame {
317    row: u16,
318    column: u16,
319    width: u16,
320    height: u16,
321}
322
323/// Internal state of the driver.
324/// Each state can lead to the next one in order of appearance.
325#[derive(Debug, Copy, Clone)]
326enum State {
327    /// Data structures not ready, call `setup`
328    Uninitialized,
329
330    /// Display hardware is off, uninitialized.
331    Off,
332    InitializingPixelMemory,
333    /// COM polarity and internal latch circuits
334    InitializingRest,
335
336    // Normal operation
337    Idle,
338    AllClearing,
339    Writing,
340
341    /// This driver is buggy. Turning off and on will try to recover it.
342    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    /// Fields responsible for sending callbacks
361    /// for actions completed in software.
362    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    /// The HIL requires updates to arbitrary rectangles.
368    /// The display supports only updating entire rows,
369    /// so edges need to be cached.
370    frame_buffer: OptionalCell<FrameBuffer<'static>>,
371
372    client: OptionalCell<&'a dyn ScreenClient>,
373    /// Buffer for incoming pixel data, coming from the client.
374    /// It's not submitted directly anywhere.
375    buffer: TakeCell<'static, [u8]>,
376
377    /// Needed for init and to flip the EXTCOMIN pin at regular intervals
378    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    /// Set up internal data structures.
416    /// Does not touch the hardware.
417    /// Idempotent.
418    pub fn setup(&'static self) -> Result<(), ErrorCode> {
419        // Needed this way to avoid exposing accessors to deferred callers.
420        // That would be unnecessary, no external data is needed.
421        // At the same time, self must be static for client registration.
422        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                // Even if we took Pin type that implements Output,
441                // it's still possible that it is *not configured as a output*
442                // at the moment.
443                // To ensure outputness, output must be configured at runtime,
444                // even though this eliminates pins
445                // which don't implement Configure due to being
446                // simple, unconfigurable outputs.
447                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                        // Cheating a little:
456                        // the frame buffer does not yet contain pixels,
457                        // so use its beginning to send the clear command.
458                        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                // TODO: investigate clearing pixels asynchronously,
490                // like the datasheet asks.
491                // It seems to turn off fine without clearing, but
492                // perhaps the state of the buffer affects power draw when off.
493
494                // The following stops extcomin timer.
495                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        // Datasheet says 2Hz or more often flipping is required
507        // for transmissive mode.
508        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        // Thankfully, this is the only command that results in the callback,
518        // so there's no danger that this will get attributed
519        // to a command that's not finished yet.
520        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            //return Err(ErrorCode::INVAL);
550        }
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 the device is in the desired state by now,
642        // then a callback needs to be sent manually.
643        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        // TODO: add LED PWM
653        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                // Better flip it once too many than go out of spec
723                // by stretching the flip period.
724                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                // Rather than initialize them separately, wait longer and do both
766                // for 2 reasons:
767                // 1. the upper limit of waiting is only specified for both,
768                // 2. and state flipping code is annoying and bug-friendly.
769                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            // can't get more buggy than buggy
802            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            // Device frame buffer is now up to date, return pixel buffer to client.
813            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
823// DeferredCall requires a unique client for each DeferredCall so that different callbacks
824// can be distinguished.
825struct 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}