aboutsummaryrefslogtreecommitdiff
path: root/quantum/debounce/sym_eager_pr.c
diff options
context:
space:
mode:
Diffstat (limited to 'quantum/debounce/sym_eager_pr.c')
-rw-r--r--quantum/debounce/sym_eager_pr.c76
1 files changed, 49 insertions, 27 deletions
diff --git a/quantum/debounce/sym_eager_pr.c b/quantum/debounce/sym_eager_pr.c
index 20ccb46f1..2ad592c5a 100644
--- a/quantum/debounce/sym_eager_pr.c
+++ b/quantum/debounce/sym_eager_pr.c
@@ -1,5 +1,6 @@
1/* 1/*
2Copyright 2019 Alex Ong<the.onga@gmail.com> 2Copyright 2019 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,27 +34,25 @@ No further inputs are accepted until DEBOUNCE milliseconds have occurred.
33# define DEBOUNCE 5 34# define DEBOUNCE 5
34#endif 35#endif
35 36
36#define debounce_counter_t uint8_t 37// Maximum debounce: 255ms
38#if DEBOUNCE > UINT8_MAX
39# undef DEBOUNCE
40# define DEBOUNCE UINT8_MAX
41#endif
42
43typedef uint8_t debounce_counter_t;
44
45#if DEBOUNCE > 0
37static bool matrix_need_update; 46static bool matrix_need_update;
38 47
39static debounce_counter_t *debounce_counters; 48static debounce_counter_t *debounce_counters;
49static fast_timer_t last_time;
40static bool counters_need_update; 50static bool counters_need_update;
41 51
42#define DEBOUNCE_ELAPSED 251 52#define DEBOUNCE_ELAPSED 0
43#define MAX_DEBOUNCE (DEBOUNCE_ELAPSED - 1)
44
45static uint8_t wrapping_timer_read(void) {
46 static uint16_t time = 0;
47 static uint8_t last_result = 0;
48 uint16_t new_time = timer_read();
49 uint16_t diff = new_time - time;
50 time = new_time;
51 last_result = (last_result + diff) % (MAX_DEBOUNCE + 1);
52 return last_result;
53}
54 53
55void update_debounce_counters(uint8_t num_rows, uint8_t current_time); 54static void update_debounce_counters(uint8_t num_rows, uint8_t elapsed_time);
56void transfer_matrix_values(matrix_row_t raw[], matrix_row_t cooked[], uint8_t num_rows, uint8_t current_time); 55static void transfer_matrix_values(matrix_row_t raw[], matrix_row_t cooked[], uint8_t num_rows);
57 56
58// 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
59void debounce_init(uint8_t num_rows) { 58void debounce_init(uint8_t num_rows) {
@@ -63,27 +62,50 @@ void debounce_init(uint8_t num_rows) {
63 } 62 }
64} 63}
65 64
65void debounce_free(void) {
66 free(debounce_counters);
67 debounce_counters = NULL;
68}
69
66void debounce(matrix_row_t raw[], matrix_row_t cooked[], uint8_t num_rows, bool changed) { 70void debounce(matrix_row_t raw[], matrix_row_t cooked[], uint8_t num_rows, bool changed) {
67 uint8_t current_time = wrapping_timer_read(); 71 bool updated_last = false;
68 bool needed_update = counters_need_update; 72
69 if (counters_need_update) { 73 if (counters_need_update) {
70 update_debounce_counters(num_rows, current_time); 74 fast_timer_t now = timer_read_fast();
75 fast_timer_t elapsed_time = TIMER_DIFF_FAST(now, last_time);
76
77 last_time = now;
78 updated_last = true;
79 if (elapsed_time > UINT8_MAX) {
80 elapsed_time = UINT8_MAX;
81 }
82
83 if (elapsed_time > 0) {
84 update_debounce_counters(num_rows, elapsed_time);
85 }
71 } 86 }
72 87
73 if (changed || (needed_update && !counters_need_update) || matrix_need_update) { 88 if (changed || matrix_need_update) {
74 transfer_matrix_values(raw, cooked, num_rows, current_time); 89 if (!updated_last) {
90 last_time = timer_read_fast();
91 }
92
93 transfer_matrix_values(raw, cooked, num_rows);
75 } 94 }
76} 95}
77 96
78// If the current time is > debounce counter, set the counter to enable input. 97// If the current time is > debounce counter, set the counter to enable input.
79void update_debounce_counters(uint8_t num_rows, uint8_t current_time) { 98static void update_debounce_counters(uint8_t num_rows, uint8_t elapsed_time) {
80 counters_need_update = false; 99 counters_need_update = false;
100 matrix_need_update = false;
81 debounce_counter_t *debounce_pointer = debounce_counters; 101 debounce_counter_t *debounce_pointer = debounce_counters;
82 for (uint8_t row = 0; row < num_rows; row++) { 102 for (uint8_t row = 0; row < num_rows; row++) {
83 if (*debounce_pointer != DEBOUNCE_ELAPSED) { 103 if (*debounce_pointer != DEBOUNCE_ELAPSED) {
84 if (TIMER_DIFF(current_time, *debounce_pointer, MAX_DEBOUNCE) >= DEBOUNCE) { 104 if (*debounce_pointer <= elapsed_time) {
85 *debounce_pointer = DEBOUNCE_ELAPSED; 105 *debounce_pointer = DEBOUNCE_ELAPSED;
106 matrix_need_update = true;
86 } else { 107 } else {
108 *debounce_pointer -= elapsed_time;
87 counters_need_update = true; 109 counters_need_update = true;
88 } 110 }
89 } 111 }
@@ -92,8 +114,7 @@ void update_debounce_counters(uint8_t num_rows, uint8_t current_time) {
92} 114}
93 115
94// upload from raw_matrix to final matrix; 116// 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) { 117static void transfer_matrix_values(matrix_row_t raw[], matrix_row_t cooked[], uint8_t num_rows) {
96 matrix_need_update = false;
97 debounce_counter_t *debounce_pointer = debounce_counters; 118 debounce_counter_t *debounce_pointer = debounce_counters;
98 for (uint8_t row = 0; row < num_rows; row++) { 119 for (uint8_t row = 0; row < num_rows; row++) {
99 matrix_row_t existing_row = cooked[row]; 120 matrix_row_t existing_row = cooked[row];
@@ -102,11 +123,9 @@ void transfer_matrix_values(matrix_row_t raw[], matrix_row_t cooked[], uint8_t n
102 // determine new value basd on debounce pointer + raw value 123 // determine new value basd on debounce pointer + raw value
103 if (existing_row != raw_row) { 124 if (existing_row != raw_row) {
104 if (*debounce_pointer == DEBOUNCE_ELAPSED) { 125 if (*debounce_pointer == DEBOUNCE_ELAPSED) {
105 *debounce_pointer = current_time; 126 *debounce_pointer = DEBOUNCE;
106 cooked[row] = raw_row; 127 cooked[row] = raw_row;
107 counters_need_update = true; 128 counters_need_update = true;
108 } else {
109 matrix_need_update = true;
110 } 129 }
111 } 130 }
112 debounce_pointer++; 131 debounce_pointer++;
@@ -114,3 +133,6 @@ void transfer_matrix_values(matrix_row_t raw[], matrix_row_t cooked[], uint8_t n
114} 133}
115 134
116bool debounce_active(void) { return true; } 135bool debounce_active(void) { return true; }
136#else
137# include "none.c"
138#endif