~ruther/avr-guess-the-number

ref: 6cb39555e50768ec4f3f25bef63cdc390409fee1 avr-guess-the-number/src/button.rs -rw-r--r-- 1.8 KiB
6cb39555 — František Boháček feat: make ports match pcb layout 2 years ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
use atmega_hal::port::{Pin, mode};

#[derive(PartialEq, Eq)]
pub enum ButtonState {
    Inactive, // button is not pressed and the state is same from last time
    Active, // button is pressed and the state is same from last time
    Pressed, // The button was just pressed
    Released // The button was just released
}

const DEBOUNCECYCLES: u8 = 50;

pub struct Button {
    input: Pin<mode::Input>,
    active_high: bool,
    last_active: bool,
    active: bool,
    integrator: u8
}

impl Button {
    pub fn create(input: Pin<mode::Input>, active_high: bool) -> Button {
        Button {
            input,
            active_high,
            last_active: false,
            active: false,
            integrator: 0,
        }
    }

    pub fn step(&mut self) {
        let mut btn_active = self.input.is_low();
        if self.active_high {
            btn_active = !btn_active;
        }

        if !btn_active {
            if self.integrator > 0 {
                self.integrator -= 1;
            }
        } else if self.integrator < DEBOUNCECYCLES {
            self.integrator += 1;
        }

        self.active = self.pressed();
    }

    fn pressed(&mut self) -> bool{
        if self.integrator == 0 {
            self.last_active = self.active;
            self.active = false;
        } else if self.integrator >= DEBOUNCECYCLES {
            self.integrator = DEBOUNCECYCLES;
            self.last_active = self.active;
            self.active = true;
        }

        self.active
    }

    pub fn state(&self) -> ButtonState {
        if self.active {
            if self.last_active {
                return ButtonState::Active;
            }

            return ButtonState::Pressed;
        }

        if !self.last_active {
            return ButtonState::Inactive;
        }

        return ButtonState::Released;
    }
}
Do not follow this link