summaryrefslogtreecommitdiffstats
path: root/quantum
diff options
context:
space:
mode:
Diffstat (limited to 'quantum')
-rw-r--r--quantum/crc.c59
-rw-r--r--quantum/crc.h44
-rw-r--r--quantum/debounce.h2
-rw-r--r--quantum/debounce/asym_eager_defer_pk.c171
-rw-r--r--quantum/debounce/none.c31
-rw-r--r--quantum/debounce/sym_defer_g.c26
-rw-r--r--quantum/debounce/sym_defer_pk.c67
-rw-r--r--quantum/debounce/sym_eager_pk.c72
-rw-r--r--quantum/debounce/sym_eager_pr.c76
-rw-r--r--quantum/debounce/tests/asym_eager_defer_pk_tests.cpp374
-rw-r--r--quantum/debounce/tests/debounce_test_common.cpp229
-rw-r--r--quantum/debounce/tests/debounce_test_common.h83
-rw-r--r--quantum/debounce/tests/rules.mk44
-rw-r--r--quantum/debounce/tests/sym_defer_g_tests.cpp223
-rw-r--r--quantum/debounce/tests/sym_defer_pk_tests.cpp225
-rw-r--r--quantum/debounce/tests/sym_eager_pk_tests.cpp237
-rw-r--r--quantum/debounce/tests/sym_eager_pr_tests.cpp280
-rw-r--r--quantum/debounce/tests/testlist.mk6
-rw-r--r--quantum/led_matrix.c34
-rw-r--r--quantum/matrix.c79
-rw-r--r--quantum/quantum.h4
-rw-r--r--quantum/rgb_matrix.c34
-rw-r--r--quantum/rgb_matrix.h2
-rw-r--r--quantum/rgb_matrix_animations/jellybean_raindrops_anim.h2
-rw-r--r--quantum/rgb_matrix_drivers.c16
-rw-r--r--quantum/serial_link/system/serial_link.c22
-rw-r--r--quantum/split_common/matrix.c83
-rw-r--r--quantum/split_common/post_config.h9
-rw-r--r--quantum/split_common/transaction_id_define.h94
-rw-r--r--quantum/split_common/transactions.c670
-rw-r--r--quantum/split_common/transactions.h54
-rw-r--r--quantum/split_common/transport.c484
-rw-r--r--quantum/split_common/transport.h165
33 files changed, 3371 insertions, 630 deletions
diff --git a/quantum/crc.c b/quantum/crc.c
new file mode 100644
index 0000000000..0d8b9d6017
--- /dev/null
+++ b/quantum/crc.c
@@ -0,0 +1,59 @@
+/* Copyright 2021 QMK
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "crc.h"
+
+__attribute__((weak)) void crc_init(void){
+ /* Software implementation nothing todo here. */
+};
+
+#if defined(CRC8_USE_TABLE)
+/**
+ * Static table used for the table_driven implementation.
+ */
+static const crc_t crc_table[256] = {0x00, 0x07, 0x0e, 0x09, 0x1c, 0x1b, 0x12, 0x15, 0x38, 0x3f, 0x36, 0x31, 0x24, 0x23, 0x2a, 0x2d, 0x70, 0x77, 0x7e, 0x79, 0x6c, 0x6b, 0x62, 0x65, 0x48, 0x4f, 0x46, 0x41, 0x54, 0x53, 0x5a, 0x5d, 0xe0, 0xe7, 0xee, 0xe9, 0xfc, 0xfb, 0xf2, 0xf5, 0xd8, 0xdf, 0xd6, 0xd1, 0xc4, 0xc3, 0xca, 0xcd, 0x90, 0x97, 0x9e, 0x99, 0x8c, 0x8b, 0x82, 0x85, 0xa8, 0xaf, 0xa6, 0xa1, 0xb4, 0xb3, 0xba, 0xbd, 0xc7, 0xc0, 0xc9, 0xce, 0xdb, 0xdc, 0xd5, 0xd2, 0xff, 0xf8, 0xf1, 0xf6, 0xe3, 0xe4, 0xed, 0xea, 0xb7, 0xb0, 0xb9, 0xbe, 0xab, 0xac, 0xa5, 0xa2, 0x8f, 0x88, 0x81, 0x86, 0x93, 0x94, 0x9d, 0x9a, 0x27, 0x20, 0x29, 0x2e, 0x3b, 0x3c, 0x35, 0x32, 0x1f, 0x18, 0x11, 0x16, 0x03, 0x04, 0x0d, 0x0a, 0x57, 0x50, 0x59, 0x5e, 0x4b, 0x4c, 0x45, 0x42, 0x6f, 0x68, 0x61, 0x66, 0x73, 0x74, 0x7d, 0x7a,
+ 0x89, 0x8e, 0x87, 0x80, 0x95, 0x92, 0x9b, 0x9c, 0xb1, 0xb6, 0xbf, 0xb8, 0xad, 0xaa, 0xa3, 0xa4, 0xf9, 0xfe, 0xf7, 0xf0, 0xe5, 0xe2, 0xeb, 0xec, 0xc1, 0xc6, 0xcf, 0xc8, 0xdd, 0xda, 0xd3, 0xd4, 0x69, 0x6e, 0x67, 0x60, 0x75, 0x72, 0x7b, 0x7c, 0x51, 0x56, 0x5f, 0x58, 0x4d, 0x4a, 0x43, 0x44, 0x19, 0x1e, 0x17, 0x10, 0x05, 0x02, 0x0b, 0x0c, 0x21, 0x26, 0x2f, 0x28, 0x3d, 0x3a, 0x33, 0x34, 0x4e, 0x49, 0x40, 0x47, 0x52, 0x55, 0x5c, 0x5b, 0x76, 0x71, 0x78, 0x7f, 0x6a, 0x6d, 0x64, 0x63, 0x3e, 0x39, 0x30, 0x37, 0x22, 0x25, 0x2c, 0x2b, 0x06, 0x01, 0x08, 0x0f, 0x1a, 0x1d, 0x14, 0x13, 0xae, 0xa9, 0xa0, 0xa7, 0xb2, 0xb5, 0xbc, 0xbb, 0x96, 0x91, 0x98, 0x9f, 0x8a, 0x8d, 0x84, 0x83, 0xde, 0xd9, 0xd0, 0xd7, 0xc2, 0xc5, 0xcc, 0xcb, 0xe6, 0xe1, 0xe8, 0xef, 0xfa, 0xfd, 0xf4, 0xf3};
+
+__attribute__((weak)) uint8_t crc8(const void *data, size_t data_len) {
+ const uint8_t *d = (const uint8_t *)data;
+ crc_t crc = 0xff;
+ size_t tbl_idx;
+
+ while (data_len--) {
+ tbl_idx = crc ^ *d;
+ crc = crc_table[tbl_idx] & 0xff;
+ d++;
+ }
+ return crc & 0xff;
+}
+#else
+__attribute__((weak)) uint8_t crc8(const void *data, size_t data_len) {
+ const uint8_t *d = (const uint8_t *)data;
+ crc_t crc = 0xff;
+ size_t i, j;
+
+ for (i = 0; i < data_len; i++) {
+ crc ^= d[i];
+ for (j = 0; j < 8; j++) {
+ if ((crc & 0x80) != 0)
+ crc = (crc_t)((crc << 1) ^ 0x31);
+ else
+ crc <<= 1;
+ }
+ }
+ return crc;
+}
+#endif \ No newline at end of file
diff --git a/quantum/crc.h b/quantum/crc.h
new file mode 100644
index 0000000000..c17f5888e2
--- /dev/null
+++ b/quantum/crc.h
@@ -0,0 +1,44 @@
+/* Copyright 2021 QMK
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#pragma once
+
+#include "quantum.h"
+
+/**
+ * The type of the CRC values.
+ *
+ * This type must be big enough to contain at least 8 bits.
+ */
+#if defined(CRC8_OPTIMIZE_SPEED)
+typedef uint_fast8_t crc_t;
+#else
+typedef uint_least8_t crc_t;
+#endif
+
+/**
+ * Initialize crc subsystem.
+ */
+__attribute__((weak)) void crc_init(void);
+
+/**
+ * Generate CRC8 value from given data.
+ *
+ * \param[in] data Pointer to a buffer of \a data_len bytes.
+ * \param[in] data_len Number of bytes in the \a data buffer.
+ * \return The calculated crc value.
+ */
+__attribute__((weak)) uint8_t crc8(const void *data, size_t data_len); \ No newline at end of file
diff --git a/quantum/debounce.h b/quantum/debounce.h
index 9ca05c6824..5043868289 100644
--- a/quantum/debounce.h
+++ b/quantum/debounce.h
@@ -9,3 +9,5 @@ void debounce(matrix_row_t raw[], matrix_row_t cooked[], uint8_t num_rows, bool
bool debounce_active(void);
void debounce_init(uint8_t num_rows);
+
+void debounce_free(void);
diff --git a/quantum/debounce/asym_eager_defer_pk.c b/quantum/debounce/asym_eager_defer_pk.c
new file mode 100644
index 0000000000..24380dc5e5
--- /dev/null
+++ b/quantum/debounce/asym_eager_defer_pk.c
@@ -0,0 +1,171 @@
+/*
+ * Copyright 2017 Alex Ong <the.onga@gmail.com>
+ * Copyright 2020 Andrei Purdea <andrei@purdea.ro>
+ * Copyright 2021 Simon Arlott
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+Basic symmetric per-key algorithm. Uses an 8-bit counter per key.
+When no state changes have occured for DEBOUNCE milliseconds, we push the state.
+*/
+
+#include "matrix.h"
+#include "timer.h"
+#include "quantum.h"
+#include <stdlib.h>
+
+#ifdef PROTOCOL_CHIBIOS
+# if CH_CFG_USE_MEMCORE == FALSE
+# error ChibiOS is configured without a memory allocator. Your keyboard may have set `#define CH_CFG_USE_MEMCORE FALSE`, which is incompatible with this debounce algorithm.
+# endif
+#endif
+
+#ifndef DEBOUNCE
+# define DEBOUNCE 5
+#endif
+
+// Maximum debounce: 127ms
+#if DEBOUNCE > 127
+# undef DEBOUNCE
+# define DEBOUNCE 127
+#endif
+
+#define ROW_SHIFTER ((matrix_row_t)1)
+
+typedef struct {
+ bool pressed : 1;
+ uint8_t time : 7;
+} debounce_counter_t;
+
+#if DEBOUNCE > 0
+static debounce_counter_t *debounce_counters;
+static fast_timer_t last_time;
+static bool counters_need_update;
+static bool matrix_need_update;
+
+#define DEBOUNCE_ELAPSED 0
+
+static void update_debounce_counters_and_transfer_if_expired(matrix_row_t raw[], matrix_row_t cooked[], uint8_t num_rows, uint8_t elapsed_time);
+static void transfer_matrix_values(matrix_row_t raw[], matrix_row_t cooked[], uint8_t num_rows);
+
+// we use num_rows rather than MATRIX_ROWS to support split keyboards
+void debounce_init(uint8_t num_rows) {
+ debounce_counters = malloc(num_rows * MATRIX_COLS * sizeof(debounce_counter_t));
+ int i = 0;
+ for (uint8_t r = 0; r < num_rows; r++) {
+ for (uint8_t c = 0; c < MATRIX_COLS; c++) {
+ debounce_counters[i++].time = DEBOUNCE_ELAPSED;
+ }
+ }
+}
+
+void debounce_free(void) {
+ free(debounce_counters);
+ debounce_counters = NULL;
+}
+
+void debounce(matrix_row_t raw[], matrix_row_t cooked[], uint8_t num_rows, bool changed) {
+ bool updated_last = false;
+
+ if (counters_need_update) {
+ fast_timer_t now = timer_read_fast();
+ fast_timer_t elapsed_time = TIMER_DIFF_FAST(now, last_time);
+
+ last_time = now;
+ updated_last = true;
+ if (elapsed_time > UINT8_MAX) {
+ elapsed_time = UINT8_MAX;
+ }
+
+ if (elapsed_time > 0) {
+ update_debounce_counters_and_transfer_if_expired(raw, cooked, num_rows, elapsed_time);
+ }
+ }
+
+ if (changed || matrix_need_update) {
+ if (!updated_last) {
+ last_time = timer_read_fast();
+ }
+
+ transfer_matrix_values(raw, cooked, num_rows);
+ }
+}
+
+static void update_debounce_counters_and_transfer_if_expired(matrix_row_t raw[], matrix_row_t cooked[], uint8_t num_rows, uint8_t elapsed_time) {
+ debounce_counter_t *debounce_pointer = debounce_counters;
+
+ counters_need_update = false;
+ matrix_need_update = false;
+
+ for (uint8_t row = 0; row < num_rows; row++) {
+ for (uint8_t col = 0; col < MATRIX_COLS; col++) {
+ matrix_row_t col_mask = (ROW_SHIFTER << col);
+
+ if (debounce_pointer->time != DEBOUNCE_ELAPSED) {
+ if (debounce_pointer->time <= elapsed_time) {
+ debounce_pointer->time = DEBOUNCE_ELAPSED;
+
+ if (debounce_pointer->pressed) {
+ // key-down: eager
+ matrix_need_update = true;
+ } else {
+ // key-up: defer
+ cooked[row] = (cooked[row] & ~col_mask) | (raw[row] & col_mask);
+ }
+ } else {
+ debounce_pointer->time -= elapsed_time;
+ counters_need_update = true;
+ }
+ }
+ debounce_pointer++;
+ }
+ }
+}
+
+static void transfer_matrix_values(matrix_row_t raw[], matrix_row_t cooked[], uint8_t num_rows) {
+ debounce_counter_t *debounce_pointer = debounce_counters;
+
+ for (uint8_t row = 0; row < num_rows; row++) {
+ matrix_row_t delta = raw[row] ^ cooked[row];
+ for (uint8_t col = 0; col < MATRIX_COLS; col++) {
+ matrix_row_t col_mask = (ROW_SHIFTER << col);
+
+ if (delta & col_mask) {
+ if (debounce_pointer->time == DEBOUNCE_ELAPSED) {
+ debounce_pointer->pressed = (raw[row] & col_mask);
+ debounce_pointer->time = DEBOUNCE;
+ counters_need_update = true;
+
+ if (debounce_pointer->pressed) {
+ // key-down: eager
+ cooked[row] ^= col_mask;
+ }
+ }
+ } else if (debounce_pointer->time != DEBOUNCE_ELAPSED) {
+ if (!debounce_pointer->pressed) {
+ // key-up: defer
+ debounce_pointer->time = DEBOUNCE_ELAPSED;
+ }
+ }
+ debounce_pointer++;
+ }
+ }
+}
+
+bool debounce_active(void) { return true; }
+#else
+# include "none.c"
+#endif
diff --git a/quantum/debounce/none.c b/quantum/debounce/none.c
new file mode 100644
index 0000000000..b03892bc5b
--- /dev/null
+++ b/quantum/debounce/none.c
@@ -0,0 +1,31 @@
+/* Copyright 2021 Simon Arlott
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "matrix.h"
+#include "quantum.h"
+#include <stdlib.h>
+
+void debounce_init(uint8_t num_rows) {}
+
+void debounce(matrix_row_t raw[], matrix_row_t cooked[], uint8_t num_rows, bool changed) {
+ for (int i = 0; i < num_rows; i++) {
+ cooked[i] = raw[i];
+ }
+}
+
+bool debounce_active(void) { return false; }
+
+void debounce_free(void) {}
diff --git a/quantum/debounce/sym_defer_g.c b/quantum/debounce/sym_defer_g.c
index 3ed9055d2a..fbefd55ede 100644
--- a/quantum/debounce/sym_defer_g.c
+++ b/quantum/debounce/sym_defer_g.c
@@ -1,5 +1,6 @@
/*
Copyright 2017 Alex Ong<the.onga@gmail.com>
+Copyright 2021 Simon Arlott
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
@@ -23,30 +24,29 @@ When no state changes have occured for DEBOUNCE milliseconds, we push the state.
# define DEBOUNCE 5
#endif
-void debounce_init(uint8_t num_rows) {}
+#if DEBOUNCE > 0
static bool debouncing = false;
+static fast_timer_t debouncing_time;
-#if DEBOUNCE > 0
-static uint16_t debouncing_time;
-void debounce(matrix_row_t raw[], matrix_row_t cooked[], uint8_t num_rows, bool changed) {
+void debounce_init(uint8_t num_rows) {}
+
+void debounce(matrix_row_t raw[], matrix_row_t cooked[], uint8_t num_rows, bool changed) {
if (changed) {
debouncing = true;
- debouncing_time = timer_read();
+ debouncing_time = timer_read_fast();
}
- if (debouncing && timer_elapsed(debouncing_time) > DEBOUNCE) {
+ if (debouncing && timer_elapsed_fast(debouncing_time) >= DEBOUNCE) {
for (int i = 0; i < num_rows; i++) {
cooked[i] = raw[i];
}
debouncing = false;
}
}
-#else // no debouncing.
-void debounce(matrix_row_t raw[], matrix_row_t cooked[], uint8_t num_rows, bool changed) {
- for (int i = 0; i < num_rows; i++) {
- cooked[i] = raw[i];
- }
-}
-#endif
bool debounce_active(void) { return debouncing; }
+
+void debounce_free(void) {}
+#else // no debouncing.
+# include "none.c"
+#endif
diff --git a/quantum/debounce/sym_defer_pk.c b/quantum/debounce/sym_defer_pk.c
index 60513f98e1..626a9be841 100644
--- a/quantum/debounce/sym_defer_pk.c
+++ b/quantum/debounce/sym_defer_pk.c
@@ -1,6 +1,7 @@
/*
Copyright 2017 Alex Ong<the.onga@gmail.com>
Copyright 2020 Andrei Purdea<andrei@purdea.ro>
+Copyright 2021 Simon Arlott
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the 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.
# define DEBOUNCE 5
#endif
+// Maximum debounce: 255ms
+#if DEBOUNCE > UINT8_MAX
+# undef DEBOUNCE
+# define DEBOUNCE UINT8_MAX
+#endif
+
#define ROW_SHIFTER ((matrix_row_t)1)
-#define debounce_counter_t uint8_t
+typedef uint8_t debounce_counter_t;
+#if DEBOUNCE > 0
static debounce_counter_t *debounce_counters;
+static fast_timer_t last_time;
static bool counters_need_update;
-#define DEBOUNCE_ELAPSED 251
-#define MAX_DEBOUNCE (DEBOUNCE_ELAPSED - 1)
-
-static uint8_t wrapping_timer_read(void) {
- static uint16_t time = 0;
- static uint8_t last_result = 0;
- uint16_t new_time = timer_read();
- uint16_t diff = new_time - time;
- time = new_time;
- last_result = (last_result + diff) % (MAX_DEBOUNCE + 1);
- return last_result;
-}
+#define DEBOUNCE_ELAPSED 0
-void update_debounce_counters_and_transfer_if_expired(matrix_row_t raw[], matrix_row_t cooked[], uint8_t num_rows, uint8_t current_time);
-void start_debounce_counters(matrix_row_t raw[], matrix_row_t cooked[], uint8_t num_rows, uint8_t current_time);
+static void update_debounce_counters_and_transfer_if_expired(matrix_row_t raw[], matrix_row_t cooked[], uint8_t num_rows, uint8_t elapsed_time);
+static void start_debounce_counters(matrix_row_t raw[], matrix_row_t cooked[], uint8_t num_rows);
// we use num_rows rather than MATRIX_ROWS to support split keyboards
void debounce_init(uint8_t num_rows) {
@@ -67,27 +65,49 @@ void debounce_init(uint8_t num_rows) {
}
}
+void debounce_free(void) {
+ free(debounce_counters);
+ debounce_counters = NULL;
+}
+
void debounce(matrix_row_t raw[], matrix_row_t cooked[], uint8_t num_rows, bool changed) {
- uint8_t current_time = wrapping_timer_read();
+ bool updated_last = false;
+
if (counters_need_update) {
- update_debounce_counters_and_transfer_if_expired(raw, cooked, num_rows, current_time);
+ fast_timer_t now = timer_read_fast();
+ fast_timer_t elapsed_time = TIMER_DIFF_FAST(now, last_time);
+
+ last_time = now;
+ updated_last = true;
+ if (elapsed_time > UINT8_MAX) {
+ elapsed_time = UINT8_MAX;
+ }
+
+ if (elapsed_time > 0) {
+ update_debounce_counters_and_transfer_if_expired(raw, cooked, num_rows, elapsed_time);
+ }
}
if (changed) {
- start_debounce_counters(raw, cooked, num_rows, current_time);
+ if (!updated_last) {
+ last_time = timer_read_fast();
+ }
+
+ start_debounce_counters(raw, cooked, num_rows);
}
}
-void update_debounce_counters_and_transfer_if_expired(matrix_row_t raw[], matrix_row_t cooked[], uint8_t num_rows, uint8_t current_time) {
+static void update_debounce_counters_and_transfer_if_expired(matrix_row_t raw[], matrix_row_t cooked[], uint8_t num_rows, uint8_t elapsed_time) {
counters_need_update = false;
debounce_counter_t *debounce_pointer = debounce_counters;
for (uint8_t row = 0; row < num_rows; row++) {
for (uint8_t col = 0; col < MATRIX_COLS; col++) {
if (*debounce_pointer != DEBOUNCE_ELAPSED) {
- if (TIMER_DIFF(current_time, *debounce_pointer, MAX_DEBOUNCE) >= DEBOUNCE) {
+ if (*debounce_pointer <= elapsed_time) {
*debounce_pointer = DEBOUNCE_ELAPSED;
cooked[row] = (cooked[row] & ~(ROW_SHIFTER << col)) | (raw[row] & (ROW_SHIFTER << col));
} else {
+ *debounce_pointer -= elapsed_time;
counters_need_update = true;
}
}
@@ -96,14 +116,14 @@ void update_debounce_counters_and_transfer_if_expired(matrix_row_t raw[], matrix
}
}
-void start_debounce_counters(matrix_row_t raw[], matrix_row_t cooked[], uint8_t num_rows, uint8_t current_time) {
+static void start_debounce_counters(matrix_row_t raw[], matrix_row_t cooked[], uint8_t num_rows) {
debounce_counter_t *debounce_pointer = debounce_counters;
for (uint8_t row = 0; row < num_rows; row++) {
matrix_row_t delta = raw[row] ^ cooked[row];
for (uint8_t col = 0; col < MATRIX_COLS; col++) {
if (delta & (ROW_SHIFTER << col)) {
if (*debounce_pointer == DEBOUNCE_ELAPSED) {
- *debounce_pointer = current_time;
+ *debounce_pointer = DEBOUNCE;
counters_need_update = true;
}
} else {
@@ -115,3 +135,6 @@ void start_debounce_counters(matrix_row_t raw[], matrix_row_t cooked[], uint8_t
}
bool debounce_active(void) { return true; }
+#else
+# include "none.c"
+#endif
diff --git a/quantum/debounce/sym_eager_pk.c b/quantum/debounce/sym_eager_pk.c
index e66cf92d79..15a3242e68 100644
--- a/quantum/debounce/sym_eager_pk.c
+++ b/quantum/debounce/sym_eager_pk.c
@@ -1,5 +1,6 @@
/*
Copyright 2017 Alex Ong<the.onga@gmail.com>
+Copyright 2021 Simon Arlott
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
@@ -33,29 +34,26 @@ No further inputs are accepted until DEBOUNCE milliseconds have occurred.
# define DEBOUNCE 5
#endif
+// Maximum debounce: 255ms
+#if DEBOUNCE > UINT8_MAX
+# undef DEBOUNCE
+# define DEBOUNCE UINT8_MAX
+#endif
+
#define ROW_SHIFTER ((matrix_row_t)1)
-#define debounce_counter_t uint8_t
+typedef uint8_t debounce_counter_t;
+#if DEBOUNCE > 0
static debounce_counter_t *debounce_counters;
+static fast_timer_t last_time;
static bool counters_need_update;
static bool matrix_need_update;
-#define DEBOUNCE_ELAPSED 251
-#define MAX_DEBOUNCE (DEBOUNCE_ELAPSED - 1)
-
-static uint8_t wrapping_timer_read(void) {
- static uint16_t time = 0;
- static uint8_t last_result = 0;
- uint16_t new_time = timer_read();
- uint16_t diff = new_time - time;
- time = new_time;
- last_result = (last_result + diff) % (MAX_DEBOUNCE + 1);
- return last_result;
-}
+#define DEBOUNCE_ELAPSED 0
-void update_debounce_counters(uint8_t num_rows, uint8_t current_time);
-void transfer_matrix_values(matrix_row_t raw[], matrix_row_t cooked[], uint8_t num_rows, uint8_t current_time);
+static void update_debounce_counters(uint8_t num_rows, uint8_t elapsed_time);
+static void transfer_matrix_values(matrix_row_t raw[], matrix_row_t cooked[], uint8_t num_rows);
// we use num_rows rather than MATRIX_ROWS to support split keyboards
void debounce_init(uint8_t num_rows) {
@@ -68,27 +66,51 @@ void debounce_init(uint8_t num_rows) {
}
}
+void debounce_free(void) {
+ free(debounce_counters);
+ debounce_counters = NULL;
+}
+
void debounce(matrix_row_t raw[], matrix_row_t cooked[], uint8_t num_rows, bool changed) {
- uint8_t current_time = wrapping_timer_read();
+ bool updated_last = false;
+
if (counters_need_update) {
- update_debounce_counters(num_rows, current_time);
+ fast_timer_t now = timer_read_fast();
+ fast_timer_t elapsed_time = TIMER_DIFF_FAST(now, last_time);
+
+ last_time = now;
+ updated_last = true;
+ if (elapsed_time > UINT8_MAX) {
+ elapsed_time = UINT8_MAX;
+ }
+
+ if (elapsed_time > 0) {
+ update_debounce_counters(num_rows, elapsed_time);
+ }
}
if (changed || matrix_need_update) {
- transfer_matrix_values(raw, cooked, num_rows, current_time);
+ if (!updated_last) {
+ last_time = timer_read_fast();
+ }
+
+ transfer_matrix_values(raw, cooked, num_rows);
}
}
// If the current time is > debounce counter, set the counter to enable input.
-void update_debounce_counters(uint8_t num_rows, uint8_t current_time) {
+static void update_debounce_counters(uint8_t num_rows, uint8_t elapsed_time) {
counters_need_update = false;
+ matrix_need_update = false;
debounce_counter_t *debounce_pointer = debounce_counters;
for (uint8_t row = 0; row < num_rows; row++) {
for (uint8_t col = 0; col < MATRIX_COLS; col++) {
if (*debounce_pointer != DEBOUNCE_ELAPSED) {
- if (TIMER_DIFF(current_time, *debounce_pointer, MAX_DEBOUNCE) >= DEBOUNCE) {
+ if (*debounce_pointer <= elapsed_time) {
*debounce_pointer = DEBOUNCE_ELAPSED;
+ matrix_need_update = true;
} else {
+ *debounce_pointer -= elapsed_time;
counters_need_update = true;
}
}
@@ -98,8 +120,7 @@ void update_debounce_counters(uint8_t num_rows, uint8_t current_time) {
}
// upload from raw_matrix to final matrix;
-void transfer_matrix_values(matrix_row_t raw[], matrix_row_t cooked[], uint8_t num_rows, uint8_t current_time) {
- matrix_need_update = false;
+static void transfer_matrix_values(matrix_row_t raw[], matrix_row_t cooked[], uint8_t num_rows) {
debounce_counter_t *debounce_pointer = debounce_counters;
for (uint8_t row = 0; row < num_rows; row++) {
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
matrix_row_t col_mask = (ROW_SHIFTER << col);
if (delta & col_mask) {
if (*debounce_pointer == DEBOUNCE_ELAPSED) {
- *debounce_pointer = current_time;
+ *debounce_pointer = DEBOUNCE;
counters_need_update = true;
existing_row ^= col_mask; // flip the bit.
- } else {
- matrix_need_update = true;
}
}
debounce_pointer++;
@@ -122,3 +141,6 @@ void transfer_matrix_values(matrix_row_t raw[], matrix_row_t cooked[], uint8_t n
}
bool debounce_active(void) { return true; }
+#else
+# include "none.c"
+#endif
diff --git a/quantum/debounce/sym_eager_pr.c b/quantum/debounce/sym_eager_pr.c
index 20ccb46f1d..2ad592c5a6 100644
--- a/quantum/debounce/sym_eager_pr.c
+++ b/quantum/debounce/sym_eager_pr.c
@@ -1,5 +1,6 @@
/*
Copyright 2019 Alex Ong<the.onga@gmail.com>
+Copyright 2021 Simon Arlott
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
@@ -33,27 +34,25 @@ No further inputs are accepted until DEBOUNCE milliseconds have occurred.
# define DEBOUNCE 5
#endif
-#define debounce_counter_t uint8_t
+// Maximum debounce: 255ms
+#if DEBOUNCE > UINT8_MAX
+# undef DEBOUNCE
+# define DEBOUNCE UINT8_MAX
+#endif
+
+typedef uint8_t debounce_counter_t;
+
+#if DEBOUNCE > 0
static bool matrix_need_update;
static debounce_counter_t *debounce_counters;
+static fast_timer_t last_time;
static bool counters_need_update;
-#define DEBOUNCE_ELAPSED 251
-#define MAX_DEBOUNCE (DEBOUNCE_ELAPSED - 1)
-
-static uint8_t wrapping_timer_read(void) {
- static uint16_t time = 0;
- static uint8_t last_result = 0;
- uint16_t new_time = timer_read();
- uint16_t diff = new_time - time;
- time = new_time;
- last_result = (last_result + diff) % (MAX_DEBOUNCE + 1);
- return last_result;
-}
+#define DEBOUNCE_ELAPSED 0
-void update_debounce_counters(uint8_t num_rows, uint8_t current_time);
-void transfer_matrix_values(matrix_row_t raw[], matrix_row_t cooked[], uint8_t num_rows, uint8_t current_time);
+static void update_debounce_counters(uint8_t num_rows, uint8_t elapsed_time);
+static void transfer_matrix_values(matrix_row_t raw[], matrix_row_t cooked[], uint8_t num_rows);
// we use num_rows rather than MATRIX_ROWS to support split keyboards
void debounce_init(uint8_t num_rows) {
@@ -63,27 +62,50 @@ void debounce_init(uint8_t num_rows) {
}
}
+void debounce_free(void) {
+ free(debounce_counters);
+ debounce_counters = NULL;
+}
+
void debounce(matrix_row_t raw[], matrix_row_t cooked[], uint8_t num_rows, bool changed) {
- uint8_t current_time = wrapping_timer_read();
- bool needed_update = counters_need_update;
+ bool updated_last = false;