From dc84818b89baa03942b551d4538fd732b8aa8699 Mon Sep 17 00:00:00 2001 From: alex-ong Date: Fri, 26 Jan 2018 18:42:09 +1100 Subject: [PATCH 1/7] core: moved deghosting into its own function --- tmk_core/common/keyboard.c | 35 ++++++++++++++++++++++------------- 1 file changed, 22 insertions(+), 13 deletions(-) diff --git a/tmk_core/common/keyboard.c b/tmk_core/common/keyboard.c index 929b862af3..9e1e3b4be1 100644 --- a/tmk_core/common/keyboard.c +++ b/tmk_core/common/keyboard.c @@ -60,6 +60,25 @@ static bool has_ghost_in_row(uint8_t row) } return false; } + +//Returns whether there was a ghost in the row. +static bool matrix_deghost(uint8_t row, matrix_row_t matrix_row, matrix_row_t* matrix_ghost) +{ + bool result = false; + if (has_ghost_in_row(row)) { + /* Keep track of whether ghosted status has changed for + * debugging. But don't update matrix_prev until un-ghosted, or + * the last key would be lost. + */ + if (debug_matrix && matrix_ghost[row] != matrix_row) { + matrix_print(); + } + result = true; + } + + matrix_ghost[row] = matrix_row; + return result; +} #endif @@ -107,23 +126,13 @@ void keyboard_task(void) matrix_row_t matrix_change = 0; matrix_scan(); + for (uint8_t r = 0; r < MATRIX_ROWS; r++) { matrix_row = matrix_get_row(r); matrix_change = matrix_row ^ matrix_prev[r]; - if (matrix_change) { + if (matrix_change) { #ifdef MATRIX_HAS_GHOST - if (has_ghost_in_row(r)) { - /* Keep track of whether ghosted status has changed for - * debugging. But don't update matrix_prev until un-ghosted, or - * the last key would be lost. - */ - if (debug_matrix && matrix_ghost[r] != matrix_row) { - matrix_print(); - } - matrix_ghost[r] = matrix_row; - continue; - } - matrix_ghost[r] = matrix_row; + if (matrix_deghost(r, matrix_row, matrix_ghost)) continue; #endif if (debug_matrix) matrix_print(); matrix_row_t col_mask = 1; From 916cd33b2fa81d1d92b86d577df1e77126b7edfd Mon Sep 17 00:00:00 2001 From: alex-ong Date: Fri, 26 Jan 2018 18:52:28 +1100 Subject: [PATCH 2/7] core: Cleaner and byte-saving way of writing de-ghosting function. Only 2 more bytes (after compilation) than the previous in-line solution --- tmk_core/common/keyboard.c | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/tmk_core/common/keyboard.c b/tmk_core/common/keyboard.c index 9e1e3b4be1..29391da49f 100644 --- a/tmk_core/common/keyboard.c +++ b/tmk_core/common/keyboard.c @@ -61,21 +61,15 @@ static bool has_ghost_in_row(uint8_t row) return false; } -//Returns whether there was a ghost in the row. +//Returns whether there was a ghost in the row, then copies new contents +//into matrix_ghost static bool matrix_deghost(uint8_t row, matrix_row_t matrix_row, matrix_row_t* matrix_ghost) -{ - bool result = false; - if (has_ghost_in_row(row)) { - /* Keep track of whether ghosted status has changed for - * debugging. But don't update matrix_prev until un-ghosted, or - * the last key would be lost. - */ - if (debug_matrix && matrix_ghost[row] != matrix_row) { - matrix_print(); - } - result = true; +{ + bool result = has_ghost_in_row(row); + if (debug_matrix && result && matrix_ghost[row] != matrix_row) + { + matrix_print(); } - matrix_ghost[row] = matrix_row; return result; } From cfa849448e2ad02fb36716d49bb3d5bfc5ca1ce5 Mon Sep 17 00:00:00 2001 From: alex-ong Date: Fri, 26 Jan 2018 21:44:24 +1100 Subject: [PATCH 3/7] Added debounce hook into keyboard.c. Implemented no-debounce method, so all existing projects will work. --- tmk_core/common.mk | 1 + tmk_core/common/debounce.c | 26 ++++++++++++++++++++++++++ tmk_core/common/debounce.h | 21 +++++++++++++++++++++ tmk_core/common/keyboard.c | 7 +++++-- 4 files changed, 53 insertions(+), 2 deletions(-) create mode 100644 tmk_core/common/debounce.c create mode 100644 tmk_core/common/debounce.h diff --git a/tmk_core/common.mk b/tmk_core/common.mk index 14951ec851..1e2c0a2168 100644 --- a/tmk_core/common.mk +++ b/tmk_core/common.mk @@ -1,5 +1,6 @@ COMMON_DIR = common SRC += $(COMMON_DIR)/host.c \ + $(COMMON_DIR)/debounce.c \ $(COMMON_DIR)/keyboard.c \ $(COMMON_DIR)/matrix.c \ $(COMMON_DIR)/action.c \ diff --git a/tmk_core/common/debounce.c b/tmk_core/common/debounce.c new file mode 100644 index 0000000000..f094fbbc98 --- /dev/null +++ b/tmk_core/common/debounce.c @@ -0,0 +1,26 @@ +/* +Copyright 2017 Alex Ong + +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 . +*/ + +#include "debounce.h" +#include "matrix.h" + +//Default implementation - no debouncing +__attribute__((weak)) void matrix_debounce(void) {} +__attribute__((weak)) matrix_row_t matrix_debounce_get_row(uint8_t row) +{ + return matrix_get_row(row); +} diff --git a/tmk_core/common/debounce.h b/tmk_core/common/debounce.h new file mode 100644 index 0000000000..2af0cf74ce --- /dev/null +++ b/tmk_core/common/debounce.h @@ -0,0 +1,21 @@ +#ifndef DEBOUNCE_H +#define DEBOUNCE_H + +#include +#include +#include "matrix.h" + +#ifdef __cplusplus +extern "C" { +#endif +/* call this every keyboard_task to debounce the matrix*/ +void matrix_debounce(void); + +/* matrix state on row */ +matrix_row_t matrix_debounce_get_row(uint8_t row); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/tmk_core/common/keyboard.c b/tmk_core/common/keyboard.c index 29391da49f..13d1a7e0f3 100644 --- a/tmk_core/common/keyboard.c +++ b/tmk_core/common/keyboard.c @@ -17,6 +17,7 @@ along with this program. If not, see . #include #include "keyboard.h" #include "matrix.h" +#include "debounce.h" #include "keymap.h" #include "host.h" #include "led.h" @@ -106,9 +107,10 @@ void keyboard_init(void) } /* - * Do keyboard routine jobs: scan mantrix, light LEDs, ... + * Do keyboard routine jobs: scan matrix, light LEDs, ... * This is repeatedly called as fast as possible. */ + void keyboard_task(void) { static matrix_row_t matrix_prev[MATRIX_ROWS]; @@ -120,9 +122,10 @@ void keyboard_task(void) matrix_row_t matrix_change = 0; matrix_scan(); + matrix_debounce(); for (uint8_t r = 0; r < MATRIX_ROWS; r++) { - matrix_row = matrix_get_row(r); + matrix_row = matrix_debounce_get_row(r); matrix_change = matrix_row ^ matrix_prev[r]; if (matrix_change) { #ifdef MATRIX_HAS_GHOST From 2928a471aeb3609688ed58f7c4adf490dc08ef0f Mon Sep 17 00:00:00 2001 From: alex-ong Date: Fri, 26 Jan 2018 22:04:28 +1100 Subject: [PATCH 4/7] GH60: Debounce_hasu algorithm for gh-60. --- keyboard/gh60/Makefile | 1 + keyboard/gh60/matrix.c | 28 +--------------- tmk_core/common.mk | 9 ++++++ tmk_core/common/debounce/debounce_hasu.c | 41 ++++++++++++++++++++++++ 4 files changed, 52 insertions(+), 27 deletions(-) create mode 100644 tmk_core/common/debounce/debounce_hasu.c diff --git a/keyboard/gh60/Makefile b/keyboard/gh60/Makefile index b0e7a30e4e..5e25ebd219 100644 --- a/keyboard/gh60/Makefile +++ b/keyboard/gh60/Makefile @@ -120,6 +120,7 @@ CONSOLE_ENABLE = yes # Console for debug(+400) COMMAND_ENABLE = yes # Commands for debug and configuration #SLEEP_LED_ENABLE = yes # Breathing sleep LED during USB suspend NKRO_ENABLE = yes # USB Nkey Rollover +DEBOUNCE_HASU = yes # use default debounce algorithm. # Optimize size but this may cause error "relocation truncated to fit" diff --git a/keyboard/gh60/matrix.c b/keyboard/gh60/matrix.c index 5a56cee010..fef18480a0 100644 --- a/keyboard/gh60/matrix.c +++ b/keyboard/gh60/matrix.c @@ -28,21 +28,14 @@ along with this program. If not, see . #include "matrix.h" -#ifndef DEBOUNCE -# define DEBOUNCE 5 -#endif -static uint8_t debouncing = DEBOUNCE; - /* matrix state(1:on, 0:off) */ static matrix_row_t matrix[MATRIX_ROWS]; -static matrix_row_t matrix_debouncing[MATRIX_ROWS]; static matrix_row_t read_cols(void); static void init_cols(void); static void unselect_rows(void); static void select_row(uint8_t row); - void matrix_init(void) { // initialize row and col @@ -52,7 +45,6 @@ void matrix_init(void) // initialize matrix state: all keys off for (uint8_t i=0; i < MATRIX_ROWS; i++) { matrix[i] = 0; - matrix_debouncing[i] = 0; } } @@ -61,27 +53,9 @@ uint8_t matrix_scan(void) for (uint8_t i = 0; i < MATRIX_ROWS; i++) { select_row(i); _delay_us(30); // without this wait read unstable value. - matrix_row_t cols = read_cols(); - if (matrix_debouncing[i] != cols) { - matrix_debouncing[i] = cols; - if (debouncing) { - debug("bounce!: "); debug_hex(debouncing); debug("\n"); - } - debouncing = DEBOUNCE; - } + matrix[i] = read_cols(); unselect_rows(); } - - if (debouncing) { - if (--debouncing) { - _delay_ms(1); - } else { - for (uint8_t i = 0; i < MATRIX_ROWS; i++) { - matrix[i] = matrix_debouncing[i]; - } - } - } - return 1; } diff --git a/tmk_core/common.mk b/tmk_core/common.mk index 1e2c0a2168..040219583d 100644 --- a/tmk_core/common.mk +++ b/tmk_core/common.mk @@ -1,4 +1,6 @@ COMMON_DIR = common +DEBOUNCE = $(COMMON_DIR)/debounce + SRC += $(COMMON_DIR)/host.c \ $(COMMON_DIR)/debounce.c \ $(COMMON_DIR)/keyboard.c \ @@ -19,6 +21,12 @@ SRC += $(COMMON_DIR)/host.c \ # Option modules + +# Debounce - if it's implemented in matrix.c, choose debounce_none +ifeq (yes,$(strip $(DEBOUNCE_HASU))) + SRC += $(DEBOUNCE)/debounce_hasu.c +endif + ifeq (yes,$(strip $(UNIMAP_ENABLE))) SRC += $(COMMON_DIR)/unimap.c OPT_DEFS += -DUNIMAP_ENABLE @@ -95,6 +103,7 @@ ifeq (yes,$(strip $(KEYMAP_SECTION_ENABLE))) endif endif + # Version string VERSION := $(shell (git describe --always --dirty || echo 'unknown') 2> /dev/null) OPT_DEFS += -DVERSION=$(VERSION) diff --git a/tmk_core/common/debounce/debounce_hasu.c b/tmk_core/common/debounce/debounce_hasu.c new file mode 100644 index 0000000000..9f9ad80f3f --- /dev/null +++ b/tmk_core/common/debounce/debounce_hasu.c @@ -0,0 +1,41 @@ +/* +Basic global debounce algorithm. +When no state changes have occured for DEBOUNCE milliseconds, we push the state. +*/ + +#include "debounce.h" +#include "matrix.h" +#include "timer.h" + +#ifndef DEBOUNCE +#define DEBOUNCE 5 +#endif + +//Default implementation - no debouncing +static matrix_row_t matrix_debounced[MATRIX_ROWS]; +static bool debouncing = false; +static uint16_t debouncing_time; + +void matrix_debounce(void) { + for (uint8_t r = 0; r < MATRIX_ROWS; r++) + { + matrix_row_t raw = matrix_get_row(r); + if (raw != matrix_debounced[r]) + { + debouncing = true; + debouncing_time = timer_read(); + } + } + + if (debouncing && timer_elapsed(debouncing_time) > DEBOUNCE) { + for (int i = 0; i < MATRIX_ROWS; i++) { + matrix_debounced[i] = matrix_get_row(i); + } + debouncing = false; + } +} + +matrix_row_t matrix_debounce_get_row(uint8_t row) +{ + return matrix_debounced[row]; +} From f9029b0cbb48b19bb9c791c5cddcea1e9b227452 Mon Sep 17 00:00:00 2001 From: alex-ong Date: Fri, 26 Jan 2018 22:09:19 +1100 Subject: [PATCH 5/7] debounce_hasu algorithm for alps64 --- keyboard/alps64/Makefile | 1 + keyboard/alps64/matrix.c | 26 +------------------------- 2 files changed, 2 insertions(+), 25 deletions(-) diff --git a/keyboard/alps64/Makefile b/keyboard/alps64/Makefile index d9968f7c79..b40178078c 100644 --- a/keyboard/alps64/Makefile +++ b/keyboard/alps64/Makefile @@ -72,6 +72,7 @@ MOUSEKEY_ENABLE ?= yes # Mouse keys(+4700) EXTRAKEY_ENABLE ?= yes # Audio control and System control(+450) CONSOLE_ENABLE ?= yes # Console for debug(+400) COMMAND_ENABLE ?= yes # Commands for debug and configuration +DEBOUNCE_HASU ?= yes # Default debounce algorithm #SLEEP_LED_ENABLE ?= yes # Breathing sleep LED during USB suspend #NKRO_ENABLE ?= yes # USB Nkey Rollover #ACTIONMAP_ENABLE ?= yes # Use 16bit action codes in keymap instead of 8bit keycodes diff --git a/keyboard/alps64/matrix.c b/keyboard/alps64/matrix.c index 109bcf2cdd..2de58ceca9 100644 --- a/keyboard/alps64/matrix.c +++ b/keyboard/alps64/matrix.c @@ -28,14 +28,8 @@ along with this program. If not, see . #include "matrix.h" -#ifndef DEBOUNCE -# define DEBOUNCE 5 -#endif -static uint8_t debouncing = DEBOUNCE; - /* matrix state(1:on, 0:off) */ static matrix_row_t matrix[MATRIX_ROWS]; -static matrix_row_t matrix_debouncing[MATRIX_ROWS]; static matrix_row_t read_cols(void); static void init_cols(void); @@ -56,7 +50,6 @@ void matrix_init(void) // initialize matrix state: all keys off for (uint8_t i=0; i < MATRIX_ROWS; i++) { matrix[i] = 0; - matrix_debouncing[i] = 0; } //debug @@ -71,27 +64,10 @@ uint8_t matrix_scan(void) for (uint8_t i = 0; i < MATRIX_ROWS; i++) { select_row(i); _delay_us(30); // without this wait read unstable value. - matrix_row_t cols = read_cols(); - if (matrix_debouncing[i] != cols) { - matrix_debouncing[i] = cols; - if (debouncing) { - debug("bounce!: "); debug_hex(debouncing); debug("\n"); - } - debouncing = DEBOUNCE; - } + matrix[i] = read_cols(); unselect_rows(); } - if (debouncing) { - if (--debouncing) { - _delay_ms(1); - } else { - for (uint8_t i = 0; i < MATRIX_ROWS; i++) { - matrix[i] = matrix_debouncing[i]; - } - } - } - return 1; } From 3cce34c5c80488e3fb01e37b08e5509f8d1f6af9 Mon Sep 17 00:00:00 2001 From: alex-ong Date: Fri, 26 Jan 2018 22:16:27 +1100 Subject: [PATCH 6/7] hbkb: debounce_hasu algorithm. Moved DEBOUNCE def to config.h. Renamed Makefile.lufa to Makefile. --- keyboard/fc660c/Makefile | 1 + keyboard/hbkb/{Makefile.lufa => Makefile} | 2 +- keyboard/hbkb/config.h | 2 +- keyboard/hbkb/matrix.c | 25 +---------------------- 4 files changed, 4 insertions(+), 26 deletions(-) rename keyboard/hbkb/{Makefile.lufa => Makefile} (98%) diff --git a/keyboard/fc660c/Makefile b/keyboard/fc660c/Makefile index 5fb62fbd2e..b53714fbc6 100644 --- a/keyboard/fc660c/Makefile +++ b/keyboard/fc660c/Makefile @@ -73,6 +73,7 @@ EXTRAKEY_ENABLE ?= yes # Audio control and System control CONSOLE_ENABLE ?= yes # Console for debug COMMAND_ENABLE ?= yes # Commands for debug and configuration NKRO_ENABLE ?= yes # USB Nkey Rollover +DEBOUNCE_HASU ?= yes # Default debounce algorithm #ACTIONMAP_ENABLE ?= yes # Use 16bit actionmap instead of 8bit keymap UNIMAP_ENABLE ?= yes # Universal keymap KEYMAP_SECTION_ENABLE ?= yes # fixed address keymap for keymap editor diff --git a/keyboard/hbkb/Makefile.lufa b/keyboard/hbkb/Makefile similarity index 98% rename from keyboard/hbkb/Makefile.lufa rename to keyboard/hbkb/Makefile index 322f219d69..4293548d3c 100644 --- a/keyboard/hbkb/Makefile.lufa +++ b/keyboard/hbkb/Makefile @@ -102,7 +102,7 @@ MOUSEKEY_ENABLE = yes # Mouse keys EXTRAKEY_ENABLE = yes # Audio control and System control CONSOLE_ENABLE = yes # Console for debug COMMAND_ENABLE = yes # Commands for debug and configuration - +DEBOUNCE_HASU = yes # default debounce algorithm # Boot Section Size in bytes # Teensy halfKay 512 diff --git a/keyboard/hbkb/config.h b/keyboard/hbkb/config.h index fef8c05ed3..b5e3c370a8 100644 --- a/keyboard/hbkb/config.h +++ b/keyboard/hbkb/config.h @@ -35,7 +35,7 @@ along with this program. If not, see . #define MATRIX_HAS_GHOST /* Set 0 if need no debouncing */ -#define DEBOUNCE 5 +#define DEBOUNCE 10 /* legacy keymap support */ #define USE_LEGACY_KEYMAP diff --git a/keyboard/hbkb/matrix.c b/keyboard/hbkb/matrix.c index 86c18b4b2a..45005d8601 100644 --- a/keyboard/hbkb/matrix.c +++ b/keyboard/hbkb/matrix.c @@ -32,14 +32,9 @@ along with this program. If not, see . * COL: PD0-7 * ROW: PB0-7, PF4-7 */ -#ifndef DEBOUNCE -# define DEBOUNCE 10 -#endif -static uint8_t debouncing = DEBOUNCE; /* matrix state(1:on, 0:off) */ static matrix_row_t matrix[MATRIX_ROWS]; -static matrix_row_t matrix_debouncing[MATRIX_ROWS]; static matrix_row_t read_cols(void); static void unselect_rows(void); @@ -62,7 +57,6 @@ void matrix_init(void) // initialize matrix state: all keys off for (uint8_t i=0; i < MATRIX_ROWS; i++) { matrix[i] = 0; - matrix_debouncing[i] = 0; } } @@ -71,27 +65,10 @@ uint8_t matrix_scan(void) for (uint8_t i = 0; i < MATRIX_ROWS; i++) { select_row(i); _delay_us(30); // without this wait read unstable value. - matrix_row_t cols = read_cols(); - if (matrix_debouncing[i] != cols) { - matrix_debouncing[i] = cols; - if (debouncing) { - debug("bounce!: "); debug_hex(debouncing); debug("\n"); - } - debouncing = DEBOUNCE; - } + matrix[i] = read_cols(); unselect_rows(); } - if (debouncing) { - if (--debouncing) { - _delay_ms(1); - } else { - for (uint8_t i = 0; i < MATRIX_ROWS; i++) { - matrix[i] = matrix_debouncing[i]; - } - } - } - return 1; } From b3f9031df7c232ebb51bf8d1b6aa890e82c0995e Mon Sep 17 00:00:00 2001 From: alex-ong Date: Fri, 26 Jan 2018 22:27:48 +1100 Subject: [PATCH 7/7] gh60: debounce_hasu if building with pjrc --- keyboard/gh60/Makefile.pjrc | 1 + 1 file changed, 1 insertion(+) diff --git a/keyboard/gh60/Makefile.pjrc b/keyboard/gh60/Makefile.pjrc index 11bd3b7840..3817b1ec2e 100644 --- a/keyboard/gh60/Makefile.pjrc +++ b/keyboard/gh60/Makefile.pjrc @@ -92,6 +92,7 @@ CONSOLE_ENABLE = yes # Console for debug COMMAND_ENABLE = yes # Commands for debug and configuration SLEEP_LED_ENABLE = yes # Breathing sleep LED during USB suspend NKRO_ENABLE = yes # USB Nkey Rollover(+500) +DEBOUNCE_HASU = yes # Default debounce algorithm #PS2_MOUSE_ENABLE = yes # PS/2 mouse(TrackPoint) support