1use embedded_hal::{
4 delay::DelayNs,
5 digital::{InputPin, OutputPin, StatefulOutputPin},
6};
7
8use crate::{
9 command::{Bits, Command, ReadWriteOp, RegisterSelection, State},
10 sender::{IfReadable, SendCommand},
11 utils::{BitOps, BitState},
12};
13
14pub struct ParallelSender<ControlPin, DBPin, BLPin, const PIN_CNT: usize, const READABLE: bool>
16where
17 ControlPin: OutputPin,
18 DBPin: OutputPin + IfReadable<READABLE>,
19 BLPin: StatefulOutputPin,
20{
21 rs_pin: ControlPin,
22 rw_pin: Option<ControlPin>,
23 en_pin: ControlPin,
24 db_pins: [DBPin; PIN_CNT],
25 bl_pin: Option<BLPin>,
26}
27
28impl<ControlPin, DBPin, BLPin> ParallelSender<ControlPin, DBPin, BLPin, 4, true>
29where
30 ControlPin: OutputPin,
31 DBPin: OutputPin + InputPin,
32 BLPin: StatefulOutputPin,
33{
34 #[allow(clippy::too_many_arguments)]
37 pub fn new_4pin(
38 rs: ControlPin,
39 rw: ControlPin,
40 en: ControlPin,
41 db4: DBPin,
42 db5: DBPin,
43 db6: DBPin,
44 db7: DBPin,
45 bl: Option<BLPin>,
46 ) -> Self {
47 Self {
48 rs_pin: rs,
49 rw_pin: Some(rw),
50 en_pin: en,
51 db_pins: [db4, db5, db6, db7],
52 bl_pin: bl,
53 }
54 }
55}
56
57impl<ControlPin, DBPin, BLPin> ParallelSender<ControlPin, DBPin, BLPin, 4, false>
58where
59 ControlPin: OutputPin,
60 DBPin: OutputPin,
61 BLPin: StatefulOutputPin,
62{
63 #[allow(clippy::too_many_arguments)]
66 pub fn new_4pin_write_only(
67 rs: ControlPin,
68 en: ControlPin,
69 db4: DBPin,
70 db5: DBPin,
71 db6: DBPin,
72 db7: DBPin,
73 bl: Option<BLPin>,
74 ) -> Self {
75 Self {
76 rs_pin: rs,
77 rw_pin: None,
78 en_pin: en,
79 db_pins: [db4, db5, db6, db7],
80 bl_pin: bl,
81 }
82 }
83}
84
85impl<ControlPin, DBPin, BLPin> ParallelSender<ControlPin, DBPin, BLPin, 8, true>
86where
87 ControlPin: OutputPin,
88 DBPin: OutputPin + InputPin,
89 BLPin: StatefulOutputPin,
90{
91 #[allow(clippy::too_many_arguments)]
94 pub fn new_8pin(
95 rs: ControlPin,
96 rw: ControlPin,
97 en: ControlPin,
98 db0: DBPin,
99 db1: DBPin,
100 db2: DBPin,
101 db3: DBPin,
102 db4: DBPin,
103 db5: DBPin,
104 db6: DBPin,
105 db7: DBPin,
106 bl: Option<BLPin>,
107 ) -> Self {
108 Self {
109 rs_pin: rs,
110 rw_pin: Some(rw),
111 en_pin: en,
112 db_pins: [db0, db1, db2, db3, db4, db5, db6, db7],
113 bl_pin: bl,
114 }
115 }
116}
117
118impl<ControlPin, DBPin, BLPin> ParallelSender<ControlPin, DBPin, BLPin, 8, false>
119where
120 ControlPin: OutputPin,
121 DBPin: OutputPin,
122 BLPin: StatefulOutputPin,
123{
124 #[allow(clippy::too_many_arguments)]
127 pub fn new_8pin_write_only(
128 rs: ControlPin,
129 en: ControlPin,
130 db0: DBPin,
131 db1: DBPin,
132 db2: DBPin,
133 db3: DBPin,
134 db4: DBPin,
135 db5: DBPin,
136 db6: DBPin,
137 db7: DBPin,
138 bl: Option<BLPin>,
139 ) -> Self {
140 Self {
141 rs_pin: rs,
142 rw_pin: None,
143 en_pin: en,
144 db_pins: [db0, db1, db2, db3, db4, db5, db6, db7],
145 bl_pin: bl,
146 }
147 }
148}
149
150impl<ControlPin, DBPin, BLPin, const PIN_CNT: usize, const READABLE: bool>
152 ParallelSender<ControlPin, DBPin, BLPin, PIN_CNT, READABLE>
153where
154 ControlPin: OutputPin,
155 DBPin: OutputPin + IfReadable<READABLE>,
156 BLPin: StatefulOutputPin,
157{
158 fn push_bits(&mut self, raw_bits: u8) {
159 self.db_pins
160 .iter_mut()
161 .enumerate()
162 .for_each(|(index, pin)| match raw_bits.check_bit(index as u8) {
163 BitState::Set => {
164 pin.set_high().ok().unwrap();
165 }
166 BitState::Clear => {
167 pin.set_low().ok().unwrap();
168 }
169 });
170 }
171}
172
173impl<ControlPin, DBPin, BLPin, const PIN_CNT: usize>
175 ParallelSender<ControlPin, DBPin, BLPin, PIN_CNT, true>
176where
177 ControlPin: OutputPin,
178 DBPin: OutputPin + InputPin,
179 BLPin: StatefulOutputPin,
180{
181 fn fetch_bits(&mut self) -> u8 {
182 self.db_pins
183 .iter_mut()
184 .enumerate()
185 .fold(0u8, |mut acc, (index, pin)| {
187 pin.set_high().ok().unwrap();
189 match pin.is_low() {
191 Ok(val) => match val {
192 false => acc.set_bit(index as u8),
193 true => acc.clear_bit(index as u8),
194 },
195 Err(_) => panic!("Something wrong when read from pin"),
196 };
197 acc
198 })
199 }
200}
201
202macro_rules! backlight_fns {
203 () => {
204 fn get_actual_backlight(&mut self) -> State {
205 match self.bl_pin.as_mut() {
206 Some(bl_pin) => match bl_pin.is_set_high().unwrap() {
207 true => State::On,
208 false => State::Off,
209 },
210 None => Default::default(),
211 }
212 }
213
214 fn set_actual_backlight(&mut self, backlight: State) {
215 if let Some(bl_pin) = self.bl_pin.as_mut() {
216 match backlight {
217 State::Off => bl_pin.set_low().unwrap(),
218 State::On => bl_pin.set_high().unwrap(),
219 }
220 }
221 }
222 };
223}
224
225impl<ControlPin, DBPin, BLPin, const PIN_CNT: usize, Delayer> SendCommand<Delayer, true>
226 for ParallelSender<ControlPin, DBPin, BLPin, PIN_CNT, true>
227where
228 ControlPin: OutputPin,
229 DBPin: OutputPin + InputPin,
230 BLPin: StatefulOutputPin,
231 Delayer: DelayNs,
232{
233 backlight_fns!();
234
235 fn send(&mut self, command: Command) -> Option<u8> {
236 assert!(
237 PIN_CNT == 4 || PIN_CNT == 8,
238 "Pins other than 4 or 8 are not supported"
239 );
240
241 self.en_pin.set_low().ok().unwrap();
242
243 match command.get_register_selection() {
244 RegisterSelection::Command => {
245 self.rs_pin.set_low().ok().unwrap();
246 }
247 RegisterSelection::Data => {
248 self.rs_pin.set_high().ok().unwrap();
249 }
250 }
251
252 {
253 let rw_pin = self.rw_pin.as_mut().expect("RW pin for readable");
254 match command.get_read_write_op() {
255 ReadWriteOp::Write => {
256 rw_pin.set_low().ok().unwrap();
257 }
258 ReadWriteOp::Read => {
259 rw_pin.set_high().ok().unwrap();
260 }
261 }
262 }
263
264 match command.get_read_write_op() {
265 ReadWriteOp::Write => {
266 let bits = command
267 .get_data()
268 .expect("Write command but no data provide");
269 match PIN_CNT {
270 4 => match bits {
271 Bits::Bit4(raw_bits) => {
272 assert!(raw_bits < 2u8.pow(4), "data is greater than 4 bits");
273 self.push_bits(raw_bits);
274 self.en_pin.set_high().ok().unwrap();
275 self.en_pin.set_low().ok().unwrap();
276 }
277 Bits::Bit8(raw_bits) => {
278 self.push_bits(raw_bits >> 4);
279 self.en_pin.set_high().ok().unwrap();
280 self.en_pin.set_low().ok().unwrap();
281 self.push_bits(raw_bits & 0b1111);
282 self.en_pin.set_high().ok().unwrap();
283 self.en_pin.set_low().ok().unwrap();
284 }
285 },
286
287 8 => {
288 if let Bits::Bit8(raw_bits) = bits {
289 self.push_bits(raw_bits);
290 self.en_pin.set_high().ok().unwrap();
291 self.en_pin.set_low().ok().unwrap();
292 } else {
293 panic!("in 8 pin mode, data should always be 8 bit")
294 }
295 }
296
297 _ => unreachable!(),
298 }
299
300 None
301 }
302 ReadWriteOp::Read => match PIN_CNT {
303 4 => {
304 self.en_pin.set_high().ok().unwrap();
305 let high_4_bits = self.fetch_bits().checked_shl(4).unwrap();
306 self.en_pin.set_low().ok().unwrap();
307 self.en_pin.set_high().ok().unwrap();
308 let low_4_bits = self.fetch_bits();
309 self.en_pin.set_low().ok().unwrap();
310 Some(high_4_bits + low_4_bits)
311 }
312
313 8 => {
314 self.en_pin.set_high().ok().unwrap();
315 let bits = self.fetch_bits();
316 self.en_pin.set_low().ok().unwrap();
317 Some(bits)
318 }
319
320 _ => unreachable!(),
321 },
322 }
323 }
324}
325
326impl<ControlPin, DBPin, BLPin, const PIN_CNT: usize, Delayer> SendCommand<Delayer, false>
327 for ParallelSender<ControlPin, DBPin, BLPin, PIN_CNT, false>
328where
329 ControlPin: OutputPin,
330 DBPin: OutputPin,
331 BLPin: StatefulOutputPin,
332 Delayer: DelayNs,
333{
334 backlight_fns!();
335
336 fn send(&mut self, command: Command) -> Option<u8> {
337 assert!(
338 PIN_CNT == 4 || PIN_CNT == 8,
339 "Pins other than 4 or 8 are not supported"
340 );
341
342 self.en_pin.set_low().ok().unwrap();
343
344 match command.get_register_selection() {
345 RegisterSelection::Command => {
346 self.rs_pin.set_low().ok().unwrap();
347 }
348 RegisterSelection::Data => {
349 self.rs_pin.set_high().ok().unwrap();
350 }
351 }
352
353 match command.get_read_write_op() {
354 ReadWriteOp::Write => {
355 let bits = command
356 .get_data()
357 .expect("Write command but no data provide");
358 match PIN_CNT {
359 4 => match bits {
360 Bits::Bit4(raw_bits) => {
361 assert!(raw_bits < 2u8.pow(4), "data is greater than 4 bits");
362 self.push_bits(raw_bits);
363 self.en_pin.set_high().ok().unwrap();
364 self.en_pin.set_low().ok().unwrap();
365 }
366 Bits::Bit8(raw_bits) => {
367 self.push_bits(raw_bits >> 4);
368 self.en_pin.set_high().ok().unwrap();
369 self.en_pin.set_low().ok().unwrap();
370 self.push_bits(raw_bits & 0b1111);
371 self.en_pin.set_high().ok().unwrap();
372 self.en_pin.set_low().ok().unwrap();
373 }
374 },
375
376 8 => {
377 if let Bits::Bit8(raw_bits) = bits {
378 self.push_bits(raw_bits);
379 self.en_pin.set_high().ok().unwrap();
380 self.en_pin.set_low().ok().unwrap();
381 } else {
382 panic!("in 8 pin mode, data should always be 8 bit")
383 }
384 }
385
386 _ => unreachable!(),
387 }
388
389 None
390 }
391 ReadWriteOp::Read => unreachable!(),
392 }
393 }
394}