1use super::hal;
2
3use cortex_m::asm::delay as cycle_delay;
4use gpio::v2::{Floating, Input, Output, PushPull};
5use hal::{
6 gpio::{self, *},
7 prelude::*
8};
9use num_enum::TryFromPrimitive;
10
11#[repr(u8)]
12#[derive(Clone, Copy, Debug, Eq, PartialEq, TryFromPrimitive)]
13pub enum Button {
17 B = 1 << 7,
18 A = 1 << 6,
19 Start = 1 << 5,
20 Sesect = 1 << 4,
21 Right = 1 << 3,
22 Down = 1 << 2,
23 Up = 1 << 1,
24 Left = 1
25}
26
27#[derive(Clone, Debug, Eq, PartialEq)]
30pub enum Event {
31 Pressed(Button),
32 Released(Button)
33}
34
35pub struct EventIter<'a> {
36 postion: u8,
37 buttons: &'a Buttons,
38 update_postions: u8
39}
40
41impl<'a> Iterator for EventIter<'a> {
42 type Item = Event;
43 fn next(&mut self) -> Option<Self::Item> {
44 for i in self.postion..8 {
45 let mask = 1 << i;
46 if mask & self.update_postions != 0 {
48 self.postion = i + 1;
49 let button = Button::try_from(mask).unwrap();
51 if self.buttons.button_pressed(button) {
52 return Some(Event::Pressed(button));
53 } else {
54 return Some(Event::Released(button));
55 }
56 }
57 }
58 None
59 }
60}
61
62pub struct Buttons {
69 pub(crate) current_state: u8,
70 pub(crate) last_state: u8,
71 pub(crate) latch: Pb0<Output<PushPull>>,
72 pub(crate) data_in: Pb30<Input<Floating>>,
74 pub(crate) clock: Pb31<Output<PushPull>>
76}
77
78impl Buttons {
79 pub fn some_pressed(&self) -> bool {
81 self.current_state != 0
82 }
83
84 pub fn none_pressed(&self) -> bool {
86 self.current_state == 0
87 }
88
89 pub fn button_pressed(&self, button: Button) -> bool {
91 self.current_state & button as u8 != 0
92 }
93
94 pub fn a_pressed(&self) -> bool {
95 self.button_pressed(Button::A)
96 }
97
98 pub fn b_pressed(&self) -> bool {
99 self.button_pressed(Button::B)
100 }
101
102 pub fn start_pressed(&self) -> bool {
103 self.button_pressed(Button::Start)
104 }
105
106 pub fn select_pressed(&self) -> bool {
107 self.button_pressed(Button::Sesect)
108 }
109
110 pub fn right_pressed(&self) -> bool {
111 self.button_pressed(Button::Right)
112 }
113
114 pub fn down_pressed(&self) -> bool {
115 self.button_pressed(Button::Down)
116 }
117
118 pub fn up_pressed(&self) -> bool {
119 self.button_pressed(Button::Up)
120 }
121
122 pub fn left_pressed(&self) -> bool {
123 self.button_pressed(Button::Left)
124 }
125
126 pub fn events(&self) -> EventIter {
132 EventIter {
133 postion: 0,
134 buttons: self,
135 update_postions: self.current_state ^ self.last_state
136 }
137 }
138
139 pub fn update(&mut self) {
155 self.latch.set_low().ok();
157 cycle_delay(7); self.latch.set_high().ok();
159 cycle_delay(1); let mut current: u8 = 0;
161
162 for _ in 0..8 {
164 current <<= 1;
165
166 self.clock.set_low().ok();
167 cycle_delay(5); if self.data_in.is_high().unwrap() {
170 current |= 1;
171 }
172 self.clock.set_high().ok();
173 }
174
175 self.last_state = self.current_state;
176 self.current_state = current;
177 }
178}