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; } 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/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/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 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/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; } diff --git a/tmk_core/common.mk b/tmk_core/common.mk index 14951ec851..040219583d 100644 --- a/tmk_core/common.mk +++ b/tmk_core/common.mk @@ -1,5 +1,8 @@ COMMON_DIR = common +DEBOUNCE = $(COMMON_DIR)/debounce + SRC += $(COMMON_DIR)/host.c \ + $(COMMON_DIR)/debounce.c \ $(COMMON_DIR)/keyboard.c \ $(COMMON_DIR)/matrix.c \ $(COMMON_DIR)/action.c \ @@ -18,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 @@ -94,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.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/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]; +} diff --git a/tmk_core/common/keyboard.c b/tmk_core/common/keyboard.c index 929b862af3..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" @@ -60,6 +61,19 @@ static bool has_ghost_in_row(uint8_t row) } return false; } + +//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 = has_ghost_in_row(row); + if (debug_matrix && result && matrix_ghost[row] != matrix_row) + { + matrix_print(); + } + matrix_ghost[row] = matrix_row; + return result; +} #endif @@ -93,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]; @@ -107,23 +122,14 @@ 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) { + 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;