~ruther/qmk_firmware

8224f62806b66f0825b68fd8c00436ee57a28e9a — Stefan Kerkmann 3 years ago cca5d35
Make debounce() signal changes in the cooked matrix as return value (#17554)

M docs/custom_matrix.md => docs/custom_matrix.md +3 -3
@@ 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;
}
```


M docs/ja/custom_matrix.md => docs/ja/custom_matrix.md +3 -3
@@ 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;
}
```


M quantum/debounce.h => quantum/debounce.h +11 -5
@@ 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);


M quantum/debounce/asym_eager_defer_pk.c => quantum/debounce/asym_eager_defer_pk.c +9 -2
@@ 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) {

M quantum/debounce/none.c => quantum/debounce/none.c +7 -4
@@ 17,13 17,16 @@
#include "matrix.h"
#include "quantum.h"
#include <stdlib.h>
#include <string.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(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) {}

M quantum/debounce/sym_defer_g.c => quantum/debounce/sym_defer_g.c +9 -3
@@ 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 <string.h>
#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) {}

M quantum/debounce/sym_defer_pk.c => quantum/debounce/sym_defer_pk.c +9 -3
@@ 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;

M quantum/debounce/sym_defer_pr.c => quantum/debounce/sym_defer_pr.c +9 -5
@@ 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) {

M quantum/debounce/sym_eager_pk.c => quantum/debounce/sym_eager_pk.c +6 -1
@@ 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++;

M quantum/debounce/sym_eager_pr.c => quantum/debounce/sym_eager_pr.c +8 -3
@@ 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;
            }
        }

M quantum/debounce/tests/debounce_test_common.cpp => quantum/debounce/tests/debounce_test_common.cpp +5 -1
@@ 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) {

M quantum/matrix.c => quantum/matrix.c +2 -3
@@ 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;

M quantum/matrix_common.c => quantum/matrix_common.c +2 -3
@@ 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