1#![deny(unsafe_code)]
2
3use super::debouncer::{Debouncer, Edge};
4
5#[derive(Debug, PartialEq, Clone, Copy)]
6pub enum PinState {
7 Low,
8 High,
9}
10
11#[derive(Debug)]
12pub struct SmallPinDebouncer {
13 inner: Debouncer<PinState, u8>,
14}
15
16impl SmallPinDebouncer {
17 pub fn new(threshold: u8, inital_state: PinState) -> Self {
18 SmallPinDebouncer {
19 inner: Debouncer::new(threshold, inital_state),
20 }
21 }
22
23 pub fn update(&mut self, state: PinState) -> Option<Edge<PinState>> {
24 self.inner.update(state)
25 }
26
27 pub fn is_high(&self) -> bool {
28 self.inner.is_state(PinState::High)
29 }
30
31 pub fn is_low(&self) -> bool {
32 self.inner.is_state(PinState::Low)
33 }
34}
35
36#[cfg(test)]
37mod tests {
38 use super::*;
39
40 #[test]
41 fn test_rising_edge() {
42 let mut debouncer: SmallPinDebouncer = SmallPinDebouncer::new(3, PinState::Low);
44 assert!(debouncer.is_low());
45
46 assert_eq!(debouncer.update(PinState::High), None);
48 assert_eq!(debouncer.update(PinState::High), None);
49 assert_eq!(
50 debouncer.update(PinState::High),
51 Some(Edge::new(PinState::Low, PinState::High))
52 );
53
54 assert_eq!(debouncer.update(PinState::High), None);
56
57 assert_eq!(debouncer.update(PinState::Low), None);
59 assert_eq!(debouncer.update(PinState::High), None);
60 assert_eq!(debouncer.update(PinState::High), None);
61 assert_ne!(
62 debouncer.update(PinState::High),
63 Some(Edge::new(PinState::Low, PinState::High))
64 );
65 }
66
67 #[test]
68 fn test_falling_edge() {
69 let mut debouncer: SmallPinDebouncer = SmallPinDebouncer::new(3, PinState::High);
71 assert!(debouncer.is_high());
72
73 assert_eq!(debouncer.update(PinState::Low), None);
75 assert_eq!(debouncer.update(PinState::Low), None);
76 assert_eq!(
77 debouncer.update(PinState::Low),
78 Some(Edge::new(PinState::High, PinState::Low))
79 );
80
81 assert_eq!(debouncer.update(PinState::Low), None);
83
84 assert_eq!(debouncer.update(PinState::High), None);
86 assert_eq!(debouncer.update(PinState::Low), None);
87 assert_eq!(debouncer.update(PinState::Low), None);
88 assert_ne!(
89 debouncer.update(PinState::Low),
90 Some(Edge::new(PinState::High, PinState::Low))
91 );
92 }
93
94 #[test]
95 fn test_debounce_16() {
96 let mut debouncer: SmallPinDebouncer = SmallPinDebouncer::new(16, PinState::Low);
98 assert!(debouncer.is_low());
99 for _ in 0..15 {
100 assert_eq!(debouncer.update(PinState::High), None);
101 assert!(!debouncer.is_high());
102 }
103 assert_eq!(
104 debouncer.update(PinState::High),
105 Some(Edge::new(PinState::Low, PinState::High))
106 );
107 assert!(debouncer.is_high());
108 assert_eq!(debouncer.update(PinState::High), None);
109 assert!(debouncer.is_high());
110 }
111
112 #[test]
113 fn test_is_low_high() {
114 let mut debouncer: SmallPinDebouncer = SmallPinDebouncer::new(8, PinState::Low);
116 assert!(debouncer.is_low());
117 assert!(!debouncer.is_high());
118
119 debouncer.update(PinState::Low);
121 assert!(debouncer.is_low());
122 assert!(!debouncer.is_high());
123
124 for _ in 0..7 {
126 assert!(debouncer.update(PinState::High).is_none());
127 assert!(!debouncer.is_low());
128 assert!(!debouncer.is_high());
129 }
130
131 assert_eq!(
133 debouncer.update(PinState::High),
134 Some(Edge::new(PinState::Low, PinState::High))
135 );
136 assert!(!debouncer.is_low());
137 assert!(debouncer.is_high());
138
139 assert!(debouncer.update(PinState::High).is_none());
141 assert!(!debouncer.is_low());
142 assert!(debouncer.is_high());
143 }
144
145 #[test]
147 fn test_ram_consumption() {
148 assert_eq!(
150 std::mem::size_of_val(&SmallPinDebouncer::new(2, PinState::Low)),
151 4
152 );
153 assert_eq!(
154 std::mem::size_of_val(&SmallPinDebouncer::new(8, PinState::Low)),
155 4
156 );
157 assert_eq!(
158 std::mem::size_of_val(&SmallPinDebouncer::new(9, PinState::Low)),
159 4
160 );
161 assert_eq!(
162 std::mem::size_of_val(&SmallPinDebouncer::new(16, PinState::Low)),
163 4
164 );
165 }
166
167 #[test]
169 fn test_initial_state() {
170 let mut debouncer_01 = SmallPinDebouncer::new(2, PinState::Low);
171 assert_eq!(debouncer_01.update(PinState::Low), None);
172 assert_eq!(debouncer_01.update(PinState::Low), None);
173 assert_eq!(debouncer_01.update(PinState::High), None);
174 assert_eq!(
175 debouncer_01.update(PinState::High),
176 Some(Edge::new(PinState::Low, PinState::High))
177 );
178
179 let mut debouncer_02 = SmallPinDebouncer::new(2, PinState::Low);
180 assert_eq!(debouncer_02.update(PinState::High), None);
181 assert_eq!(
182 debouncer_02.update(PinState::High),
183 Some(Edge::new(PinState::Low, PinState::High))
184 );
185 assert_eq!(debouncer_02.update(PinState::Low), None);
186 assert_eq!(
187 debouncer_02.update(PinState::Low),
188 Some(Edge::new(PinState::High, PinState::Low))
189 );
190
191 let mut debouncer_03 = SmallPinDebouncer::new(2, PinState::High);
192 assert_eq!(debouncer_03.update(PinState::Low), None);
193 assert_eq!(
194 debouncer_03.update(PinState::Low),
195 Some(Edge::new(PinState::High, PinState::Low))
196 );
197 assert_eq!(debouncer_03.update(PinState::High), None);
198 assert_eq!(
199 debouncer_03.update(PinState::High),
200 Some(Edge::new(PinState::Low, PinState::High))
201 );
202
203 let mut debouncer_04 = SmallPinDebouncer::new(2, PinState::High);
204 assert_eq!(debouncer_04.update(PinState::High), None);
205 assert_eq!(debouncer_04.update(PinState::High), None);
206 assert_eq!(debouncer_04.update(PinState::Low), None);
207 assert_eq!(
208 debouncer_04.update(PinState::Low),
209 Some(Edge::new(PinState::High, PinState::Low))
210 );
211 }
212
213 #[test]
214 fn test_long_running_02() {
215 let mut debouncer: SmallPinDebouncer = SmallPinDebouncer::new(2, PinState::Low);
216 assert_eq!(debouncer.update(PinState::High), None);
217 assert_eq!(
218 debouncer.update(PinState::High),
219 Some(Edge::new(PinState::Low, PinState::High))
220 );
221 assert_eq!(debouncer.update(PinState::High), None);
222 assert_eq!(debouncer.update(PinState::High), None);
223 assert_eq!(debouncer.update(PinState::Low), None);
224 assert_eq!(
225 debouncer.update(PinState::Low),
226 Some(Edge::new(PinState::High, PinState::Low))
227 );
228 assert_eq!(debouncer.update(PinState::High), None);
229 assert_eq!(debouncer.update(PinState::Low), None);
230 assert_eq!(debouncer.update(PinState::Low), None);
231 assert_eq!(debouncer.update(PinState::Low), None);
232 assert_eq!(debouncer.update(PinState::High), None);
233 assert_eq!(
234 debouncer.update(PinState::High),
235 Some(Edge::new(PinState::Low, PinState::High))
236 );
237 assert_eq!(debouncer.update(PinState::High), None);
238 assert_eq!(debouncer.update(PinState::High), None);
239 assert_eq!(debouncer.update(PinState::Low), None);
240 assert_eq!(
241 debouncer.update(PinState::Low),
242 Some(Edge::new(PinState::High, PinState::Low))
243 );
244 assert_eq!(debouncer.update(PinState::High), None);
245 assert_eq!(
246 debouncer.update(PinState::High),
247 Some(Edge::new(PinState::Low, PinState::High))
248 );
249 assert_eq!(debouncer.update(PinState::High), None);
250 assert_eq!(debouncer.update(PinState::Low), None);
251 assert_eq!(
252 debouncer.update(PinState::Low),
253 Some(Edge::new(PinState::High, PinState::Low))
254 );
255 assert_eq!(debouncer.update(PinState::Low), None);
256 assert_eq!(debouncer.update(PinState::High), None);
257 assert_eq!(debouncer.update(PinState::Low), None);
258 assert_eq!(debouncer.update(PinState::High), None);
259 assert_eq!(debouncer.update(PinState::Low), None);
260 assert_eq!(debouncer.update(PinState::High), None);
261 assert_eq!(debouncer.update(PinState::Low), None);
262 assert_eq!(debouncer.update(PinState::High), None);
263 assert_eq!(debouncer.update(PinState::Low), None);
264 assert_eq!(debouncer.update(PinState::High), None);
265 assert_eq!(
266 debouncer.update(PinState::High),
267 Some(Edge::new(PinState::Low, PinState::High))
268 );
269 assert_eq!(debouncer.update(PinState::High), None);
270 assert_eq!(debouncer.update(PinState::High), None);
271 assert_eq!(debouncer.update(PinState::Low), None);
272 assert_eq!(
273 debouncer.update(PinState::Low),
274 Some(Edge::new(PinState::High, PinState::Low))
275 );
276 assert_eq!(debouncer.update(PinState::High), None);
277 assert_eq!(
278 debouncer.update(PinState::High),
279 Some(Edge::new(PinState::Low, PinState::High))
280 );
281 assert_eq!(debouncer.update(PinState::Low), None);
282 assert_eq!(
283 debouncer.update(PinState::Low),
284 Some(Edge::new(PinState::High, PinState::Low))
285 );
286 assert_eq!(debouncer.update(PinState::High), None);
287 assert_eq!(debouncer.update(PinState::Low), None);
288 assert_eq!(debouncer.update(PinState::High), None);
289 assert_eq!(debouncer.update(PinState::Low), None);
290 assert_eq!(debouncer.update(PinState::High), None);
291 assert_eq!(debouncer.update(PinState::Low), None);
292 assert_eq!(debouncer.update(PinState::High), None);
293 assert_eq!(
294 debouncer.update(PinState::High),
295 Some(Edge::new(PinState::Low, PinState::High))
296 );
297 assert_eq!(debouncer.update(PinState::High), None);
298 assert_eq!(debouncer.update(PinState::Low), None);
299 assert_eq!(
300 debouncer.update(PinState::Low),
301 Some(Edge::new(PinState::High, PinState::Low))
302 );
303 assert_eq!(debouncer.update(PinState::Low), None);
304 assert_eq!(debouncer.update(PinState::Low), None);
305 assert_eq!(debouncer.update(PinState::Low), None);
306 assert_eq!(debouncer.update(PinState::Low), None);
307 assert_eq!(debouncer.update(PinState::High), None);
308 assert_eq!(
309 debouncer.update(PinState::High),
310 Some(Edge::new(PinState::Low, PinState::High))
311 );
312 assert_eq!(debouncer.update(PinState::High), None);
313 assert_eq!(debouncer.update(PinState::High), None);
314 assert_eq!(debouncer.update(PinState::Low), None);
315 assert_eq!(
316 debouncer.update(PinState::Low),
317 Some(Edge::new(PinState::High, PinState::Low))
318 );
319 assert_eq!(debouncer.update(PinState::Low), None);
320 assert_eq!(debouncer.update(PinState::High), None);
321 assert_eq!(
322 debouncer.update(PinState::High),
323 Some(Edge::new(PinState::Low, PinState::High))
324 );
325 assert_eq!(debouncer.update(PinState::Low), None);
326 assert_eq!(
327 debouncer.update(PinState::Low),
328 Some(Edge::new(PinState::High, PinState::Low))
329 );
330 assert_eq!(debouncer.update(PinState::Low), None);
331 assert_eq!(debouncer.update(PinState::Low), None);
332 assert_eq!(debouncer.update(PinState::High), None);
333 assert_eq!(debouncer.update(PinState::Low), None);
334 assert_eq!(debouncer.update(PinState::High), None);
335 assert_eq!(debouncer.update(PinState::Low), None);
336 assert_eq!(debouncer.update(PinState::Low), None);
337 assert_eq!(debouncer.update(PinState::Low), None);
338 assert_eq!(debouncer.update(PinState::High), None);
339 assert_eq!(
340 debouncer.update(PinState::High),
341 Some(Edge::new(PinState::Low, PinState::High))
342 );
343 assert_eq!(debouncer.update(PinState::Low), None);
344 assert_eq!(debouncer.update(PinState::High), None);
345 assert_eq!(debouncer.update(PinState::High), None);
346 assert_eq!(debouncer.update(PinState::Low), None);
347 assert_eq!(debouncer.update(PinState::High), None);
348 assert_eq!(debouncer.update(PinState::High), None);
349 assert_eq!(debouncer.update(PinState::Low), None);
350 assert_eq!(
351 debouncer.update(PinState::Low),
352 Some(Edge::new(PinState::High, PinState::Low))
353 );
354 assert_eq!(debouncer.update(PinState::High), None);
355 assert_eq!(
356 debouncer.update(PinState::High),
357 Some(Edge::new(PinState::Low, PinState::High))
358 );
359 assert_eq!(debouncer.update(PinState::High), None);
360 assert_eq!(debouncer.update(PinState::Low), None);
361 assert_eq!(
362 debouncer.update(PinState::Low),
363 Some(Edge::new(PinState::High, PinState::Low))
364 );
365 assert_eq!(debouncer.update(PinState::Low), None);
366 assert_eq!(debouncer.update(PinState::High), None);
367 assert_eq!(debouncer.update(PinState::Low), None);
368 assert_eq!(debouncer.update(PinState::Low), None);
369 assert_eq!(debouncer.update(PinState::Low), None);
370 assert_eq!(debouncer.update(PinState::Low), None);
371 assert_eq!(debouncer.update(PinState::Low), None);
372 assert_eq!(debouncer.update(PinState::High), None);
373 assert_eq!(debouncer.update(PinState::Low), None);
374 assert_eq!(debouncer.update(PinState::High), None);
375 }
376
377 #[test]
378 fn test_long_running_04() {
379 let mut debouncer: SmallPinDebouncer = SmallPinDebouncer::new(4, PinState::Low);
380 assert_eq!(debouncer.update(PinState::High), None);
381 assert_eq!(debouncer.update(PinState::High), None);
382 assert_eq!(debouncer.update(PinState::High), None);
383 assert_eq!(
384 debouncer.update(PinState::High),
385 Some(Edge::new(PinState::Low, PinState::High))
386 );
387 assert_eq!(debouncer.update(PinState::Low), None);
388 assert_eq!(debouncer.update(PinState::Low), None);
389 assert_eq!(debouncer.update(PinState::High), None);
390 assert_eq!(debouncer.update(PinState::Low), None);
391 assert_eq!(debouncer.update(PinState::Low), None);
392 assert_eq!(debouncer.update(PinState::Low), None);
393 assert_eq!(debouncer.update(PinState::High), None);
394 assert_eq!(debouncer.update(PinState::High), None);
395 assert_eq!(debouncer.update(PinState::High), None);
396 assert_eq!(debouncer.update(PinState::High), None);
397 assert_eq!(debouncer.update(PinState::Low), None);
398 assert_eq!(debouncer.update(PinState::Low), None);
399 assert_eq!(debouncer.update(PinState::High), None);
400 assert_eq!(debouncer.update(PinState::High), None);
401 assert_eq!(debouncer.update(PinState::High), None);
402 assert_eq!(debouncer.update(PinState::Low), None);
403 assert_eq!(debouncer.update(PinState::Low), None);
404 assert_eq!(debouncer.update(PinState::Low), None);
405 assert_eq!(debouncer.update(PinState::High), None);
406 assert_eq!(debouncer.update(PinState::Low), None);
407 assert_eq!(debouncer.update(PinState::High), None);
408 assert_eq!(debouncer.update(PinState::Low), None);
409 assert_eq!(debouncer.update(PinState::High), None);
410 assert_eq!(debouncer.update(PinState::Low), None);
411 assert_eq!(debouncer.update(PinState::High), None);
412 assert_eq!(debouncer.update(PinState::Low), None);
413 assert_eq!(debouncer.update(PinState::High), None);
414 assert_eq!(debouncer.update(PinState::High), None);
415 assert_eq!(debouncer.update(PinState::High), None);
416 assert_eq!(debouncer.update(PinState::High), None);
417 assert_eq!(debouncer.update(PinState::Low), None);
418 assert_eq!(debouncer.update(PinState::Low), None);
419 assert_eq!(debouncer.update(PinState::High), None);
420 assert_eq!(debouncer.update(PinState::High), None);
421 assert_eq!(debouncer.update(PinState::Low), None);
422 assert_eq!(debouncer.update(PinState::Low), None);
423 assert_eq!(debouncer.update(PinState::High), None);
424 assert_eq!(debouncer.update(PinState::Low), None);
425 assert_eq!(debouncer.update(PinState::High), None);
426 assert_eq!(debouncer.update(PinState::Low), None);
427 assert_eq!(debouncer.update(PinState::High), None);
428 assert_eq!(debouncer.update(PinState::Low), None);
429 assert_eq!(debouncer.update(PinState::High), None);
430 assert_eq!(debouncer.update(PinState::High), None);
431 assert_eq!(debouncer.update(PinState::High), None);
432 assert_eq!(debouncer.update(PinState::Low), None);
433 assert_eq!(debouncer.update(PinState::Low), None);
434 assert_eq!(debouncer.update(PinState::Low), None);
435 assert_eq!(
436 debouncer.update(PinState::Low),
437 Some(Edge::new(PinState::High, PinState::Low))
438 );
439 assert_eq!(debouncer.update(PinState::Low), None);
440 assert_eq!(debouncer.update(PinState::Low), None);
441 assert_eq!(debouncer.update(PinState::High), None);
442 assert_eq!(debouncer.update(PinState::High), None);
443 assert_eq!(debouncer.update(PinState::High), None);
444 assert_eq!(
445 debouncer.update(PinState::High),
446 Some(Edge::new(PinState::Low, PinState::High))
447 );
448 assert_eq!(debouncer.update(PinState::Low), None);
449 assert_eq!(debouncer.update(PinState::Low), None);
450 assert_eq!(debouncer.update(PinState::Low), None);
451 assert_eq!(debouncer.update(PinState::High), None);
452 assert_eq!(debouncer.update(PinState::High), None);
453 assert_eq!(debouncer.update(PinState::Low), None);
454 assert_eq!(debouncer.update(PinState::Low), None);
455 assert_eq!(debouncer.update(PinState::Low), None);
456 assert_eq!(
457 debouncer.update(PinState::Low),
458 Some(Edge::new(PinState::High, PinState::Low))
459 );
460 assert_eq!(debouncer.update(PinState::High), None);
461 assert_eq!(debouncer.update(PinState::Low), None);
462 assert_eq!(debouncer.update(PinState::High), None);
463 assert_eq!(debouncer.update(PinState::Low), None);
464 assert_eq!(debouncer.update(PinState::Low), None);
465 assert_eq!(debouncer.update(PinState::Low), None);
466 assert_eq!(debouncer.update(PinState::High), None);
467 assert_eq!(debouncer.update(PinState::High), None);
468 assert_eq!(debouncer.update(PinState::Low), None);
469 assert_eq!(debouncer.update(PinState::High), None);
470 assert_eq!(debouncer.update(PinState::High), None);
471 assert_eq!(debouncer.update(PinState::Low), None);
472 assert_eq!(debouncer.update(PinState::High), None);
473 assert_eq!(debouncer.update(PinState::High), None);
474 assert_eq!(debouncer.update(PinState::Low), None);
475 assert_eq!(debouncer.update(PinState::Low), None);
476 assert_eq!(debouncer.update(PinState::High), None);
477 assert_eq!(debouncer.update(PinState::High), None);
478 assert_eq!(debouncer.update(PinState::High), None);
479 assert_eq!(debouncer.update(PinState::Low), None);
480 assert_eq!(debouncer.update(PinState::Low), None);
481 assert_eq!(debouncer.update(PinState::Low), None);
482 assert_eq!(debouncer.update(PinState::High), None);
483 assert_eq!(debouncer.update(PinState::Low), None);
484 assert_eq!(debouncer.update(PinState::Low), None);
485 assert_eq!(debouncer.update(PinState::Low), None);
486 assert_eq!(debouncer.update(PinState::Low), None);
487 assert_eq!(debouncer.update(PinState::Low), None);
488 assert_eq!(debouncer.update(PinState::High), None);
489 assert_eq!(debouncer.update(PinState::Low), None);
490 assert_eq!(debouncer.update(PinState::High), None);
491 }
492}