aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--common_features.mk13
-rw-r--r--docs/feature_debounce_type.md146
-rw-r--r--quantum/debounce/readme.md28
-rw-r--r--quantum/debounce/sym_defer_g.c (renamed from quantum/debounce/sym_g.c)0
-rw-r--r--quantum/debounce/sym_defer_pk.c (renamed from quantum/debounce/sym_pk.c)0
-rw-r--r--quantum/debounce/sym_eager_pk.c (renamed from quantum/debounce/eager_pk.c)0
-rw-r--r--quantum/debounce/sym_eager_pr.c (renamed from quantum/debounce/eager_pr.c)0
7 files changed, 139 insertions, 48 deletions
diff --git a/common_features.mk b/common_features.mk
index 1f110d081..ed6908f4b 100644
--- a/common_features.mk
+++ b/common_features.mk
@@ -397,9 +397,20 @@ ifneq ($(strip $(CUSTOM_MATRIX)), yes)
397 endif 397 endif
398endif 398endif
399 399
400# Support for translating old names to new names:
401ifeq ($(strip $(DEBOUNCE_TYPE)),sym_g)
402 DEBOUNCE_TYPE:=sym_defer_g
403else ifeq ($(strip $(DEBOUNCE_TYPE)),eager_pk)
404 DEBOUNCE_TYPE:=sym_eager_pk
405else ifeq ($(strip $(DEBOUNCE_TYPE)),sym_pk)
406 DEBOUNCE_TYPE:=sym_defer_pk
407else ifeq ($(strip $(DEBOUNCE_TYPE)),eager_pr)
408 DEBOUNCE_TYPE:=sym_eager_pr
409endif
410
400DEBOUNCE_DIR:= $(QUANTUM_DIR)/debounce 411DEBOUNCE_DIR:= $(QUANTUM_DIR)/debounce
401# Debounce Modules. Set DEBOUNCE_TYPE=custom if including one manually. 412# Debounce Modules. Set DEBOUNCE_TYPE=custom if including one manually.
402DEBOUNCE_TYPE?= sym_g 413DEBOUNCE_TYPE?= sym_defer_g
403ifneq ($(strip $(DEBOUNCE_TYPE)), custom) 414ifneq ($(strip $(DEBOUNCE_TYPE)), custom)
404 QUANTUM_SRC += $(DEBOUNCE_DIR)/$(strip $(DEBOUNCE_TYPE)).c 415 QUANTUM_SRC += $(DEBOUNCE_DIR)/$(strip $(DEBOUNCE_TYPE)).c
405endif 416endif
diff --git a/docs/feature_debounce_type.md b/docs/feature_debounce_type.md
index 65b4ea1e5..83ebafe60 100644
--- a/docs/feature_debounce_type.md
+++ b/docs/feature_debounce_type.md
@@ -1,43 +1,151 @@
1# Debounce algorithm 1# Contact bounce / contact chatter
2 2
3QMK supports multiple debounce algorithms through its debounce API. 3Mechanical switches often don't have a clean single transition between pressed and unpressed states.
4
5In an ideal world, when you press a switch, you would expect the digital pin to see something like this:
6(X axis showing time
7```
8voltage +----------------------
9 ^ |
10 | |
11 | ------------------+
12 ----> time
13```
14
15However in the real world you will actually see contact bounce, which will look like multiple 1->0 and 0->1 transitions,
16until the value finally settles.
17```
18 +-+ +--+ +-------------
19 | | | | |
20 | | | | |
21+-----------------+ +-+ +-+
22```
23The time it takes for the switch to settle might vary with switch type, age, and even pressing technique.
24
25If the device chooses not to mitigate contact bounce, then often actions that happen when the switch is pressed are repeated
26multiple times.
27
28There are many ways to handle contact bounce ("Debouncing"). Some include employing additional hardware, for example an RC filter,
29while there are various ways to do debouncing in software too, often called debounce algorithms. This page discusses software
30debouncing methods available in QMK.
31
32While technically not considered contact bounce/contact chatter, some switch technologies are susceptible to noise, meaning,
33while the key is not changing state, sometimes short random 0->1 or 1->0 transitions might be read by the digital circuit, for example:
34```
35 +-+
36 | |
37 | |
38+-----------------+ +--------------------
39```
40
41Many debounce methods (but not all) will also make the device resistant to noise. If you are working with a technology that is
42susceptible to noise, you must choose a debounce method that will also mitigate noise for you.
43
44## Types of debounce algorithms
4 45
5The logic for which debounce method called is below. It checks various defines that you have set in rules.mk 461) Unit of time: Timestamp (milliseconds) vs Cycles (scans)
47 * Debounce algorithms often have a 'debounce time' parameter, that specifies the maximum settling time of the switch contacts.
48 This time might be measured in various units:
49 * Cycles-based debouncing waits n cycles (scans), decreasing count by one each matrix_scan
50 * Timestamp-based debouncing stores the millisecond timestamp a change occurred, and does substraction to figure out time elapsed.
51 * Timestamp-based debouncing is usually superior, especially in the case of noise-resistant devices because settling times of physical
52 switches is specified in units of time, and should not depend on the matrix scan-rate of the keyboard.
53 * Cycles-based debouncing is sometimes considered inferior, because the settling time that it is able to compensate for depends on the
54 performance of the matrix scanning code. If you use cycles-based debouncing, and you significantly improve the performance of your scanning
55 code, you might end up with less effective debouncing. A situation in which cycles-based debouncing might be preferable is when
56 noise is present, and the scanning algorithm is slow, or variable speed. Even if your debounce algorithm is fundamentally noise-resistant,
57 if the scanning is slow, and you are using a timestamp-based algorithm, you might end up making a debouncing decision based on only two
58 sampled values, which will limit the noise-resistance of the algorithm.
59 * Currently all built-in debounce algorithms support timestamp-based debouncing only. In the future we might
60 implement cycles-based debouncing, and it will be selectable via a ```config.h``` macro.
61
622) Symmetric vs Asymmetric
63 * Symmetric - apply the same debouncing algorithm, to both key-up and key-down events.
64 * Recommended naming convention: ```sym_*```
65 * Asymmetric - apply different debouncing algorithms to key-down and key-up events. E.g. Eager key-down, Defer key-up.
66 * Recommended naming convention: ```asym_*``` followed by details of the type of algorithm in use, in order, for key-down and then key-up
67
683) Eager vs Defer
69 * Eager - any key change is reported immediately. All further inputs for DEBOUNCE ms are ignored.
70 * Eager algorithms are not noise-resistant.
71 * Recommended naming conventions:
72 * ```sym_eager_*```
73 * ```asym_eager_*_*```: key-down is using eager algorithm
74 * ```asym_*_eager_*```: key-up is using eager algorithm
75 * Defer - wait for no changes for DEBOUNCE ms before reporting change.
76 * Defer algorithms are noise-resistant
77 * Recommended naming conventions:
78 * ```sym_defer_*```
79 * ```asym_defer_*_*```: key-down is using eager algorithm
80 * ```asym_*_defer_*```: key-up is using eager algorithm
81
824) Global vs Per-Key vs Per-Row
83 * Global - one timer for all keys. Any key change state affects global timer
84 * Recommended naming convention: ```*_g```
85 * Per-key - one timer per key
86 * Recommended naming convention: ```*_pk```
87 * Per-row - one timer per row
88 * Recommended naming convention: ```*_pr```
89 * Per-key and per-row algorithms consume more resources (in terms of performance,
90 and ram usage), but fast typists might prefer them over global.
91
92## Debounce algorithms supported by QMK
93
94QMK supports multiple debounce algorithms through its debounce API.
95The logic for which debounce method called is below. It checks various defines that you have set in ```rules.mk```
6 96
7``` 97```
8DEBOUNCE_DIR:= $(QUANTUM_DIR)/debounce 98DEBOUNCE_DIR:= $(QUANTUM_DIR)/debounce
9DEBOUNCE_TYPE?= sym_g 99DEBOUNCE_TYPE?= sym_defer_g
10ifneq ($(strip $(DEBOUNCE_TYPE)), custom) 100ifneq ($(strip $(DEBOUNCE_TYPE)), custom)
11 QUANTUM_SRC += $(DEBOUNCE_DIR)/$(strip $(DEBOUNCE_TYPE)).c 101 QUANTUM_SRC += $(DEBOUNCE_DIR)/$(strip $(DEBOUNCE_TYPE)).c
12endif 102endif
13``` 103```
14 104
15# Debounce selection 105### Debounce selection
16 106
17| DEBOUNCE_TYPE | Description | What else is needed | 107| DEBOUNCE_TYPE | Description | What else is needed |
18| ------------- | --------------------------------------------------- | ----------------------------- | 108| ------------- | --------------------------------------------------- | ----------------------------- |
19| Not defined | Use the default algorithm, currently sym_g | Nothing | 109| Not defined | Use the default algorithm, currently sym_defer_g | Nothing |
20| custom | Use your own debounce code | ```SRC += debounce.c``` add your own debounce.c and implement necessary functions | 110| custom | Use your own debounce code | ```SRC += debounce.c``` add your own debounce.c and implement necessary functions |
21| anything_else | Use another algorithm from quantum/debounce/* | Nothing | 111| Anything Else | Use another algorithm from quantum/debounce/* | Nothing |
22 112
23**Regarding split keyboards**: 113**Regarding split keyboards**:
24The debounce code is compatible with split keyboards. 114The debounce code is compatible with split keyboards.
25 115
26# Use your own debouncing code 116### Selecting an included debouncing method
27* Set ```DEBOUNCE_TYPE = custom```. 117Keyboards may select one of the already implemented debounce methods, by adding to ```rules.mk``` the following line:
28* Add ```SRC += debounce.c``` 118```
119DEBOUNCE_TYPE = <name of algorithm>
120```
121Where name of algorithm is one of:
122* ```sym_defer_g``` - debouncing per keyboard. On any state change, a global timer is set. When ```DEBOUNCE``` milliseconds of no changes has occurred, all input changes are pushed.
123 * This is the current default algorithm. This is the highest performance algorithm with lowest memory usage, and it's also noise-resistant.
124* ```sym_eager_pr``` - debouncing per row. On any state change, response is immediate, followed by locking the row ```DEBOUNCE``` milliseconds of no further input for that row.
125For use in keyboards where refreshing ```NUM_KEYS``` 8-bit counters is computationally expensive / low scan rate, and fingers usually only hit one row at a time. This could be
126appropriate for the ErgoDox models; the matrix is rotated 90°, and hence its "rows" are really columns, and each finger only hits a single "row" at a time in normal use.
127* ```sym_eager_pk``` - debouncing per key. On any state change, response is immediate, followed by ```DEBOUNCE``` milliseconds of no further input for that key
128* ```sym_defer_pk``` - debouncing per key. On any state change, a per-key timer is set. When ```DEBOUNCE``` milliseconds of no changes have occurred on that key, the key status change is pushed.
129
130### A couple algorithms that could be implemented in the future:
131* ```sym_defer_pr```
132* ```sym_eager_g```
133* ```asym_eager_defer_pk```
134
135### Use your own debouncing code
136You have the option to implement you own debouncing algorithm. To do this:
137* Set ```DEBOUNCE_TYPE = custom``` in ```rules.mk```.
138* Add ```SRC += debounce.c``` in ```rules.mk```
29* Add your own ```debounce.c```. Look at current implementations in ```quantum/debounce``` for examples. 139* Add your own ```debounce.c```. Look at current implementations in ```quantum/debounce``` for examples.
30* Debouncing occurs after every raw matrix scan. 140* Debouncing occurs after every raw matrix scan.
31* Use num_rows rather than MATRIX_ROWS, so that split keyboards are supported correctly. 141* Use num_rows rather than MATRIX_ROWS, so that split keyboards are supported correctly.
142* If the algorithm might be applicable to other keyboards, please consider adding it to ```quantum/debounce```
32 143
33# Changing between included debouncing methods 144### Old names
34You can either use your own code, by including your own debounce.c, or switch to another included one. 145The following old names for existing algorithms will continue to be supported, however it is recommended to use the new names instead.
35Included debounce methods are:
36* eager_pr - debouncing per row. On any state change, response is immediate, followed by locking the row ```DEBOUNCE``` milliseconds of no further input for that row.
37For use in keyboards where refreshing ```NUM_KEYS``` 8-bit counters is computationally expensive / low scan rate, and fingers usually only hit one row at a time. This could be
38appropriate for the ErgoDox models; the matrix is rotated 90°, and hence its "rows" are really columns, and each finger only hits a single "row" at a time in normal use.
39* eager_pk - debouncing per key. On any state change, response is immediate, followed by ```DEBOUNCE``` milliseconds of no further input for that key
40* sym_g - debouncing per keyboard. On any state change, a global timer is set. When ```DEBOUNCE``` milliseconds of no changes has occured, all input changes are pushed.
41* sym_pk - debouncing per key. On any state change, a per-key timer is set. When ```DEBOUNCE``` milliseconds of no changes have occured on that key, the key status change is pushed.
42 146
147* sym_g - old name for sym_defer_g
148* eager_pk - old name for sym_eager_pk
149* sym_pk - old name for sym_defer_pk
150* eager_pr - old name for sym_eager_pr
43 151
diff --git a/quantum/debounce/readme.md b/quantum/debounce/readme.md
deleted file mode 100644
index f77f78c76..000000000
--- a/quantum/debounce/readme.md
+++ /dev/null
@@ -1,28 +0,0 @@
1Debounce algorithms belong in this folder.
2Here are a few ideas
3
41) Global vs Per-Key vs Per-Row
5 * Global - one timer for all keys. Any key change state affects global timer
6 * Per key - one timer per key
7 * Per row - one timer per row
8
92) Eager vs symmetric vs asymmetric
10 * Eager - any key change is reported immediately. All further inputs for DEBOUNCE ms are ignored.
11 * Symmetric - wait for no changes for DEBOUNCE ms before reporting change
12 * Asymmetric - wait for different times depending on key-down/key-up. E.g. Eager key-down, DEBOUNCE ms key up.
13
143) Timestamp vs cycles
15 * old old old code waits n cycles, decreasing count by one each matrix_scan
16 * newer code stores the millisecond the change occurred, and does subraction to figure out time elapsed.
17 * Timestamps are superior, i don't think cycles will ever be used again once upgraded.
18
19The default algorithm is symmetric and global.
20Here are a few that could be implemented:
21
22sym_g.c
23sym_pk.c
24sym_pr.c
25sym_pr_cycles.c
26eager_g.c
27eager_pk.c
28eager_pr.c //could be used in ergo-dox!
diff --git a/quantum/debounce/sym_g.c b/quantum/debounce/sym_defer_g.c
index 3ed9055d2..3ed9055d2 100644
--- a/quantum/debounce/sym_g.c
+++ b/quantum/debounce/sym_defer_g.c
diff --git a/quantum/debounce/sym_pk.c b/quantum/debounce/sym_defer_pk.c
index f404cf9c4..f404cf9c4 100644
--- a/quantum/debounce/sym_pk.c
+++ b/quantum/debounce/sym_defer_pk.c
diff --git a/quantum/debounce/eager_pk.c b/quantum/debounce/sym_eager_pk.c
index 93a40ad44..93a40ad44 100644
--- a/quantum/debounce/eager_pk.c
+++ b/quantum/debounce/sym_eager_pk.c
diff --git a/quantum/debounce/eager_pr.c b/quantum/debounce/sym_eager_pr.c
index d12931fdd..d12931fdd 100644
--- a/quantum/debounce/eager_pr.c
+++ b/quantum/debounce/sym_eager_pr.c