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;