-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbuttons.c
85 lines (64 loc) · 2.01 KB
/
buttons.c
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
78
79
80
81
82
83
84
85
#include <stdlib.h>
#include "buttons.h"
static button_t btns[4];
static uint8_t btn_state[] = {BTN_RELEASE, BTN_RELEASE, BTN_RELEASE, BTN_RELEASE};
static absolute_time_t debounce_due[] = {0, 0, 0, 0};
static uint8_t btn_get_index(uint8_t pin) {
return pin - BTN_MIN_PIN;
}
button_t *btn_get(uint8_t pin) {
button_t *btn;
uint8_t btn_index = btn_get_index(pin);
btn = &btns[btn_index];
return btn;
}
void btn_debounce(uint8_t pin, uint32_t event_mask, int8_t *confirm_pin, uint8_t *btn_action) {
absolute_time_t _debounce_due;
absolute_time_t now = get_absolute_time();
uint8_t btn_index = btn_get_index(pin);
uint8_t last_state = btn_state[btn_index];
uint8_t new_state = (event_mask == GPIO_IRQ_EDGE_RISE) ? BTN_PRESS : BTN_RELEASE;
if (last_state == new_state) {
return;
}
_debounce_due = debounce_due[btn_index];
if (now < _debounce_due) {
return;
}
btn_state[btn_index] = new_state;
debounce_due[btn_index] = delayed_by_ms(now, DEBOUNCE_TIME_MS);
*confirm_pin = pin;
*btn_action = new_state;
}
void btn_create_array() {
for (uint8_t i = 0; i < 4; i++) {
button_t btn;
btn.pin = -1;
btn.pressed_at = nil_time;
btn.released_at = nil_time;
btns[i] = btn;
}
}
void btn_handled(button_t *btn, absolute_time_t now) {
btn->released_at = now;
}
uint8_t btn_is_pressed(button_t *btn) {
return btn->pressed_at > btn->released_at;
}
uint8_t btn_is_long_press(button_t *btn) {
absolute_time_t now = get_absolute_time();
uint32_t diff = absolute_time_diff_us(btn->pressed_at, now) / 1000;
if (diff >= LONG_PRESS_TIME_MS) {
return 1;
}
return 0;
}
uint8_t btn_is_double_press(button_t *btn) {
absolute_time_t now = get_absolute_time();
uint32_t diff = absolute_time_diff_us(btn->released_at, btn->pressed_at) / 1000;
if (diff <= DOUBLE_PRESS_TIME_MS) {
btn_handled(btn, now);
return 1;
}
return 0;
}