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.c72
1 files changed, 47 insertions, 25 deletions
diff --git a/quantum/debounce/sym_eager_pk.c b/quantum/debounce/sym_eager_pk.c
index e66cf92d7..15a3242e6 100644
--- a/quantum/debounce/sym_eager_pk.c
+++ b/quantum/debounce/sym_eager_pk.c
@@ -1,5 +1,6 @@
1/* 1/*
2Copyright 2017 Alex Ong<the.onga@gmail.com> 2Copyright 2017 Alex Ong<the.onga@gmail.com>
3Copyright 2021 Simon Arlott
3This program is free software: you can redistribute it and/or modify 4This program is free software: you can redistribute it and/or modify
4it under the terms of the GNU General Public License as published by 5it under the terms of the GNU General Public License as published by
5the Free Software Foundation, either version 2 of the License, or 6the Free Software Foundation, either version 2 of the License, or
@@ -33,29 +34,26 @@ No further inputs are accepted until DEBOUNCE milliseconds have occurred.
33# define DEBOUNCE 5 34# define DEBOUNCE 5
34#endif 35#endif
35 36
37// Maximum debounce: 255ms
38#if DEBOUNCE > UINT8_MAX
39# undef DEBOUNCE
40# define DEBOUNCE UINT8_MAX
41#endif
42
36#define ROW_SHIFTER ((matrix_row_t)1) 43#define ROW_SHIFTER ((matrix_row_t)1)
37 44
38#define debounce_counter_t uint8_t 45typedef uint8_t debounce_counter_t;
39 46
47#if DEBOUNCE > 0
40static debounce_counter_t *debounce_counters; 48static debounce_counter_t *debounce_counters;
49static fast_timer_t last_time;
41static bool counters_need_update; 50static bool counters_need_update;
42static bool matrix_need_update; 51static bool matrix_need_update;
43 52
44#define DEBOUNCE_ELAPSED 251 53#define DEBOUNCE_ELAPSED 0
45#define MAX_DEBOUNCE (DEBOUNCE_ELAPSED - 1)
46
47static uint8_t wrapping_timer_read(void) {
48 static uint16_t time = 0;
49 static uint8_t last_result = 0;
50 uint16_t new_time = timer_read();
51 uint16_t diff = new_time - time;
52 time = new_time;
53 last_result = (last_result + diff) % (MAX_DEBOUNCE + 1);
54 return last_result;
55}
56 54
57void update_debounce_counters(uint8_t num_rows, uint8_t current_time); 55static void update_debounce_counters(uint8_t num_rows, uint8_t elapsed_time);
58void transfer_matrix_values(matrix_row_t raw[], matrix_row_t cooked[], uint8_t num_rows, uint8_t current_time); 56static void transfer_matrix_values(matrix_row_t raw[], matrix_row_t cooked[], uint8_t num_rows);
59 57
60// we use num_rows rather than MATRIX_ROWS to support split keyboards 58// we use num_rows rather than MATRIX_ROWS to support split keyboards
61void debounce_init(uint8_t num_rows) { 59void debounce_init(uint8_t num_rows) {
@@ -68,27 +66,51 @@ void debounce_init(uint8_t num_rows) {
68 } 66 }
69} 67}
70 68
69void debounce_free(void) {
70 free(debounce_counters);
71 debounce_counters = NULL;
72}
73
71void debounce(matrix_row_t raw[], matrix_row_t cooked[], uint8_t num_rows, bool changed) { 74void debounce(matrix_row_t raw[], matrix_row_t cooked[], uint8_t num_rows, bool changed) {
72 uint8_t current_time = wrapping_timer_read(); 75 bool updated_last = false;
76
73 if (counters_need_update) { 77 if (counters_need_update) {
74 update_debounce_counters(num_rows, current_time); 78 fast_timer_t now = timer_read_fast();
79 fast_timer_t elapsed_time = TIMER_DIFF_FAST(now, last_time);
80
81 last_time = now;
82 updated_last = true;
83 if (elapsed_time > UINT8_MAX) {
84 elapsed_time = UINT8_MAX;
85 }
86
87 if (elapsed_time > 0) {
88 update_debounce_counters(num_rows, elapsed_time);
89 }
75 } 90 }
76 91
77 if (changed || matrix_need_update) { 92 if (changed || matrix_need_update) {
78 transfer_matrix_values(raw, cooked, num_rows, current_time); 93 if (!updated_last) {
94 last_time = timer_read_fast();
95 }
96
97 transfer_matrix_values(raw, cooked, num_rows);
79 } 98 }
80} 99}
81 100
82// If the current time is > debounce counter, set the counter to enable input. 101// If the current time is > debounce counter, set the counter to enable input.
83void update_debounce_counters(uint8_t num_rows, uint8_t current_time) { 102static void update_debounce_counters(uint8_t num_rows, uint8_t elapsed_time) {
84 counters_need_update = false; 103 counters_need_update = false;
104 matrix_need_update = false;
85 debounce_counter_t *debounce_pointer = debounce_counters; 105 debounce_counter_t *debounce_pointer = debounce_counters;
86 for (uint8_t row = 0; row < num_rows; row++) { 106 for (uint8_t row = 0; row < num_rows; row++) {
87 for (uint8_t col = 0; col < MATRIX_COLS; col++) { 107 for (uint8_t col = 0; col < MATRIX_COLS; col++) {
88 if (*debounce_pointer != DEBOUNCE_ELAPSED) { 108 if (*debounce_pointer != DEBOUNCE_ELAPSED) {
89 if (TIMER_DIFF(current_time, *debounce_pointer, MAX_DEBOUNCE) >= DEBOUNCE) { 109 if (*debounce_pointer <= elapsed_time) {
90 *debounce_pointer = DEBOUNCE_ELAPSED; 110 *debounce_pointer = DEBOUNCE_ELAPSED;
111 matrix_need_update = true;
91 } else { 112 } else {
113 *debounce_pointer -= elapsed_time;
92 counters_need_update = true; 114 counters_need_update = true;
93 } 115 }
94 } 116 }
@@ -98,8 +120,7 @@ void update_debounce_counters(uint8_t num_rows, uint8_t current_time) {
98} 120}
99 121
100// upload from raw_matrix to final matrix; 122// upload from raw_matrix to final matrix;
101void transfer_matrix_values(matrix_row_t raw[], matrix_row_t cooked[], uint8_t num_rows, uint8_t current_time) { 123static void transfer_matrix_values(matrix_row_t raw[], matrix_row_t cooked[], uint8_t num_rows) {
102 matrix_need_update = false;
103 debounce_counter_t *debounce_pointer = debounce_counters; 124 debounce_counter_t *debounce_pointer = debounce_counters;
104 for (uint8_t row = 0; row < num_rows; row++) { 125 for (uint8_t row = 0; row < num_rows; row++) {
105 matrix_row_t delta = raw[row] ^ cooked[row]; 126 matrix_row_t delta = raw[row] ^ cooked[row];
@@ -108,11 +129,9 @@ void transfer_matrix_values(matrix_row_t raw[], matrix_row_t cooked[], uint8_t n
108 matrix_row_t col_mask = (ROW_SHIFTER << col); 129 matrix_row_t col_mask = (ROW_SHIFTER << col);
109 if (delta & col_mask) { 130 if (delta & col_mask) {
110 if (*debounce_pointer == DEBOUNCE_ELAPSED) { 131 if (*debounce_pointer == DEBOUNCE_ELAPSED) {
111 *debounce_pointer = current_time; 132 *debounce_pointer = DEBOUNCE;
112 counters_need_update = true; 133 counters_need_update = true;
113 existing_row ^= col_mask; // flip the bit. 134 existing_row ^= col_mask; // flip the bit.
114 } else {
115 matrix_need_update = true;
116 } 135 }
117 } 136 }
118 debounce_pointer++; 137 debounce_pointer++;
@@ -122,3 +141,6 @@ void transfer_matrix_values(matrix_row_t raw[], matrix_row_t cooked[], uint8_t n
122} 141}
123 142
124bool debounce_active(void) { return true; } 143bool debounce_active(void) { return true; }
144#else
145# include "none.c"
146#endif