-
Notifications
You must be signed in to change notification settings - Fork 0
/
buttons.cpp
124 lines (106 loc) · 3.36 KB
/
buttons.cpp
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
#include "buttons.h"
#include "common.h"
#include "animations.h"
#include "tickerScheduler.h"
extern const uint32_t minPressThreshold = 2; // 0.2 seconds
extern const uint32_t longPressThreshold = 24; // 2.4 seconds
extern const uint32_t maxPressThreshold = 150; // 15 seconds
TrellisCallback keyPressCallback(keyEvent evt)
{
if (evt.bit.EDGE != SEESAW_KEYPAD_EDGE_RISING &&
evt.bit.EDGE != SEESAW_KEYPAD_EDGE_FALLING)
return 0;
const int buttonIndex = (int)evt.bit.NUM;
const uint64_t prevPressed = state.buttons.pressed;
if (evt.bit.EDGE == SEESAW_KEYPAD_EDGE_RISING)
{
setFlag(state.buttons.pressed, buttonIndex);
}
else
clearFlag(state.buttons.pressed, buttonIndex);
if (prevPressed != state.buttons.pressed)
{
setFlag(state.buttons.changedState, buttonIndex);
}
#ifdef DEBUG
static char buff[17];
Serial.print("button ");
snprintf(buff, sizeof(buff), "%02u", buttonIndex + 1);
Serial.print(buff);
if (evt.bit.EDGE == SEESAW_KEYPAD_EDGE_RISING)
Serial.print(" DOWN");
else
Serial.print(" UP");
Serial.print(". buttonsPressed: 0x");
// state.buttons.pressed = 0xffffffffffffffffULL;
snprintf(buff, sizeof(buff), "%016llx", state.buttons.pressed);
Serial.print(buff);
Serial.print(". delta: 0x");
snprintf(buff, sizeof(buff), "%016llx", state.buttons.pressed ^ prevPressed);
Serial.print(buff);
Serial.println("");
#endif
return 0;
}
inline static void _bumpCounter(uint32_t &counter)
{
if (counter < 0xfffffffeUL)
++counter;
}
void buttons100msTick()
{
if (state.buttons.pressed)
{
for (int i = 0; i < 64; ++i)
{
if (getFlag(state.buttons.pressed, i))
_bumpCounter(state.buttons.buttonPressedCounter[i]);
// If button is in the aborted mask, baseline its counter to make that known.
// This is expected to happend when button was stuck before and then it got
// unstuck but no notifications about it was sent out yet.
if (getFlag(state.buttons.abortedPendingPressEvent, i) &&
state.buttons.buttonPressedCounter[i] < maxPressThreshold)
{
state.buttons.buttonPressedCounter[i] = maxPressThreshold;
}
}
}
}
void buttons1secTick()
{
static int buttonsQuiescedCount = 0;
if (state.buttons.pressed || state.buttons.pendingPressEvent == 0)
{
buttonsQuiescedCount = 0;
return;
}
if (++buttonsQuiescedCount < 2)
return;
const uint64_t pressed = state.buttons.pendingPressEvent ^ state.buttons.pendingLongPressEvent;
const uint64_t longPressed = state.buttons.pendingLongPressEvent;
#ifdef DEBUG
static char buff[17];
Serial.print("event buttonsPressed 0x");
snprintf(buff, sizeof(buff), "%016llx", pressed);
Serial.println(buff);
Serial.print("event buttonsLongPressed 0x");
snprintf(buff, sizeof(buff), "%016llx", longPressed);
Serial.println(buff);
Serial.print("event buttonsAborted 0x");
snprintf(buff, sizeof(buff), "%016llx", state.buttons.abortedPendingPressEvent);
Serial.println(buff);
#endif
localButtonProcess(pressed, longPressed);
sendButtonEvent();
// Reset all values after sending event
state.buttons.pendingPressEvent = 0;
state.buttons.pendingLongPressEvent = 0;
state.buttons.abortedPendingPressEvent = 0;
}
void initButtons(TickerScheduler &ts)
{
// Init tickers
const uint32_t oneSec = 1000;
ts.sched(buttons100msTick, 100);
ts.sched(buttons1secTick, oneSec);
}