M5Unit-KEYBOARD 0.1.0 git rev:b58d024
Loading...
Searching...
No Matches
bitwise_state.hpp
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: 2026 M5Stack Technology CO LTD
3 *
4 * SPDX-License-Identifier: MIT
5 */
10#ifndef M5_UNIT_KEYBOARD_UTILITY_BITWISE_STATE_HPP
11#define M5_UNIT_KEYBOARD_UTILITY_BITWISE_STATE_HPP
12
13#include <array>
14#include <bitset>
15#include <cstddef>
16#include <cstdint>
17
18namespace m5 {
19namespace unit {
20namespace keyboard_bitwise {
21
29template <size_t N>
30struct BitwiseState {
31 using bits_t = std::bitset<N>;
32
33 bits_t now{};
34 bits_t prev{};
35 bits_t holding{};
36
37 bits_t pressed{};
38 bits_t released{};
39 bits_t was_hold{};
40 bits_t repeating{};
41
42 std::array<uint32_t, N> press_at{};
43 std::array<uint32_t, N> last_repeat_at{};
44
45 uint32_t holding_threshold_ms{800};
46 uint32_t repeat_initial_ms{400};
47 uint32_t repeat_rate_ms{400};
48
49 inline void resetOneShot()
50 {
51 pressed.reset();
52 released.reset();
53 was_hold.reset();
54 repeating.reset();
55 }
56
57 inline void resetAll()
58 {
59 now.reset();
60 prev.reset();
61 holding.reset();
62 resetOneShot();
63 press_at.fill(0U);
64 last_repeat_at.fill(0U);
65 }
66
67 inline void setKey(const size_t kidx, const bool is_pressed, const uint32_t now_ms)
68 {
69 if (kidx >= N) return;
70 if (is_pressed) {
71 if (!now.test(kidx)) {
72 press_at[kidx] = now_ms;
73 last_repeat_at[kidx] = 0U;
74 }
75 now.set(kidx);
76 } else {
77 now.reset(kidx);
78 }
79 }
80
81 inline void computeEdges()
82 {
83 const bits_t changed = now ^ prev;
84 pressed = changed & now;
85 released = changed & ~now;
86 }
87
88 inline void tickHoldRepeat(const uint32_t now_ms)
89 {
90 for (size_t i = 0; i < N; ++i) {
91 if (now.test(i)) {
92 const uint32_t elapsed = now_ms - press_at[i];
93 if (elapsed >= holding_threshold_ms) {
94 if (!holding.test(i)) was_hold.set(i);
95 holding.set(i);
96 }
97 if (elapsed >= repeat_initial_ms) {
98 if (last_repeat_at[i] == 0U || (now_ms - last_repeat_at[i]) >= repeat_rate_ms) {
99 repeating.set(i);
100 last_repeat_at[i] = now_ms;
101 }
102 }
103 } else {
104 holding.reset(i);
105 last_repeat_at[i] = 0U;
106 }
107 }
108 }
109
110 inline void commitPrev()
111 {
112 prev = now;
113 }
114};
116
117} // namespace keyboard_bitwise
118} // namespace unit
119} // namespace m5
120
121#endif
Top level namespace of M5Stack.
Unit-related namespace.
Per-key state tracking (now / prev / edge / hold / repeat) with timestamps.