display_driver/panel/
reset.rs1use embedded_hal::digital::OutputPin;
2use embedded_hal_async::delay::DelayNs;
3
4use crate::{DisplayBus, DisplayError};
5
6pub enum LCDResetOption<P: OutputPin> {
8 PinHigh(P),
10 PinLow(P),
12 Bus,
14 Software,
16 None,
18}
19
20impl<P: OutputPin> LCDResetOption<P> {
21 pub fn new_pin(pin: P) -> Self {
23 Self::PinLow(pin)
24 }
25
26 pub fn new_pin_with_level(pin: P, reset_level: bool) -> Self {
28 if reset_level {
29 Self::PinHigh(pin)
30 } else {
31 Self::PinLow(pin)
32 }
33 }
34
35 pub fn release(self) -> Option<P> {
37 match self {
38 Self::PinHigh(pin) => Some(pin),
39 Self::PinLow(pin) => Some(pin),
40 Self::Bus => None,
41 Self::Software => None,
42 Self::None => None,
43 }
44 }
45
46 pub fn is_none(&self) -> bool {
47 matches!(self, Self::None)
48 }
49}
50
51impl LCDResetOption<NoResetPin> {
52 pub fn new_bus() -> Self {
54 Self::Bus
55 }
56
57 pub fn new_software() -> Self {
59 Self::Software
60 }
61
62 pub fn none() -> Self {
64 Self::None
65 }
66}
67
68pub struct LCDResetHandler<'a, P: OutputPin, B: DisplayBus, D: DelayNs> {
70 option: &'a mut LCDResetOption<P>,
71 bus: &'a mut B,
72 delay: &'a mut D,
73 gap_ms: u8,
74 wait_ms: u8,
75 software_reset_cmd: Option<&'a [u8]>,
76}
77
78impl<'a, P: OutputPin, B: DisplayBus, D: DelayNs> LCDResetHandler<'a, P, B, D> {
79 pub fn new(
81 option: &'a mut LCDResetOption<P>,
82 bus: &'a mut B,
83 delay: &'a mut D,
84 gap_ms: u8,
85 wait_ms: u8,
86 software_reset_cmd: Option<&'a [u8]>,
87 ) -> Self {
88 Self {
89 option,
90 bus,
91 delay,
92 gap_ms,
93 wait_ms,
94 software_reset_cmd,
95 }
96 }
97
98 pub fn set_reset(&mut self, reset: bool) -> Result<(), B::Error> {
100 match *self.option {
101 LCDResetOption::PinHigh(ref mut pin) => {
102 if reset {
103 pin.set_high().map_err(|_| unreachable!())
104 } else {
105 pin.set_low().map_err(|_| unreachable!())
106 }
107 }
108 LCDResetOption::PinLow(ref mut pin) => {
109 if reset {
110 pin.set_low().map_err(|_| unreachable!())
111 } else {
112 pin.set_high().map_err(|_| unreachable!())
113 }
114 }
115 LCDResetOption::Bus => self.bus.set_reset(reset).map_err(|err| match err {
116 DisplayError::BusError(e) => e,
117 DisplayError::Unsupported => panic!("Bus cannot reset"),
118 _ => unreachable!(),
119 }),
120 LCDResetOption::Software => Ok(()),
121 LCDResetOption::None => unreachable!(),
122 }
123 }
124
125 pub async fn reset(&mut self) -> Result<(), B::Error> {
127 if matches!(self.option, LCDResetOption::Software) {
128 if let Some(cmd) = self.software_reset_cmd {
129 self.bus.write_cmd(cmd).await?;
130 self.delay.delay_ms(self.wait_ms as u32).await;
131 }
132 return Ok(());
133 }
134
135 if !self.option.is_none() {
136 self.set_reset(false)?;
137 self.delay.delay_ms(self.gap_ms as u32).await;
138 self.set_reset(true)?;
139 self.delay.delay_ms(self.gap_ms as u32).await;
140 self.set_reset(false)?;
141 self.delay.delay_ms(self.wait_ms as u32).await;
142 }
143 Ok(())
144 }
145}
146
147pub struct NoResetPin {}
149impl embedded_hal::digital::ErrorType for NoResetPin {
150 type Error = core::convert::Infallible;
151}
152
153impl embedded_hal::digital::OutputPin for NoResetPin {
154 fn set_low(&mut self) -> Result<(), Self::Error> {
155 Ok(())
156 }
157
158 fn set_high(&mut self) -> Result<(), Self::Error> {
159 Ok(())
160 }
161}