diff --git a/docs/custom_matrix.md b/docs/custom_matrix.md index 8f6878f94a6c..6d6ae5e97268 100644 --- a/docs/custom_matrix.md +++ b/docs/custom_matrix.md @@ -81,17 +81,17 @@ void matrix_init(void) { } uint8_t matrix_scan(void) { - bool matrix_has_changed = false; + bool changed = false; // TODO: add matrix scanning routine here // Unless hardware debouncing - use the configured debounce routine - debounce(raw_matrix, matrix, MATRIX_ROWS, changed); + changed = debounce(raw_matrix, matrix, MATRIX_ROWS, changed); // This *must* be called for correct keyboard behavior matrix_scan_quantum(); - return matrix_has_changed; + return changed; } ``` diff --git a/docs/ja/custom_matrix.md b/docs/ja/custom_matrix.md index 277fc658d3a2..2c697bb1489f 100644 --- a/docs/ja/custom_matrix.md +++ b/docs/ja/custom_matrix.md @@ -87,17 +87,17 @@ void matrix_init(void) { } uint8_t matrix_scan(void) { - bool matrix_has_changed = false; + bool changed = false; // TODO: ここにマトリックススキャンルーチンを追加します // ハードウェアによるデバウンスがない場合 - 設定されているデバウンスルーチンを使用します - debounce(raw_matrix, matrix, MATRIX_ROWS, changed); + changed = debounce(raw_matrix, matrix, MATRIX_ROWS, changed); // 正しいキーボード動作のためにこれを呼び出す*必要があります* matrix_scan_quantum(); - return matrix_has_changed; + return changed; } ``` diff --git a/quantum/debounce.h b/quantum/debounce.h index 3532d9cd7b79..a8629654c20f 100644 --- a/quantum/debounce.h +++ b/quantum/debounce.h @@ -1,10 +1,16 @@ #pragma once -// raw is the current key state -// on entry cooked is the previous debounced state -// on exit cooked is the current debounced state -// changed is true if raw has changed since the last call -void debounce(matrix_row_t raw[], matrix_row_t cooked[], uint8_t num_rows, bool changed); +/** + * @brief Debounce raw matrix events according to the choosen debounce algorithm. + * + * @param raw The current key state + * @param cooked The debounced key state + * @param num_rows Number of rows to debounce + * @param changed True if raw has changed since the last call + * @return true Cooked has new keychanges after debouncing + * @return false Cooked is the same as before + */ +bool debounce(matrix_row_t raw[], matrix_row_t cooked[], uint8_t num_rows, bool changed); void debounce_init(uint8_t num_rows); diff --git a/quantum/debounce/asym_eager_defer_pk.c b/quantum/debounce/asym_eager_defer_pk.c index b1eb4a2b7be7..4745c6f4654f 100644 --- a/quantum/debounce/asym_eager_defer_pk.c +++ b/quantum/debounce/asym_eager_defer_pk.c @@ -55,6 +55,7 @@ static debounce_counter_t *debounce_counters; static fast_timer_t last_time; static bool counters_need_update; static bool matrix_need_update; +static bool cooked_changed; # define DEBOUNCE_ELAPSED 0 @@ -77,8 +78,9 @@ void debounce_free(void) { debounce_counters = NULL; } -void debounce(matrix_row_t raw[], matrix_row_t cooked[], uint8_t num_rows, bool changed) { +bool debounce(matrix_row_t raw[], matrix_row_t cooked[], uint8_t num_rows, bool changed) { bool updated_last = false; + cooked_changed = false; if (counters_need_update) { fast_timer_t now = timer_read_fast(); @@ -102,6 +104,8 @@ void debounce(matrix_row_t raw[], matrix_row_t cooked[], uint8_t num_rows, bool transfer_matrix_values(raw, cooked, num_rows); } + + return cooked_changed; } 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) { @@ -123,7 +127,9 @@ static void update_debounce_counters_and_transfer_if_expired(matrix_row_t raw[], matrix_need_update = true; } else { // key-up: defer - cooked[row] = (cooked[row] & ~col_mask) | (raw[row] & col_mask); + matrix_row_t cooked_next = (cooked[row] & ~col_mask) | (raw[row] & col_mask); + cooked_changed |= cooked_next ^ cooked[row]; + cooked[row] = cooked_next; } } else { debounce_pointer->time -= elapsed_time; @@ -152,6 +158,7 @@ static void transfer_matrix_values(matrix_row_t raw[], matrix_row_t cooked[], ui if (debounce_pointer->pressed) { // key-down: eager cooked[row] ^= col_mask; + cooked_changed = true; } } } else if (debounce_pointer->time != DEBOUNCE_ELAPSED) { diff --git a/quantum/debounce/none.c b/quantum/debounce/none.c index 8a85cc04a8d0..4cff5e05e260 100644 --- a/quantum/debounce/none.c +++ b/quantum/debounce/none.c @@ -17,13 +17,16 @@ #include "matrix.h" #include "quantum.h" #include +#include 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(matrix_row_t raw[], matrix_row_t cooked[], uint8_t num_rows, bool changed) { + bool cooked_changed = memcmp(raw, cooked, sizeof(matrix_row_t) * num_rows) != 0; + + memcpy(cooked, raw, sizeof(matrix_row_t) * num_rows); + + return cooked_changed; } void debounce_free(void) {} diff --git a/quantum/debounce/sym_defer_g.c b/quantum/debounce/sym_defer_g.c index 47450992a492..d04310a76151 100644 --- a/quantum/debounce/sym_defer_g.c +++ b/quantum/debounce/sym_defer_g.c @@ -20,6 +20,7 @@ When no state changes have occured for DEBOUNCE milliseconds, we push the state. #include "matrix.h" #include "timer.h" #include "quantum.h" +#include #ifndef DEBOUNCE # define DEBOUNCE 5 #endif @@ -30,18 +31,23 @@ static fast_timer_t debouncing_time; void debounce_init(uint8_t num_rows) {} -void debounce(matrix_row_t raw[], matrix_row_t cooked[], uint8_t num_rows, bool changed) { +bool debounce(matrix_row_t raw[], matrix_row_t cooked[], uint8_t num_rows, bool changed) { + bool cooked_changed = false; + if (changed) { debouncing = true; debouncing_time = timer_read_fast(); } if (debouncing && timer_elapsed_fast(debouncing_time) >= DEBOUNCE) { - for (int i = 0; i < num_rows; i++) { - cooked[i] = raw[i]; + if (memcmp(cooked, raw, sizeof(matrix_row_t) * num_rows) != 0) { + memcpy(cooked, raw, sizeof(matrix_row_t) * num_rows); + cooked_changed = true; } debouncing = false; } + + return cooked_changed; } void debounce_free(void) {} diff --git a/quantum/debounce/sym_defer_pk.c b/quantum/debounce/sym_defer_pk.c index 9dee29e28e65..7b59b5e10076 100644 --- a/quantum/debounce/sym_defer_pk.c +++ b/quantum/debounce/sym_defer_pk.c @@ -48,6 +48,7 @@ typedef uint8_t debounce_counter_t; static debounce_counter_t *debounce_counters; static fast_timer_t last_time; static bool counters_need_update; +static bool cooked_changed; # define DEBOUNCE_ELAPSED 0 @@ -70,8 +71,9 @@ void debounce_free(void) { debounce_counters = NULL; } -void debounce(matrix_row_t raw[], matrix_row_t cooked[], uint8_t num_rows, bool changed) { +bool debounce(matrix_row_t raw[], matrix_row_t cooked[], uint8_t num_rows, bool changed) { bool updated_last = false; + cooked_changed = false; if (counters_need_update) { fast_timer_t now = timer_read_fast(); @@ -95,6 +97,8 @@ void debounce(matrix_row_t raw[], matrix_row_t cooked[], uint8_t num_rows, bool start_debounce_counters(raw, cooked, num_rows); } + + return cooked_changed; } 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) { @@ -104,8 +108,10 @@ static void update_debounce_counters_and_transfer_if_expired(matrix_row_t raw[], for (uint8_t col = 0; col < MATRIX_COLS; col++) { if (*debounce_pointer != DEBOUNCE_ELAPSED) { if (*debounce_pointer <= elapsed_time) { - *debounce_pointer = DEBOUNCE_ELAPSED; - cooked[row] = (cooked[row] & ~(ROW_SHIFTER << col)) | (raw[row] & (ROW_SHIFTER << col)); + *debounce_pointer = DEBOUNCE_ELAPSED; + matrix_row_t cooked_next = (cooked[row] & ~(ROW_SHIFTER << col)) | (raw[row] & (ROW_SHIFTER << col)); + cooked_changed |= cooked[row] ^ cooked_next; + cooked[row] = cooked_next; } else { *debounce_pointer -= elapsed_time; counters_need_update = true; diff --git a/quantum/debounce/sym_defer_pr.c b/quantum/debounce/sym_defer_pr.c index ce24f0922fea..452c4599d0a7 100644 --- a/quantum/debounce/sym_defer_pr.c +++ b/quantum/debounce/sym_defer_pr.c @@ -46,11 +46,12 @@ void debounce_free(void) { last_raw = NULL; } -void debounce(matrix_row_t raw[], matrix_row_t cooked[], uint8_t num_rows, bool changed) { - uint16_t now = timer_read(); - uint16_t elapsed16 = TIMER_DIFF_16(now, last_time); - last_time = now; - uint8_t elapsed = (elapsed16 > 255) ? 255 : elapsed16; +bool debounce(matrix_row_t raw[], matrix_row_t cooked[], uint8_t num_rows, bool changed) { + uint16_t now = timer_read(); + uint16_t elapsed16 = TIMER_DIFF_16(now, last_time); + last_time = now; + uint8_t elapsed = (elapsed16 > 255) ? 255 : elapsed16; + bool cooked_changed = false; uint8_t* countdown = countdowns; @@ -63,10 +64,13 @@ void debounce(matrix_row_t raw[], matrix_row_t cooked[], uint8_t num_rows, bool } else if (*countdown > elapsed) { *countdown -= elapsed; } else if (*countdown) { + cooked_changed |= cooked[row] ^ raw_row; cooked[row] = raw_row; *countdown = 0; } } + + return cooked_changed; } bool debounce_active(void) { diff --git a/quantum/debounce/sym_eager_pk.c b/quantum/debounce/sym_eager_pk.c index fe3e88bb061b..f736d1645cd4 100644 --- a/quantum/debounce/sym_eager_pk.c +++ b/quantum/debounce/sym_eager_pk.c @@ -49,6 +49,7 @@ static debounce_counter_t *debounce_counters; static fast_timer_t last_time; static bool counters_need_update; static bool matrix_need_update; +static bool cooked_changed; # define DEBOUNCE_ELAPSED 0 @@ -71,8 +72,9 @@ void debounce_free(void) { debounce_counters = NULL; } -void debounce(matrix_row_t raw[], matrix_row_t cooked[], uint8_t num_rows, bool changed) { +bool debounce(matrix_row_t raw[], matrix_row_t cooked[], uint8_t num_rows, bool changed) { bool updated_last = false; + cooked_changed = false; if (counters_need_update) { fast_timer_t now = timer_read_fast(); @@ -96,6 +98,8 @@ void debounce(matrix_row_t raw[], matrix_row_t cooked[], uint8_t num_rows, bool transfer_matrix_values(raw, cooked, num_rows); } + + return cooked_changed; } // If the current time is > debounce counter, set the counter to enable input. @@ -132,6 +136,7 @@ static void transfer_matrix_values(matrix_row_t raw[], matrix_row_t cooked[], ui *debounce_pointer = DEBOUNCE; counters_need_update = true; existing_row ^= col_mask; // flip the bit. + cooked_changed = true; } } debounce_pointer++; diff --git a/quantum/debounce/sym_eager_pr.c b/quantum/debounce/sym_eager_pr.c index 29b0cabefbe0..aad5ca351b89 100644 --- a/quantum/debounce/sym_eager_pr.c +++ b/quantum/debounce/sym_eager_pr.c @@ -48,6 +48,7 @@ static bool matrix_need_update; static debounce_counter_t *debounce_counters; static fast_timer_t last_time; static bool counters_need_update; +static bool cooked_changed; # define DEBOUNCE_ELAPSED 0 @@ -67,8 +68,9 @@ void debounce_free(void) { debounce_counters = NULL; } -void debounce(matrix_row_t raw[], matrix_row_t cooked[], uint8_t num_rows, bool changed) { +bool debounce(matrix_row_t raw[], matrix_row_t cooked[], uint8_t num_rows, bool changed) { bool updated_last = false; + cooked_changed = false; if (counters_need_update) { fast_timer_t now = timer_read_fast(); @@ -92,6 +94,8 @@ void debounce(matrix_row_t raw[], matrix_row_t cooked[], uint8_t num_rows, bool transfer_matrix_values(raw, cooked, num_rows); } + + return cooked_changed; } // If the current time is > debounce counter, set the counter to enable input. @@ -123,8 +127,9 @@ static void transfer_matrix_values(matrix_row_t raw[], matrix_row_t cooked[], ui // determine new value basd on debounce pointer + raw value if (existing_row != raw_row) { if (*debounce_pointer == DEBOUNCE_ELAPSED) { - *debounce_pointer = DEBOUNCE; - cooked[row] = raw_row; + *debounce_pointer = DEBOUNCE; + cooked[row] = raw_row; + cooked_changed |= cooked[row] ^ raw[row]; counters_need_update = true; } } diff --git a/quantum/debounce/tests/debounce_test_common.cpp b/quantum/debounce/tests/debounce_test_common.cpp index 0d5a7bb76648..bd98e329554a 100644 --- a/quantum/debounce/tests/debounce_test_common.cpp +++ b/quantum/debounce/tests/debounce_test_common.cpp @@ -125,11 +125,15 @@ void DebounceTest::runDebounce(bool changed) { std::copy(std::begin(input_matrix_), std::end(input_matrix_), std::begin(raw_matrix_)); std::copy(std::begin(output_matrix_), std::end(output_matrix_), std::begin(cooked_matrix_)); - debounce(raw_matrix_, cooked_matrix_, MATRIX_ROWS, changed); + bool cooked_changed = debounce(raw_matrix_, cooked_matrix_, MATRIX_ROWS, changed); if (!std::equal(std::begin(input_matrix_), std::end(input_matrix_), std::begin(raw_matrix_))) { FAIL() << "Fatal error: debounce() modified raw matrix at " << strTime() << "\ninput_matrix: changed=" << changed << "\n" << strMatrix(input_matrix_) << "\nraw_matrix:\n" << strMatrix(raw_matrix_); } + + if (std::equal(std::begin(output_matrix_), std::end(output_matrix_), std::begin(cooked_matrix_)) && cooked_changed) { + FAIL() << "Fatal error: debounce() did detect a wrong cooked matrix change at " << strTime() << "\noutput_matrix: cooked_changed=" << cooked_changed << "\n" << strMatrix(output_matrix_) << "\ncooked_matrix:\n" << strMatrix(cooked_matrix_); + } } void DebounceTest::checkCookedMatrix(bool changed, const std::string &error_message) { diff --git a/quantum/matrix.c b/quantum/matrix.c index db59b73754f5..db683104edaa 100644 --- a/quantum/matrix.c +++ b/quantum/matrix.c @@ -337,10 +337,9 @@ uint8_t matrix_scan(void) { if (changed) memcpy(raw_matrix, curr_matrix, sizeof(curr_matrix)); #ifdef SPLIT_KEYBOARD - debounce(raw_matrix, matrix + thisHand, ROWS_PER_HAND, changed); - changed = (changed || matrix_post_scan()); + changed = debounce(raw_matrix, matrix + thisHand, ROWS_PER_HAND, changed) | matrix_post_scan(); #else - debounce(raw_matrix, matrix, ROWS_PER_HAND, changed); + changed = debounce(raw_matrix, matrix, ROWS_PER_HAND, changed); matrix_scan_quantum(); #endif return (uint8_t)changed; diff --git a/quantum/matrix_common.c b/quantum/matrix_common.c index 2cf84843471a..68f0e38297fa 100644 --- a/quantum/matrix_common.c +++ b/quantum/matrix_common.c @@ -169,10 +169,9 @@ __attribute__((weak)) uint8_t matrix_scan(void) { bool changed = matrix_scan_custom(raw_matrix); #ifdef SPLIT_KEYBOARD - debounce(raw_matrix, matrix + thisHand, ROWS_PER_HAND, changed); - changed = (changed || matrix_post_scan()); + changed = debounce(raw_matrix, matrix + thisHand, ROWS_PER_HAND, changed) | matrix_post_scan(); #else - debounce(raw_matrix, matrix, ROWS_PER_HAND, changed); + changed = debounce(raw_matrix, matrix, ROWS_PER_HAND, changed); matrix_scan_quantum(); #endif