1use embedded_hal::digital::OutputPin;
2
3use super::{Interface, InterfaceKind};
4
5pub trait OutputBus {
9 type Word: Copy;
11
12 const KIND: InterfaceKind;
14
15 type Error: core::fmt::Debug;
17
18 fn set_value(&mut self, value: Self::Word) -> Result<(), Self::Error>;
20}
21
22macro_rules! generic_bus {
23 ($GenericxBitBus:ident { type Word = $Word:ident; const KIND: InterfaceKind = $InterfaceKind:expr; Pins {$($PX:ident => $x:tt,)*}}) => {
24 pub struct $GenericxBitBus<$($PX, )*> {
26 pins: ($($PX, )*),
27 last: Option<$Word>,
28 }
29
30 impl<$($PX, )*> $GenericxBitBus<$($PX, )*>
31 where
32 $($PX: OutputPin, )*
33 {
34 pub fn new(pins: ($($PX, )*)) -> Self {
38 Self { pins, last: None }
39 }
40
41 pub fn release(self) -> ($($PX, )*) {
43 self.pins
44 }
45 }
46
47 impl<$($PX, )* E> OutputBus
48 for $GenericxBitBus<$($PX, )*>
49 where
50 $($PX: OutputPin<Error = E>, )*
51 E: core::fmt::Debug,
52 {
53 type Word = $Word;
54 type Error = E;
55
56 const KIND: InterfaceKind = $InterfaceKind;
57
58 fn set_value(&mut self, value: Self::Word) -> Result<(), Self::Error> {
59 if self.last == Some(value) {
63 return Ok(())
64 }
65
66 let last = self.last.take();
69
70 let changed = match last {
71 Some(old_value) => value ^ old_value,
72 None => !0, };
74
75 $(
76 let mask = 1 << $x;
77 if changed & mask != 0 {
78 if value & mask != 0 {
79 self.pins.$x.set_high()
80 } else {
81 self.pins.$x.set_low()
82 }
83 ?;
84 }
85 )*
86
87 self.last = Some(value);
88 Ok(())
89 }
90 }
91
92 impl<$($PX, )*> From<($($PX, )*)>
93 for $GenericxBitBus<$($PX, )*>
94 where
95 $($PX: OutputPin, )*
96 {
97 fn from(pins: ($($PX, )*)) -> Self {
98 Self::new(pins)
99 }
100 }
101 };
102}
103
104generic_bus! {
105 Generic8BitBus {
106 type Word = u8;
107 const KIND: InterfaceKind = InterfaceKind::Parallel8Bit;
108 Pins {
109 P0 => 0,
110 P1 => 1,
111 P2 => 2,
112 P3 => 3,
113 P4 => 4,
114 P5 => 5,
115 P6 => 6,
116 P7 => 7,
117 }
118 }
119}
120
121generic_bus! {
122 Generic16BitBus {
123 type Word = u16;
124 const KIND: InterfaceKind = InterfaceKind::Parallel16Bit;
125 Pins {
126 P0 => 0,
127 P1 => 1,
128 P2 => 2,
129 P3 => 3,
130 P4 => 4,
131 P5 => 5,
132 P6 => 6,
133 P7 => 7,
134 P8 => 8,
135 P9 => 9,
136 P10 => 10,
137 P11 => 11,
138 P12 => 12,
139 P13 => 13,
140 P14 => 14,
141 P15 => 15,
142 }
143 }
144}
145
146#[derive(Clone, Copy, Debug)]
148#[cfg_attr(feature = "defmt", derive(defmt::Format))]
149pub enum ParallelError<BUS, DC, WR> {
150 Bus(BUS),
152 Dc(DC),
154 Wr(WR),
156}
157
158pub struct ParallelInterface<BUS, DC, WR> {
168 bus: BUS,
169 dc: DC,
170 wr: WR,
171}
172
173impl<BUS, DC, WR> ParallelInterface<BUS, DC, WR>
174where
175 BUS: OutputBus,
176 BUS::Word: From<u8> + Eq + core::ops::BitXor<Output = BUS::Word>,
178 DC: OutputPin,
179 WR: OutputPin,
180{
181 pub fn new(bus: BUS, dc: DC, wr: WR) -> Self {
183 Self { bus, dc, wr }
184 }
185
186 pub fn release(self) -> (BUS, DC, WR) {
189 (self.bus, self.dc, self.wr)
190 }
191
192 fn send_word(
194 &mut self,
195 word: BUS::Word,
196 ) -> Result<(), ParallelError<BUS::Error, DC::Error, WR::Error>> {
197 self.wr.set_low().map_err(ParallelError::Wr)?;
198 self.bus.set_value(word).map_err(ParallelError::Bus)?;
199 self.wr.set_high().map_err(ParallelError::Wr)
200 }
201}
202
203impl<BUS, DC, WR> Interface for ParallelInterface<BUS, DC, WR>
204where
205 BUS: OutputBus,
206 BUS::Word: From<u8> + Eq + core::ops::BitXor<Output = BUS::Word>,
209 DC: OutputPin,
210 WR: OutputPin,
211{
212 type Word = BUS::Word;
213 type Error = ParallelError<BUS::Error, DC::Error, WR::Error>;
214
215 const KIND: InterfaceKind = BUS::KIND;
216
217 async fn send_command(&mut self, command: u8, args: &[u8]) -> Result<(), Self::Error> {
218 self.dc.set_low().map_err(ParallelError::Dc)?;
220 self.send_word(BUS::Word::from(command))?;
221
222 self.dc.set_high().map_err(ParallelError::Dc)?;
224 for &arg in args {
225 self.send_word(BUS::Word::from(arg))?;
226 }
227
228 Ok(())
229 }
230
231 async fn send_data_slice(&mut self, data: &[Self::Word]) -> Result<(), Self::Error> {
232 for &word in data {
235 self.send_word(word)?;
236 }
237 Ok(())
238 }
239}