aboutsummaryrefslogtreecommitdiff
path: root/quantum/debounce/sym_eager_pk.c
diff options
context:
space:
mode:
Diffstat (limited to 'quantum/debounce/sym_eager_pk.c')
-rw-r--r--quantum/debounce/sym_eager_pk.c118
1 files changed, 118 insertions, 0 deletions
diff --git a/quantum/debounce/sym_eager_pk.c b/quantum/debounce/sym_eager_pk.c
new file mode 100644
index 000000000..93a40ad44
--- /dev/null
+++ b/quantum/debounce/sym_eager_pk.c
@@ -0,0 +1,118 @@
1/*
2Copyright 2017 Alex Ong<the.onga@gmail.com>
3This program is free software: you can redistribute it and/or modify
4it under the terms of the GNU General Public License as published by
5the Free Software Foundation, either version 2 of the License, or
6(at your option) any later version.
7This program is distributed in the hope that it will be useful,
8but WITHOUT ANY WARRANTY; without even the implied warranty of
9MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10GNU General Public License for more details.
11You should have received a copy of the GNU General Public License
12along with this program. If not, see <http://www.gnu.org/licenses/>.
13*/
14
15/*
16Basic per-key algorithm. Uses an 8-bit counter per key.
17After pressing a key, it immediately changes state, and sets a counter.
18No further inputs are accepted until DEBOUNCE milliseconds have occurred.
19*/
20
21#include "matrix.h"
22#include "timer.h"
23#include "quantum.h"
24#include <stdlib.h>
25
26#ifndef DEBOUNCE
27# define DEBOUNCE 5
28#endif
29
30#define ROW_SHIFTER ((matrix_row_t)1)
31
32#define debounce_counter_t uint8_t
33
34static debounce_counter_t *debounce_counters;
35static bool counters_need_update;
36static bool matrix_need_update;
37
38#define DEBOUNCE_ELAPSED 251
39#define MAX_DEBOUNCE (DEBOUNCE_ELAPSED - 1)
40
41static uint8_t wrapping_timer_read(void) {
42 static uint16_t time = 0;
43 static uint8_t last_result = 0;
44 uint16_t new_time = timer_read();
45 uint16_t diff = new_time - time;
46 time = new_time;
47 last_result = (last_result + diff) % (MAX_DEBOUNCE + 1);
48 return last_result;
49}
50
51void update_debounce_counters(uint8_t num_rows, uint8_t current_time);
52void transfer_matrix_values(matrix_row_t raw[], matrix_row_t cooked[], uint8_t num_rows, uint8_t current_time);
53
54// we use num_rows rather than MATRIX_ROWS to support split keyboards
55void debounce_init(uint8_t num_rows) {
56 debounce_counters = (debounce_counter_t *)malloc(num_rows * MATRIX_COLS * sizeof(debounce_counter_t));
57 int i = 0;
58 for (uint8_t r = 0; r < num_rows; r++) {
59 for (uint8_t c = 0; c < MATRIX_COLS; c++) {
60 debounce_counters[i++] = DEBOUNCE_ELAPSED;
61 }
62 }
63}
64
65void debounce(matrix_row_t raw[], matrix_row_t cooked[], uint8_t num_rows, bool changed) {
66 uint8_t current_time = wrapping_timer_read();
67 if (counters_need_update) {
68 update_debounce_counters(num_rows, current_time);
69 }
70
71 if (changed || matrix_need_update) {
72 transfer_matrix_values(raw, cooked, num_rows, current_time);
73 }
74}
75
76// If the current time is > debounce counter, set the counter to enable input.
77void update_debounce_counters(uint8_t num_rows, uint8_t current_time) {
78 counters_need_update = false;
79 debounce_counter_t *debounce_pointer = debounce_counters;
80 for (uint8_t row = 0; row < num_rows; row++) {
81 for (uint8_t col = 0; col < MATRIX_COLS; col++) {
82 if (*debounce_pointer != DEBOUNCE_ELAPSED) {
83 if (TIMER_DIFF(current_time, *debounce_pointer, MAX_DEBOUNCE) >= DEBOUNCE) {
84 *debounce_pointer = DEBOUNCE_ELAPSED;
85 } else {
86 counters_need_update = true;
87 }
88 }
89 debounce_pointer++;
90 }
91 }
92}
93
94// upload from raw_matrix to final matrix;
95void transfer_matrix_values(matrix_row_t raw[], matrix_row_t cooked[], uint8_t num_rows, uint8_t current_time) {
96 matrix_need_update = false;
97 debounce_counter_t *debounce_pointer = debounce_counters;
98 for (uint8_t row = 0; row < num_rows; row++) {
99 matrix_row_t delta = raw[row] ^ cooked[row];
100 matrix_row_t existing_row = cooked[row];
101 for (uint8_t col = 0; col < MATRIX_COLS; col++) {
102 matrix_row_t col_mask = (ROW_SHIFTER << col);
103 if (delta & col_mask) {
104 if (*debounce_pointer == DEBOUNCE_ELAPSED) {
105 *debounce_pointer = current_time;
106 counters_need_update = true;
107 existing_row ^= col_mask; // flip the bit.
108 } else {
109 matrix_need_update = true;
110 }
111 }
112 debounce_pointer++;
113 }
114 cooked[row] = existing_row;
115 }
116}
117
118bool debounce_active(void) { return true; }