display_driver/panel/
initseq.rs1use embedded_hal_async::delay::DelayNs;
2
3use crate::DisplayBus;
4
5#[derive(Clone, Copy)]
7pub enum InitStep<'a> {
8 SingleCommand(u8),
10 CommandWithParams(u8, &'a [u8]),
12 DelayMs(u8),
14 Nop,
16 Nested(&'a [InitStep<'a>]),
21}
22
23impl InitStep<'static> {
24 pub const fn maybe_cmd(cmd: Option<u8>) -> Self {
25 match cmd {
26 Some(cmd) => Self::SingleCommand(cmd),
27 None => Self::Nop,
28 }
29 }
30
31 pub const fn cmd_if(cond: bool, cmd: u8) -> Self {
32 Self::SingleCommand(if cond { cmd } else { 0 })
33 }
34
35 pub const fn cmd_if_with<const N: usize>(
36 cond: bool,
37 cmd: u8,
38 params: &'static [u8; N],
39 ) -> Self {
40 Self::CommandWithParams(if cond { cmd } else { 0 }, params)
41 }
42
43 pub const fn maybe_cmd_with<const N: usize>(cmd: u8, params: Option<&'static [u8; N]>) -> Self {
44 match params {
45 Some(p) => Self::CommandWithParams(cmd, p),
46 None => Self::Nop,
47 }
48 }
49
50 pub const fn select_cmd(cond: bool, cmd_true: u8, cmd_false: u8) -> Self {
51 Self::SingleCommand(if cond { cmd_true } else { cmd_false })
52 }
53}
54
55pub struct SequencedInit<'a, D: DelayNs, B: DisplayBus, I: Iterator<Item = InitStep<'a>>> {
57 steps: I,
58 delay: &'a mut D,
59 display_bus: &'a mut B,
60}
61
62impl<'a, D: DelayNs, B: DisplayBus, I: Iterator<Item = InitStep<'a>>> SequencedInit<'a, D, B, I> {
63 pub fn new(steps: I, delay: &'a mut D, display_bus: &'a mut B) -> Self {
65 Self {
66 steps,
67 delay,
68 display_bus,
69 }
70 }
71
72 async fn exec_atomic_step(&mut self, step: InitStep<'a>) -> Result<(), B::Error> {
75 match step {
76 InitStep::SingleCommand(cmd) => self.display_bus.write_cmd(&[cmd]).await,
77 InitStep::CommandWithParams(cmd, data) => {
78 self.display_bus.write_cmd_with_params(&[cmd], data).await
79 }
80 InitStep::DelayMs(ms) => {
81 self.delay.delay_ms(ms as u32).await;
82 Ok(())
83 }
84 InitStep::Nop => Ok(()),
85 InitStep::Nested(_) => {
86 panic!("We only support 1 level in InitStep.");
87 }
88 }
89 }
90
91 pub async fn sequenced_init(&mut self) -> Result<(), B::Error> {
93 while let Some(step) = self.steps.next() {
94 match step {
95 InitStep::Nested(sub_steps) => {
97 for sub_step in sub_steps.iter() {
98 self.exec_atomic_step(*sub_step).await?;
100 }
101 }
102 _ => self.exec_atomic_step(step).await?,
104 }
105 }
106
107 Ok(())
108 }
109}
110
111pub async fn sequenced_init<'a, D: DelayNs, B: DisplayBus, I: Iterator<Item = InitStep<'a>>>(
113 steps: I,
114 delay: &'a mut D,
115 display_bus: &'a mut B,
116) -> Result<(), B::Error> {
117 SequencedInit::new(steps, delay, display_bus)
118 .sequenced_init()
119 .await
120}