1use super::hal;
2
3use cortex_m::asm::delay as cycle_delay;
4use gpio::{Floating, Input, Output, PushPull};
5use hal::gpio::{self, *};
6use hal::prelude::*;
7
8#[derive(Debug, PartialEq)]
9pub enum Keys {
10 SelectDown,
11 SelectUp,
12 StartDown,
13 StartUp,
14 BDown,
15 BUp,
16 ADown,
17 AUp,
18
19 UpUp,
20 UpDown,
21 DownUp,
22 DownDown,
23 LeftUp,
24 LeftDown,
25 RightUp,
26 RightDown,
27}
28
29pub struct ButtonIter {
30 pub pressed: u8,
31 pub released: u8,
32 pub bit_index: u8,
33}
34
35fn mask_to_event(mask: u8, released: u8, pressed: u8) -> Option<Keys> {
37 let pressed_bool = mask & pressed == mask;
38 let released_bool = mask & released == mask;
39
40 match mask {
41 0x80 => {
42 if released_bool {
43 Some(Keys::BUp)
44 } else if pressed_bool {
45 Some(Keys::BDown)
46 } else {
47 None
48 }
49 }
50 0x40 => {
51 if released_bool {
52 Some(Keys::AUp)
53 } else if pressed_bool {
54 Some(Keys::ADown)
55 } else {
56 None
57 }
58 }
59 0x20 => {
60 if released_bool {
61 Some(Keys::StartUp)
62 } else if pressed_bool {
63 Some(Keys::StartDown)
64 } else {
65 None
66 }
67 }
68 0x10 => {
69 if released_bool {
70 Some(Keys::SelectUp)
71 } else if pressed_bool {
72 Some(Keys::SelectDown)
73 } else {
74 None
75 }
76 }
77
78 0x08 => {
79 if released_bool {
80 Some(Keys::RightUp)
81 } else if pressed_bool {
82 Some(Keys::RightDown)
83 } else {
84 None
85 }
86 }
87 0x04 => {
88 if released_bool {
89 Some(Keys::DownUp)
90 } else if pressed_bool {
91 Some(Keys::DownDown)
92 } else {
93 None
94 }
95 }
96 0x02 => {
97 if released_bool {
98 Some(Keys::UpUp)
99 } else if pressed_bool {
100 Some(Keys::UpDown)
101 } else {
102 None
103 }
104 }
105 0x01 => {
106 if released_bool {
107 Some(Keys::LeftUp)
108 } else if pressed_bool {
109 Some(Keys::LeftDown)
110 } else {
111 None
112 }
113 }
114 _ => None,
115 }
116}
117
118impl Iterator for ButtonIter {
119 type Item = Keys;
120
121 fn next(&mut self) -> Option<Keys> {
122 if self.bit_index >= 8 {
124 return None;
125 }
126
127 while {
129 let mask = 0x01 << self.bit_index;
130 self.bit_index += 1;
131
132 let event = mask_to_event(mask, self.released, self.pressed);
133 if event.is_some() {
134 return event;
135 }
136
137 self.bit_index < 8
138 } {}
139
140 None
141 }
142}
143
144pub struct ButtonReader {
146 pub latch: Pb0<Output<PushPull>>,
148 pub data_in: Pb30<Input<Floating>>,
150 pub clock: Pb31<Output<PushPull>>,
152 pub last: u8,
153}
154
155impl ButtonReader {
164 pub fn events(&mut self) -> ButtonIter {
167 self.latch.set_low().ok();
168 cycle_delay(7); self.latch.set_high().ok();
170 cycle_delay(1); let mut current: u8 = 0;
173
174 for _i in 0..8 {
175 current <<= 1;
176
177 self.clock.set_low().ok();
178 cycle_delay(5); if self.data_in.is_high().unwrap() {
181 current |= 1;
182 }
183 self.clock.set_high().ok();
184 }
185
186 let iter = ButtonIter {
187 pressed: (self.last ^ current) & current,
188 released: (self.last ^ current) & self.last,
189 bit_index: 0,
190 };
191
192 self.last = current;
193
194 iter
195 }
196}