-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathButtons.h
More file actions
129 lines (117 loc) · 4.79 KB
/
Buttons.h
File metadata and controls
129 lines (117 loc) · 4.79 KB
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
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
/*------------------------------------------------------/
/ Copyright (c) 2023, Elehobica
/ Released under the BSD-2-Clause
/ refer to https://opensource.org/licenses/BSD-2-Clause
/------------------------------------------------------*/
#pragma once
#include "pico/stdlib.h"
#include "pico/util/queue.h"
#include <stdint.h>
typedef enum _button_event_type_t {
EVT_NONE,
EVT_SINGLE,
EVT_MULTI,
EVT_LONG,
EVT_LONG_LONG,
EVT_ON,
EVT_OFF
} button_event_type_t;
typedef struct _button_event_t {
uint32_t button_id;
const char* button_name;
button_event_type_t type;
uint8_t click_count;
uint8_t repeat_count;
} button_event_t;
typedef struct _button_config_t {
bool is_button; // Set true if it's a button or set false if it's a switch
bool active_high; // Set false if button is connected between GND and pin with pull-up
bool multi_clicks; // Detect multiple clicks if true, detect single click if false
uint8_t filter_size; // Filter size to process raw status
uint8_t act_finish_cnt; // Button action detection starts when status keeps false at latest continuous actFinishCnt times (only if multiClicks)
uint8_t repeat_detect_cnt; // Continuous counts to detect Repeat click when continuous push (only if !multiClicks. ignored if 0. if defined Long/LongLong detect disabled)
uint8_t repeat_skip; // Skip count for Repeat click detection (every scan if 0)
uint8_t long_detect_cnt; // Continuous counts to detect Long Push (ignored if 0)
uint8_t long_long_detect_cnt; // Continuous counts to detect LongLong Push (ignored if 0)
} button_config_t;
typedef uint64_t button_history_t;
typedef struct _button_t {
const uint32_t id;
const char* name;
const uint pin;
const button_config_t* config;
button_history_t history;
button_history_t filtered;
uint8_t rpt_cnt;
static uint32_t max_id;
static void reg_id(uint32_t id) { if (id >= max_id) max_id = id + 1; }
static uint32_t gen_id() { return max_id++; }
_button_t(const uint32_t id_, const char* name_, const uint pin_, const button_config_t* config_) : id(id_), name(name_), pin(pin_), config(config_) { reg_id(id); }
_button_t(const char* name_, const uint pin_, const button_config_t* config_) : id(gen_id()), name(name_), pin(pin_), config(config_) {}
} button_t;
class Buttons {
public:
static constexpr int EVENT_QUEUE_LENGTH = 1;
static constexpr button_config_t DEFAULT_BUTTON_SINGLE_CONFIG = {
true, // is_button
false, // active_high
false, // multi_clicks
1, // filter_size
0, // act_finish_cnt
0, // repeat_detect_cnt
0, // repeat_skip
0, // long_detect_cnt
0 // long_long_detect_cnt
};
static constexpr button_config_t DEFAULT_BUTTON_SINGLE_REPEAT_CONFIG = {
true, // is_button
false, // active_high
false, // multi_clicks
1, // filter_size
0, // act_finish_cnt
10, // repeat_detect_cnt
2, // repeat_skip
0, // long_detect_cnt
0 // long_long_detect_cnt
};
static constexpr button_config_t DEFAULT_BUTTON_MULTI_CONFIG = {
true, // is_button
false, // active_high
true, // multi_clicks
1, // filter_size
5, // act_finish_cnt
0, // repeat_detect_cnt
2, // repeat_skip
15, // long_detect_cnt
39 // long_long_detect_cnt
};
static constexpr button_config_t DEFAULT_SWITCH_CONFIG = {
false, // is_button
false, // active_high
false, // multi_clicks
1, // filter_size
0, // act_finish_cnt
0, // repeat_detect_cnt
0, // repeat_skip
0, // long_detect_cnt
0 // long_long_detect_cnt
};
Buttons(button_t* buttons, int size, uint8_t scan_skip = 0);
virtual ~Buttons() {};
void scan_periodic();
bool get_button_event(button_event_t& button_event);
private:
button_t* _buttons;
int _size;
uint8_t _scan_skip;
uint32_t _scan_count;
queue_t btn_evt_queue;
void clear_history(button_history_t& history, bool flag);
bool get_pos_history(button_history_t& history, int i);
void unshift_history(button_history_t& history, bool sts);
uint8_t get_recent_stay_pushed_counts(button_history_t& history);
uint8_t get_recent_stay_released_counts(button_history_t& history);
uint8_t count_rising_edge_core(uint64_t u64, bool single);
uint8_t count_rising_edge(button_history_t& history, bool single);
uint8_t count_falling_edge(button_history_t& history, bool single);
};