1#![no_implicit_prelude]
21
22extern crate core;
23
24use core::clone::Clone;
25use core::cmp::{Eq, PartialEq};
26use core::convert::From;
27use core::marker::Copy;
28use core::matches;
29use core::mem::discriminant;
30use core::ops::{Deref, DerefMut};
31use core::ptr::NonNull;
32
33use crate::frame::ShiftRegister;
34
35pub enum WakeReason {
36 None,
37 RTC,
38 ButtonA,
39 ButtonB,
40 ButtonC,
41 ButtonD,
42 ButtonE,
43 External,
44}
45
46pub struct Buttons {
47 sr: ShiftRegister,
48 state: u8,
49}
50pub struct ButtonsPtr(NonNull<Buttons>);
51
52pub type Button = WakeReason;
53
54const BUTTON_A: u8 = 0x01u8;
55const BUTTON_B: u8 = 0x02u8;
56const BUTTON_C: u8 = 0x04u8;
57const BUTTON_D: u8 = 0x08u8;
58const BUTTON_E: u8 = 0x10u8;
59const BUTTON_RTC: u8 = 0x20u8;
60const BUTTON_EXTERNAL: u8 = 0x40u8;
61
62impl Buttons {
63 #[inline(always)]
64 pub fn clear(&mut self) {
65 self.state = 0
66 }
67 #[inline(always)]
68 pub fn state(&self) -> u8 {
69 self.state
70 }
71 #[inline(always)]
72 pub fn read(&mut self) -> u8 {
73 self.state = self.sr.read();
74 self.state
75 }
76 #[inline(always)]
77 pub fn button_a(&self) -> bool {
78 self.state & BUTTON_A != 0
79 }
80 #[inline(always)]
81 pub fn button_b(&self) -> bool {
82 self.state & BUTTON_B != 0
83 }
84 #[inline(always)]
85 pub fn button_c(&self) -> bool {
86 self.state & BUTTON_C != 0
87 }
88 #[inline(always)]
89 pub fn button_d(&self) -> bool {
90 self.state & BUTTON_D != 0
91 }
92 #[inline(always)]
93 pub fn button_e(&self) -> bool {
94 self.state & BUTTON_E != 0
95 }
96 #[inline]
97 pub fn pressed(&self) -> Button {
98 match self.state {
99 _ if self.state & BUTTON_A != 0 => Button::ButtonA,
100 _ if self.state & BUTTON_B != 0 => Button::ButtonB,
101 _ if self.state & BUTTON_C != 0 => Button::ButtonC,
102 _ if self.state & BUTTON_D != 0 => Button::ButtonD,
103 _ if self.state & BUTTON_E != 0 => Button::ButtonE,
104 _ if self.state & BUTTON_RTC != 0 => Button::RTC,
105 _ if self.state & BUTTON_EXTERNAL != 0 => Button::External,
106 _ => Button::None,
107 }
108 }
109 #[inline(always)]
110 pub fn button_any(&self) -> bool {
111 self.state & 0x1F != 0
112 }
113 #[inline(always)]
114 pub fn set_raw(&mut self, v: u8) {
115 self.state = v
116 }
117 #[inline(always)]
118 pub fn set(&mut self, v: Button) {
119 self.set_raw(match v {
120 Button::ButtonA => BUTTON_A,
121 Button::ButtonB => BUTTON_B,
122 Button::ButtonC => BUTTON_C,
123 Button::ButtonD => BUTTON_D,
124 Button::ButtonE => BUTTON_E,
125 Button::RTC => BUTTON_RTC,
126 Button::External => BUTTON_EXTERNAL,
127 Button::None => 0u8,
128 })
129 }
130 #[inline(always)]
131 pub fn read_pressed(&mut self) -> bool {
132 self.read() & 0x1F != 0 || self.state & BUTTON_EXTERNAL != 0
133 }
134 #[inline]
135 pub fn pressed_buttons(&self) -> Button {
136 match self.state {
137 _ if self.state & BUTTON_A != 0 => Button::ButtonA,
138 _ if self.state & BUTTON_B != 0 => Button::ButtonB,
139 _ if self.state & BUTTON_C != 0 => Button::ButtonC,
140 _ if self.state & BUTTON_D != 0 => Button::ButtonD,
141 _ if self.state & BUTTON_E != 0 => Button::ButtonE,
142 _ => Button::None,
143 }
144 }
145 #[inline(always)]
146 pub fn shift_register(&self) -> &ShiftRegister {
147 &self.sr
148 }
149
150 #[inline(always)]
151 pub(crate) fn new(state: u8, sr: ShiftRegister) -> Buttons {
152 Buttons { sr, state }
153 }
154}
155impl ButtonsPtr {
156 #[inline(always)]
157 pub(crate) fn new(i: &mut Buttons) -> ButtonsPtr {
158 ButtonsPtr(unsafe { NonNull::new_unchecked(i) })
159 }
160}
161impl WakeReason {
162 #[inline(always)]
163 pub fn wake_from_ext(&self) -> bool {
164 matches!(self, WakeReason::External)
165 }
166 #[inline(always)]
167 pub fn wake_from_rtc(&self) -> bool {
168 matches!(self, WakeReason::RTC)
169 }
170 #[inline(always)]
171 pub fn wake_from_button(&self) -> bool {
172 matches!(
173 self,
174 WakeReason::ButtonA | WakeReason::ButtonB | WakeReason::ButtonC | WakeReason::ButtonD | WakeReason::ButtonE
175 )
176 }
177}
178
179impl Clone for Buttons {
180 #[inline(always)]
181 fn clone(&self) -> Buttons {
182 Buttons {
183 sr: self.sr.clone(),
184 state: self.state.clone(),
185 }
186 }
187}
188
189impl Deref for ButtonsPtr {
190 type Target = Buttons;
191
192 #[inline(always)]
193 fn deref(&self) -> &Buttons {
194 unsafe { self.0.as_ref() }
195 }
196}
197impl DerefMut for ButtonsPtr {
198 #[inline(always)]
199 fn deref_mut(&mut self) -> &mut Buttons {
200 unsafe { self.0.as_mut() }
201 }
202}
203
204impl Eq for WakeReason {}
205impl Copy for WakeReason {}
206impl Clone for WakeReason {
207 #[inline(always)]
208 fn clone(&self) -> WakeReason {
209 *self
210 }
211}
212impl From<u8> for WakeReason {
213 #[inline]
214 fn from(v: u8) -> WakeReason {
215 match v {
216 _ if v & 0x40 != 0 => WakeReason::External,
217 _ if v & 0x20 != 0 => WakeReason::RTC,
218 _ if v & 0x10 != 0 => WakeReason::ButtonE,
219 _ if v & 0x08 != 0 => WakeReason::ButtonD,
220 _ if v & 0x04 != 0 => WakeReason::ButtonC,
221 _ if v & 0x02 != 0 => WakeReason::ButtonB,
222 _ if v & 0x01 != 0 => WakeReason::ButtonA,
223 _ => WakeReason::None,
224 }
225 }
226}
227impl PartialEq for WakeReason {
228 #[inline(always)]
229 fn eq(&self, other: &Self) -> bool {
230 discriminant(self) == discriminant(other)
231 }
232}