diff options
Diffstat (limited to 'quantum/debounce')
| -rw-r--r-- | quantum/debounce/asym_eager_defer_pk.c | 1 | ||||
| -rw-r--r-- | quantum/debounce/none.c | 2 | ||||
| -rw-r--r-- | quantum/debounce/sym_defer_g.c | 2 | ||||
| -rw-r--r-- | quantum/debounce/sym_defer_pk.c | 1 | ||||
| -rw-r--r-- | quantum/debounce/sym_defer_pr.c | 72 | ||||
| -rw-r--r-- | quantum/debounce/sym_eager_pk.c | 1 | ||||
| -rw-r--r-- | quantum/debounce/sym_eager_pr.c | 1 | ||||
| -rw-r--r-- | quantum/debounce/tests/rules.mk | 5 | ||||
| -rw-r--r-- | quantum/debounce/tests/sym_defer_pr_tests.cpp | 238 | ||||
| -rw-r--r-- | quantum/debounce/tests/testlist.mk | 1 | 
10 files changed, 316 insertions, 8 deletions
diff --git a/quantum/debounce/asym_eager_defer_pk.c b/quantum/debounce/asym_eager_defer_pk.c index 81f39383c4..b1eb4a2b7b 100644 --- a/quantum/debounce/asym_eager_defer_pk.c +++ b/quantum/debounce/asym_eager_defer_pk.c @@ -165,7 +165,6 @@ static void transfer_matrix_values(matrix_row_t raw[], matrix_row_t cooked[], ui      }  } -bool debounce_active(void) { return true; }  #else  #    include "none.c"  #endif diff --git a/quantum/debounce/none.c b/quantum/debounce/none.c index b03892bc5b..8a85cc04a8 100644 --- a/quantum/debounce/none.c +++ b/quantum/debounce/none.c @@ -26,6 +26,4 @@ void debounce(matrix_row_t raw[], matrix_row_t cooked[], uint8_t num_rows, bool      }  } -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 9155eb914c..8cac1c37f9 100644 --- a/quantum/debounce/sym_defer_g.c +++ b/quantum/debounce/sym_defer_g.c @@ -44,8 +44,6 @@ void debounce(matrix_row_t raw[], matrix_row_t cooked[], uint8_t num_rows, bool      }  } -bool debounce_active(void) { return debouncing; } -  void debounce_free(void) {}  #else  // no debouncing.  #    include "none.c" diff --git a/quantum/debounce/sym_defer_pk.c b/quantum/debounce/sym_defer_pk.c index 1b698ba347..9dee29e28e 100644 --- a/quantum/debounce/sym_defer_pk.c +++ b/quantum/debounce/sym_defer_pk.c @@ -134,7 +134,6 @@ static void start_debounce_counters(matrix_row_t raw[], matrix_row_t cooked[], u      }  } -bool debounce_active(void) { return true; }  #else  #    include "none.c"  #endif diff --git a/quantum/debounce/sym_defer_pr.c b/quantum/debounce/sym_defer_pr.c new file mode 100644 index 0000000000..8b33acc6a2 --- /dev/null +++ b/quantum/debounce/sym_defer_pr.c @@ -0,0 +1,72 @@ +/* +Copyright 2021 Chad Austin <chad@chadaustin.me> +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/>. +*/ + +/* +Symmetric per-row debounce algorithm. Changes only apply when +DEBOUNCE milliseconds have elapsed since the last change. +*/ + +#include "matrix.h" +#include "timer.h" +#include "quantum.h" +#include <stdlib.h> + +#ifndef DEBOUNCE +#    define DEBOUNCE 5 +#endif + +static uint16_t last_time; +// [row] milliseconds until key's state is considered debounced. +static uint8_t* countdowns; +// [row] +static matrix_row_t* last_raw; + +void debounce_init(uint8_t num_rows) { +    countdowns = (uint8_t*)calloc(num_rows, sizeof(uint8_t)); +    last_raw   = (matrix_row_t*)calloc(num_rows, sizeof(matrix_row_t)); + +    last_time = timer_read(); +} + +void debounce_free(void) { +    free(countdowns); +    countdowns = NULL; +    free(last_raw); +    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; + +    uint8_t* countdown = countdowns; + +    for (uint8_t row = 0; row < num_rows; ++row, ++countdown) { +        matrix_row_t raw_row = raw[row]; + +        if (raw_row != last_raw[row]) { +            *countdown    = DEBOUNCE; +            last_raw[row] = raw_row; +        } else if (*countdown > elapsed) { +            *countdown -= elapsed; +        } else if (*countdown) { +            cooked[row] = raw_row; +            *countdown  = 0; +        } +    } +} + +bool debounce_active(void) { return true; } diff --git a/quantum/debounce/sym_eager_pk.c b/quantum/debounce/sym_eager_pk.c index 9da000ea9a..deec463649 100644 --- a/quantum/debounce/sym_eager_pk.c +++ b/quantum/debounce/sym_eager_pk.c @@ -140,7 +140,6 @@ static void transfer_matrix_values(matrix_row_t raw[], matrix_row_t cooked[], ui      }  } -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 eda92a263b..29b0cabefb 100644 --- a/quantum/debounce/sym_eager_pr.c +++ b/quantum/debounce/sym_eager_pr.c @@ -132,7 +132,6 @@ static void transfer_matrix_values(matrix_row_t raw[], matrix_row_t cooked[], ui      }  } -bool debounce_active(void) { return true; }  #else  #    include "none.c"  #endif diff --git a/quantum/debounce/tests/rules.mk b/quantum/debounce/tests/rules.mk index e908dd6f67..8318b1c668 100644 --- a/quantum/debounce/tests/rules.mk +++ b/quantum/debounce/tests/rules.mk @@ -28,6 +28,11 @@ debounce_sym_defer_pk_SRC := $(DEBOUNCE_COMMON_SRC) \  	$(QUANTUM_PATH)/debounce/sym_defer_pk.c \  	$(QUANTUM_PATH)/debounce/tests/sym_defer_pk_tests.cpp +debounce_sym_defer_pr_DEFS := $(DEBOUNCE_COMMON_DEFS) +debounce_sym_defer_pr_SRC := $(DEBOUNCE_COMMON_SRC) \ +	$(QUANTUM_PATH)/debounce/sym_defer_pr.c \ +	$(QUANTUM_PATH)/debounce/tests/sym_defer_pr_tests.cpp +  debounce_sym_eager_pk_DEFS := $(DEBOUNCE_COMMON_DEFS)  debounce_sym_eager_pk_SRC := $(DEBOUNCE_COMMON_SRC) \  	$(QUANTUM_PATH)/debounce/sym_eager_pk.c \ diff --git a/quantum/debounce/tests/sym_defer_pr_tests.cpp b/quantum/debounce/tests/sym_defer_pr_tests.cpp new file mode 100644 index 0000000000..417e1f4ca2 --- /dev/null +++ b/quantum/debounce/tests/sym_defer_pr_tests.cpp @@ -0,0 +1,238 @@ +/* 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 "gtest/gtest.h" + +#include "debounce_test_common.h" + +TEST_F(DebounceTest, OneKeyShort1) { +    addEvents({ +        /* Time, Inputs, Outputs */ +        {0, {{0, 1, DOWN}}, {}}, + +        {5, {}, {{0, 1, DOWN}}}, +        /* 0ms delay (fast scan rate) */ +        {5, {{0, 1, UP}}, {}}, + +        {10, {}, {{0, 1, UP}}}, +    }); +    runEvents(); +} + +TEST_F(DebounceTest, OneKeyShort2) { +    addEvents({ +        /* Time, Inputs, Outputs */ +        {0, {{0, 1, DOWN}}, {}}, + +        {5, {}, {{0, 1, DOWN}}}, +        /* 1ms delay */ +        {6, {{0, 1, UP}}, {}}, + +        {11, {}, {{0, 1, UP}}}, +    }); +    runEvents(); +} + +TEST_F(DebounceTest, OneKeyShort3) { +    addEvents({ +        /* Time, Inputs, Outputs */ +        {0, {{0, 1, DOWN}}, {}}, + +        {5, {}, {{0, 1, DOWN}}}, +        /* 2ms delay */ +        {7, {{0, 1, UP}}, {}}, + +        {12, {}, {{0, 1, UP}}}, +    }); +    runEvents(); +} + +TEST_F(DebounceTest, OneKeyTooQuick1) { +    addEvents({ +        /* Time, Inputs, Outputs */ +        {0, {{0, 1, DOWN}}, {}}, +        /* Release key exactly on the debounce time */ +        {5, {{0, 1, UP}}, {}}, +    }); +    runEvents(); +} + +TEST_F(DebounceTest, OneKeyTooQuick2) { +    addEvents({ +        /* Time, Inputs, Outputs */ +        {0, {{0, 1, DOWN}}, {}}, + +        {5, {}, {{0, 1, DOWN}}}, +        {6, {{0, 1, UP}}, {}}, + +        /* Press key exactly on the debounce time */ +        {11, {{0, 1, DOWN}}, {}}, +    }); +    runEvents(); +} + +TEST_F(DebounceTest, OneKeyBouncing1) { +    addEvents({ +        /* Time, Inputs, Outputs */ +        {0, {{0, 1, DOWN}}, {}}, +        {1, {{0, 1, UP}}, {}}, +        {2, {{0, 1, DOWN}}, {}}, +        {3, {{0, 1, UP}}, {}}, +        {4, {{0, 1, DOWN}}, {}}, +        {5, {{0, 1, UP}}, {}}, +        {6, {{0, 1, DOWN}}, {}}, +        {11, {}, {{0, 1, DOWN}}}, /* 5ms after DOWN at time 7 */ +    }); +    runEvents(); +} + +TEST_F(DebounceTest, OneKeyBouncing2) { +    addEvents({ +        /* Time, Inputs, Outputs */ +        {0, {{0, 1, DOWN}}, {}}, +        {5, {}, {{0, 1, DOWN}}}, +        {6, {{0, 1, UP}}, {}}, +        {7, {{0, 1, DOWN}}, {}}, +        {8, {{0, 1, UP}}, {}}, +        {9, {{0, 1, DOWN}}, {}}, +        {10, {{0, 1, UP}}, {}}, +        {15, {}, {{0, 1, UP}}}, /* 5ms after UP at time 10 */ +    }); +    runEvents(); +} + +TEST_F(DebounceTest, OneKeyLong) { +    addEvents({ +        /* Time, Inputs, Outputs */ +        {0, {{0, 1, DOWN}}, {}}, + +        {5, {}, {{0, 1, DOWN}}}, + +        {25, {{0, 1, UP}}, {}}, + +        {30, {}, {{0, 1, UP}}}, + +        {50, {{0, 1, DOWN}}, {}}, + +        {55, {}, {{0, 1, DOWN}}}, +    }); +    runEvents(); +} + +TEST_F(DebounceTest, TwoKeysShort) { +    addEvents({ +        /* Time, Inputs, Outputs */ +        {0, {{0, 1, DOWN}}, {}}, +        {1, {{0, 2, DOWN}}, {}}, + +        {6, {}, {{0, 1, DOWN}, {0, 2, DOWN}}}, + +        {7, {{0, 1, UP}}, {}}, +        {8, {{0, 2, UP}}, {}}, + +        {13, {}, {{0, 1, UP}, {0, 2, UP}}}, +    }); +    runEvents(); +} + +TEST_F(DebounceTest, TwoKeysSimultaneous1) { +    addEvents({ +        /* Time, Inputs, Outputs */ +        {0, {{0, 1, DOWN}, {0, 2, DOWN}}, {}}, + +        {5, {}, {{0, 1, DOWN}, {0, 2, DOWN}}}, +        {6, {{0, 1, UP}, {0, 2, UP}}, {}}, + +        {11, {}, {{0, 1, UP}, {0, 2, UP}}}, +    }); +    runEvents(); +} + +TEST_F(DebounceTest, TwoKeysSimultaneous2) { +    addEvents({ +        /* Time, Inputs, Outputs */ +        {0, {{0, 1, DOWN}}, {}}, +        {1, {{0, 2, DOWN}}, {}}, + +        {6, {}, {{0, 1, DOWN}, {0, 2, DOWN}}}, +        {7, {{0, 2, UP}}, {}}, +        {9, {{0, 1, UP}}, {}}, + +        // Debouncing loses the specific ordering -- both events report simultaneously. +        {14, {}, {{0, 1, UP}, {0, 2, UP}}}, +    }); +    runEvents(); +} + +TEST_F(DebounceTest, OneKeyDelayedScan1) { +    addEvents({ +        /* Time, Inputs, Outputs */ +        {0, {{0, 1, DOWN}}, {}}, + +        /* Processing is very late */ +        {300, {}, {{0, 1, DOWN}}}, +        /* Immediately release key */ +        {300, {{0, 1, UP}}, {}}, + +        {305, {}, {{0, 1, UP}}}, +    }); +    time_jumps_ = true; +    runEvents(); +} + +TEST_F(DebounceTest, OneKeyDelayedScan2) { +    addEvents({ +        /* Time, Inputs, Outputs */ +        {0, {{0, 1, DOWN}}, {}}, + +        /* Processing is very late */ +        {300, {}, {{0, 1, DOWN}}}, +        /* Release key after 1ms */ +        {301, {{0, 1, UP}}, {}}, + +        {306, {}, {{0, 1, UP}}}, +    }); +    time_jumps_ = true; +    runEvents(); +} + +TEST_F(DebounceTest, OneKeyDelayedScan3) { +    addEvents({ +        /* Time, Inputs, Outputs */ +        {0, {{0, 1, DOWN}}, {}}, + +        /* Release key before debounce expires */ +        {300, {{0, 1, UP}}, {}}, +    }); +    time_jumps_ = true; +    runEvents(); +} + +TEST_F(DebounceTest, OneKeyDelayedScan4) { +    addEvents({ +        /* Time, Inputs, Outputs */ +        {0, {{0, 1, DOWN}}, {}}, + +        /* Processing is a bit late */ +        {50, {}, {{0, 1, DOWN}}}, +        /* Release key after 1ms */ +        {51, {{0, 1, UP}}, {}}, + +        {56, {}, {{0, 1, UP}}}, +    }); +    time_jumps_ = true; +    runEvents(); +} diff --git a/quantum/debounce/tests/testlist.mk b/quantum/debounce/tests/testlist.mk index c54c45aa63..f7bd520698 100644 --- a/quantum/debounce/tests/testlist.mk +++ b/quantum/debounce/tests/testlist.mk @@ -1,6 +1,7 @@  TEST_LIST += \  	debounce_sym_defer_g \  	debounce_sym_defer_pk \ +	debounce_sym_defer_pr \  	debounce_sym_eager_pk \  	debounce_sym_eager_pr \  	debounce_asym_eager_defer_pk  | 
