aboutsummaryrefslogtreecommitdiff
path: root/quantum/debounce/sym_defer_pk.c
diff options
context:
space:
mode:
Diffstat (limited to 'quantum/debounce/sym_defer_pk.c')
-rw-r--r--quantum/debounce/sym_defer_pk.c67
1 files changed, 45 insertions, 22 deletions
diff --git a/quantum/debounce/sym_defer_pk.c b/quantum/debounce/sym_defer_pk.c
index 60513f98e..626a9be84 100644
--- a/quantum/debounce/sym_defer_pk.c
+++ b/quantum/debounce/sym_defer_pk.c
@@ -1,6 +1,7 @@
1/* 1/*
2Copyright 2017 Alex Ong<the.onga@gmail.com> 2Copyright 2017 Alex Ong<the.onga@gmail.com>
3Copyright 2020 Andrei Purdea<andrei@purdea.ro> 3Copyright 2020 Andrei Purdea<andrei@purdea.ro>
4Copyright 2021 Simon Arlott
4This program is free software: you can redistribute it and/or modify 5This program is free software: you can redistribute it and/or modify
5it under the terms of the GNU General Public License as published by 6it under the terms of the GNU General Public License as published by
6the Free Software Foundation, either version 2 of the License, or 7the Free Software Foundation, either version 2 of the License, or
@@ -33,28 +34,25 @@ When no state changes have occured for DEBOUNCE milliseconds, we push the state.
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;
42 51
43#define DEBOUNCE_ELAPSED 251 52#define DEBOUNCE_ELAPSED 0
44#define MAX_DEBOUNCE (DEBOUNCE_ELAPSED - 1)
45
46static uint8_t wrapping_timer_read(void) {
47 static uint16_t time = 0;
48 static uint8_t last_result = 0;
49 uint16_t new_time = timer_read();
50 uint16_t diff = new_time - time;
51 time = new_time;
52 last_result = (last_result + diff) % (MAX_DEBOUNCE + 1);
53 return last_result;
54}
55 53
56void update_debounce_counters_and_transfer_if_expired(matrix_row_t raw[], matrix_row_t cooked[], uint8_t num_rows, uint8_t current_time); 54static void update_debounce_counters_and_transfer_if_expired(matrix_row_t raw[], matrix_row_t cooked[], uint8_t num_rows, uint8_t elapsed_time);
57void start_debounce_counters(matrix_row_t raw[], matrix_row_t cooked[], uint8_t num_rows, uint8_t current_time); 55static void start_debounce_counters(matrix_row_t raw[], matrix_row_t cooked[], uint8_t num_rows);
58 56
59// we use num_rows rather than MATRIX_ROWS to support split keyboards 57// we use num_rows rather than MATRIX_ROWS to support split keyboards
60void debounce_init(uint8_t num_rows) { 58void debounce_init(uint8_t num_rows) {
@@ -67,27 +65,49 @@ void debounce_init(uint8_t num_rows) {
67 } 65 }
68} 66}
69 67
68void debounce_free(void) {
69 free(debounce_counters);
70 debounce_counters = NULL;
71}
72
70void debounce(matrix_row_t raw[], matrix_row_t cooked[], uint8_t num_rows, bool changed) { 73void debounce(matrix_row_t raw[], matrix_row_t cooked[], uint8_t num_rows, bool changed) {
71 uint8_t current_time = wrapping_timer_read(); 74 bool updated_last = false;
75
72 if (counters_need_update) { 76 if (counters_need_update) {
73 update_debounce_counters_and_transfer_if_expired(raw, cooked, num_rows, current_time); 77 fast_timer_t now = timer_read_fast();
78 fast_timer_t elapsed_time = TIMER_DIFF_FAST(now, last_time);
79
80 last_time = now;
81 updated_last = true;
82 if (elapsed_time > UINT8_MAX) {
83 elapsed_time = UINT8_MAX;
84 }
85
86 if (elapsed_time > 0) {
87 update_debounce_counters_and_transfer_if_expired(raw, cooked, num_rows, elapsed_time);
88 }
74 } 89 }
75 90
76 if (changed) { 91 if (changed) {
77 start_debounce_counters(raw, cooked, num_rows, current_time); 92 if (!updated_last) {
93 last_time = timer_read_fast();
94 }
95
96 start_debounce_counters(raw, cooked, num_rows);
78 } 97 }
79} 98}
80 99
81void update_debounce_counters_and_transfer_if_expired(matrix_row_t raw[], matrix_row_t cooked[], uint8_t num_rows, uint8_t current_time) { 100static void update_debounce_counters_and_transfer_if_expired(matrix_row_t raw[], matrix_row_t cooked[], uint8_t num_rows, uint8_t elapsed_time) {
82 counters_need_update = false; 101 counters_need_update = false;
83 debounce_counter_t *debounce_pointer = debounce_counters; 102 debounce_counter_t *debounce_pointer = debounce_counters;
84 for (uint8_t row = 0; row < num_rows; row++) { 103 for (uint8_t row = 0; row < num_rows; row++) {
85 for (uint8_t col = 0; col < MATRIX_COLS; col++) { 104 for (uint8_t col = 0; col < MATRIX_COLS; col++) {
86 if (*debounce_pointer != DEBOUNCE_ELAPSED) { 105 if (*debounce_pointer != DEBOUNCE_ELAPSED) {
87 if (TIMER_DIFF(current_time, *debounce_pointer, MAX_DEBOUNCE) >= DEBOUNCE) { 106 if (*debounce_pointer <= elapsed_time) {
88 *debounce_pointer = DEBOUNCE_ELAPSED; 107 *debounce_pointer = DEBOUNCE_ELAPSED;
89 cooked[row] = (cooked[row] & ~(ROW_SHIFTER << col)) | (raw[row] & (ROW_SHIFTER << col)); 108 cooked[row] = (cooked[row] & ~(ROW_SHIFTER << col)) | (raw[row] & (ROW_SHIFTER << col));
90 } else { 109 } else {
110 *debounce_pointer -= elapsed_time;
91 counters_need_update = true; 111 counters_need_update = true;
92 } 112 }
93 } 113 }
@@ -96,14 +116,14 @@ void update_debounce_counters_and_transfer_if_expired(matrix_row_t raw[], matrix
96 } 116 }
97} 117}
98 118
99void start_debounce_counters(matrix_row_t raw[], matrix_row_t cooked[], uint8_t num_rows, uint8_t current_time) { 119static void start_debounce_counters(matrix_row_t raw[], matrix_row_t cooked[], uint8_t num_rows) {
100 debounce_counter_t *debounce_pointer = debounce_counters; 120 debounce_counter_t *debounce_pointer = debounce_counters;
101 for (uint8_t row = 0; row < num_rows; row++) { 121 for (uint8_t row = 0; row < num_rows; row++) {
102 matrix_row_t delta = raw[row] ^ cooked[row]; 122 matrix_row_t delta = raw[row] ^ cooked[row];
103 for (uint8_t col = 0; col < MATRIX_COLS; col++) { 123 for (uint8_t col = 0; col < MATRIX_COLS; col++) {
104 if (delta & (ROW_SHIFTER << col)) { 124 if (delta & (ROW_SHIFTER << col)) {
105 if (*debounce_pointer == DEBOUNCE_ELAPSED) { 125 if (*debounce_pointer == DEBOUNCE_ELAPSED) {
106 *debounce_pointer = current_time; 126 *debounce_pointer = DEBOUNCE;
107 counters_need_update = true; 127 counters_need_update = true;
108 } 128 }
109 } else { 129 } else {
@@ -115,3 +135,6 @@ void start_debounce_counters(matrix_row_t raw[], matrix_row_t cooked[], uint8_t
115} 135}
116 136
117bool debounce_active(void) { return true; } 137bool debounce_active(void) { return true; }
138#else
139# include "none.c"
140#endif