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)]
148pub enum ParallelError<BUS, DC, WR> {
149 Bus(BUS),
151 Dc(DC),
153 Wr(WR),
155}
156
157pub struct ParallelInterface<BUS, DC, WR> {
167 bus: BUS,
168 dc: DC,
169 wr: WR,
170}
171
172impl<BUS, DC, WR> ParallelInterface<BUS, DC, WR>
173where
174 BUS: OutputBus,
175 BUS::Word: From<u8> + Eq + core::ops::BitXor<Output = BUS::Word>,
177 DC: OutputPin,
178 WR: OutputPin,
179{
180 pub fn new(bus: BUS, dc: DC, wr: WR) -> Self {
182 Self { bus, dc, wr }
183 }
184
185 pub fn release(self) -> (BUS, DC, WR) {
188 (self.bus, self.dc, self.wr)
189 }
190
191 fn send_word(
193 &mut self,
194 word: BUS::Word,
195 ) -> Result<(), ParallelError<BUS::Error, DC::Error, WR::Error>> {
196 self.wr.set_low().map_err(ParallelError::Wr)?;
197 self.bus.set_value(word).map_err(ParallelError::Bus)?;
198 self.wr.set_high().map_err(ParallelError::Wr)
199 }
200}
201
202impl<BUS, DC, WR> Interface for ParallelInterface<BUS, DC, WR>
203where
204 BUS: OutputBus,
205 BUS::Word: From<u8> + Eq + core::ops::BitXor<Output = BUS::Word>,
208 DC: OutputPin,
209 WR: OutputPin,
210{
211 type Word = BUS::Word;
212 type Error = ParallelError<BUS::Error, DC::Error, WR::Error>;
213
214 const KIND: InterfaceKind = BUS::KIND;
215
216 async fn send_command(&mut self, command: u8, args: &[u8]) -> Result<(), Self::Error> {
217 self.dc.set_low().map_err(ParallelError::Dc)?;
219 self.send_word(BUS::Word::from(command))?;
220
221 self.dc.set_high().map_err(ParallelError::Dc)?;
223 for &arg in args {
224 self.send_word(BUS::Word::from(arg))?;
225 }
226
227 Ok(())
228 }
229
230 async fn send_data_slice(&mut self, data: &[Self::Word]) -> Result<(), Self::Error> {
231 for &word in data {
234 self.send_word(word)?;
235 }
236 Ok(())
237 }
238}