inky_frame/hw/
buttons.rs

1// Permission is hereby granted, free of charge, to any person obtaining a copy
2// of this software and associated documentation files (the "Software"), to deal
3// in the Software without restriction, including without limitation the rights
4// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
5// copies of the Software, and to permit persons to whom the Software is
6// furnished to do so, subject to the following conditions:
7//
8// The above copyright notice and this permission notice shall be included in
9// all copies or substantial portions of the Software.
10//
11// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
12// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
13// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
14// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
15// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
16// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
17// SOFTWARE.
18//
19
20#![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}