shift_register_driver/
sipo.rs1use core::cell::RefCell;
4use hal::digital::OutputPin;
5use core::mem;
6use core::ptr;
7
8trait ShiftRegisterInternal {
9 fn update(&self, index: usize, command: bool);
10}
11
12pub struct ShiftRegisterPin<'a>
14{
15 shift_register: &'a ShiftRegisterInternal,
16 index: usize,
17}
18
19impl<'a> ShiftRegisterPin<'a>
20{
21 fn new(shift_register: &'a ShiftRegisterInternal, index: usize) -> Self {
22 ShiftRegisterPin { shift_register, index }
23 }
24}
25
26impl<'a> OutputPin for ShiftRegisterPin<'a>
27{
28 fn set_low(&mut self) {
29 self.shift_register.update(self.index, false);
30 }
31
32 fn set_high(&mut self) {
33 self.shift_register.update(self.index, true);
34 }
35}
36
37macro_rules! ShiftRegisterBuilder {
38 ($name: ident, $size: expr) => {
39 pub struct $name<Pin1, Pin2, Pin3>
41 where Pin1: OutputPin,
42 Pin2: OutputPin,
43 Pin3: OutputPin,
44 {
45 clock: RefCell<Pin1>,
46 latch: RefCell<Pin2>,
47 data: RefCell<Pin3>,
48 output_state: RefCell<[bool; $size]>,
49 }
50
51 impl<Pin1, Pin2, Pin3> ShiftRegisterInternal for $name<Pin1, Pin2, Pin3>
52 where Pin1: OutputPin,
53 Pin2: OutputPin,
54 Pin3: OutputPin,
55 {
56 fn update(&self, index: usize, command: bool) {
58 self.output_state.borrow_mut()[index] = command;
59 let output_state = self.output_state.borrow();
60 self.latch.borrow_mut().set_low();
61
62 for i in 1..=output_state.len() {
63 if output_state[output_state.len()-i] {self.data.borrow_mut().set_high();}
64 else {self.data.borrow_mut().set_low();}
65 self.clock.borrow_mut().set_high();
66 self.clock.borrow_mut().set_low();
67 }
68
69 self.latch.borrow_mut().set_high();
70 }
71 }
72
73
74 impl<Pin1, Pin2, Pin3> $name<Pin1, Pin2, Pin3>
75 where Pin1: OutputPin,
76 Pin2: OutputPin,
77 Pin3: OutputPin,
78 {
79 pub fn new(clock: Pin1, latch: Pin2, data: Pin3) -> Self {
81 $name {
82 clock: RefCell::new(clock),
83 latch: RefCell::new(latch),
84 data: RefCell::new(data),
85 output_state: RefCell::new([false; $size]),
86 }
87 }
88
89 pub fn decompose(&self) -> [ShiftRegisterPin; $size] {
91 let mut pins: [ShiftRegisterPin; $size];
92
93 unsafe {
94 pins = mem::uninitialized();
95 for (index, elem) in pins[..].iter_mut().enumerate() {
96 ptr::write(elem, ShiftRegisterPin::new(self, index));
97 }
98 }
99
100 pins
101 }
102
103 pub fn release(self) -> (Pin1, Pin2, Pin3) {
105 let Self{clock, latch, data, output_state: _} = self;
106 (clock.into_inner(), latch.into_inner(), data.into_inner())
107 }
108 }
109
110 }
111}
112
113ShiftRegisterBuilder!(ShiftRegister8, 8);
114ShiftRegisterBuilder!(ShiftRegister16, 16);
115ShiftRegisterBuilder!(ShiftRegister24, 24);
116ShiftRegisterBuilder!(ShiftRegister32, 32);
117ShiftRegisterBuilder!(ShiftRegister40, 40);
118ShiftRegisterBuilder!(ShiftRegister48, 48);
119ShiftRegisterBuilder!(ShiftRegister56, 56);
120ShiftRegisterBuilder!(ShiftRegister64, 64);
121ShiftRegisterBuilder!(ShiftRegister72, 72);
122ShiftRegisterBuilder!(ShiftRegister80, 80);
123ShiftRegisterBuilder!(ShiftRegister88, 88);
124ShiftRegisterBuilder!(ShiftRegister96, 96);
125ShiftRegisterBuilder!(ShiftRegister104, 104);
126ShiftRegisterBuilder!(ShiftRegister112, 112);
127ShiftRegisterBuilder!(ShiftRegister120, 120);
128ShiftRegisterBuilder!(ShiftRegister128, 128);
129
130pub type ShiftRegister<Pin1, Pin2, Pin3> = ShiftRegister8<Pin1, Pin2, Pin3>;